【Android智能硬件开发】【011】安卓串口转USB

情景

一般硬件设备提供的内置串口数量是有限的,当串口不够用时,就需要通过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);
	    }
	}

源码下载

Android CH34X串口转USB.zip

版权声明:本文为CSDN博主「命运之手」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013718730/article/details/122879641

命运之手

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

基于STM32F103的智能门锁系统

基于STM32F103的智能门锁系统 直接说明实现了什么效果 1 指纹解锁(基于AS608) 2 RFID解锁(基于RC522) 3 密码解锁 (基于LCD电容屏触摸控制) 4 蓝牙解锁

ESP32 LVGL8.1 实现太空人显示

注:本博客作为学习笔记,有错误的地方希望指正 一、ESP32 LVGL工程配置 首先要通过液晶屏显示太空人,我们这里主要有两种方式可以实现,第一种直接使用厂家只带的液晶屏幕驱动去实现图