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

预训练YOLO检测控制Arduino Uno LED脚本故障求助

问题:YOLO检测结果无法触发Arduino LED控制

需求背景

通过预训练YOLO模型检测摄像头画面中的标签,控制Arduino Uno上的LED对应亮起:

  • "G" → 绿灯亮
  • "R" → 红灯亮
  • "Y" → 黄灯亮
  • "A" → 红黄灯同时亮
  • "0" → 关闭所有LED

Arduino控制代码

char command;

void setup() {
    Serial.begin(9600);
    pinMode(2, OUTPUT);  // Green LED pin
    pinMode(3, OUTPUT);  // Red LED pin
    pinMode(4, OUTPUT);  // Yellow LED pin
}

void loop() {
    if (Serial.available() > 0) {
        command = Serial.read();
        if (command == 'G') {
            // Turn on green LED
            digitalWrite(2, HIGH);
            digitalWrite(3, LOW);  // Turn off red LED
            digitalWrite(4, LOW);  // Turn off yellow LED
        } else if (command == 'R') {
            // Turn on red LED
            digitalWrite(2, LOW);   // Turn off green LED
            digitalWrite(3, HIGH);
            digitalWrite(4, LOW);   // Turn off yellow LED
        } else if (command == 'Y') {
            // Turn on yellow LED
            digitalWrite(2, LOW);   // Turn off green LED
            digitalWrite(3, LOW);   // Turn off red LED
            digitalWrite(4, HIGH);
        } else if (command == 'A') {
            // Turn on both red and yellow LEDs
            digitalWrite(2, LOW);   // Turn off green LED
            digitalWrite(3, HIGH);
            digitalWrite(4, HIGH);
        } else if (command == '0') {
            // Turn off all LEDs
            digitalWrite(2, LOW);
            digitalWrite(3, LOW);
            digitalWrite(4, LOW);
        }
    }
}

YOLO模型标签定义

#Classes
names:
  0: aaa
  1: bbb
  2: ccc

问题重现(Python代码)

from ultralytics import YOLO
import serial
import time
import sys

# Load my YOLO model using
model = YOLO("best.pt")

# Open the serial port for communication with Arduino
arduino = serial.Serial('COM3', 9600)  # Change 'COM3' to your Arduino port

# Map the class labels to corresponding Arduino commands
label_commands = {
    'aaa': 'G',
    'bbb': 'R',
    'ccc': 'Y',
    'aaa_bbb': 'A',
    'aaa_bbb_ccc': 'A',
    'none': '0'
}

while True:
    try:
        results = model.predict(source="0", show=True)  # assumes '0' is your source identifier

        # Extract the detected labels from results
        detected_labels = [item['label'] for item in results.xyxy[0].numpy()]

        # Determine the Arduino command based on detected labels
        if 'aaa' in detected_labels and 'bbb' in detected_labels and 'ccc' in detected_labels:
            command = label_commands['aaa_bbb_ccc']
        elif 'aaa' in detected_labels and 'bbb' in detected_labels:
            command = label_commands['aaa_bbb']
        elif 'aaa' in detected_labels:
            command = label_commands['aaa']
        elif 'bbb' in detected_labels and 'ccc' in detected_labels:
            command = label_commands['aaa_bbb_ccc']
        elif 'bbb' in detected_labels:
            command = label_commands['bbb']
        elif 'ccc' in detected_labels:
            command = label_commands['ccc']
        else:
            command = label_commands['none']

        # Print the command for debugging
        print(f"Sending command to Arduino: {command}")
        sys.stdout.flush()  # Flush the standard output

        # Send the command to Arduino
        arduino.write(command.encode())

    except Exception as e:
        print(f"Error: {e}")
        sys.stdout.flush()  # Flush the standard output

    # Wait for 5 seconds before sending the next command
    time.sleep(5)

异常现象

  • Arduino连接正常,单独通过Python发送指令可正常控制LED
  • 运行上述代码时,控制台仅输出YOLO检测日志,调试打印语句无输出
  • Arduino完全接收不到指令

问题原因与修复方案

1. YOLO结果提取逻辑错误

Ultralytics YOLO的results.xyxy[0]并非字典结构,无法直接用item['label']提取标签。正确方式是通过boxes.cls获取类别ID,再映射到模型的标签名称。

2. 串口初始化缺少延时

Arduino上电后需要2-3秒完成初始化,直接打开串口发送指令会导致通信失败。

3. 指令判断逻辑错误

原代码中bbb和ccc同时检测到时错误映射到aaa_bbb_ccc的指令,不符合需求。

完整修复后的Python代码

from ultralytics import YOLO
import serial
import time
import sys

# Load YOLO model
model = YOLO("best.pt")

# Open serial port and wait for Arduino initialization
arduino = serial.Serial('COM3', 9600)  # 修改为你的Arduino端口
time.sleep(2)

# Label to command mapping
label_commands = {
    'aaa': 'G',
    'bbb': 'R',
    'ccc': 'Y',
    'aaa_bbb': 'A',
    'aaa_bbb_ccc': 'A',
    'bbb_ccc': 'A',
    'none': '0'
}

while True:
    try:
        # 关闭YOLO默认日志,方便查看调试信息
        results = model.predict(source="0", show=True, verbose=False)

        detected_labels = []
        # 检查是否有检测结果
        if results and len(results[0].boxes) > 0:
            for box in results[0].boxes:
                cls_id = int(box.cls[0])
                detected_labels.append(model.names[cls_id])
        
        # 去重,避免同一标签多次检测导致重复判断
        detected_labels = list(set(detected_labels))

        # 判断对应指令
        if all(label in detected_labels for label in ['aaa', 'bbb', 'ccc']):
            command = label_commands['aaa_bbb_ccc']
        elif 'aaa' in detected_labels and 'bbb' in detected_labels:
            command = label_commands['aaa_bbb']
        elif 'bbb' in detected_labels and 'ccc' in detected_labels:
            command = label_commands['bbb_ccc']
        elif 'aaa' in detected_labels:
            command = label_commands['aaa']
        elif 'bbb' in detected_labels:
            command = label_commands['bbb']
        elif 'ccc' in detected_labels:
            command = label_commands['ccc']
        else:
            command = label_commands['none']

        # 调试输出
        print(f"Detected labels: {detected_labels} | Sending command: {command}")
        sys.stdout.flush()

        # 发送指令到Arduino
        arduino.write(command.encode())

    except Exception as e:
        print(f"Error: {str(e)}")
        sys.stdout.flush()

    time.sleep(5)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:14:51