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()
_
プロパティ _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__)
_
正解はPythonのバージョンに依存します-これは今日私をしばらくつまずかせてくれました。コメントの一部は、現在Python 2.7.9および同様に最新のpySerial。
したがって、Piでは、Arduino Cのser.inWaiting()
に似たSerial.available()
を使用できます。両方とも受信バッファーのバイト数を返します。 pySerial> = 3.0の場合、_ser.in_waiting
_を使用します(これは関数ではなく属性であることに注意してください- http://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.in_waiting )
ちなみに、Pi(およびおそらく古いPython/pySerials)では、import serial ; print (serial.__version__)
は属性エラーになりますが、新しいバージョンでは機能します。
以下のようにコードを書きました。それを使用してコードを変更できることを願っています
import serial
import csv
import os
import time
import sys
import string
from threading import Timer
def main():
pass
if __name__ == '__main__':
main()
COUNT=0
f=open("test.csv","w+");
result = csv.writer(f,delimiter=',')
result_statement=("Dir","ACTUATOR_ON_OFF","MODE","DATE","TIME"," TRACKER DESIRED ANGLE"," TRACKER ACTUAL ANGLE")
result.writerow(result_statement)
f.close()
while COUNT<=100:
#while():
time.sleep(60)
ser=serial.Serial()
ser.port=12
ser.baudrate=9600
ser.open()
str=ser.read(150)
# print "string are:\n",str
print type(str)
val=str.split(":")
# print "value is:\n",val
lines=str.split("\r\n")
# print "line statement are :\n",lines
COUNT=COUNT+1
print COUNT
f=open("test.csv","a+");
result = csv.writer(f,delimiter=',')
wst=[]
for line in lines[:-1]:
parts=line.split(":")
for p in parts[1:]:
wst.append(p)
#result = csv.writer(f,delimiter=',')
#wst.append(parts[1:])
print "wst:\n",wst
result.writerow(wst)
f.close()
f.close()
ser.close()
私は同じように同じ問題を解決しました。このコードの唯一の欠点は、最初に文字「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()