Arduino通过I2C发送字符串报错及多float值传输方案咨询
报错原因
接收端调用的Wire.read()每次仅返回1个字节的int类型数据,无法直接赋值给char t_buffer[7]数组,这是类型不兼容报错的直接原因。你在发送端一次性发送了7字节的温度字符串,接收端需要循环读取所有字节存入数组。
修复后的接收端参考代码
#include <Wire.h> #include <LiquidCrystal.h> LiquidCrystal lcd(7, 8, 9, 10, 11, 12); char t_buffer[7]; void setup() { Serial.begin(9600); lcd.begin(16, 2); Wire.begin(9); Wire.onReceive(receiveEvent); } void receiveEvent(int bytes) { int index = 0; // 循环读取所有可用字节,避免数组越界 while(Wire.available() && index < 7) { t_buffer[index] = Wire.read(); index++; } // 强制添加字符串结束符,避免LCD打印乱码 t_buffer[6] = '\0'; } void loop() { lcd.setCursor(0, 0); lcd.print("Temp (C): "); lcd.setCursor(0,1); lcd.print(t_buffer); delay(100); }
另外你发送端代码里重复写了两次pinMode(buzzer, OUTPUT),可以删掉其中冗余的一行。
多float传输方案说明
时序控制依次发送的合理性
这种方案可以实现功能,但稳定性较差,一旦某次传输出现丢字节的情况,后续所有数据的时序都会错位,大概率会出现长期乱码的问题。
更稳定的替代方案
推荐两种常用的稳定方案:
- 方案1:结构体二进制打包传输
两端定义完全一致的结构体,直接把所有要传的传感器数值打包成二进制数据一次性发送,无需转字符串,传输效率高、精度无损失,也不会出现时序错位问题。
发送端示例:
接收端示例:// 收发两端必须定义完全相同的结构体 struct SensorData { float temp; float light; int gas; }; SensorData sendBuf; // 循环内赋值 sendBuf.temp = temp; sendBuf.light = light; sendBuf.gas = gasInput; // 发送 Wire.beginTransmission(9); Wire.write((uint8_t *)&sendBuf, sizeof(sendBuf)); Wire.endTransmission();
后续直接调用struct SensorData { float temp; float light; int gas; }; SensorData recvBuf; void receiveEvent(int bytes) { Wire.readBytes((uint8_t *)&recvBuf, sizeof(recvBuf)); }recvBuf.temp、recvBuf.light等变量即可使用,无需额外解析。 - 方案2:带分隔符的字符串传输
如果需要保留字符串传输的形式,可以在每个数值之间添加逗号、换行符等特殊分隔符,接收端根据分隔符拆分数据,就算单次传输丢包也不会影响后续数据的解析。
内容的提问来源于stack exchange,提问作者Chronos
相关产品推荐
相关产品推荐

