4. pySerial基础操作

好,咱们进入实战环节的第一个硬骨头——pySerial。说实话,很多初学者一上来就写代码,结果串口打不开、数据读不到,折腾半天发现是参数配错了。我当年也干过这种事,调了一下午,最后发现波特率设成了9600,设备那边是115200……嗯,这种低级错误,犯过一次就记住了。

4.1 安装与导入:第一步别走偏

pySerial不是Python自带的库,你得先装。我个人习惯用pip安装,简单粗暴:

pip install pyserial

装完之后,在代码里导入:

import serial

注意,是serial,不是pyserial。我见过有人写import pyserial,结果报错半天找不到原因。你想想看,库名叫pySerial,但导入的时候用的是serial,这确实有点反直觉。

小提示:如果你用的是虚拟环境,记得先激活环境再装库。我曾经在系统Python里装了一遍,然后在虚拟环境里跑代码,死活找不到模块……这种坑,踩过一次就长记性了。

4.2 打开串口:两种方式,任你选

打开串口有两种方式,我一般用第一种,因为更直观。

方式一:创建实例时直接配置

import serial

ser = serial.Serial(
    port='COM3',        # Windows下用COM口,Linux下用/dev/ttyUSB0
    baudrate=115200,    # 波特率
    timeout=1           # 超时时间,单位秒
)

这种方式一步到位,适合大多数场景。但要注意,如果串口被其他程序占用了,这里会直接报错。我在项目中遇到过这种情况——调试的时候开了两个终端,结果第二个就打不开了。

方式二:先创建实例,再手动打开

ser = serial.Serial()
ser.port = 'COM3'
ser.baudrate = 115200
ser.timeout = 1
ser.open()

这种方式更灵活,适合需要动态修改参数的场景。比如你写了一个配置界面,让用户自己选端口和波特率,那就用这种方式。

警告:调用open()之前,一定要确保所有参数都设置好了。我曾经漏设了波特率,结果默认是9600,和设备对不上,数据全是乱码。嗯,这种问题排查起来特别费劲。

4.3 配置参数:端口、波特率、超时

这三个参数是串口通信的核心,说白了就是“跟谁说话、说多快、等多久”。

参数 说明 常见值
port 串口端口号 Windows: COM1~COM256
Linux: /dev/ttyUSB0, /dev/ttyAMA0
baudrate 波特率,即每秒传输的符号数 9600, 19200, 38400, 115200, 921600
timeout 读取超时时间(秒) None(阻塞)、0(非阻塞)、正数(超时秒数)

端口(port):Windows下是COM口,Linux下是tty设备。怎么查?Windows去设备管理器看,Linux用ls /dev/tty*。我建议你写代码的时候,先手动确认一下端口号,别想当然。

波特率(baudrate):这个必须和设备一致。设备说115200,你就得设115200,差一点都不行。我记得有一次调试飞控,波特率设成了57600,飞控那边是115200,结果读上来的数据全是乱码,我还以为是硬件坏了……

超时(timeout):这个参数很关键。设成None表示一直等,直到读到数据;设成0表示不等,没数据就返回;设成正数表示最多等多少秒。我一般设成1秒,既不会卡死,也不会频繁空转。

核心要点:超时设置直接影响程序的健壮性。如果设成None,一旦设备不发送数据,你的程序就卡死了。我建议在正式项目中,永远不要用None,至少设个1秒或2秒。

4.4 关闭串口:别忘了收尾

用完串口一定要关掉,不然下次就打不开了。代码很简单:

ser.close()

但问题是,很多人写着写着就忘了。我建议用with语句来自动管理:

with serial.Serial('COM3', 115200, timeout=1) as ser:
    # 在这里读写数据
    pass
# 退出with块后,串口自动关闭

这种方式最安全,不会因为异常退出而漏掉close()。我在项目中一直用这种方式,省心。

避坑指南:我曾经在程序崩溃后,串口没关掉,结果下次启动时提示“端口被占用”。解决办法是重启电脑,或者用工具强制释放端口。嗯,从那以后我就老老实实用with语句了。

4.5 完整示例:打开、配置、关闭一条龙

下面是一个完整的示例,包含了打开、配置、读写和关闭:

import serial
import time

try:
    # 打开串口
    ser = serial.Serial(
        port='COM3',
        baudrate=115200,
        timeout=1
    )
    
    print(f"串口已打开: {ser.port}, 波特率: {ser.baudrate}")
    
    # 发送数据
    ser.write(b'Hello, World!\n')
    
    # 读取数据
    response = ser.readline()
    print(f"收到: {response}")
    
    # 等待一会儿
    time.sleep(0.1)
    
except serial.SerialException as e:
    print(f"串口错误: {e}")
    
finally:
    # 确保关闭串口
    if 'ser' in locals() and ser.is_open:
        ser.close()
        print("串口已关闭")

这个例子虽然简单,但包含了所有关键步骤。你想想看,实际项目中无非就是在这个基础上加循环、加协议解析、加异常处理。

4.6 知识体系总览

下面这张图帮你理清pySerial基础操作的核心逻辑:

pySerial基础操作知识体系 pySerial核心操作 打开串口 方式一:构造时配置 方式二:先创建后配置 推荐:with语句自动管理 配置参数 port:端口号 baudrate:波特率 timeout:超时时间

这张图把pySerial基础操作的三个核心环节串起来了。你从“打开串口”开始,根据场景选合适的方式;然后配置端口、波特率、超时这三个关键参数;最后别忘了关闭串口。说白了,就是这三步走。

我的经验:刚开始学的时候,别急着写复杂的读写逻辑。先把打开、配置、关闭这三步跑通,确认串口能正常连接。我每次调试新设备,都是先写一个最简单的“打开-关闭”脚本,确认硬件没问题了,再往上加功能。这样出了问题,排查范围小得多。

好了,pySerial的基础操作就这些。记住:端口要对、波特率要匹配、超时要有、用完要关。这四个要点记住了,串口通信的第一步就算站稳了。


可可精品资料库