Arduino中I2C OLED显示屏打印异常问题求助
问题排查与修复
核心错误点
- 字符串缺少结束符
\0:display.println依赖C风格字符串的结束符确定显示长度,原代码接收字符后未手动添加\0,会导致函数读取内存中随机数据,引发显示偏移或乱码。 - 数组越界风险:
cnt变量无上限检查,当串口接收字符数超过buff长度(10)时,会覆盖其他变量内存,导致程序逻辑混乱,后续无法正常显示。 - 未处理串口接收结束标志:原代码只要串口有数据就触发显示,未等待完整字符串(比如输入的换行符),可能显示不完整内容,且多次触发显示逻辑。
- 误用
println:println会自动添加换行符,导致第二次显示时Y轴偏移,破坏固定位置的显示逻辑。
修复后的代码
#define OLED_RESET -1 Adafruit_SSD1306 display(OLED_RESET); char buff[10] = {0}; // 初始化全0,确保默认包含结束符 int cnt = 0; int alpha = 0; void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.setTextColor(WHITE); Serial.begin(9600); } void loop() { while (Serial.available()) { char a = Serial.read(); // 以换行符作为字符串结束标志,同时限制cnt不超过数组长度-1(预留结束符位置) if (a == '\n' || cnt >= sizeof(buff) - 1) { buff[cnt] = '\0'; // 手动添加字符串结束符 alpha = 1; cnt = 0; // 重置计数器 } else { buff[cnt++] = a; } } if (alpha == 1) { display.clearDisplay(); display.setCursor(0, 0); display.setTextSize(1); display.print(buff); // 用print代替println,避免自动换行 display.display(); alpha = 0; memset(buff, 0, sizeof(buff)); // 清空缓冲区,避免旧数据残留 } }
修复说明
- 添加字符串结束符:在接收完完整字符串(或达到数组上限)时手动添加
\0,确保display.print能正确识别字符串长度。 - 数组边界检查:限制
cnt不超过sizeof(buff)-1,预留结束符位置,彻底避免数组越界。 - 处理结束标志:以换行符
\n作为字符串接收完成的标志,确保只有完整输入才触发显示。 - 替换
println为print:取消自动换行逻辑,固定显示位置在(0,0)。 - 清空缓冲区:每次显示后用
memset清空buff,避免旧数据干扰下一次显示。
内容的提问来源于stack exchange,提问作者Rj Choudhary
相关产品推荐
相关产品推荐

