树莓派与Arduino串口通信异常:舵机控制失败求助
解决树莓派与Arduino串口通信的设备识别及IO错误问题
问题概述
尝试通过树莓派串口发送指令,让Arduino控制舵机,但频繁出现ttyACM0/ttyACM1设备找不到或写入IO错误的问题,已尝试连接稳定化、换线、重启、更新Python、sudo运行等操作,问题依旧。
现有代码
Arduino 代码
#include <Servo.h> Servo servodown; void setup() { servodown.attach(8); Serial.begin(9600); } void loop() { if (Serial.available() > 0) { String receivedString = Serial.readStringUntil('\n'); int nr = receivedString.toInt(); if (nr >= 0 && nr <= 360) { Serial.print("Drehe auf "); Serial.println(nr, DEC); servodown.write(nr/2); } else { Serial.println("Digga deine Zahl ist nicht gültig"); } } }
树莓派 Python 代码
import serial import time print("Programm startet...") degrees = input("Gradzahl bitte!") if __name__ == "__main__": ser = serial.Serial("/dev/ttyACM1", 9600, timeout=1) ser.reset_input_buffer() while True: ser.write(str(degrees).encode("utf-8")) line = ser.readline().decode("utf-8").rstrip() print(line) time.sleep(1)
出现的错误
错误1:IO写入失败
Traceback (most recent call last): File "main.py", line 12, in <module> ser.write(str(degrees).encode("utf-8")) File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 571, in write raise SerialException('write failed: {}'.format(e)) serial.serialutil.SerialException: write failed: [Errno 5] Input/output error
错误2:设备不存在
Traceback (most recent call last): File "main.py", line 8, in <module> ser = serial.Serial("/dev/ttyACM0", 9600, timeout=1) File "/usr/lib/python2.7/dist-packages/serial/serialutil.py", line 240, in __init__ self.open() File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 268, in open raise SerialException(msg.errno, "could not open port {}: {}".format(self._port, msg)) serial.serialutil.SerialException: [Errno 2] could not open port /dev/ttyACM0: [Errno 2] No such file or directory: '/dev/ttyACM0'
解决方案步骤
1. 确定正确的串口设备路径
- 先断开Arduino,执行命令:
ls /dev/ttyACM* /dev/ttyUSB*,记录输出(此时应该没有对应设备) - 连接Arduino,再次执行上述命令,新增的设备就是目标串口
- 也可以用
dmesg | grep tty查看系统识别到的串口日志,找到类似usb-acm的设备行,确认路径
2. 修复权限问题
- 将当前用户加入
dialout组,避免每次用sudo:sudo usermod -a -G dialout $USER - 注销并重新登录,让权限生效
3. 调整Python代码的串口初始化逻辑
- 避免硬编码设备路径,添加设备存在性检查;同时确保发送的指令带换行符(匹配Arduino的
readStringUntil('\n')读取逻辑):import serial import time import os def get_serial_port(): # 自动检测ACM/USB串口 ports = [f"/dev/{port}" for port in os.listdir("/dev") if port.startswith("ttyACM") or port.startswith("ttyUSB")] if ports: return ports[0] raise Exception("No Arduino serial port found") print("Programm startet...") if __name__ == "__main__": try: ser = serial.Serial(get_serial_port(), 9600, timeout=1) time.sleep(2) # 给Arduino重启预留时间 ser.reset_input_buffer() while True: degrees = input("Gradzahl bitte!") # 发送带换行符的指令 ser.write((degrees + "\n").encode("utf-8")) line = ser.readline().decode("utf-8").rstrip() if line: print(line) time.sleep(0.5) except Exception as e: print(f"Fehler: {e}")
4. 检查Arduino的串口冲突
- 确保Arduino上传代码后,串口监视器已关闭,避免树莓派无法占用串口
- 部分Arduino(如Uno)在串口连接时会自动重启,Python代码中加入
time.sleep(2)等待重启完成
5. 排查硬件与驱动问题
- 用
lsusb检查是否识别到Arduino设备:lsusb | grep Arduino,如果没有,说明硬件或驱动有问题 - 尝试更换USB端口,优先用树莓派的USB 2.0端口(避免USB 3.0的干扰)
额外提示
- 原Arduino代码中
nr/2的整数除法逻辑没问题,可将输入的0-360转换为舵机支持的0-180度范围 - 可以用
minicom工具测试串口通信是否正常,手动发送指令验证Arduino的响应:sudo minicom -b 9600 -D /dev/ttyACM0
内容的提问来源于stack exchange,提问作者Mats4411
相关产品推荐
相关产品推荐

