pyserial中Serial.available()的等价物是什么?

时间:2016-07-28 19:22:20

标签: python serial-port

当我尝试在Arduino上读取多行串行数据时,我使用以下习语:

String message = "";
while (Serial.available()){
    message = message + serial.read()
}

在Arduino C中,Serial.available()返回可从串行缓冲区读取的字节数(参见Docs)。 python中Serial.available()的等效内容是什么?

例如,如果我需要读取多行串行数据,我希望得到以下代码:

import serial
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=0.050)
...
while ser.available():
    print ser.readline()

6 个答案:

答案 0 :(得分:9)

属性Serial.in_waiting返回“接收缓冲区中的字节数”。

这似乎相当于Serial.available()的描述:“已经到达并存储在串行接收缓冲区中的字节数......”

尝试:

import serial
ser = serial.Serial('/dev/ttyACM0', 9600, timeout=0.050)
...
while ser.in_waiting:  # Or: while ser.inWaiting():
    print ser.readline()

对于pyserial 3.0之前的版本,请使用.inWaiting()。要确定您的pyserial版本,请执行以下操作:

import serial
print(serial.__version__)

答案 1 :(得分:1)

我编写了如下代码。希望你能用它来修改你的代码

{{1}}

答案 2 :(得分:1)

我解决了同样的问题。这段代码的唯一缺点是,当我第一次发送字母'a'时,ser.inWaiting()将返回0.为了消除这种影响,我在它之前增加了1秒的延迟。这似乎解决了这个问题。

在我的情况下,ATmega16发回一个8或12位的字符串。所以,我将通过ser.inWaiting()获得到达RPi的位数,然后我将用ser.read()读取那么多数据,将它们组合成ser.read(ser.inWaiting())

import RPi.GPIO as GPIO
from time import sleep
import serial # version is 3.2.1

ser = serial.Serial('/dev/rfcomm0', 9600)
ser.parity = serial.PARITY_ODD
ser.parity = serial.PARITY_NONE

GPIO.setmode(GPIO.BOARD)

led1 = 16
led2 = 18
button = 7

GPIO.setup(led1, GPIO.OUT)
GPIO.setup(led2, GPIO.OUT)
GPIO.setup(button, GPIO.IN, pull_up_down = GPIO.PUD_UP)

try:
    while True:
        choice = raw_input("Enter 'a' if you want to turn LED ON or 'b' "
                       + "to turn the LED OFF: ")
        if (choice == "a"):
            print "Sending command to turn LED ON"
            GPIO.output(led1, GPIO.HIGH)
            sleep(1)
            GPIO.output(led1, GPIO.LOW)
            #Send the actual data
            ser.write('a');
            #Receive what ATmega it send back
            sleep(1)
            received_data = ser.read(ser.inWaiting())
            print "Received data: " + received_data

        elif (choice == "b"):
            print "Sending command to turn LED OFF"
            GPIO.output(led2, GPIO.HIGH)
            sleep(1)
            GPIO.output(led2, GPIO.LOW)
            #Send the actual data
            ser.write('b');
            #Receive what ATmega it sends back
            sleep(1)
            received_data = ser.read(ser.inWaiting())
            print "Received data: " + received_data

        else:
            print "Invalid command"
            GPIO.output(led1, GPIO.HIGH)
            GPIO.output(led2, GPIO.HIGH)
            sleep(.3)
            GPIO.output(led1, GPIO.LOW)
            GPIO.output(led2, GPIO.LOW)
            sleep(.3)
            GPIO.output(led1, GPIO.HIGH)
            GPIO.output(led2, GPIO.HIGH)
            sleep(.3)
            GPIO.output(led1, GPIO.LOW)
            GPIO.output(led2, GPIO.LOW)
            #send invalid command
            ser.write(choice);
            #receive what ATmega sends back
            sleep(1)
            received_data = ser.read(ser.inWaiting())
            print "Received data: " + received_data

finally:
    GPIO.cleanup()

答案 3 :(得分:1)

正确的答案将取决于Python的版本 - 这已经让我绊倒了一段时间。我怀疑一些评论是在Raspberry Pi上运行的,目前它在Python 2.7.9上并且同样不及当前的pySerial。

所以在Pi上你可以使用类似于Arduino C中ser.inWaiting()的{​​{1}} - 都返回接收缓冲区中的字节数;对于pySerial> = 3.0,您使用Serial.available()(请注意,这是一个属性而非函数 - http://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.in_waiting

顺便说一句,在Pi(可能是较旧的Pythons / pySerials)ser.in_waiting会导致属性错误但适用于较新版本。

答案 4 :(得分:0)

您可以将 ser.readline()timeout=1 一起使用

答案 5 :(得分:0)

当您初始化端口和波特率时,您必须设置超时,因为没有超时 ser.readline() 不起作用。