Arduino搭配ESP01及433MHz收发模块ArduinoJson解析异常排查
问题产生原因
- 433MHz接收缓冲区无字符串终止符
你发射的"85648217"刚好是8个字符,对应接收缓冲区uint8_t buf[8]长度完全匹配,接收完成后缓冲区末尾没有补充字符串结束符\0,强制转换为char*类型拼接URL时,会读取缓冲区后续的随机内存数据,导致输出内容带乱码。 - 串口读取JSON数据逻辑异常
你发送URL后调用Serial.readString()读取ESP01返回的API响应,该函数默认以1秒超时为结束标志,极易出现读不全响应、读到多余无效数据的问题,传给ArduinoJson的内容不符合JSON格式,直接触发解析错误。 - 错误处理逻辑不合理
解析失败后直接执行return中断当前loop(),未清空串口缓冲区就结束本次流程,会导致后续串口数据错位,乱码问题持续出现。
修复方案
- 调整433接收缓冲区大小,接收完成后补充终止符:将缓冲区长度设为9,接收成功后立刻给末尾赋值
\0,保证字符串转换正常。 - 优化串口响应读取逻辑:改用
Serial.readStringUntil('\n')读取完整行响应,或者提前设置合理的串口超时时间,确保读取到完整的JSON内容。 - 调整错误处理逻辑:解析失败后不要直接return,增加串口缓冲区清空操作后继续执行,避免后续数据错位。
- 预留足够的JSON解析容量:根据实际API返回的JSON大小调整缓冲区容量,避免因容量不足截断数据导致解析失败。
修复后完整代码
#include <ArduinoJson.h> #include <RH_ASK.h> #include <SPI.h> #define RX 0 #define TX 1 using namespace std; unsigned char rxBuf[512]; RH_ASK rf_driver; void setup() { rf_driver.init(); Serial.begin(9600); // 调整串口超时时间为2秒,适配ESP01响应延迟 Serial.setTimeout(2000); } void loop() { // 缓冲区长度+1留位置放结束符 uint8_t buf[9]; uint8_t buflen = sizeof(buf) - 1; if (rf_driver.recv(buf, &buflen)) { // 补充字符串结束符 buf[buflen] = '\0'; Serial.println("https://example.com/example/example/"+(String((char*)buf))+";headers\n"); // 读取完整JSON响应,可根据实际ESP01返回的换行规则调整终止符 String message = Serial.readStringUntil('\n'); // 根据实际JSON大小调整容量,建议比实际最大返回值大20% const size_t capacity = JSON_OBJECT_SIZE(1) + 60; DynamicJsonDocument doc(capacity); DeserializationError error = deserializeJson(doc, message); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); // 清空串口残留数据 while(Serial.available()) Serial.read(); } else { Serial.println(doc["attribute"].as<const char*>()); Serial.println(message); } } }
内容的提问来源于stack exchange,提问作者mrneedshelpalot
相关产品推荐
相关产品推荐

