
本文详解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("串口已关闭。")关键注意事项:
立即学习“Python免费学习笔记(深入)”;
- ✅ 始终使用 bytes([n]) 将0–255范围内的整数转为单字节;若需发送多字节整数(如16位),请用struct.pack();
- ✅ 务必显式设置 write_timeout(推荐0或1),避免程序意外挂起;
- ✅ 使用try/except/finally确保串口最终被关闭,防止资源泄漏;
- ✅ 发送前确认目标设备(如另一端的COM3)已正确打开并配置相同波特率(9600)、数据位(8)、停止位(1)、无校验(N);
- ✅ 在真实硬件场景中,建议配合逻辑分析仪或串口调试助手验证波形与数据。
通过以上修正,即可稳定、可靠地实现定时数字发送,为嵌入式通信、设备控制等应用打下坚实基础。










