Arduino Leonardo与UNO使用SoftwareSerial通信时数据异常
问题排查与解决:Arduino Leonardo与UNO SoftwareSerial 1字节收发异常
核心问题分析
SoftwareSerial在不同Arduino板上的硬件兼容性存在差异,尤其是Leonardo(基于ATmega32U4)与UNO(ATmega328P)之间,常见触发数据混乱的原因包括:
- 波特率同步误差
- 软串口引脚的中断资源冲突
- Leonardo的USB虚拟串口与软串口的优先级冲突
分步排查与修复
1. 强制波特率匹配与硬件启动延迟
确保两端代码波特率完全一致,且在串口初始化后添加延迟,给硬件足够的稳定时间:
UNO发送端代码调整:
#include <SoftwareSerial.h> SoftwareSerial mySerial(8, 9); // RX, TX byte sendData = 0; void setup() { mySerial.begin(9600); delay(100); // 等待串口硬件稳定 } void loop() { mySerial.write(sendData); sendData++; delay(500); }
Leonardo接收端代码调整:
#include <SoftwareSerial.h> SoftwareSerial mySerial(9, 8); // RX对应UNO的TX,TX对应UNO的RX,交叉连接 byte recvData; void setup() { Serial.begin(9600); // USB虚拟串口,用于输出到监视器 mySerial.begin(9600); delay(100); // 等待串口硬件稳定 } void loop() { if (mySerial.available() > 0) { recvData = mySerial.read(); Serial.print("Received: "); Serial.println(recvData); } }
2. 避开冲突引脚
Leonardo的10、11、12、13引脚同时承担SPI功能,软串口使用时会与SPI中断冲突,建议优先选择带硬件中断的引脚2/3(SoftwareSerial对这类引脚兼容性更好):
- UNO端:修改为
SoftwareSerial mySerial(2, 3); - Leonardo端:对应修改为
SoftwareSerial mySerial(3, 2);(保持交叉连接:UNO TX→Leonardo RX)
3. 改用硬件串口替代软串口
软串口本身是模拟实现,稳定性远不如硬件串口,直接替换能彻底解决多数兼容性问题:
- UNO端:使用硬件串口
Serial(引脚0/1),注意上传代码时需先断开引脚0/1的连接,上传完成后再重新连接 - Leonardo端:使用硬件串口
Serial1(引脚0/1),USB虚拟串口Serial保留用于输出到监视器
UNO硬件串口发送代码:
byte sendData = 0; void setup() { Serial.begin(9600); delay(100); } void loop() { Serial.write(sendData); sendData++; delay(500); }
Leonardo硬件串口接收代码:
byte recvData; void setup() { Serial.begin(9600); // USB监视器输出 Serial1.begin(9600); // 硬件串口,引脚0(RX)/1(TX) delay(100); } void loop() { if (Serial1.available() > 0) { recvData = Serial1.read(); Serial.print("Received: "); Serial.println(recvData); } }
4. 检查物理连接
- 必须确保两块板子的GND完全共地,共地不良是串口数据乱码的常见诱因
- 接线长度控制在1米以内,避免信号干扰;若需长距离传输,建议搭配电平转换模块或RS485模块
验证步骤
- 将调整后的代码分别上传到对应板子
- 打开Leonardo的USB串口监视器,波特率设置为9600
- 观察输出是否为连续递增的数值(0,1,2,3...),每0.5秒更新一次
内容的提问来源于stack exchange,提问作者user16540876
相关产品推荐
相关产品推荐

