树莓派Pico与主机USB双向通信问题:Ping-Pong响应异常
Raspberry Pi Pico USB双向Ping-Pong通信故障修复
我尝试通过Raspberry Pi Pico的内置micro-USB端口实现双向通信:主机发送"ping",Pico接收后返回"pong"。目前Pico能正常接收主机的"ping",但返回的"pong"只显示在Thonny控制台,主机完全收不到。尝试用sys.stdout.print(b"pong\n")替代sys.stdout.write时,还触发了错误:AttributeError: 'TextIOWrapper' object has no attribute 'print'。
两端原代码
主机端代码(运行在电脑)
# 此代码需在电脑运行,不可在Pico上执行! import serial import time import sys # 打开串行连接 s = serial.Serial("/dev/cu.usbmodem1101", 115200) # 这是Pico在我Mac上的设备名 while True: s.write(b"ping\n") print("sent 'ping'") time.sleep(1) response = s.readline() print(f"received '{response}'") time.sleep(1)
Pico端原代码(通过Thonny部署)
import time import sys while True: # 读取主机发送的指令 v = sys.stdin.readline().strip() print(f"received '{v}'") time.sleep(1) sys.stdout.write(b"pong\n") print("sent 'pong'")
问题原因
- 输出目标错误:用Thonny直接运行Pico代码时,
sys.stdout默认绑定到Thonny的调试控制台,而非USB串行端口,所以返回内容只会显示在Thonny中,主机无法接收。 - 流类型不匹配:
sys.stdout是文本IO流,不能直接写入字节串(b"pong\n"),必须传入字符串格式内容。 - 输出缓冲延迟:文本流输出存在缓冲机制,若不强制刷新,内容不会立即发送到USB串口。
修复方案
方案一:修改代码并设置Pico开机自启
将Pico代码修改为以下内容,保存为main.py上传到Pico,断开Thonny连接后重启Pico,再运行主机端代码:
import time import sys while True: # 读取主机发送的指令(去除首尾空白字符) v = sys.stdin.readline().strip() # 发送"pong"到主机:使用字符串写入,强制刷新缓冲确保即时发送 sys.stdout.write("pong\n") sys.stdout.flush() time.sleep(1)
若需要保留调试输出,可添加
print(f"received '{v}'")和print("sent 'pong'"),但这些内容会在Thonny连接时显示在控制台,不影响主机接收返回值。
方案二:Thonny调试时的临时处理
如果需要在Thonny中实时调试,同时让主机接收返回值,需确保:
- Pico代码中使用字符串写入
sys.stdout,并添加sys.stdout.flush()。 - 确保Thonny未独占串行端口:在Thonny的「运行」→「配置解释器」中,确认Pico的串行连接设置为允许外部访问。(此方法稳定性不如方案一,优先推荐开机自启方式)
主机端代码无需修改,只需确认设备路径(/dev/cu.usbmodem1101)与你的电脑上Pico的实际设备名一致。
内容的提问来源于stack exchange,提问作者Bartek Pacia
相关产品推荐
相关产品推荐

