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

Arduino读取两个MQTT主题并将Payload存入不同变量的问题求助

问题原因与解决方法

问题根源

C语言中char类型字符串必须以**空字符'\0'**作为结束标志,你的代码仅将MQTT payload的字符复制到数组中,未添加这个终止符。串口打印Serial.println()时会持续读取内存直到遇到'\0',因此会越界读取到相邻变量的内容,导致两个变量的内容拼接输出。同时你定义的数组char myTemp[5]空间不足,无法同时容纳有效字符和终止符,进一步加剧了越界问题。

解决方案

1. 调整数组大小,预留终止符空间

将数组定义从char myTemp[5]改为char myTemp[6],确保能容纳最多5个有效字符+1个'\0'。

2. 复制payload后添加终止符

无论用循环复制还是字符串函数复制,都要手动添加'\0'标记字符串结束位置,同时限制复制的字符数,避免数组越界。

修改后的完整代码

// 数组大小改为6,预留空字符位置
char myTemp[6];
char myHum[6];

void callback(char *topic, byte *payload, unsigned int length) {
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);

  if (String(topic) == "arduino/temp") {
    Serial.println(strcmp(topic, "arduino/temp") == 0);
    Serial.print("Message:");
    // 用Serial.write直接打印payload,替代循环更高效
    Serial.write(payload, length);
    Serial.println();
    
    // 安全复制payload到数组:最多复制5个字符(数组大小-1)
    strncpy(myTemp, (char*)payload, sizeof(myTemp)-1);
    // 强制添加字符串终止符,确保不会越界
    myTemp[sizeof(myTemp)-1] = '\0';
    
    Serial.println(myTemp);
    Serial.println("-----------------------");
  } else {
    Serial.println(strcmp(topic, "arduino/humid") == 0);
    Serial.print("Message:");
    Serial.write(payload, length);
    Serial.println();
    
    strncpy(myHum, (char*)payload, sizeof(myHum)-1);
    myHum[sizeof(myHum)-1] = '\0';
    
    Serial.println(myHum);
    Serial.println("-----------------------");
  }
}

关键修改点说明

  • 数组扩容:从5位改为6位,留出'\0'的位置
  • 使用strncpy替代手动循环:更简洁安全,限制复制字符数为数组大小-1,避免越界
  • 强制添加终止符:即使payload长度超过数组预留空间,也能保证字符串正常结束
  • 用Serial.write(payload, length)打印payload:无需循环逐个字符打印,效率更高

内容的提问来源于stack exchange,提问作者paulr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:20:38