Android——USB to COM port (CH340) to communicate with the sensor

I use the environment

  • CH340 adapter
  • Android5.1,RK3188
  • Android6.0,RK3288

About CH34 official jar package and the use of problems (official address)

  • The biggest problem is that I can’t modify the serial port baud rate. It has always been running at 19200, but my sensor is 9600. It should be possible to modify it in theory, but even the official APK cannot be modified. I had to find him to post it.

Final solution

initialization

  • Add in your build.gradle (project)
allprojects {
    
    
    repositories {
    
    
        ...
        maven {
    
     url 'https://jitpack.io' }
    }
}
  • Add dependency
dependencies {
    
    
    implementation 'com.github.mik3y:usb-serial-for-android:2.2.2'
}
  • Add permissions
<uses-feature android:name="android.hardware.usb.host" />
  • In res/xml/add under device_filter.xml , within the project Demo CH340 official website also, this step is equivalent to a list of resources to add a filter used, if the demand is not recognized (such as inserting automatically acquire rights, etc.) can not be added.
<resource>
	<usb-device product-id="29987" vendor-id="6790" />
	<usb-device product-id="21795" vendor-id="6790" />
	<usb-device product-id="21778" vendor-id="6790" />
	
	//补充
	<usb-device vendor-id="1024" product-id="50010"/>
	<usb-device vendor-id="1024" product-id="24577"/>
	<usb-device vendor-id="6790" product-id="29987"/>
	<usb-device vendor-id="1027" product-id="24577"/>
</resource>
  • If you want to get permission after the device is plugged in, you need AndroidManifestto complete the following code in
<activity
    android:name="..."
    ...>
    <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    </intent-filter>
    <meta-data
        android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/device_filter" />
</activity>

Introduction

  • Get UsbManager
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
  • Get device port
//获取所有端口-->usbSerialPorts
List<UsbSerialDriver> usbSerialDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
List<UsbSerialPort> usbSerialPorts = new ArrayList<>();
for (UsbSerialDriver driver : usbSerialDrivers) {
    
    
    usbSerialPorts.addAll(driver.getPorts());
}
//扫描所有端口,找到自己需要的端口-->usbPort 
for (UsbSerialPort port : usbSerialPorts) {
    
    
    UsbDevice device = port.getDriver().getDevice();
    //ID值自行参考自己设备
    if (device.getVendorId() == USB_VENDOR_ID && device.getProductId() == USB_PRODUCT_ID) {
    
    
        usbPort = port;
    }
}
  • Check permissions and open ports
if (usbManager.hasPermission(device)) {
    
    
    //有权限,开启端口
    UsbDeviceConnection connection = usbManager.openDevice(usbPort.getDriver().getDevice());
    if (connection == null) {
    
    
        Log.d(TAG, "open: connection == null");
        return;
    }
    try {
    
    
        usbPort.open(connection);
        usbPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
    } catch (IOException e) {
    
    
        closePort();
    } catch (RuntimeException e2) {
    
    
        e2.printStackTrace();
    }
} else {
    
    
    //无权限,弹出权限获取窗口并配置广播
    PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(DIALOG_USB_PERMISSION), 0);
    usbManager.requestPermission(device, usbPermissionIntent);
}

Sample, involving broadcast + barrier-free automatic access to USB permissions code

  • Create interface
interface USBReceiver {
    
    
    void receive(String s);
}
  • Create a separate USB service
public class USBReadService extends Service {
    
    
    private final static String TAG = "USBReadService";

    SerialInputOutputManager mSerialIoManager;
    ExecutorService          mExecutor = Executors.newSingleThreadExecutor();

