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

基于Python控制Arduino实现智能交通灯Demo的技术咨询

Arduino USB代码上传与Python动态控制方案

一、让Arduino通过USB读取代码并运行

Arduino默认通过USB串口接收编译后的二进制代码并烧录运行,分手动和自动化两种方式:

手动基础流程

  • 编写控制LED的Arduino代码(比如串口指令接收框架),保存为.ino文件
  • 打开Arduino IDE,选择对应板型(如Uno)和USB端口(如COM3)
  • 点击「上传」按钮,IDE自动编译并烧录代码,完成后Arduino自动重启运行

自动化脚本上传(适合Python集成)

用arduino-cli工具实现Python触发上传:

  1. 安装arduino-cli,添加到系统PATH
  2. 初始化配置:arduino-cli config init
  3. 安装对应板型核心包(以Uno为例):arduino-cli core install arduino:avr
  4. Python中用subprocess调用上传命令:
import subprocess

def upload_sketch(port, sketch_folder, board="arduino:avr:uno"):
    cmd = [
        "arduino-cli", "upload",
        "-p", port,
        "-b", board,
        sketch_folder
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode == 0:
        print("代码上传成功")
    else:
        print(f"上传失败:{result.stderr}")
  • sketch_folder是包含.ino文件的Arduino项目文件夹路径

二、参数变更时更新Arduino逻辑的两种方案

方案1:动态生成并上传新脚本(适合逻辑大幅变更)

如果需要修改引脚定义、底层触发逻辑等,可通过Python生成新的Arduino代码再上传:

  1. 准备Arduino代码模板(sketch_template.ino),用占位符替代可变参数:
const int car_lights[] = {CAR_PINS};
const int pedestrian_lights[] = {PED_PINS};

void setup() {
  Serial.begin(9600);
  for(int i=0; i<sizeof(car_lights)/sizeof(int); i++) pinMode(car_lights[i], OUTPUT);
  for(int i=0; i<sizeof(pedestrian_lights)/sizeof(int); i++) pinMode(pedestrian_lights[i], OUTPUT);
}

void loop() {
  if(Serial.available() > 0){
    String cmd = Serial.readStringUntil('\n');
    if(cmd.startsWith("CAR")){
      int idx = cmd.split(',')[1].toInt();
      int state = cmd.split(',')[2].toInt();
      digitalWrite(car_lights[idx], state);
    } else if(cmd.startsWith("PED")){
      int idx = cmd.split(',')[1].toInt();
      int state = cmd.split(',')[2].toInt();
      digitalWrite(pedestrian_lights[idx], state);
    }
  }
}
  1. Python中替换占位符生成新代码:
def generate_sketch(car_pins, ped_pins, template_path, output_path):
    with open(template_path, 'r') as f:
        template = f.read()
    car_str = ",".join(map(str, car_pins))
    ped_str = ",".join(map(str, ped_pins))
    new_sketch = template.replace("CAR_PINS", car_str).replace("PED_PINS", ped_str)
    with open(output_path, 'w') as f:
        f.write(new_sketch)
  1. 参数变更时,先调用generate_sketch生成代码,再用upload_sketch上传

方案2:串口发送控制指令(适合时序参数微调,无需重启)

如果只是调整绿灯时长、切换顺序等时序参数,直接通过串口发指令更高效:

  1. 先上传上述模板中的Arduino代码(固定引脚,只处理串口指令)
  2. Python用pyserial库发送控制指令:
import serial
import time

class TrafficController:
    def __init__(self, port, baud=9600):
        self.ser = serial.Serial(port, baud, timeout=1)
        time.sleep(2)  # 等待Arduino初始化

    def set_light(self, light_type, idx, state):
        cmd = f"{light_type},{idx},{state}\n"
        self.ser.write(cmd.encode())

    def run_sequence(self, sequence):
        for item in sequence:
            typ, idx, state, dur = item
            self.set_light(typ, idx, state)
            time.sleep(dur)

# 示例:机器学习输出新时序后执行
if __name__ == "__main__":
    ctrl = TrafficController("COM3")
    new_sequence = [
        ("CAR", 0, 1, 40),  # 0号车绿灯亮40秒
        ("CAR", 0, 0, 2),   # 灭2秒
        ("PED", 0, 1, 20),  # 0号行人绿灯亮20秒
        # 更多时序步骤...
    ]
    ctrl.run_sequence(new_sequence)
  • 安装依赖:pip install pyserial

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 02:15:51