Arduino Uno SoftwareSerial库轮流接收数据异常问题求助
Arduino SoftwareSerial 轮流监听无接收数据问题解决
问题核心
使用SoftwareSerial的listen()切换两个串口设备时,单个设备单独传输正常,但轮流接收时读不到数据,本质原因是发送指令后没有给设备足够的响应时间——代码里写完数据立刻进入读取循环,此时设备还没来得及返回数据,直接跳过了读取逻辑。
解决方案
- 增加响应等待机制:发送指令后,循环等待数据到达或超时,确保设备有足够时间返回数据
- 切换监听前清空缓冲区:避免之前的残留数据干扰当前读取
- 优化读取逻辑:等待预期的字节数后再读取,提升可靠性
修改后的代码
#include <SoftwareSerial.h> SoftwareSerial portOne(4, 7); uint32_t read_1[2] = {}; SoftwareSerial portTwo(2, 8); uint32_t read_2[2] = {}; // 设备响应超时时间(可根据实际设备调整) const unsigned long RESPONSE_TIMEOUT = 500; void setup() { Serial.begin(9600); portOne.begin(9600); portTwo.begin(9600); } void loop() { readFromPortOne(); delay(100); readFromPortTwo(); delay(100); } void readFromPortOne(){ portOne.listen(); // 清空缓冲区,清除残留数据 while(portOne.available()) portOne.read(); portOne.write(0x4a); unsigned long startTime = millis(); // 等待数据到达或超时 while(millis() - startTime < RESPONSE_TIMEOUT){ // 等待预期的2个字节全部到达 if(portOne.available() >= 2){ read_1[0] = portOne.read(); read_1[1] = portOne.read(); break; } } Serial.print("read_1[0]: "); Serial.println(read_1[0]); Serial.print("read_1[1]: "); Serial.println(read_1[1]); } void readFromPortTwo(){ portTwo.listen(); // 清空缓冲区 while(portTwo.available()) portTwo.read(); portTwo.write(0x4c); unsigned long startTime = millis(); while(millis() - startTime < RESPONSE_TIMEOUT){ if(portTwo.available() >= 2){ read_2[0] = portTwo.read(); read_2[1] = portTwo.read(); break; } } Serial.print("read_2[0]: "); Serial.println(read_2[0]); Serial.print("read_2[1]: "); Serial.println(read_2[1]); }
额外提示
RESPONSE_TIMEOUT的数值需要根据你的设备实际响应速度调整,确保设备能在超时前返回数据- SoftwareSerial同一时间只能监听一个端口,波特率过高容易出现丢包,优先考虑使用硬件串口
- 如果设备返回字节数不固定,可以把读取逻辑改为循环读取直到超时,而非等待固定字节数
内容的提问来源于stack exchange,提问作者itehno
相关产品推荐
相关产品推荐

