pyserial使用

  • python版本大于2.7

  • pyserial版本:

import serial
print('serial版本:',serial.__version__)

# 或者直接 在终端:pip list

1. 查询串口

import serial
import serial.tools.list_ports

# 获取所有串口设备实例。
# 如果没找到串口设备,则输出:“无串口设备。”
# 如果找到串口设备,则依次输出每个设备对应的串口号和描述信息。
ports_list = list(serial.tools.list_ports.comports())
if len(ports_list) <= 0:
print("无串口设备。")
else:
print("可用的串口设备如下:")
for comport in ports_list:
print(list(comport)[0], list(comport)[1]) # 第一个就是串口号,第二个为描述信息

1.1 串口字典

  • 当我们想要实现类似串口工具的查询功能时,可以使用:
Com_Dict = None # 存放串口字典

def port_check(self):
# 检测所有存在的串口,将信息存储在字典中
self.Com_Dict = {}
port_list = list(serial.tools.list_ports.comports()) # 获取串口信息
# 索引0:将为我们提供设备的值 索引1:描述 索引2:共享端口的 hwid

for port in port_list:
self.Com_Dict["%s" % port[0]] = "%s" % port[1]
self.combox.addItem(port[0])
self.write_log("Find " + str(port[0])) # 日志输出

if len(self.Com_Dict) == 0:
self.state_label.setText("无串口")
self.write_log("Not find com!") # 日志输出

2. 串口配置

# 方式1:调用函数接口打开串口时传入配置参数
import serial

ser = serial.Serial("COM17", 115200) # 打开COM17,将波特率配置为115200,其余参数使用默认值
if ser.isOpen(): # 判断串口是否成功打开
print("打开串口成功。")
print(ser.name) # 输出串口号
else:
print("打开串口失败。")

# 或者
ser = serial.Serial(
port="COMxx",
baudrate=115200,
bytesize=serial.SEVENBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_TWO,
timeout=0.5)
  • 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。
  • rts/cts - 硬件(RTS/CTS)流控,可取值为 True, False,==md 有些设备不带硬件RTS==。
  • dsr/dtr - 硬件(DSR/DTR)流控,可取值为 True, False。
  • timeout - 读超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。当设置为 None 时,表示阻塞式读取,一直读到期望的所有数据才返回;当设置为 0 时,表示非阻塞式读取,无论读取到多少数据都立即返回;当设置为其他数值时,表示设置具体的超时时间(以秒为单位),如果在该时间内没有读取到所有数据,则直接返回。
  • write_timeout: 写超时时间,可取值为 None, 0 或者其他具体数值(支持小数)。参数值起到的效果参考 timeout 参数。

3. 发数据

  • write() 方法只能发送 bytes 类型的数据,所以需要对字符串进行 encode 编码。
  • write() 方法执行完成后,会将发送的字节数作为返回值
  • 在打开串口时,可以为 write() 方法配置超时时间。
import serial

# 打开 COM17,将波特率配置为115200.
ser = serial.Serial(port="COM17", baudrate=115200)

# 串口发送 ABCDEFG,并输出发送的字节数。
write_len = ser.write("ABCDEFG".encode('utf-8'))
print("串口发出{}个字节。".format(write_len))

ser.close()

# 发送字符串则需要
input_s="ABCGD"
if input_s != "":
input_s = (input_s + '\r\n').encode('utf-8') # 很多以\r\n 作为结束符
self.ser.write(input_s)

4.读数据

  • read() 方法默认一次读取一个字节,可以通过传入参数指定每次读取的字节数。
  • read() 方法会将读取的内容作为返回值,类型为 bytes。
  • 在打开串口时,可以为 read() 方法配置超时时间。
import serial

# 打开 COM17,将波特率配置为115200, 读超时时间为1秒
ser = serial.Serial(port="COM17", baudrate=115200, timeout=1)

# 读取串口输入信息并输出。
while True:
com_input = ser.read(10)
if com_input: # 如果读取结果非空,则输出
print(com_input)

ser.close()

5. 数据处理

5.1 struct.unpack()

  • 这是 Python 中 struct 模块提供的函数之一,用于解析字节流(即二进制数据)。它的作用是根据给定的格式字符串将字节流解析为相应的 Python 数据类型。
  • < 表示使用小端字节序解析数据(即低位字节在前)。
  • 'I' 表示无符号整数(4字节)。
  • 'H' 表示无符号短整数(2字节)。
  • 'i' 表示带符号整数(4字节)。
  • 'f' 表示浮点数(4字节)。
  • 'B' 表示无符号字节(1字节)。

例如:

accelerometer_x = struct.unpack('<f', data[50:54])[0]
accelerometer_y = struct.unpack('<f', data[54:58])[0]
accelerometer_z = struct.unpack('<f', data[58:62])[0]
gyro_x = struct.unpack('<f', data[62:66])[0]
gyro_y = struct.unpack('<f', data[66:70])[0]
gyro_z = struct.unpack('<f', data[70:74])[0]

5.2 dbinascii.b2a_hex()

  • 通常数据采用二进制协议通讯,即数据以字节流形式传递,则有时候我们需要将其转换为正常的十六进制数。
ser = serial.Serial("com5", 115200)
while True:
recv_data = ser.readline()
data = str(binascii.b2a_hex(ser.readline()))