【串口通信】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

猜你想看:

### 回答1: Pythonserial模块是用于读写串口的工具。serial.read()是用于从串口读取数据的函数,它会一直阻塞程序直到接收到数据。当调用serial.read()时,它会尝试读取一个字节的数据,如果在超时时间内未接收到数据,则会返回空值。如果需要读取多个字节的数据,可以在read()函数中指定读取的字节数。例如,如果需要读取10个字节的数据,可以使用serial.read(10)。 ### 回答2: Python中的serial库提供了一种简便的方式来进行串口通信,其中的serial.read()函数用于从串口中接收数据。实际上,这个函数读取串口缓冲区中的数据,并返回读取到的字节数。下面我将对其进行更详细的解释。 首先,我们需要导入serial库,然后创建一个串口对象。例如,可以使用以下代码: ``` import serial ser = serial.Serial('COM1', 9600) ``` 上述代码中,我们通过serial.Serial函数创建了一个串口对象ser,将其连接至COM1端口,并设置波特率为9600。你可以根据实际情况修改这些参数。 接下来,我们可以使用serial.read()函数从串口中读取数据。该函数的用法如下: ``` data = ser.read(size) ``` 其中,size参数表示需要读取的字节数。函数将返回一个字节串,其中包含了读取到的数据。需要注意的是,如果在指定的时间内没有可读取的字节,则函数将会超时。 如果你想读取固定数量的字节数据,可以使用以下代码示例: ``` data = ser.read(10) # 读取10个字节的数据 ``` 你也可以基于实际情况采用其他读取策略,例如在接收到特定字符时停止读取。在此之前,请确保调用serial.read()之前已经打开了串口连接。 最后,当你读取完所有需要的数据后,记得关闭串口连接以释放资源。可以使用以下代码: ``` ser.close() # 关闭串口连接 ``` 以上便是关于使用Python中的serial.read()函数接收串口数据的简单解释。你可以根据自己的需求和具体情况进行进一步的应用。 ### 回答3: Python中的serial.read()函数用于从串口接收数据。它是Serial模块中的一个方法,需要先导入Serial模块才能使用。 在使用serial.read()函数之前,我们需要先创建一个串口对象。可以通过Serial模块的Serial()构造函数来创建串口对象,并指定串口的端口号、波特率等参数。 在接收串口数据时,可以使用serial.read()函数。这个函数的作用是从串口中读取指定数量的字节数据,并返回读取到的数据。可以将读取到的数据赋值给一个变量,以便后续操作。 在调用serial.read()函数时,需要指定要读取的字节数量作为参数。当串口中的数据量小于指定数量时,函数将阻塞并等待足够的数据可用。同时,函数还可以使用超时参数来设置阻塞的最长等待时间。 示例代码如下所示: ```python import serial # 创建串口对象 ser = serial.Serial(port='COM1', baudrate=9600) # 读取串口数据 data = ser.read(10) # 读取10个字节的数据 # 打印读取到的数据 print(data) ``` 上述代码创建了一个名为ser的串口对象,并指定了串口的端口号和波特率。通过调用ser.read(10)函数,读取了10个字节的数据,并将其赋值给data变量。最后,通过print语句输出了读取到的数据。 需要注意的是,serial.read()函数一次只能读取一定数量的字节数据,如果要读取更多的数据,可以使用循环结构来多次调用该函数。同时,还可以使用其他函数来读取不同类型的数据,如serial.readline()函数用于读取一行文本数据。 总之,通过Pythonserial.read()函数,我们可以方便地从串口接收数据,并将其用于后续的数据处理和分析。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zeeland

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值