3. pyserial库安装与基础配置

好了,到了真正动手的环节了。这一章我们搞定 pyserial 的安装和基础配置。别小看这一步,我见过太多人在串口参数上栽跟头——波特率设错、超时没配,折腾半天还以为硬件坏了。

3.1 安装 pyserial:两种方式

安装其实很简单,两条命令的事。但我建议你用第二种,尤其是做项目的时候。

方式一:直接 pip 安装

pip install pyserial

这条命令会把 pyserial 装到系统全局的 Python 环境里。方便是方便,但如果你同时做多个项目,依赖版本打架就麻烦了。

方式二:虚拟环境安装(我推荐)

python -m venv uart_env
source uart_env/bin/activate   # Linux/Mac
uart_env\Scripts\activate      # Windows
pip install pyserial
我的习惯:每个项目都建独立的虚拟环境。之前有个同事,全局装了一堆库,升级 pyserial 时把另一个项目的依赖搞崩了,排查了一下午。虚拟环境隔离干净,省心。

3.2 验证安装

装完之后,进 Python 交互环境敲一行:

import serial
print(serial.__version__)

能正常输出版本号,就说明装好了。如果报错 ModuleNotFoundError,检查一下是不是在虚拟环境里装的,或者 pip 装到了不同的 Python 版本上。

3.3 串口参数设置:核心五要素

串口通信说白了就是两边约好「怎么说话」。参数对不上,数据就是乱码。我当年第一次调 Modbus 设备,波特率设成了 9600,设备是 19200,出来的数据跟天书一样。

下面这五个参数,一个都不能错:

参数 常用值 说明
波特率 9600, 19200, 115200 每秒传输的符号数,两边必须一致
数据位 7, 8 大多设备用 8 位,老设备可能用 7
停止位 1, 1.5, 2 常用 1 位,慢速设备可能用 2
校验位 None, Even, Odd 无校验最常见,工业环境有时用偶校验
流控制 None, RTS/CTS, XON/XOFF 大多不用,特殊设备才需要

代码里怎么配?看这个例子:

import serial

ser = serial.Serial(
    port='/dev/ttyAMA0',   # 树莓派上的串口设备
    baudrate=9600,
    bytesize=serial.EIGHTBITS,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    timeout=1               # 这个后面重点讲
)
注意:树莓派的串口设备名因型号和配置而异。老款可能是 /dev/ttyAMA0,新款或开启了蓝牙的可能变成 /dev/ttyS0 或 /dev/serial0。我建议用 /dev/serial0,它是软链接,自动指向当前可用的硬件串口。

3.4 超时处理:最容易忽略的坑

超时这个参数,说白了就是「等多久不等了」。不设超时,程序可能卡死;设得太短,数据没读完就被丢了。

pyserial 支持三种超时模式:

  • None:阻塞模式,一直等到数据来。慎用,一旦设备没响应,程序就卡死了。
  • 0:非阻塞模式,立即返回。适合轮询场景,但需要自己处理数据拼包。
  • 正数(秒):等待指定时间,超时返回已读取的数据。最常用。

我一般这么设:

# 读超时 1 秒,写超时 0.5 秒
ser = serial.Serial(
    port='/dev/serial0',
    baudrate=115200,
    timeout=1,
    write_timeout=0.5
)

避坑指南:我曾经调试一个扫码枪,设了 timeout=0.1,结果数据总是少几个字节。后来发现扫码枪发送间隔 200ms,超时太短导致数据被截断。改成 timeout=0.5 就正常了。

经验法则:超时时间至少是设备发送间隔的 2-3 倍。

3.5 完整示例:打开与关闭串口

写代码要养成好习惯——用完就关。不然下次打开会报 Permission denied。

import serial

try:
    ser = serial.Serial(
        port='/dev/serial0',
        baudrate=9600,
        timeout=1
    )
    print(f"串口已打开: {ser.port}")
    print(f"参数: {ser.baudrate} {ser.bytesize} {ser.parity} {ser.stopbits}")
    
    # 这里做你的通信逻辑...
    
except serial.SerialException as e:
    print(f"打开串口失败: {e}")
finally:
    if 'ser' in locals() and ser.is_open:
        ser.close()
        print("串口已关闭")

嗯,这里要注意:finally 块里一定要判断 is_open,不然重复关闭会报错。

3.6 本章知识体系

下面这张图把 pyserial 的基础配置流程串起来了,你照着这个思路走,基本不会漏东西:

pyserial 基础配置流程 ① 安装 pyserial ② import serial ③ 配置串口参数 port / baudrate / bytesize / parity / stopbits ④ 设置超时(timeout / write_timeout) ⑤ serial.Serial() ⑥ ser.close() 安装方式 pip install pyserial 或虚拟环境安装 验证: print(serial.__version__) 超时模式 None → 阻塞(慎用) 0 → 非阻塞(轮询) 正数 → 超时返回(推荐)

这张图把从安装到关闭的完整链路画清楚了。你每次配串口,按这个流程走一遍,基本不会漏参数。

小技巧:调试阶段可以用 ser.is_open 检查串口状态,用 ser.get_settings() 打印当前参数,方便排查问题。