serial模块(也称为pyserial)是Python中用于串口通信的标准库,支持Windows、Linux和macOS等多个平台。
安装pyserial
pip install pyserial
基本使用方法
1. 打开串口连接
import serial
# 打开串口
ser = serial.Serial(
port='COM3', # Windows下的串口号
# port='/dev/ttyUSB0', # Linux下的设备名
baudrate=9600, # 波特率
bytesize=8, # 数据位
parity='N', # 校验位(N无校验/E偶校验/O奇校验)
stopbits=1, # 停止位
timeout=1 # 读取超时时间(秒)
)
print(f"串口状态: {'打开' if ser.is_open else '关闭'}")
print(f"串口设置: {ser}")
2. 发送数据
data_to_send = "Hello, Serial!\r\n" # 通常需要加回车换行
ser.write(data_to_send.encode('utf-8')) # 需要编码为字节
3. 接收数据
# 读取一行(直到遇到换行符)
received = ser.readline().decode('utf-8').strip()
print(f"收到数据: {received}")
# 或者读取指定字节数
data = ser.read(10) # 读取10个字节
print(f"收到数据: {data}")
# 检查接收缓冲区中有多少字节等待读取
bytes_waiting = ser.in_waiting
print(f"等待读取的字节数: {bytes_waiting}")
4. 关闭串口
ser.close()
print(f"串口状态: {'打开' if ser.is_open else '关闭'}")
实用技巧
1. 自动检测可用串口
import serial.tools.list_ports
ports = serial.tools.list_ports.comports()
for port in ports:
print(f"找到串口: {port.device} - {port.description}")
2. 使用with语句自动管理资源
with serial.Serial('COM3', 9600, timeout=1) as ser:
ser.write(b'AT\r\n')
response = ser.readline()
print(response.decode('utf-8'))
3. 二进制数据收发
# 发送二进制数据
ser.write(bytes([0x41, 0x42, 0x43])) # 发送ABC的ASCII码
# 接收二进制数据
binary_data = ser.read(5) # 读取5个字节
print(f"收到二进制数据: {binary_data}")
4. 设置RTS/CTS硬件流控
ser = serial.Serial('COM3', 115200, rtscts=True)
常见问题解决
-
权限问题(Linux/Mac):
sudo chmod 666 /dev/ttyUSB0
或将自己加入dialout组:
sudo usermod -a -G dialout $USER
-
串口被占用:
-
确保没有其他程序正在使用该串口
-
关闭所有串口终端软件
-
-
数据接收不完整:
-
检查波特率、数据位、停止位和校验位设置
-
增加读取超时时间
-
-
中文乱码:
-
确保发送和接收使用相同的编码(通常utf-8或gbk)
-
完整示例
import serial
import threading
def read_from_port(ser):
while True:
if ser.in_waiting > 0:
data = ser.readline().decode('utf-8').strip()
print(f"收到: {data}")
def main():
port = input("请输入串口号(如COM3或/dev/ttyUSB0): ")
baudrate = int(input("请输入波特率(如9600): "))
try:
ser = serial.Serial(port, baudrate, timeout=1)
print(f"已连接 {port} @ {baudrate} bps")
# 启动读取线程
thread = threading.Thread(target=read_from_port, args=(ser,))
thread.daemon = True
thread.start()
# 主线程处理发送
while True:
message = input("发送(输入quit退出): ")
if message.lower() == 'quit':
break
ser.write((message + '\r\n').encode('utf-8'))
except serial.SerialException as e:
print(f"串口错误: {e}")
finally:
if 'ser' in locals() and ser.is_open:
ser.close()
print("串口已关闭")
if __name__ == "__main__":
main()
2097

被折叠的 条评论
为什么被折叠?



