
本文讲解如何在 python 中基于 pyserial 接收串口数据,并通过 if 语句精准判断接收到的字符串(如 "hello")以触发对应函数,纠正常见逻辑错误并提供可运行的完整示例。
本文讲解如何在 python 中基于 pyserial 接收串口数据,并通过 if 语句精准判断接收到的字符串(如 "hello")以触发对应函数,纠正常见逻辑错误并提供可运行的完整示例。
在使用 pyserial 处理串口通信时,一个常见需求是:当上位机(如 Arduino、ESP32 或其他设备)发送特定指令(例如 "hello")时,Python 端执行相应操作(如打印问候、点亮 LED、启动任务等)。但初学者常误将串口状态判断(如 ser.is_open)与数据内容判断混为一谈——正如原代码中 if ser.is_open == hello: 这一行,不仅变量 hello 未定义,更根本的问题是:ser.is_open 返回布尔值(True/False),与接收的数据内容完全无关。
✅ 正确做法是:对 ser.readline() 获取的字节流解码为字符串后,去除首尾空白符(含换行 \n、回车 \r)再进行精确比对。推荐使用 .strip() 方法,它能可靠处理不同平台下的行结束符。
以下是修正后的完整可运行代码:
import serial
import time
def on_hello_received():
print("Hi! 'hello' command received.")
# ✅ 在此处添加你希望执行的逻辑,例如:
# control_led(True)
# start_sensor_reading()
# send_response(ser, "ack")
try:
ser = serial.Serial(port='/dev/tty.usbmodem11201', baudrate=9600, timeout=1)
print(f"Serial port {ser.port} opened successfully.")
while True:
line = ser.readline() # 返回 bytes,如 b'hello\r\n'
if line: # 非空才处理
try:
text = line.decode('utf-8').strip() # 安全解码 + 去除空白
print(f"Received: '{text}'")
if text == "hello":
on_hello_received()
# ✅ 可扩展其他指令
elif text == "quit":
print("Exiting...")
break
elif text == "ping":
ser.write(b"pong\n") # 回复响应(需确保设备支持接收)
except UnicodeDecodeError:
print("Warning: Non-UTF-8 data received, skipped.")
time.sleep(0.01) # 防止空循环占用过高 CPU
except serial.SerialException as e:
print(f"Serial error: {e}")
except KeyboardInterrupt:
print("\nUser interrupted.")
finally:
if 'ser' in locals() and ser.is_open:
ser.close()
print("Serial port closed.")? 关键注意事项:
-
ser.readline()默认以\n为终止符,若设备发送无换行(如print("hello")而非println),请改用ser.read(n)或设置ser.timeout后手动拼接缓冲区; - 始终对
decode()操作做异常捕获,避免因乱码或二进制数据导致程序崩溃; - 使用
.strip()而非.rstrip('\n')更健壮,兼容\r\n(Windows)、\n(Unix/Linux/macOS)甚至多余空格; - 在真实项目中,建议加入指令校验(如 CRC、长度限制)和防重复触发机制(如去抖延时),提升鲁棒性。
掌握这一模式后,你可轻松扩展为多指令控制系统——只需在 if/elif 链中添加新分支,让串口通信真正成为你项目的“命令中枢”。

















