You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:57:01