Arduino与Processing通信:首次启动时串口缓冲区填充null的原因排查
Arduino串口发送至Processing首次启动出现大量空字节问题解决
问题描述
我编写了Arduino向Processing发送字符串的代码,Processing以ASCII格式打印该字符串。程序上传至Arduino后首次启动Processing时,串口缓冲区初始会被填充大量null值(ASCII码0);第二次启动Processing时,缓冲区则正常为空。使用正版Arduino Uno,更换其他Arduino设备及笔记本测试后仍存在该问题,可排除硬件故障。
相关代码
Arduino代码
void setup() { Serial.begin(9600); //delay(1000) Serial.println("the quick brown fox jumps over the lazy dog"); delay(1000); } void loop() { }
Processing代码
import processing.serial.*; Serial myPort; void setup() { myPort= new Serial(this, "COM3", 9600); } void draw() { if (myPort.available()>0) { int c =myPort.read(); print(c,","); } }
Processing首次启动输出
0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,116 ,104 ,101 ,32 ,113 ,117 ,105 ,99 ,107 ,32 ,98 ,114 ,111 ,119 ,110 ,32 ,102 ,111 ,120 ,32 ,106 ,117 ,109 ,112 ,115 ,32 ,111 ,118 ,101 ,114 ,32 ,116 ,104 ,101 ,32 ,108 ,97 ,122 ,121 ,32 ,100 ,111 ,103
问题原因
Arduino完成串口初始化后立刻发送数据,但此时Processing的串口连接尚未完全建立,串口握手过程中产生的空字节被读入缓冲区。第二次启动Processing时,Arduino已经完成了初始数据发送,因此不会再出现空字节。
解决方法
方法1:给Arduino添加启动延迟
在串口初始化后增加延迟,等待Processing完成串口连接后再发送数据:
void setup() { Serial.begin(9600); delay(1500); // 预留足够时间让Processing建立串口连接 Serial.println("the quick brown fox jumps over the lazy dog"); delay(1000); } void loop() { }
方法2:Processing主动触发Arduino发送
让Processing先发送触发信号,Arduino收到信号后再发送字符串,从根源避免时序不匹配:
- 修改后的Arduino代码:
void setup() { Serial.begin(9600); } void loop() { if (Serial.available() > 0) { char trigger = Serial.read(); if (trigger == 's') { // 收到's'字符时发送目标字符串 Serial.println("the quick brown fox jumps over the lazy dog"); delay(1000); } } }
- 修改后的Processing代码:
import processing.serial.*; Serial myPort; void setup() { myPort = new Serial(this, "COM3", 9600); delay(1000); // 等待串口连接稳定 myPort.write('s'); // 发送触发信号 } void draw() { if (myPort.available()>0) { int c = myPort.read(); print(c,","); } }
方法3:Processing中过滤空字节
如果不想修改Arduino代码,可在Processing读取数据时直接跳过ASCII码为0的空字节:
import processing.serial.*; Serial myPort; void setup() { myPort = new Serial(this, "COM3", 9600); } void draw() { if (myPort.available()>0) { int c = myPort.read(); if (c != 0) { // 只处理非空字节 print(c,","); } } }
内容的提问来源于stack exchange,提问作者Robot12
相关产品推荐
相关产品推荐

