Android11串口通信接收ASCII数据出现乱码的原因排查
Android11串口通信ASCII数据乱码问题排查与解决
可能的原因及对应方案
1. 电平不匹配导致硬件层面数据错误
即使串口参数(波特率、停止位等)完全匹配,若发送端与Android设备的串口电平类型不一致,会直接导致接收字节错乱:
- 若发送端是RS232电平,而Android设备串口是TTL电平,未加电平转换模块(如MAX232)的话,RS232的负逻辑电平会被TTL串口识别为错误的字节值。
- 解决:添加RS232转TTL模块,确保两端电平匹配后再测试。
2. BufferedInputStream缓冲机制不适合串口实时读取
串口是异步流式传输,BufferedInputStream的内部缓冲会导致数据累积、延迟或读取到残留的旧数据:
- 比如之前未读取的垃圾数据会被缓存,和新数据一起被读出,导致收到的字节混乱。
- 解决:直接使用
FileInputStream读取串口,避免缓冲带来的干扰。
3. Android11权限限制未正确处理
Android11对设备节点(如/dev/ttyS*)的访问权限管控更严格:
- 若APP未获得对应串口设备的读写权限,可能出现读取数据异常或乱码。
- 解决:
- 在Manifest中添加权限:
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />(需root场景)或对应定制系统的串口专属权限。 - 通过ADB命令给串口设备授权:
adb shell chmod 666 /dev/ttySx(替换x为实际串口号)。
- 在Manifest中添加权限:
优化后的接收代码示例
替换BufferedInputStream为FileInputStream,并优化读取逻辑:
private FileInputStream mSerialInputStream; @Override//每隔 100 毫秒会触发一次run public void run() { if (Thread.currentThread().isInterrupted()) return; try { if (mSerialInputStream == null || mSerialInputStream.available() == 0) return; byte[] received = new byte[1024]; int size = mSerialInputStream.read(received); if (size > 0 && serialInter != null) { byte[] data = Arrays.copyOf(received, size); serialInter.readData(path, data, size); } } catch (IOException e) { Log.e(TAG, "串口读取数据异常:" + e.toString()); } }
验证步骤
- 用PC端串口助手直接连接发送端,确认发送的"123"能被正确解析为字节49、50、51、0,排除发送端问题。
- 在Android设备上使用成熟的串口测试APP连接目标串口,验证是否能正确接收数据,排除设备硬件或系统底层问题。
内容的提问来源于stack exchange,提问作者Arctic
相关产品推荐
相关产品推荐

