基于ArduinoJSON的Python-Arduino串口通信故障排查
问题排查与修复方案
核心问题分析
- Python发送的JSON格式无效:原代码直接将字典转为字符串,生成带单引号的
{'command': 'ON'},不符合JSON必须使用双引号的规范,导致ArduinoJSON解析失败。 - Arduino存在悬空指针:
command指针指向局部StaticJsonDocument内的数据,该文档在代码块结束后被销毁,指针变为无效,引发未定义行为。 - 缺少串口输出逻辑:原Arduino代码未实现持续打印"ON"的需求。
- 变量未初始化:
command指针初始未赋值,调用strcmp时会出现不可预测的结果。
修复后的Python代码
import serial import time import json # 引入json模块生成合法JSON # 打开串口(根据实际端口调整) ser = serial.Serial('COM3', 9600, timeout=1) def send_command(command): data = {"command": command} # 生成标准JSON字符串并添加换行符,方便Arduino按行读取 json_data = json.dumps(data) + '\n' ser.write(json_data.encode('utf-8')) time.sleep(1) # 给Arduino预留处理时间 # 示例:发送点亮LED指令 send_command("ON") # 延迟后关闭串口(确保Arduino完成处理) time.sleep(2) ser.close()
关键修改:
- 使用
json.dumps()生成标准JSON格式(双引号) - 添加换行符
\n,让Arduino可以按行读取完整的JSON数据
修复后的Arduino代码
#include <ArduinoJson.h> const int ledPin = 12; char command[10] = "OFF"; // 用字符数组存储指令,初始化为OFF void setup() { Serial.begin(9600); pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); // 初始状态LED熄灭 } void loop() { // 读取串口传入的一行数据 if (Serial.available() > 0) { String input = Serial.readStringUntil('\n'); StaticJsonDocument<200> doc; // 解析JSON数据 DeserializationError error = deserializeJson(doc, input); if (error) { Serial.print(F("解析错误: ")); Serial.println(error.c_str()); return; } // 确保command字段存在,再复制到本地数组 if (doc.containsKey("command")) { strncpy(command, doc["command"].as<const char*>(), sizeof(command)-1); command[sizeof(command)-1] = '\0'; // 确保字符串以空字符结尾 } } // 根据指令控制LED if (strcmp(command, "ON") == 0) { digitalWrite(ledPin, HIGH); Serial.println("ON"); // 持续打印ON信息 } else if (strcmp(command, "OFF") == 0) { digitalWrite(ledPin, LOW); Serial.println("OFF"); // 打印OFF信息(可选) } delay(100); // 控制打印频率,避免串口刷屏过快 }
关键修改:
- 将
const char* command改为字符数组char command[10],避免悬空指针问题 - 使用
Serial.readStringUntil('\n')读取完整的一行JSON数据 - 添加
doc.containsKey("command")检查,避免缺失字段导致的错误 - 增加
Serial.println()实现持续打印指令状态 - 初始化LED状态为熄灭,避免初始未知状态
测试步骤
- 将修复后的Arduino代码上传到开发板
- 打开Arduino串口监视器(波特率9600)
- 运行Python代码发送"ON"指令
- 观察LED是否持续点亮,串口监视器是否持续输出"ON"
内容的提问来源于stack exchange,提问作者Ioannis Christodoulakis
相关产品推荐
相关产品推荐

