杰瑞科技汇

python inwaiting

Of course! The term inwaiting() is not a built-in Python function, but it's a very common method found in libraries for serial communication. It's used to check how many bytes are currently available in the input buffer, waiting to be read.

python inwaiting-图1
(图片来源网络,侵删)

This is most famously associated with the pyserial library, which is the standard for working with serial ports in Python.

Let's break it down.

What is inwaiting()?

The inwaiting() method, when called on a serial port object, returns the number of bytes that have been received by the computer and stored in the serial port's internal input buffer but have not yet been read by your Python program.

Think of it like a queue at a post office:

python inwaiting-图2
(图片来源网络,侵删)
  • Data is the mail.
  • The serial port is the post office.
  • The input buffer is the post office's mailroom.
  • Your Python program is the postal worker.
  • inwaiting() is the postal worker asking, "How many pieces of mail are waiting in the mailroom for me to process?"

Why is it useful?

inwaiting() is crucial for robust serial communication, especially when dealing with protocols that send messages of variable length.

  1. Preventing Data Loss: Without checking inwaiting(), you might only read one byte at a time using ser.read(1). If data is arriving faster than you can read it, the buffer will fill up, and new incoming data will be lost (this is called an "overrun error").
  2. Reading Complete Messages: Many protocols send messages terminated by a special character (like a newline \n). You can use inwaiting() to read all available bytes until the buffer is empty, ensuring you capture the entire message at once.
  3. Non-blocking Loops: In applications like robotics or data logging, you often have a main loop. inwaiting() allows you to check for data without your program getting stuck waiting (ser.read() can be blocking). You can only attempt to read if data is actually present.

How to Use inwaiting() with pyserial

First, you need to install the library if you haven't already:

pip install pyserial

Here is a complete, practical example.

Scenario

We have a device (like an Arduino or a sensor) connected to a serial port that sends data. We want to read all the data that has arrived, even if multiple messages were sent in quick succession.

python inwaiting-图3
(图片来源网络,侵删)

Example Code

import serial
import time
# --- Configuration ---
# IMPORTANT: You must change 'COM3' to your actual serial port.
# On Linux, it might be '/dev/ttyUSB0' or '/dev/ttyACM0'.
# On macOS, it might be '/dev/tty.usbserial-XXXX'.
SERIAL_PORT = 'COM3'
BAUD_RATE = 9600
TIMEOUT = 1  # Seconds to wait for data
# --- Main Program ---
try:
    # 1. Establish the serial connection
    ser = serial.Serial(
        port=SERIAL_PORT,
        baudrate=BAUD_RATE,
        timeout=TIMEOUT
    )
    print(f"Successfully connected to {ser.portstr}")
    # Simulate a device sending data.
    # In a real scenario, you'd have another device or program sending this.
    # You can test this by sending data from the Arduino Serial Monitor.
    print("\nSimulating incoming data...")
    # Let's imagine the device sends:
    # "Sensor A: 25.1\nSensor B: 30.4\nHello\n"
    # 2. Main loop to read data
    while True:
        # Check how many bytes are waiting in the buffer
        bytes_to_read = ser.in_waiting
        if bytes_to_read > 0:
            print(f"-> {bytes_to_read} byte(s) available in the buffer.")
            # Read all available bytes at once
            received_data = ser.read(bytes_to_read)
            # Decode the bytes to a string and print
            # The 'ignore' error handler skips any non-decodable bytes
            message = received_data.decode('utf-8', errors='ignore').strip()
            if message: # Only print if there's something to show
                print(f"   Received: '{message}'")
        else:
            # No data waiting, do other tasks or just wait a bit
            # print("No data waiting...")
            time.sleep(0.1) # Small delay to prevent a busy-wait loop
except serial.SerialException as e:
    print(f"Error: Could not open serial port {SERIAL_PORT}.")
    print(f"Details: {e}")
except KeyboardInterrupt:
    print("\nProgram terminated by user.")
finally:
    # 3. Ensure the serial port is closed when the program exits
    if 'ser' in locals() and ser.is_open:
        ser.close()
        print("Serial port closed.")

How to Run This Example

  1. Find your port: Open your device manager (Windows) or run ls /dev/tty* (Linux/macOS) to find your serial port.
  2. Change SERIAL_PORT: Update the SERIAL_PORT variable in the code to your port.
  3. Run the script: python your_script_name.py
  4. Send data: Open another serial terminal (like Arduino IDE's Serial Monitor, PuTTY, or screen) and connect to the same port. Type a message and press Enter. You will see the script detect the incoming bytes and print the full message.

Common Pitfalls and Important Notes

  1. in_waiting vs inwaiting()

    • in_waiting (Property): In modern versions of pyserial (3.0 and later), in_waiting is a property, not a method. You access it without parentheses: ser.in_waiting.
    • inwaiting() (Method): In older versions of pyserial, it was a method, so you called it with parentheses: ser.inwaiting().
    • Recommendation: Always use ser.in_waiting. It is the current standard and is more "Pythonic" (properties are generally preferred over methods for simple attribute access).
  2. Blocking vs. Non-blocking:

    • ser.in_waiting is a non-blocking check. It tells you what's available right now.
    • ser.read() can be blocking. If you call ser.read(10) but only 5 bytes are in the buffer, it will wait (up to the timeout you set) for the remaining 5 bytes.
  3. Buffer Overflow: Even with in_waiting, if your program is too slow and data arrives extremely fast, the buffer can still overflow. The buffer size is platform-dependent but usually quite large (e.g., 4096 bytes). For most applications, reading with ser.read(ser.in_waiting) is fast enough to prevent this.

Summary

Term What it is Why you use it
in_waiting A property of a pyserial object that returns the number of unread bytes in the input buffer. To check for available data before reading, preventing data loss and allowing for efficient, non-blocking program loops.
read() A method that reads a specified number of bytes from the buffer. To actually retrieve the data from the serial port after you've used in_waiting to confirm it's there.
分享:
扫描分享到社交APP
上一篇
下一篇