更新记录
1.0.0(2026-10-13) 下载此版本
初始版本
平台兼容性
uni-app(3.96)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | Android插件版本 | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | 7.0 | 1.0.0 | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(5.31)
| Chrome | Safari | Android | Android插件版本 | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|---|
| - | - | 7.0 | 1.0.0 | × | × | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | × | √ |
ep-uts-serial-port
串口通信 UTS 插件,支持 Android / iOS / 鸿蒙 (HarmonyOS) 三端,提供统一的串口读写、设备枚举 API。
核心特性:
- 所有读/写/打开操作均在后台线程执行,不阻塞主线程不会卡死 UI
- 内置端口互斥:同一路径重复构造实例会自动关闭旧端口,避免占用冲突
平台支持
| 平台 | 支持情况 | 底层机制 |
|---|---|---|
| Android | ✅ | UsbManager USB Host API + CDC-ACM 协议 |
| iOS | ✅ | TCP Socket 连接串口服务器(如 USR-TCP232) |
| 鸿蒙 (HarmonyOS) | ✅ | @kit.BasicServicesKit serialManager API |
注意: iOS 不支持直接访问硬件串口,需配合串口服务器使用,
path填写host:port格式。
快速开始
安装
将本插件目录放入项目的 uni_modules/ 下即可,或通过 HBuilderX 插件市场导入。
基本用法
import { SerialPort } from '@/uni_modules/ep-uts-serial-port'
// 1. 枚举可用设备
const devices = SerialPort.getDeviceList()
console.log(devices) // [{ name: "CP210x (10C4:EA60)", path: "/dev/bus/usb/001/003", driver: "CP210x", vid: 4292, pid: 60000 }]
// 2. 创建并打开串口(path 支持 VID:PID 格式或设备名)
const sp = new SerialPort(devices[0]?.path ?? '10C4:EA60', {
baudRate: 9600,
dataBits: 8,
stopBits: 1,
parity: 'none',
timeout: 1000
})
sp.open({
success: () => {
console.log('串口已打开')
// 开始监听数据
sp.onData(data => console.log('收到:', data))
},
fail: e => console.error('打开失败:', e)
})
// 3. 发送数据
sp.send('POWER ON\r\n', {
success: () => console.log('发送成功'),
fail: e => console.error('发送失败:', e)
})
// 4. 发送二进制数据
sp.sendBinary('\x01\x02\xff', {
success: () => console.log('二进制发送成功')
})
// 5. 同步读取指定长度数据
const result = sp.read(1024, 2000) // 读1024字节,2秒超时
// 6. 停止监听 & 关闭
sp.offData() // 停止接收监听
sp.close() // 关闭串口
API 参考
new SerialPort(path, config?)
创建串口实例。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path |
string |
✅ | 设备路径。Android 填 getDeviceList() 返回的 USB 设备名或 VID:PID 格式(如 "10C4:EA60");鸿蒙填设备名如 "ttySAC0";iOS 填 "host:port" |
config |
SerialConfig |
❌ | 串口配置,不传则使用默认值 |
SerialConfig 类型
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
baudRate |
number |
9600 |
波特率 |
dataBits |
number |
8 |
数据位(5/6/7/8) |
stopBits |
number |
1 |
停止位(1/2) |
parity |
string |
"none" |
校验位:"none" / "odd" / "even" / "mark" / "space" |
timeout |
number |
1000 |
读超时,单位毫秒 |
实例方法
open(options?)
打开串口。
sp.open({
success: () => {},
fail: (error: string) => {}
})
onData(callback)
注册数据接收监听,打开后会启动后台读取。
sp.onData((data: string) => {
console.log('收到数据:', data)
})
offData()
取消数据接收监听,停止后台读取。
sp.offData()
send(data, options?)
发送文本数据。
sp.send('AT\r\n', {
success: () => console.log('已发送'),
fail: (e) => console.error(e)
})
sendBinary(binaryString, options?)
发送二进制数据,每个字符的 charCode 作为一个字节。
// 发送字节 0x01 0x02 0xFF
sp.sendBinary('\x01\x02\xff', {
success: () => console.log('已发送'),
fail: (e) => console.error(e)
})
read(length?, timeoutMs?)
同步读取指定长度的数据,返回读取到的字符串。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
length |
number |
1024 |
期望读取的字节数 |
timeoutMs |
number |
1000 |
超时时间(毫秒) |
const data = sp.read(512, 2000)
if (data) {
console.log('读到:', data)
}
close()
关闭串口,释放资源。
sp.close()
isOpen()
返回串口是否已打开。
if (sp.isOpen()) {
sp.send('OK')
}
getConfig()
返回当前串口的实际配置(鸿蒙端实际配置可能与传入参数不同)。
const cfg = sp.getConfig()
console.log(cfg.baudRate, cfg.dataBits)
静态方法
SerialPort.getDeviceList()
获取可用串口设备列表,返回 SerialPortInfo[]。
const list = SerialPort.getDeviceList()
// [{ name: "ttyUSB0", path: "/dev/ttyUSB0", driver: "USB" }]
| 平台 | 行为 |
|---|---|
| Android | 扫描 USB Host 设备,识别 CP210x / CH340 / FTDI / PL2303 / Arduino 等 CDC-ACM 设备 |
| iOS | 返回空数组 [](无直接串口) |
| 鸿蒙 | 调用 serialManager.getPortList() |
SerialPortInfo 类型
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string |
设备展示名称 |
path |
string |
用于 SerialPort 构造函数的路径 |
driver |
string |
驱动类型如 "USB" / "UART" / "CDC-ACM" / "CP210x" / "CH340" |
vid |
number |
USB Vendor ID(仅 Android USB 设备有值) |
pid |
number |
USB Product ID(仅 Android USB 设备有值) |
线程模型
为防止 IO 操作阻塞主线程导致 UI 卡死,各平台读写均在独立线程执行:
| 操作 | Android | iOS | 鸿蒙 |
|---|---|---|---|
open() |
✅ 后台线程 | ✅ NSThread | ✅ 原生异步 |
send() |
✅ 后台线程 | ✅ NSThread | ✅ Promise 异步 |
sendBinary() |
✅ 后台线程 | ✅ NSThread | ✅ Promise 异步 |
onData 回调 |
✅ 守护线程循环读 | ✅ RunLoop 非阻塞 | ✅ setTimeout 轮询 |
read() |
✅ 后台线程 + 等待 | ⚠️ 主线程等待 | ⚠️ 同步阻塞调用 |
read()为同步方法,内部虽然在 Android/iOS 上使用后台线程,但调用方仍需等待返回。如需纯异步获取数据,请使用onData回调方式。
端口互斥
插件内部维护一个全局 openedPorts 注册表。当构造新实例时,如果发现同一路径(如 /dev/ttyUSB0)已有旧实例在使用,会自动关闭旧的再注册新的,避免端口被多个实例抢占导致通信异常。
const sp1 = new SerialPort('/dev/ttyUSB0')
sp1.open()
// 后续另一个地方又创建了同端口实例
const sp2 = new SerialPort('/dev/ttyUSB0') // 自动调用 sp1.close()
sp2.open() // sp1 已被释放,sp2 正常使用
错误码
所有错误通过 SerialError 类抛出,包含 errCode 和 errMsg。
| 错误码 | 说明 |
|---|---|
9011001 |
串口未打开,请先调用 open() |
9011002 |
串口已被占用 |
9011003 |
串口设备不存在或无法访问 |
9011004 |
权限不足,无法访问串口 |
9011005 |
串口配置参数无效 |
9011006 |
数据读取超时 |
9011007 |
数据写入失败 |
9011008 |
串口通信异常 |
9011009 |
操作被中断 |
各平台注意事项
Android
- 基于 Android USB Host API(
UsbManager),无需 Root 权限 - 首次打开设备时系统会弹出 USB 权限授权对话框,用户同意后即可通信
- 使用 CDC-ACM 协议(USB Communications Device Class),兼容主流串口芯片: CP210x (Silicon Labs)、CH340 (QinHeng)、FTDI、PL2303 (Prolific)、Arduino、STM32 等
open()成功后自动通过 CDC-ACMSET_LINE_CODING控制传输配置波特率/数据位/停止位/校验位send/sendBinary/open均在独立Thread中执行,不阻塞主线程onData在守护线程中通过bulkTransfer循环读取,不消耗主线程资源read()内部起线程执行 IO,等待返回时用 5ms 间隔轮询- 需要在
AndroidManifest.xml中声明android.hardware.usb.hostfeature
iOS
- 不支持直接访问硬件串口,
path需填写串口服务器的"host:port"格式 - 常见串口服务器:USR-TCP232、有人 USR-W610 等
- 底层使用
CFStream创建 TCP Socket 连接 - 波特率等参数需在串口服务器端配置,本插件仅透传
send/sendBinary/open使用NSThread.detachNewThreadSelector异步执行- 数据接收基于 RunLoop 的 Stream 事件循环,运行在独立线程上
read()在主线程等待底层流数据,建议优先使用onData异步回调
鸿蒙 (HarmonyOS)
- 最低系统版本 HarmonyOS 5.1 / API 19
- 依赖
@kit.BasicServicesKit的serialManager模块 - 打开串口时自动检查并请求权限(
requestSerialRight) open()/send()/sendBinary()均为原生异步 API,不阻塞主线程- 后台读取采用
setTimeout轮询方式,10ms 间隔,非阻塞 read()调用readSync为同步阻塞,建议仅在可接受阻塞的场景使用- 支持 21 种波特率(50 ~ 1152000)
open()成功后getConfig()返回硬件实际参数
综合示例
import { SerialPort } from '@/uni_modules/ep-uts-serial-port'
// Android 路径示例:getDeviceList() 返回的 USB 设备名
// const devices = SerialPort.getDeviceList()
// const androidPath = devices[0].path // "/dev/bus/usb/001/003"
// 或直接用 VID:PID 格式
const androidPath = '10C4:EA60' // CP210x 常用 PID
// 鸿蒙 路径示例
const harmonyPath = 'ttySAC0'
// iOS 路径示例(串口服务器)
const iosPath = '192.168.1.100:8899'
// 初始化
const sp = new SerialPort(androidPath, {
baudRate: 115200,
dataBits: 8,
stopBits: 1,
parity: 'none',
timeout: 2000
})
sp.open({
success: () => {
uni.showToast({ title: '串口已连接', icon: 'success' })
// 监听回复
sp.onData(data => {
console.log('设备返回:', data)
if (data.includes('OK')) {
console.log('指令执行成功')
}
})
// 发送指令
sp.send('POWER ON\r\n')
},
fail: e => {
uni.showToast({ title: '连接失败: ' + e, icon: 'error' })
}
})
// 应用退出时关闭
// 在 onUnload / onHide 等生命周期中
sp.offData()
sp.close()

收藏人数:
下载插件并导入HBuilder
赞赏(0)
下载 2
赞赏 0
下载 12674768
赞赏 1955
赞赏
京公网安备:11010802035340号