Arduino与Processing串口通信问题求助:发送的两条字符串仅存入Processing首个变量
解决Processing读取Arduino串口字符串时两条消息存入同一变量的问题
我来帮你搞定这个串口读取的坑——你的代码逻辑里犯了一个典型的时序匹配错误,咱们一步步拆解问题,再给你靠谱的解决方案:
问题根源分析
你在Arduino的setup()里一次性发送了两行字符串,但Processing的draw()函数默认每秒会跑60次左右。这里的矛盾点在于:
- 串口数据的传输是需要时间的,Arduino发完第一条消息后,Processing可能还没来得及处理,第二条消息才刚在路上;
- 你在同一个
draw()循环里连续调用两次readStringUntil('\n'),第一次调用时可能只读到了第一条消息,第二次调用时缓冲区里还没第二条,所以s2为空; - 等下一次
draw()循环触发时,第二条消息才到达缓冲区,这时候又被第一个readStringUntil('\n')读到,存入s1——最终就出现了两条消息都进s1,s2始终为空的情况。
修复方案:用串口事件替代轮询
Processing提供了专门的串口事件处理机制,比在draw()里瞎轮询靠谱多了。我们可以根据Arduino发送消息的标识(开头的1.和2.),把消息分配到对应的变量里:
修改后的Processing代码:
import processing.serial.*; Serial myPort; // 提前声明要存储的两个变量,初始化为空字符串 String s1 = ""; String s2 = ""; void setup() { myPort = new Serial(this, "COM3", 9600); // 设置缓冲区,当收到换行符时触发串口事件 myPort.bufferUntil('\n'); } // 串口事件函数:只有当串口收到完整一行数据时才会触发 void serialEvent(Serial myPort) { String incoming = myPort.readStringUntil('\n'); if (incoming != null) { // 去掉字符串首尾的换行、空格等冗余字符 incoming = incoming.trim(); // 根据消息开头的标识分配到对应变量 if (incoming.startsWith("1.")) { s1 = incoming; println("s1已更新:", s1); } else if (incoming.startsWith("2.")) { s2 = incoming; println("s2已更新:", s2); } } } void draw() { // 这里可以放你的绘图逻辑,不需要再处理串口读取了 }
额外优化建议
- 测试用的Arduino代码调整:如果想持续测试,可以把发送逻辑放到
loop()里,每隔几秒发一次:
void setup() { Serial.begin(9600); delay(1000); // 给串口初始化留时间 } void loop() { Serial.println("1.first message"); Serial.println("2.second message"); delay(2000); // 每隔2秒发送一次,方便观察效果 }
- 调试小技巧:可以在
serialEvent里先打印所有收到的原始数据,确认串口是否正确接收:
void serialEvent(Serial myPort) { String incoming = myPort.readStringUntil('\n'); if (incoming != null) { println("原始收到的数据:", incoming); // 先看原始数据,排查问题 incoming = incoming.trim(); // 后续的分配逻辑... } }
这样修改后,你就能稳稳地把两条消息分别存入s1和s2啦~
内容的提问来源于stack exchange,提问作者Robot12
相关产品推荐
相关产品推荐

