预训练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
相关产品推荐
相关产品推荐

