【串口通信】python serial库时read、readline、read_all等方法的区别

【串口通信】python serial库时read、readline、read_all等方法的区别

💖 作者简介:大家好,我是Zeeland,全栈领域优质创作者。📝 CSDN主页:Zeeland🔥📣 我的博客:Zeeland📚 Github主页: Undertone0809 (Zeeland) (github.com)🎉 支持我:点赞👍+收藏⭐️+留言📝💬介绍:The mixture of software dev+Iot+ml+anything🔥

1. 概况

Python中Serial在读取数据的时候具有几种方法,本文将简单介绍一下如何使用serial库解析串口的数据。

2. 介绍

本文需要用到的几种方法和属性,大概看看就好,主要看下面的教程如何使用。

方法功能serial.read(size)读取size字节的数据serial.readline()读取一行的数据serial.readlines()读取多行的数据,将数据保存到数组里serial.read_all()读取一个timeout周期内的全部数据(常用方法)serial.read_all读取串口所有的参数信息serial_timeout(参数)超时属性,下面具体介绍

3. 快速上手

下面的场景我们需要用用COM4串口发送一串字符串"hello world",波特率9600,如何使用python的serial库进行解析串口发送来的数据?

直接上代码

import serial

ser = serial.Serial("COM2", 9600, timeout=0.01)

while True:

data = ser.read_all()

if data:

rec_str = data.decode('utf-8')

print(rec_str)

这里我创建了两个虚拟的串口进行模拟,COM2向COM1发送了两次hello world,而Python端实现了COM1,监听来自COM2的消息,用read_all()方法读取接收到的数据,接收到的数据类型是bytes类型的,因此我们需要将bytes数组转成字符串print出来,如下图所示。

而初始化的时候这里的timeout是指在设定的timeout时间范围内,如果读取的字节数据是有效的(就是非空)那就直接返回,否则一直会等到这个设定的timeout时间并返回这段时间所读的全部字节数据。

简单来说你可以理解为每timeout秒读一次数据,而如果timeout太小,数据量太大,可能一次发送不完,会数据未读完的状态。

也就是说,如果我的timeout设置为0.01,现在我有一个串口通信的传感器,传感器通过串口使用COM2发送一次数据,传感器如果在0.01秒内将所有数据都传输过来,就保存到缓存buffer中,到了0.01秒后会调用一次read_all()就可以读取到传感器发送到buffer中的数据了;如果传感器在0.01秒内没有将数据发送全的话,buffer中的数据就是不完全的,就会返回不完全的数据;如果传感器在0.01秒内发送了数据的话,buffer也会返回两组合在一起的数据。

注意:timeout的设置至关重要,如果不是特别高频的数据的话,timeout=0.01的100Hz完全够了,当然timeout最小支持多少要看你的波特率。如果我0.3秒发送了一次数据,timeout设置0.01,就可以返回一次完整的数据;如果我0.01秒发送一次数据,timeout设置0.3,那么一次就会返回30次数据,所以这就是timeout的作用。

前面引入了buffer的概念,这里你应该可以知道,你可以直接把buffer理解为一个文件夹,读数据的方式是和file是一样的,只是引入的timeout的概念,使得buffer 内的数据会以 1/timeout 的频率进行刷新。如果你把buffer当做file理解,那么readline()就是读取buffer中的一行,如果你的数据中存在\n这样的换行,那么用readline()先让不合适,很容易产生漏读的问题,而且如果你在一个timeout周期内没有用readline()处理完所有你想要的数据的话,buffer就刷新了,因此通过笔者的实践和项目经历读数据只推荐用read_all()来读取。

4. 更好的解决方案——cushy-serial

cushy-serial是一个轻量级的Serial框架,初衷是希望使Serial编程变得更加简单、快捷,因此,相较于传统的pyserial,该框架可以更加快速地构建起一个serial程序,其可以兼容pyserial的所有特性,并且自定义serial消息异步回调,无需花费精力在多线程上,项目地址:https://github.com/Undertone0809/cushy-serial

主要特性

兼容pyserial的所有特性自定义serial消息异步回调,无需花费精力在多线程上提供串口定时任务方便实现和管理多个serial连接可自定义消息协议,兼容性强

快速上手

pip install cushy-serial --upgrade

下面是一个简单的serial程序,当python客户端接收到来自串口的信息时会自动回调

from cushy_serial import CushySerial

serial = CushySerial("COM1", 9600)

serial.send("I am python client")

@serial.on_message()

def handle_serial_message(msg: bytes):

str_msg = msg.decode("utf-8")

print(f"[serial] rec msg: {str_msg}")

需要说明的是,CushySerial兼容了Serial中所有的功能,因此,你可以在CushySerial中使用Serial的所有功能。

运行结果如下

如果你想要执行定时任务,CushySerial也提供了相关的解决方案,你可以方便的轮询发送指令,并获取来自串口的信息,示例如下:

from cushy_serial import CushySerial, enable_log

enable_log()

serial = CushySerial("COM1", 9600)

instruction = bytes([0x01, 0x06, 0x00, 0x7F, 0x00, 0x01, 0x79, 0xD2])

# msg为你要轮询发送的指令,interval为轮询的时间间隔,times为执行次数,可不填写

@serial.polling_task(msg=instruction, interval=0.5, times=5)

def handle_rec_msg(rec_msg):

print(f"[serial] rec polling message: {rec_msg}")

5. 总结

在平时串口通信中,最好使用read_all()方法,并选定合适的timeout。timeout的参考资料:相关链接要是懒一点就直接用cushy-serial

猜你想看:

【pyqt、mysql、爬虫】新冠疫情信息管理系统(详细图文)总结两种最常用的python打包方式Python最佳实践-构建自己的第三方库【broadcast-service】一个轻量级Python发布订阅者框架

相关推荐

小米红米6 Pro(4GB/32GB/全网通)
det365娱乐场所官方网

小米红米6 Pro(4GB/32GB/全网通)

📅 08-07 👁️ 297
三维建模软件有哪些
365投注终止

三维建模软件有哪些

📅 09-13 👁️ 3371
感恩是一種生活態度──基督徒的感恩經典語錄
365投注终止

感恩是一種生活態度──基督徒的感恩經典語錄

📅 08-06 👁️ 7175