情景
一般硬件设备提供的内置串口数量是有限的,当串口不够用时,就需要通过USB来外接这些设备
CH341是一种芯片,它可以将以串口方式进行通信的设备,转接到USB口上进行通信
使用该方案,需要购买对应的CH341转换器,将串口设备转接到USB口上,转换器支持一个USB口接多个串口设备
准备
引入CH34XMultiUARTDriver.jar
这是一个串口转USB的驱动,支持CH341等型号的芯片
核心代码
//连接CH34X设备
CH34X.connect();
CH34X.read();
//定期读取CH34X设备参数
CH34xHandler.read();
WorkThread.postByLoop(CH34xHandler::write);
package com.android.driver.ch34x;
import android.app.PendingIntent;
import android.content.Intent;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Looper;
import com.easing.commons.android.app.CommonApplication;
import com.easing.commons.android.bin.Bytes;
import com.easing.commons.android.code.Console;
import com.easing.commons.android.helper.exception.BizException;
import com.easing.commons.android.thread.Threads;
import com.easing.commons.android.thread.WorkThread;
import java.util.ArrayList;
import java.util.List;
import cn.wch.lib.ch34xMultiDriver;
import cn.wch.lib.ch34xMultiManager;
@SuppressWarnings("all")
public class CH34X {
protected static UsbManager service;
protected static ch34xMultiManager manager;
protected static List<UsbDevice> deviceList;
protected static final List<Reader> readers = new ArrayList();
protected static boolean connected = false;
//判断设备是否连接
public static boolean connected() {
return connected;
}
//检查权限
public static boolean checkPermission() {
boolean hasPermission = true;
for (UsbDevice device : deviceList) {
boolean ret = service.hasPermission(device);
if (!ret)
hasPermission = false;
}
Console.info("CH34X Permission Check : " + hasPermission);
return hasPermission;
}
//检测并连接设备
public static void connect() {
service = CommonApplication.ctx.getSystemService(UsbManager.class);
manager = new ch34xMultiManager(CommonApplication.ctx, service);
WorkThread.postByLoop("#CH34X连接线程", () -> {
try {
if (connected)
return;
if (Looper.myLooper() == null)
Looper.prepare();
//搜索设备
manager.initDeviceList();
deviceList = manager.usbDeviceList;
Console.info("CH34X Find Device : " + deviceList.size());
//检查并申请权限
if (!checkPermission()) {
for (UsbDevice device : deviceList) {
Intent intent = new Intent("cn.wch.USB_PERMISSION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(CommonApplication.ctx, 0, intent, 0);
service.requestPermission(device, pendingIntent);
}
}
//打开设备
boolean isDeviceOpen = true;
for (UsbDevice device : deviceList) {
boolean ret = manager.OpenUsbDevice(device);
if (!ret)
isDeviceOpen = false;
}
Console.info("CH34X Open Device : " + isDeviceOpen);
//连接失败
if (!isDeviceOpen)
throw BizException.of("CH34X Connect Fail");
//连接成功
connected = true;
Console.info("CH34X Connect Success");
//配置设备
boolean isDeviceConfigured = true;
int index = 0;
for (UsbDevice device : deviceList) {
ch34xMultiDriver driver = manager.ch34xDriverList.get(index);
index++;
boolean ret = driver.SetConfig(9600, (byte) 1, (byte) 8, (byte) 0, (byte) 0);
if (!ret)
isDeviceConfigured = false;
}
Console.info("CH34X Configure Device : " + isDeviceConfigured);
} catch (Throwable e) {
manager.CloseAll();
Console.error("CH34X Connect Fail");
}
Threads.sleep(3 * 1000L);
});
}
//读数据
public static void read() {
WorkThread.post(() -> {
final byte[] buffer = new byte[10 * 1024];
while (true) {
if (!connected)
continue;
try {
int index = 0;
for (UsbDevice device : deviceList) {
ch34xMultiDriver driver = manager.ch34xDriverList.get(index);
manager.SemDeviceList.acquire();
int length = driver.ReadData(buffer, 10 * 1024);
manager.SemDeviceList.release();
if (length > 0) {
byte[] newBytes = Bytes.copy(buffer, 0, length);
onMessageRead(index, newBytes);
}
index++;
}
Threads.sleep(500);
} catch (Throwable e) {
Console.error("CH34X Read Fail");
}
}
});
}
//数据读取成功
public static void onMessageRead(int deviceIndex, byte[] bytes) {
String hex = Bytes.byteArrayToHex(bytes);
Console.info("CH34X Read", "Device-" + deviceIndex, hex);
for (Reader reader : readers)
reader.onMessageRead(deviceIndex, bytes);
}
//写数据
public static void write(Integer deviceIndex, byte[] bytes) {
if (!connected)
return;
if (deviceIndex == null)
deviceIndex = 0;
try {
int index = 0;
for (UsbDevice device : deviceList) {
if (index != deviceIndex)
continue;
ch34xMultiDriver driver = manager.ch34xDriverList.get(index);
manager.SemDeviceList.acquire();
int ret = driver.WriteData(bytes, bytes.length);
manager.SemDeviceList.release();
String hex = Bytes.byteArrayToHex(bytes);
Console.info("CH34X Write", "Device-" + deviceIndex, hex);
index++;
}
} catch (Throwable e) {
Console.error("CH34X Write Fail");
}
}
//添加读取回调
public static void addReader(Reader reader) {
readers.add(reader);
}
//移除读取回调
public static void removeReader(Reader reader) {
readers.remove(reader);
}
}
源码下载
版权声明:本文为CSDN博主「命运之手」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013718730/article/details/122879641
暂无评论