webentwicklung-frage-antwort-db.com.de

Was ist das Äquivalent von Serial.available () in pyserial?

Wenn ich versuche, mehrere Zeilen serieller Daten auf einem Arduino zu lesen, verwende ich folgende Redewendung:

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

In Arduino C gibt Serial.available() die Anzahl der verfügbaren Bytes aus dem seriellen Puffer zurück (siehe Docs ). Was ist das Äquivalent von Serial.available() in Python?

Wenn ich zum Beispiel mehrere Zeilen serieller Daten lesen muss, würde ich erwarten, dass der folgende Code verwendet wird:

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

Die Eigenschaft Serial.in_waiting gibt die "Anzahl der Bytes im Empfangspuffer" zurück. 

Dies scheint gleichbedeutend mit der Beschreibung von Serial.available() zu sein: "Die Anzahl der Bytes ... die bereits eingetroffen sind und im seriellen Empfangspuffer gespeichert sind."

Versuchen:

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

Verwenden Sie für Versionen vor pyserial 3.0 .inWaiting(). Gehen Sie folgendermaßen vor, um Ihre physische Version zu ermitteln:

import serial
print(serial.__version__)
9
Robᵩ

Eine korrekte Antwort hängt von der Version von Python ab - dies hat mich heute für einige Zeit in die Irre geführt. Ich vermute, einige der Kommentare liefen auf Raspberry Pi, das sich derzeit auf Python 2.7.9 befindet, und in ähnlicher Weise pySerial.

Auf einem Pi können Sie also ser.inWaiting() verwenden, was Serial.available() in Arduino C ähnelt. Beide geben die Anzahl der Bytes im Empfangspuffer zurück. Für pySerial> = 3.0 verwenden Sie ser.in_waiting (beachten Sie, dass dies kein Attribut ist - http://pyserial.readthedocs.io/de/latest/pyserial_api.html#serial.Serial.in_waiting )

Übrigens führt import serial ; print (serial.__version__) auf einem Pi (und vermutlich älteren Pythons/pySerials) zu einem Attribut-Fehler, funktioniert aber bei neueren Versionen.

1
jaydublu2002

Ich habe das gleiche Problem so gelöst. Der einzige Nachteil dieses Codes ist, dass ser.inWaiting () beim ersten Senden des Buchstabens 'a' 0 zurückgibt. Um diesen Effekt zu entfernen, habe ich eine Verzögerung von 1 Sekunde davor hinzugefügt. Das scheint das Problem zu lösen.

In meinem Fall sendet ATmega16 eine Zeichenfolge entweder 8 oder 12 Bit zurück. Also bekomme ich die Anzahl der Bits, die mit ser.inWaiting () in RPi eintreffen, und dann lese ich diese Daten mit ser.read () und kombiniere sie in 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

Ich habe meinen Code wie folgt geschrieben. Ich hoffe, Sie können es verwenden, um Ihren Code zu ändern

import serial
import csv
import os
import time
import sys
import string
from threading import Timer

def main():
    pass

if __== '__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()
0
Ajit Nayak