如何实现有stdin输入时终止UART读取并转发输入内容?
解决UART持续发送时无法响应键盘输入的问题
问题根源
原代码用elif做分支判断,当UART持续无间隙发数据时,uart.any()始终为真,程序永远碰不到键盘检测逻辑;而且处理键盘输入后没有正确恢复UART读取流程,导致后续没法再接收UART数据。
修复方案
用poll同时监听UART和标准输入(stdin)的事件,实现两者实时响应,不用依赖分支判断。检测到键盘输入时,读取完整内容发送到UART,之后继续监听UART数据。
修复后的代码
from machine import UART, Pin import utime from select import poll, POLLIN # 初始化UART uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1)) uart.init(bits=8, parity=None, stop=1) utime.sleep(0.5) # 创建poll对象,同时注册UART和stdin poll_obj = poll() poll_obj.register(uart, POLLIN) poll_obj.register(stdin, POLLIN) while True: # 非阻塞监听事件,超时设为0实现实时检测 events = poll_obj.poll(0) for obj, event in events: if obj is uart: # 读取UART数据并显示 if uart.any(): data = uart.read() try: data_str = data.decode('ascii') print(data_str, end='') # 避免重复换行 except UnicodeDecodeError: # 处理非ASCII二进制数据 print(f"[二进制数据]: {data.hex()}") elif obj is stdin: # 读取完整键盘输入(直到回车) input_str = stdin.readline() if input_str: # 发送到UART,保留换行符 uart.write(input_str) print(f"已发送: {input_str.strip()}")
关键修改说明
- 双输入源同时监听:把UART和stdin都注册到poll对象,通过
poll(0)实现非阻塞实时检测,解决单分支优先级问题。 - 全事件循环处理:每次循环都检查所有待处理事件,不管UART有没有数据,都能响应键盘输入。
- 完整输入读取:用
readline()读取完整输入行(直到回车),避免逐字符处理的麻烦,保证输入内容完整发送。 - 异常兼容处理:添加ASCII解码异常捕获,适配UART可能发送的非ASCII二进制数据。
内容的提问来源于stack exchange,提问作者petrbon
相关产品推荐
相关产品推荐

