用 Python 玩转串口(基于 pySerial)

引言

对于嵌入式设备,串口可谓是最常用的接口。在裸机编程中,串口通常用于输出程序的运行或调试信息;在嵌入式操作系统中,串口通常会作为系统的控制台接口。如果掌握了Python操作串口的方法,那我们就可以利用Python强大的数据处理能力,快速开发出许多好用的工具。

串口的基本操作

在使用 Python 之前,我们先回想一下平时我们是如何使用串口的。总结来说,无非就是下面几个步骤:
首先,我们需要确定要使用的串口号。
其次,配置波特率、数据位、奇偶校验位、停止位、DTR/DSR、RTS/CTS 和 XON/XOFF。
第三,打开串口。
第四,收发数据。
第五,关闭串口。
接下来,我们就来研究下用 Python 怎么实现上面的这些步骤。

初识 pySerial

pySerial 是 Python 中用于操作串口的第三方模块,它支持 Windows、Linux、OSX、BSD等多个平台。如果要使用 pySerial 模块,首先必须保证 Python 版本高于 Python 2.7 或者 Python 3.4。另外,如果你是用的是 Windows 系统,那必须使用 Win7 及以上的版本。
pySerial 的安装很简单,只需要执行一条命令:pip install pyserial
安装完成后,只需要在 Python 代码中使用 import serial 语句导入该模块即可。

确定串口号


   
   
  1. import serial
  2. import serial.tools.list_ports
  3. # 获取所有串口设备实例。
  4. # 如果没找到串口设备,则输出:“无串口设备。”
  5. # 如果找到串口设备,则依次输出每个设备对应的串口号和描述信息。
  6. ports_list = list(serial.tools.list_ports.comports())
  7. if len(ports_list) <= 0:
  8. print( "无串口设备。")
  9. else:
  10. print( "可用的串口设备如下:")
  11. for comport in ports_list:
  12. print( list(comport)[ 0], list(comport)[ 1])

运行结果:


   
   
  1. 可用的串口设备如下:
  2. COM 4 蓝牙链接上的标准串行 (COM 4)
  3. COM 6 蓝牙链接上的标准串行 (COM 6)
  4. COM 5 蓝牙链接上的标准串行 (COM 5)
  5. COM 18 Prolific PL 2303GT USB Serial COM Port (COM 18)
  6. COM 17 Prolific USB-to-Serial Comm Port (COM 17)
  7. COM 3 蓝牙链接上的标准串行 (COM 3)

配置串口 & 打开串口

pySerial 配置和打开串口有两种方式,第一种方式是在调用函数接口打开串口时传入配置参数,第二种方式是先配置参数,然后再打开串口。这两种方式操作的效果一样,此处我们只介绍第一种。


   
   
  1. # 方式1:调用函数接口打开串口时传入配置参数
  2. import serial
  3. ser = serial.Serial( "COM17", 115200) # 打开COM17,将波特率配置为115200,其余参数使用默认值
  4. if ser.isOpen(): # 判断串口是否成功打开
  5. print( "打开串口成功。")
  6. print(ser.name) # 输出串口号
  7. else:
  8. print( "打开串口失败。")

在使用 serial.Serial() 创建串口实例时,可以传入的参数很多,常用的参数如下(默认值用红色标记):

  • port - 串口设备名或 None。
  • baudrate - 波特率,可以是50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000。
  • bytesize - 数据位,可取值为:FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS。
  • parity - 校验位,可取值为:PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, PARITY_SPACE。
  • stopbits - 停止位,可取值为:STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TOW。
  • xonxoff - 软件流控,可取值为 True, False。
  • rtscts - 硬件(RTS/CTS)流控,可取值为 True, False。
  • dsr/dtr - 硬件(DSR/DTR)流控,可取值为 True, False。
  • timeout - 读超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。当设置为 None 时,表示阻塞式读取,一直读到期望的所有数据才返回;当设置为 0 时,表示非阻塞式读取,无论读取到多少数据都立即返回;当设置为其他数值时,表示设置具体的超时时间(以秒为单位),如果在该时间内没有读取到所有数据,则直接返回。
  • write_timeout: 写超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。参数值起到的效果参考 timeout 参数。

   
   
  1. import serial
  2. # 打开 COM17,将波特率配置为115200,数据位为7,停止位为2,无校验位,读超时时间为0.5秒。
  3. ser = serial.Serial(port= "COM17",
  4. baudrate= 115200,
  5. bytesize=serial.SEVENBITS,
  6. parity=serial.PARITY_NONE,
  7. stopbits=serial.STOPBITS_TWO,
  8. timeout= 0.5)

关闭串口

