更新记录

1.0.8(2024-06-26)

  • 修改sendBytes函数内部逻辑,使用该函数发送数据时若没有控制符\n或者\r,则自动拼接\n,否则不处理
  • 修复同时连接多个设备时,只能打开第一个的问题

1.0.7(2024-06-25)

  • 修复由于上次缓冲区数据引起的数据错误问题

1.0.6(2024-06-25)

  • 添加类型导出,有需要可从interface.uts中导入
  • 新增设备属性vendorId(供应商id)
  • 新增getMaxPacketSize函数,用于获取usb每次传输最大数据量(字节)
  • 修改类型ReturnFormatDataType,其中STRING修改为ASCII
  • 修改read实现逻辑
  • 修复消息订阅函数subscribe传输大量数据时,数据丢失问题
查看更多

平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.99,Android:4.4w,iOS:不支持 × × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序
× × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × × × × × × × ×

usb-serial

UTS开发文档

UTS 语法 UTS API插件 UTS 组件插件 Hello UTS


插件说明

本插件参考于usb-serial-for-android项目

usb转串口支持如下USB转串口转换芯片:

  • FTDI FT232R, FT232H, FT2232H, FT4232H, FT230X, FT231X, FT234XD
  • Prolific PL2303
  • Silabs CP2102, CP210*
  • Qinheng CH340, CH341A, CH9102

更多信息参考usb-serial-for-android


已实现功能

  • [x] 获取设备列表
  • [x] 打开指定设备
  • [x] 设置参数
  • [x] 读取数据
  • [x] 监听数据
  • [x] 写入数据
  • [x] 插入设备提示、唤起app
  • [ ] 流控
  • [ ] ...

使用方法

1、导入插件,打包自定义基座

2、引入插件 —— UsbSerial

import { UsbSerial } from '@/uni_modules/shmily-usb-serial';

3、初始化实例

const usbSerial = new UsbSerial();

4、查询设备

const list = usbSerial.getDeviceList();

示例如下:

[
    {
        "productName": "USB Serial",
        "deviceId": 1008,
        "deviceName": "/dev/bus/usb/001/008",
        "productId": 29987,
        "protocol": 0
    },
    {
        "productName": "ILITEK-TP",
        "deviceId": 2005,
        "deviceName": "/dev/bus/usb/002/005",
        "productId": 1,
        "protocol": 0
    },
    {
        "productName": "802.11ac NIC",
        "deviceId": 2004,
        "deviceName": "/dev/bus/usb/002/004",
        "productId": 51217,
        "protocol": 0
    }
]

5、打开设备并设置参数

// 外层别忘了加async,或者使用.then
const success = await usbSerial.connect({
    productName: 'USB Serial', // 产品名称,请填写实际值,若没有,则传空''
    productId: 29987, // 产品id,请填写实际值
    baudRate: 115200, // 波特率,请填写实际值
    dataBits: 8, // 数据位,请填写实际值
    stopBits: 1, // 停止位,请填写实际值
    parity: 0,   // 校验位,请填写实际值
});
//  根据success判断是否打开成功,失败的情况有可能设备不存在或者出错了

6、读取数据(不建议,优先使用消息订阅

// HEX 或者 ASCII 是固定写法,不要改成其他值
const { content, success } = usbSerial.read('HEX');
// content: 32 2E 33 39 0D 0A 

or

const { content, success } = usbSerial.read('ASCII');
// content: 2.38\r\n

// 根据success判断是否读取成功,content是读取到的数据
// 如果读取失败,content返回的是原因,比如:Serial port is not connected

7、发送数据

// 字节数组格式
// 如果设备指定是0D(\r)结束,请手动拼接,默认是0A(\n)
// usbSerial.sendBytes('hello world\r');
usbSerial.sendBytes('hello world'); // 等同于usbSerial.sendBytes('hello world\n')
// 16进制格式
usbSerial.sendHex('5A 04 01 5F');

8、订阅、取消订阅消息(回调建议使用节流函数包装下)(推荐

// 订阅
usbSerial.subscribe({
  dataType: 'HEX',
  bufferSize: 64 // 如果出现丢失数据的情况,可以适当调整下大小
}, (data) => {});

or

usbSerial.subscribe({
  dataType: 'ASCII',
  bufferSize: 64
}, (data) => {});
// data是监听到的数据,格式同read
// 取消订阅
usbSerial.unsubscribe();

9、订阅、取消订阅设备

// 订阅
usbSerial.registerUsbAttach((action) => {
// action: true表示设备插入   false表示设备移除
});
// 取消订阅
usbSerial.unregisterUsbAttach();

10、关闭连接

// 外层别忘了加async,或者使用.then
const success = await usbSerial.disconnect();
// 根据success判断是否关闭成功

11、持续授权(如果没有这样的需求,不要设置

第一步:项目根目录下创建AndroidManifest.xml文件,写入以下内容:

  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    package="app包名">
    <application>
      <activity android:name="io.dcloud.PandoraEntry">
        <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>
    </application>
  </manifest>

app包名替换成你app实际的Android包名, 包名可以在打包页面查看。

第二步:将示例工程根目录下面的nativeResources目录复制到你的项目根目录下,确保 nativeResources/res/xml/device_filter.xml 存在,至此配置完成,重新打包自定义基座后生效。

在第一次打开设备授权时勾选 "[√]连接xxx后一律打开xxx" 即可实现持续授权,app重启或者USB设备重新插拔也不需要申请权限。但是如果系统重启了,需要重新授权!!!

注意:配置持续授权后,设备插入时会自动唤起app,如果app处于后台,会自动切换到前台。如果app未启动,会自动打开app。

12、多设备通信

如果需要同时读写多个设备,只需创建多个实例即可:

如果多个设备的productName和productId一致,暂时不能区分设备

// 实例1,和设备a通信
const usbSerial1 = new UsbSerial();
await usbSerial1.connect({
  // ...
  // 填写参数1
});
// 实例2。和设备b通信
const usbSerial2 = new UsbSerial();
await usbSerial2.connect({
  // ...
  // 填写参数2
});

其他的操作参考前面的步骤,注意使用对应的实例就行了。


提供的其他方法

// 设备是否已打开
const isConnect = usbSerial.isConnect();
// true or false
// 获取USB每次传输最大数据量
const size = usbSerial.getMaxPacketSize();

类型参考

/**
 * @param deviceName 设备名称
 * @param deviceId 设备id
 * @param protocol 协议编号
 * @param vendorId 供应商id
 * @param productId 产品id
 * @param productName 产品名称
 */
type IDeviceItem = {
  deviceName : string,
  deviceId : number,
  protocol : number,
  vendorId : number,
  productId : number,
  productName ?: string
}

/**
 * @param productName 产品名称
 * @param productId 产品
 * @param baudRate 波特率
 * @param dataBits 数据位
 * @param stopBits 停止位
 * @param parity 校验位
 */
type IConnectOptions = {
  productName : string,
  productId : number,
  baudRate : number,
  dataBits : number,
  stopBits : number,
  parity : number,
}

/**
 * @param content 读取数据
 * @param success 操作是否成功
 */
type IUsbData = {
  content : string | null,
  success : boolean
}

/**
 * 数据类型:16进制或者ASCII字符
 */
type IDataType = 'HEX' | 'ASCII';

隐私、权限声明

1. 本插件需要申请的系统权限列表:

USB读写权限

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问