树莓派向Arduino发送JSON时timeFrame字段显示null问题求助
问题分析与解决
可能的原因
串口接收不完整
Serial.readString()默认读取到换行符\n就停止,如果树莓派发送的JSON没有以换行结尾,或者发送过程中被拆分成多个数据包,jsonInput就会是不完整的JSON字符串,反序列化后嵌套字段自然读不到,返回null。嵌套对象访问未做存在性检查
直接链式访问json["timeFrame"]["mins"]时,如果timeFrame对象因为反序列化失败不存在,就会返回空值,导致后续转换出错。
解决方案
第一步:确认串口接收的JSON完整性
在反序列化前先打印接收到的内容,排查是否完整:
void readJSON() { jsonInput = Serial.readString(); // 打印接收内容,检查是否为完整JSON Serial.println("Received JSON:"); Serial.println(jsonInput); StaticJsonDocument<200> json; DeserializationError error = deserializeJson(json, jsonInput); // 检查反序列化是否成功 if (error) { Serial.print("Deserialization failed: "); Serial.println(error.c_str()); return; } // 后续逻辑... }
如果打印内容不完整,调整串口接收方式:
- 让树莓派发送JSON时末尾加换行符
\n; - 改用
Serial.readStringUntil('\0')(若发送时以空字符结尾); - 或者通过判断JSON首尾字符(开头
{、结尾})确保读到完整数据包。
第二步:安全访问嵌套对象
先获取timeFrame对象,确认存在后再读取子字段:
if (json["cmd"] == "RFID") { if(json["valid"].as<bool>()){ // 显式转换为bool避免类型问题 blinkGreenLED(); // 先获取timeFrame对象 JsonObject timeFrame = json["timeFrame"]; if (timeFrame) { // 确认对象存在 int mm = timeFrame["mins"].as<int>(); int ss = timeFrame["secs"].as<int>(); printText("Access granted!", 0); printText("Checkpoint " + String(json["checkpoint"].as<int>()), 1); printText("Time left: " + String(mm) + ":" + String(ss), 2); } else { Serial.println("timeFrame object not found!"); printText("Time error!", 2); } } else { blinkRedLED(); printText("Access denied!", 0); } }
额外注意点
- 转换整数到字符串时,用
String(mm)比as<String>()更可靠,后者对整数类型的转换偶尔会有兼容性问题; StaticJsonDocument<200>的大小足够你的JSON,若后续扩展JSON结构,可以用ArduinoJson助手计算所需最小内存。
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

