杰瑞科技汇

Python inwaiting函数如何获取串口待读数据量?

inwaiting 并不是一个 Python 的内置函数,也不是标准库的一部分(如 os, sys, time 等)。

Python inwaiting函数如何获取串口待读数据量?-图1
(图片来源网络,侵删)

inwaiting 是一个非常常见的属性(attribute),它通常出现在与串口通信相关的库中,最著名的就是 pyserial

你的问题更准确地说是:“Python 中 pyserial 库的 inwaiting 属性是做什么用的?”

下面我将详细解释这个属性。


inwaiting 是什么?

inwaitingpyserial 库中 Serial 对象的一个只读属性

Python inwaiting函数如何获取串口待读数据量?-图2
(图片来源网络,侵删)

它的作用是:查询串口输入缓冲区中当前等待读取的字节数。

当你从串口设备(如 Arduino、传感器、GPS模块等)接收数据时,这些数据并不会立刻全部被 Python 程序读取,而是会先存入一个临时的“缓冲区”里。inwaiting 就能告诉你这个缓冲区里还堆积了多少个字节的数据没被处理。

为什么需要 inwaiting

在串口通信中,数据是流式的,它不像文件那样有明确的“,发送方可能会分多次发送一长串数据,而接收方需要知道什么时候才算收到了一条完整的信息。

inwaiting 主要用于以下场景:

Python inwaiting函数如何获取串口待读数据量?-图3
(图片来源网络,侵删)
  1. 判断数据是否完整:如果你知道一次发送的数据包大小(10个字节),你就可以检查 inwaiting 的值。inwaiting >= 10,就说明缓冲区里至少有10个字节可以读了,可以尝试读取一个完整的数据包。
  2. 一次性读取所有可用数据:有时你希望把当前缓冲区里所有的数据都读出来,不管有多少个字节,这时就可以用 inwaiting 的值来确定要读取的长度,避免只读取一部分数据而把剩下的留在缓冲区里,造成数据混乱。
  3. 避免数据丢失:如果你的程序处理数据的速度慢于数据接收的速度,inwaiting 的值就会不断增大,通过监控它,你可以判断数据接收的负载情况,及时调整读取策略,防止缓冲区溢出导致数据丢失。

如何使用 inwaiting(代码示例)

请确保你已经安装了 pyserial 库:

pip install pyserial

下面是一个完整的示例,演示了如何使用 inwaiting 属性。

这个例子模拟了一个场景:一个设备(这里是模拟的)不断向串口发送数据,而我们的 Python 程序则负责读取并处理这些数据。

import serial
import time
# --- 配置串口参数 ---
# 请根据你的实际情况修改这些参数
SERIAL_PORT = 'COM3'  # Windows 系统如 'COM3', 'COM4'
# SERIAL_PORT = '/dev/ttyUSB0' # Linux 系统如 '/dev/ttyUSB0'
# SERIAL_PORT = '/dev/tty.usbserial-XXXX' # macOS 系统如 '/dev/tty.usbserial-XXXX0'
BAUD_RATE = 9600
TIMEOUT = 1  # 读取超时时间(秒)
def main():
    # --- 1. 打开串口连接 ---
    try:
        ser = serial.Serial(
            port=SERIAL_PORT,
            baudrate=BAUD_RATE,
            timeout=TIMEOUT
        )
        print(f"成功打开串口 {ser.name}")
        ser.flushInput() # 清空输入缓冲区
    except serial.SerialException as e:
        print(f"无法打开串口: {e}")
        return
    # --- 2. 模拟数据发送和接收 ---
    try:
        while True:
            # 检查串口缓冲区中是否有数据等待
            if ser.in_waiting > 0:
                # 获取缓冲区中等待的字节数
                bytes_to_read = ser.in_waiting
                print(f"检测到 {bytes_to_read} 个字节等待读取...")
                # 读取所有可用的数据
                # 注意:如果数据量非常大,一次性读取可能会占用大量内存
                # 此时可以设置一个合理的读取长度,ser.read(1024)
                received_data = ser.read(bytes_to_read)
                # 将接收到的字节转换为字符串并打印
                # 假设设备发送的是 ASCII 编码的文本
                try:
                    decoded_message = received_data.decode('ascii', errors='ignore')
                    print(f"接收到数据: '{decoded_message}'")
                except UnicodeDecodeError:
                    print(f"接收到原始字节: {received_data}")
            # 稍微等待一下,避免CPU占用过高
            time.sleep(0.1)
    except KeyboardInterrupt:
        print("\n程序被用户中断。")
    except Exception as e:
        print(f"发生错误: {e}")
    finally:
        # --- 3. 关闭串口连接 ---
        if ser.is_open:
            ser.close()
            print("串口已关闭。")
if __name__ == '__main__':
    main()

代码解释:

  1. ser = serial.Serial(...): 创建一个 Serial 对象,并配置好串口名、波特率和超时时间。timeout=1 的意思是,如果调用 ser.read() 时缓冲区里没有数据,程序会等待最多1秒,如果1秒后还没有数据,就返回空数据,而不是无限期地等待下去。
  2. ser.in_waiting: 这是核心用法,在 while 循环中,我们不断检查这个值。
  3. if ser.in_waiting > 0:: 如果这个值大于0,说明缓冲区里有数据。
  4. bytes_to_read = ser.in_waiting: 我们把缓冲区里等待的字节数存起来。
  5. received_data = ser.read(bytes_to_read): 调用 ser.read() 并传入要读取的字节数,这样就能一次性把缓冲区里所有的数据都读出来,不会遗漏。
  6. ser.close(): 在程序结束前,一定要关闭串口,释放资源。

inwaiting vs. in_waiting

在较新版本的 pyserial 中,推荐使用 in_waiting(带下划线)。inwaiting 是旧版本中使用的名称,为了向后兼容性,它通常仍然可用,但官方文档和最佳实践都建议使用 in_waiting

两者功能完全相同,你可以在你的代码中任选其一。

# 推荐使用(新版本)
bytes_available = ser.in_waiting
# 也可以使用(旧版本,通常也有效)
bytes_available = ser.inwaiting
特性 描述
名称 inwaiting (旧版) 或 in_waiting (新版,推荐)
类型 属性,不是函数
所属库 pyserial
作用 查询串口输入缓冲区中未读数据的字节数
主要用途 判断数据是否完整、一次性读取所有数据、监控数据接收负载
示例用法 if ser.in_waiting > 0: data = ser.read(ser.in_waiting)

希望这个解释能帮助你完全理解 inwaiting 的用法!

分享:
扫描分享到社交APP
上一篇
下一篇