当我尝试在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()
答案 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()
不起作用。