web-dev-qa-db-ja.com

pyserialのSerial.available()と同等のものは何ですか?

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()
_
8
Michael Molter

プロパティ _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__)
_
10
Robᵩ

正解は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__)は属性エラーになりますが、新しいバージョンでは機能します。

1
jaydublu2002

以下のようにコードを書きました。それを使用してコードを変更できることを願っています

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()
1
Ajit Nayak

私は同じように同じ問題を解決しました。このコードの唯一の欠点は、最初に文字「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()
1
Evaldas22