关闭串口很简单,直接调用 close() 方法即可。


   
   
  1. import serial
  2. ser = serial.Serial( "COM17", 115200) # 打开 COM17,将波特率配置为115200,其余参数使用默认值
  3. if ser.isOpen(): # 判断串口是否成功打开
  4. print( "打开串口成功。")
  5. else:
  6. print( "打开串口失败。")
  7. ser.close()
  8. if ser.isOpen(): # 判断串口是否关闭
  9. print( "串口未关闭。")
  10. else:
  11. print( "串口已关闭。")

发送数据 write()

关于write() 方法,需要了解如下几点:
① write() 方法只能发送 bytes 类型的数据,所以需要对字符串进行 encode 编码。
② write() 方法执行完成后,会将发送的字节数作为返回值。
③ 在打开串口时,可以为 write() 方法配置超时时间


   
   
  1. import serial
  2. # 打开 COM17,将波特率配置为115200.
  3. ser = serial.Serial(port= "COM17", baudrate= 115200)
  4. # 串口发送 ABCDEFG,并输出发送的字节数。
  5. write_len = ser.write( "ABCDEFG".encode( 'utf-8'))
  6. print( "串口发出{}个字节。". format(write_len))
  7. ser.close()

读取数据 read()

关于 read() 方法,需要了解如下几点:
① read() 方法默认一次读取一个字节,可以通过传入参数指定每次读取的字节数。
② read() 方法会将读取的内容作为返回值,类型为 bytes。
③ 在打开串口时,可以为 read() 方法配置超时时间。


   
   
  1. import serial
  2. # 打开 COM17,将波特率配置为115200, 读超时时间为1秒
  3. ser = serial.Serial(port= "COM17", baudrate= 115200, timeout= 1)
  4. # 读取串口输入信息并输出。
  5. while True:
  6. com_input = ser.read( 10)
  7. if com_input: # 如果读取结果非空,则输出
  8. print(com_input)
  9. ser.close()

总结

以上就是对 pySerial 模块使用方法的简单总结,如果想要了解更多 pySerial 细节,可以参考 pySerial官方文档

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在使用 PySerial 和 PyQt5 实现串口实时状态发现并选择的过程中,我们可以使用 QComboBox 组件来实现串口的选择,使用 PySerial 库来进行串口的实时状态发现。 首先,我们需要安装 PySerial 库,可以使用以下命令进行安装: ``` pip install pyserial ``` 接着,我们需要在 PyQt5 界面中添加一个 QComboBox 组件,用于显示可用的串口。代码如下: ```python from PyQt5.QtWidgets import QComboBox # 创建一个 QComboBox 对象 self.combo_box = QComboBox(self) # 将 QComboBox 添加到界面上 self.layout.addWidget(self.combo_box) ``` 接着,我们需要使用 PySerial 库来实现串口的实时状态发现。代码如下: ```python import serial.tools.list_ports # 获取可用的串口列表 ports = serial.tools.list_ports.comports() # 遍历可用的串口列表,将串口添加到 QComboBox 中 for port in ports: self.combo_box.addItem(port.device) ``` 以上代码会获取所有可用的串口,并将它们添加到 QComboBox 中。 最后,我们需要在 QComboBox 中选择串口,以便进行通信。代码如下: ```python import serial # 获取选中的串口 port_name = self.combo_box.currentText() # 创建串口对象 ser = serial.Serial(port_name, 9600) ``` 以上代码会获取当前选中的串口名称,并创建一个串口对象以进行通信。 综上所述,我们可以使用 PyQt5 和 PySerial 库来实现串口实时状态发现并选择。完整的代码示例如下: ```python from PyQt5.QtWidgets import QComboBox, QWidget, QVBoxLayout import serial.tools.list_ports import serial class SerialMonitor(QWidget): def __init__(self): super().__init__() # 创建一个垂直布局 self.layout = QVBoxLayout(self) # 创建一个 QComboBox 对象 self.combo_box = QComboBox(self) # 将 QComboBox 添加到界面上 self.layout.addWidget(self.combo_box) # 获取可用的串口列表 ports = serial.tools.list_ports.comports() # 遍历可用的串口列表,将串口添加到 QComboBox 中 for port in ports: self.combo_box.addItem(port.device) # 为 QComboBox 组件添加回调函数 self.combo_box.currentIndexChanged.connect(self.on_serial_port_selected) def on_serial_port_selected(self): # 获取选中的串口 port_name = self.combo_box.currentText() # 创建串口对象 ser = serial.Serial(port_name, 9600) # 在此处进行串口通信 ``` 在以上代码中,我们创建了一个名为 SerialMonitor 的 QWidget 子类,它包含一个 QComboBox 和一个垂直布局。我们使用 PySerial 库获取可用的串口列表,并将串口名称添加到 QComboBox 中。在选择串口时,我们使用 PySerial 创建一个串口对象以进行通信。你可以在 on_serial_port_selected 函数中添加任何你需要的串口通信代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值