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

基于ArduinoJSON的Python-Arduino串口通信故障排查

问题排查与修复方案

核心问题分析

  1. Python发送的JSON格式无效:原代码直接将字典转为字符串,生成带单引号的{'command': 'ON'},不符合JSON必须使用双引号的规范,导致ArduinoJSON解析失败。
  2. Arduino存在悬空指针:command指针指向局部StaticJsonDocument内的数据,该文档在代码块结束后被销毁,指针变为无效,引发未定义行为。
  3. 缺少串口输出逻辑:原Arduino代码未实现持续打印"ON"的需求。
  4. 变量未初始化: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状态为熄灭,避免初始未知状态

测试步骤

  1. 将修复后的Arduino代码上传到开发板
  2. 打开Arduino串口监视器(波特率9600)
  3. 运行Python代码发送"ON"指令
  4. 观察LED是否持续点亮,串口监视器是否持续输出"ON"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:24:52