一、串口技术解析
- 核心定义
串口(Serial Port)是一种通过逐位顺序传输实现设备间通信的接口,其核心特点包括:
• 低成本:仅需一对传输线即可完成双向通信,尤其适用于远距离场景(如工业控制)。
• 协议多样性:支持RS-232(短距离通信,常见于计算机外设)、RS-485(长距离抗干扰)等标准。
• 速度限制:传输速率较低(典型波特率为9600~115200bps),适用于非实时性要求场景。
- 核心参数
串口通信需配置以下参数(双方必须一致):
参数 | 可选值 | 作用说明 |
---|---|---|
波特率 | 9600/115200等 | 决定每秒传输的符号数(bps) |
数据位 | 5-8位(常用8位) | 单个数据包的有效位数 |
停止位 | 1/1.5/2位 | 标识数据包结束 |
校验位 | 无/奇校验/偶校验 | 错误检测机制(如RS-232的奇偶校验) |
二、Android接收串口数据实现方案
- 硬件准备
• 物理串口支持:部分工业级Android设备内置串口(如/dev/ttyS3
)。
• USB转串口模块:通过OTG连接USB转TTL/RS-485模块扩展串口功能。
• 线缆匹配:根据设备接口类型选择DB9、RJ45等连接线。
- 软件实现步骤
步骤1:权限配置
在AndroidManifest.xml
中添加串口操作权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.hardware.usb.host"/> <!-- USB转串口时需添加 -->
步骤2:引入串口库
推荐使用第三方库(如android-serialport-api
或usb-serial-for-android
)简化开发:
dependencies {
implementation 'io.github.xmaihh:serialport:2.1.1'
}
步骤3:初始化串口
配置串口参数并打开设备(示例代码):
val serialPort = SerialPort.Builder()
.setPort("/dev/ttyS3") // 设备路径(需系统权限或Root)
.setBaudRate(115200) // 需与硬件设备匹配
.setDataBits(8) // 数据位
.setParity(SerialPort.PARITY_NONE) // 校验方式
.build()
.apply { open() }
步骤4:启动数据接收线程
通过独立线程读取输入流,避免阻塞主线程:
Thread {
val inputStream = serialPort.inputStream
val buffer = ByteArray(1024)
while (serialPort.isOpen) {
try {
val bytesRead = inputStream.read(buffer)
if (bytesRead > 0) {
val data = String(buffer, 0, bytesRead)
runOnUiThread { updateUI(data) } // 更新UI
}
} catch (e: IOException) {
Log.e("SerialPort", "接收异常: ${e.message}")
}
}
}.start()
步骤5:UI更新与数据处理
在updateUI()
中实现数据展示或协议解析:
private fun updateUI(data: String) {
textView.text = "接收数据: $data"
// 示例:解析Modbus协议
if (data.startsWith("0xAA")) {
val value = data.substring(2, 6).toInt(16)
progressBar.progress = value
}
}
三、关键问题与优化
- 常见问题
问题现象 | 解决方案 |
---|---|
设备未检测到 | 检查/dev/tty* 权限及路径正确性 |
数据接收不全或乱码 | 校验波特率、数据位配置一致性 |
高并发数据丢失 | 使用同步锁或环形缓冲区管理读写 |
- 高级优化
• 数据校验:添加CRC或校验和机制防止传输错误。
• 协议封装:定义包头/包尾标识解决粘包问题(如0xAA
起始符)。
• 异步监听:通过SerialPortEventListener
实现事件驱动模型。
四、应用场景
- 工业控制:与PLC通信实现设备监控(Modbus协议)。
- 物联网终端:连接温湿度传感器采集环境数据。
- 支付设备:驱动客显屏幕显示交易金额。