    @Override
    public void onCreate() {
    
    
        super.onCreate();
        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        IntentFilter usbDeviceStateFilter = new IntentFilter();
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        usbDeviceStateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        usbDeviceStateFilter.addAction(DIALOG_USB_PERMISSION);
        registerReceiver(mUsbReceiver, usbDeviceStateFilter);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    
    
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
    
        refreshDevice();
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 刷新获取设备列表
     */
    public void refreshDevice() {
    
    
        //获取所有端口
        List<UsbSerialDriver> usbSerialDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);
        List<UsbSerialPort> usbSerialPorts = new ArrayList<>();
        for (UsbSerialDriver driver : usbSerialDrivers) {
    
    
            usbSerialPorts.addAll(driver.getPorts());
        }
        //扫描所有端口,找到自己需要的端口
        usbPort = null;
        for (UsbSerialPort port : usbSerialPorts) {
    
    
            UsbDevice device = port.getDriver().getDevice();
            if (device.getVendorId() == USB_VENDOR_ID && device.getProductId() == USB_PRODUCT_ID) {
    
    
                usbPort = port;
                //检查权限
                if (usbManager.hasPermission(device)) {
    
    
                    Log.d(TAG, "有权限");
                    open();
                } else {
    
    
                    Log.d(TAG, "没有权限");
                    //弹出权限窗口并配置广播
                    PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(DIALOG_USB_PERMISSION), 0);
                    usbManager.requestPermission(device, usbPermissionIntent);
                }
                break;
            }
        }
    }

    void open() {
    
    
        UsbDeviceConnection connection = usbManager.openDevice(usbPort.getDriver().getDevice());
        if (connection == null) {
    
    
            Log.d(TAG, "open: connection == null");
            return;
        }
        try {
    
    
            usbPort.open(connection);
            usbPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
        } catch (IOException e) {
    
    
            closePort();
        } catch (RuntimeException e2) {
    
    
            e2.printStackTrace();
        }

        onDeviceStateChange();
    }

    BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    
    
        @Override
        public void onReceive(Context context, Intent intent) {
    
    
            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
    
    
                Log.d(TAG, "onReceive: USB插入");
                refreshDevice();
            }
            if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(intent.getAction())) {
    
    
                Log.d(TAG, "onReceive: USB拔出");
                refreshDevice();
            }
            if (DIALOG_USB_PERMISSION.equals(intent.getAction())) {
    
    
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
    
    
                    Log.d(TAG, "onReceive: 用户允许了弹窗的权限");
                    open();
                } else {
    
    
                    Log.d(TAG, "onReceive: 用户取消了弹窗的权限");
                }
            }
        }
    };

    private void stopIoManager() {
    
    
        if (mSerialIoManager != null) {
    
    
            mSerialIoManager.stop();
            mSerialIoManager = null;
        }
    }

    private void startIoManager() {
    
    
        if (usbPort != null) {
    
    
            mSerialIoManager = new SerialInputOutputManager(usbPort, mListener);
            mSerialIoManager.setReadTimeout(20);
            mExecutor.submit(mSerialIoManager);
        }
    }

    private void onDeviceStateChange() {
    
    
        stopIoManager();
        startIoManager();
    }

    private void closePort() {
    
    
        if (usbPort != null) {
    
    
            try {
    
    
                usbPort.close();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
            usbPort = null;
        }
    }

    @Override
    public void onDestroy() {
    
    
        unregisterReceiver(mUsbReceiver);
        closePort();
        stopIoManager();
        mExecutor.shutdown();
        super.onDestroy();
    }
}
  • use
Intent intent = new Intent(this, USBReadService.class);
startService(intent);

/**
 * USB监听
 */
public static SerialInputOutputManager.Listener mListener = new SerialInputOutputManager.Listener() {
    
    
    @Override
    public void onRunError(Exception e) {
    
    
        Log.d(TAG, "Runner stopped.");
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onNewData(byte[] data) {
    
    
     
    }
};

/**
 * USB输出
 *
 * @param data 输出的数据
 */
static void write(byte[] data) {
    
    
    if (usbPort != null) {
    
    
        try {
    
    
            usbPort.write(data, 200);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    } else {
    
    
        Log.d(TAG, "write: usbPort == null");
    }
}
  • other
//Z-TEK
static final int USB_VENDOR_ID  = 1027;     //供应商id
static final int USB_PRODUCT_ID = 24577;    //产品id

static UsbSerialPort   usbPort   = null;
static UsbManager      usbManager;
static ArrayList<Byte> usbBuffer = new ArrayList<>();

public static String DIALOG_USB_PERMISSION = "com.example.ysy200811_1scx.DIALOG_USB_PERMISSION";

Attachment: Automatically obtain USB permissions [ Portal ]

Guess you like

Origin blog.csdn.net/qq_36881363/article/details/104811643