本文详解python中使用pyserial向com端口发送数字时的常见错误(如类型不匹配、写入阻塞),并提供带超时控制、定时发送的健壮实现方案。
在Python中通过pyserial库向COM端口(如COM4)发送数据时,一个典型误区是直接传入整数(如ser.write(21))。实际上,serial.Serial.write()方法仅接受字节对象(bytes或bytearray),而非整数、字符串或其它类型。若传入整数,会触发TypeError;而即使手动修正为bytes([21]),若未配置写入超时(write_timeout),当目标设备未就绪或接收缓冲区满时,write()仍可能无限阻塞——这正是原代码“操作挂起”的根本原因。
timeout参数仅控制读取操作(read())的等待时长,对写入无效;真正影响write()行为的是write_timeout参数。将其设为0表示非阻塞写入(即立即返回,成功则返回实际写入字节数,失败则抛出serial.TimeoutException);设为None则为无限等待(默认行为,易导致卡死);设为正数则为最大等待毫秒数。
以下是发送数字21到COM4、每秒一次、持续5秒的完整可运行示例:
import serial
import time
# 配置串口:指定 write_timeout=0 实现非阻塞写入
ser = serial.Serial('COM4', baudrate=9600, write_timeout=0)
# 将数字21转换为单字节对象(0x15)
data_to_send = bytes([21])
try:
for i in range(5):
# 执行写入,捕获可能的异常
written = ser.write(data_to_send)
print(f"第{i+1}次:成功发送 {written} 字节(值:{data_to_send[0]})")
time.sleep(1)
except serial.SerialTimeoutException:
print("错误:
写入超时,请检查目标设备是否连接正常或串口配置是否匹配。")
except serial.SerialException as e:
print(f"串口异常:{e}")
finally:
if ser.is_open:
ser.close()
print("串口已关闭。")关键注意事项:
通过以上修正,即可稳定、可靠地实现定时数字发送,为嵌入式通信、设备控制等应用打下坚实基础。