本人手头的板子是Esp32,因为工作需要要把板子与手机连线,通过手机Otg功能进行串口通信,开发了一个简单的串口通信助手,现在记录下:
driver library配置
这里为了方便直接用lib。用到的是usb-serial-for-android
1.在project的build.gradle里添加:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
2.在app/module的build.gradle里添加:
dependencies {
implementation 'com.github.mik3y:usb-serial-for-android:3.4.0'
}
3.Sync project
4.在AndroidManifest.xml添加:
<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>
其中,在res目录下新建xml目录,添加device_filter.xml文件,实例如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 0x0403 / 0x60??: FTDI -->
<usb-device vendor-id="1027" product-id="24577" /> <!-- 0x6001: FT232R -->
<usb-device vendor-id="1027" product-id="24592" /> <!-- 0x6010: FT2232H -->
<usb-device vendor-id="1027" product-id="24593" /> <!-- 0x6011: FT4232H -->
<usb-device vendor-id="1027" product-id="24596" /> <!-- 0x6014: FT232H -->
<usb-device vendor-id="1027" product-id="24597" /> <!-- 0x6015: FT230X, FT231X, FT234XD -->
<!-- 0x10C4 / 0xEA??: Silabs CP210x -->
<usb-device vendor-id="4292" product-id="60000" /> <!-- 0xea60: CP2102 and other CP210x single port devices -->
<usb-device vendor-id="4292" product-id="60016" /> <!-- 0xea70: CP2105 -->
<usb-device vendor-id="4292" product-id="60017" /> <!-- 0xea71: CP2108 -->
<!-- 0x067B / 0x23?3: Prolific PL2303x -->
<usb-device vendor-id="1659" product-id="8963" /> <!-- 0x2303: PL2303HX, HXD, TA, ... -->
<usb-device vendor-id="1659" product-id="9123" /> <!-- 0x23a3: PL2303GC -->
<usb-device vendor-id="1659" product-id="9139" /> <!-- 0x23b3: PL2303GB -->
<usb-device vendor-id="1659" product-id="9155" /> <!-- 0x23c3: PL2303GT -->
<usb-device vendor-id="1659" product-id="9171" /> <!-- 0x23d3: PL2303GL -->
<usb-device vendor-id="1659" product-id="9187" /> <!-- 0x23e3: PL2303GE -->
<usb-device vendor-id="1659" product-id="9203" /> <!-- 0x23f3: PL2303GS -->
<!-- 0x1a86 / 0x?523: Qinheng CH34x -->
<usb-device vendor-id="6790" product-id="21795" /> <!-- 0x5523: CH341A -->
<usb-device vendor-id="6790" product-id="29987" /> <!-- 0x7523: CH340 -->
<!-- CDC driver -->
<usb-device vendor-id="9025" /> <!-- 0x2341 / ......: Arduino -->
<usb-device vendor-id="5824" product-id="1155" /> <!-- 0x16C0 / 0x0483: Teensyduino -->
<usb-device vendor-id="1003" product-id="8260" /> <!-- 0x03EB / 0x2044: Atmel Lufa -->
<usb-device vendor-id="7855" product-id="4" /> <!-- 0x1eaf / 0x0004: Leaflabs Maple -->
<usb-device vendor-id="3368" product-id="516" /> <!-- 0x0d28 / 0x0204: ARM mbed -->
<usb-device vendor-id="1155" product-id="22336" /><!-- 0x0483 / 0x5740: ST CDC -->
</resources>
注: 这里的vendor-id和product-id每个设备都不一样,电脑上连接设备后通过设备管理器-端口-右键属性-详细信息-选择硬件id查看对应的vendor-id和product-id后,按照格式后进行添加。
连接并监听端口
需要先允许应用权限:
// Find all available drivers from attached devices.
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
if (availableDrivers.isEmpty()) {
return;
}
// Open a connection to the first available driver.
UsbSerialDriver driver = availableDrivers.get(0);
UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
if (connection == null) {
// add UsbManager.requestPermission(driver.getDevice(), ..) handling here
Toast.makeText(this, "Permission Error", Toast.LENGTH_SHORT).show();
return;
}
port = driver.getPorts().get(0); // Most devices have just one port (port 0)
try {
port.open(connection);
} catch (IOException e) {
e.printStackTrace();
}
try {
//这里设置
port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
} catch (IOException e) {
e.printStackTrace();
}
if(port.isOpen()){
//progressBar.setVisibility(View.VISIBLE);
//output("Set port Success!");
mSerialIoManager = new SerialInputOutputManager(port, mListener);//添加监听
mSerialIoManager.start();//开始
}
这里我是连上后就立刻开始监听,Listener设置如下:
private final SerialInputOutputManager.Listener mListener =
new SerialInputOutputManager.Listener() {
@Override
public void onRunError(Exception e) {
Log.d("TAG", "Runner stopped.");
}
@Override
public void onNewData(final byte[] data) {
//TODO 新的数据
runOnUiThread(()->{output(new String(data));});
//这里每次听到数据都直接打印出结果
}
};
发送数据
try {
//这里1000可以设置为0,表示一直等到数据发送成功
port.write(strSend.getBytes(),1000);
Toast.makeText(this, "Write Successful", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
关闭连接
try {
port.close();
} catch (IOException e) {
e.printStackTrace();
}
if(!port.isOpen()){
//output("Close Port!");
//progressBar.setVisibility(View.INVISIBLE);
}
这样就实现了一个简单的串口通信app,后续还需要针对需求进行修改。