wake-up-neo.com

Der serielle Empfang von Arduino zu Raspberry Pi mit PySerial stoppt nach einer Weile

Ich arbeite an einem Projekt, in dem ich jeweils 25 Zeichendaten erhalten muss, um sie in Raspberry Pi zu verarbeiten. Hier ist der Beispielcode, der einige Daten generiert, die ich von Arduino erhalten möchte:

char i =0;
char  a =0;
char b=0;


void setup(){

 Serial.begin(9600);
 for(i=0;i<25;i++){

    Serial.print('l');}
    Serial.print('\n');
    delay(2000);
}


void loop(){

 for(i=0;i<25;i++){
     for(a=0;a<i;a++){
      if((a==9)||(a==19)||(a==24))
          Serial.print('l');
      else
          Serial.print('d');   
     }
     for(b=0;b<25-i;b++){
          Serial.print('l');
     }


     delay(2000);
  }
}

Es wird eine Zeile wie 'llllddddllldddd ...' gesendet. Diese Zeile ist 25 Zeichen lang. Nun möchte ich dies mit Raspberry Pi erhalten. Hier ist der Code, den ich zu arbeiten versuche:

ser = serial.Serial('/dev/AMA0',9600,timeout=1)
ser.open()

try:
   serial_data = ser.readline()
   print serial_data
except serial.serialutil.SerialException:
   pass

Dieser Code empfängt 5 Sekunden lang sehr korrekt Daten und hört dann plötzlich auf zu empfangen.

Wenn ich außerdem Folgendes versuche, erhalte ich keine Ausgabe oder Eingabe-/Ausgabefehler.

serial_data = ser.readline()
print serial_data

EDIT1: Okay, ich habe die Ausnahme jetzt kommentiert. Es gibt den folgenden Fehler:

 raise SerialException('device reporst rediness to read but returned no data (device disconnected?)')
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected?)

Was ist der richtige Weg, um 25-Zeichen-Daten von Arduino in Himbeere über PySerial zu erhalten? Jede Hilfe wird sehr geschätzt.

9
mozcelikors

Ich hatte das gleiche Problem und brach mir für eine gute Zeit den Kopf

Lauf

ps -ef | grep tty

Wenn die Ausgabe so aussieht

root      2522     1  0 06:08 ?        00:00:00 /sbin/getty -L ttyAMA0 115200 vt100

Dann müssen Sie getty daran hindern, Daten an diesen Port zu senden

Um den seriellen Port des Raspberry Pi zu verwenden, müssen Sie getty (das Programm, das den Anmeldebildschirm anzeigt) deaktivieren, indem Sie diese Zeile in der Datei/etc/inittab suchen

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Und kommentieren Sie es aus, indem Sie ein # davor setzen

#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100)

Um zu verhindern, dass der Raspberry Pi beim Booten Daten an die seriellen Schnittstellen sendet, rufen Sie die Datei /boot/cmdline.txt auf, suchen Sie die Zeile und entfernen Sie sie

console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

Starten Sie den Raspberry Pi neu

Kredit, bei dem Kredit fällig ist: http://blog.oscarliang.net/raspberry-pi-and-arduino-connected-serial-gpio/ hat mir geholfen herauszufinden, wie man getty diable

12
user2387729

Ich hatte damit zu kämpfen, als ich GPS-Daten in Raspberry Pi las. Die Ausgabe stoppt nach ca. 10 Sekunden und meldet sich

 device reports readiness to read but returned no data (device disconnected?)

Die in fast allen Foren angegebenen Lösungen beziehen sich auf Raspberry Pi 2 with Wheezy. Ich habe es endlich geschafft, kontinuierliches GPS-Streaming in meinem Raspberry Pi3 mit Jessie zu bekommen, indem ich Folgendes ausgeführt habe:

  1. setze enable_uart=1 und füge dtoverlay=pi3-disable-bt in /boot/config.txt hinzu. dann neu starten
  2. Ich musste meine /boot/cmdline.txt auf ändern

    dwc_otg.lpm_enable=0 console=tty1 console=serial0,9600 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

    dann neu starten

  3. stoppen Sie getty: Sudo systemctl stop [email protected]

    zu deaktivieren: Sudo systemctl stop [email protected]

Sie müssen vorsichtig mit der Datei /boot/cmdline.txt sein. Jeder Fehler in der Datei kann dazu führen, dass Ihr Raspberry Pi nicht startet. Es ist besser, eine Sicherungskopie der Datei zu erstellen, bevor Sie sie bearbeiten. Stellen Sie auch die Baudrate richtig ein. In meinem Fall war es 9600. Hoffe, das hilft!

2
Chandan Purohit

Früher bekam ich das oft, und dann sagte mir ein Freund, ich solle das Arduino auffordern, Daten von Python abzurufen.

Beschreibung unten


erwägen Sie, dass der Arduino nur Daten sendet, wenn Sie von Ihrem Python-Programm dazu aufgefordert werden:

Prompt.py

#!/usr/bin/python
import serial, time
ser = serial.Serial('/dev/ttyACM0',  115200, timeout = 0.1)

#if you only want to send data to arduino (i.e. a signal to move a servo)
def send( theinput ):
  ser.write( theinput )
  while True:
    try:
      time.sleep(0.01)
      break
    except:
      pass
  time.sleep(0.1)

#if you would like to tell the arduino that you would like to receive data from the arduino
def send_and_receive( theinput ):
  ser.write( theinput )
  while True:
    try:
      time.sleep(0.01)
      state = ser.readline()
      print state
      return state
    except:
      pass
  time.sleep(0.1)

f = open('dataFile.txt','a')

while 1 :
    arduino_sensor = send_and_receive('1')
    f.write(arduino_sensor)
    f.close()
    f = open('dataFile.txt','a')

Prompt.ino

void setup () {   pinMode(13, OUTPUT);   Serial.begin(115200); } 
    void loop() {

  if (Serial.available())    {

     ch = Serial.read();

     if ( ch == '1' ) { 
       Serial.println(analogRead(A0)); // if '1' is received, then send back analog read A0
     } 
     else if (ch == '2') {    
       digitalWrite(13,HIGH); // if '2' is received, turn on the led attached to 13
     } 
     else if (ch == '3') {
       digitalWrite(13,LOW); // if '3' is received then turn off the led attached 13
     } else {
       delay(10);
     }
   }    
}

Außerdem habe ich ein Github-Repository erstellt, das einige weitere Beispiele für die Python-Arduino-Kommunikation enthält:

https://github.com/gskielian/Arduino-DataLogging/blob/master/PySerial/README.md

1
gskielian

Während Ihrer loop-Funktion in Ihrem Arduino-Code beenden Sie niemals einen newline char \n, dies ist nur ein Problem mit ser.readline(), da es bis zu einem \n-Zeichen liest.

Während Ihrer Funktion setup senden Sie korrekt ein Zeichen \n, das den zu sendenden Anfangswert, aber nicht die Daten erklären kann.

vielleicht ändern Sie Ihren Arduino-Code wie folgt:

void loop(){
    for(i=0;i<25;i++){
        for(a=0;a<i;a++){
            if((a==9)||(a==19)||(a==24)) {
              Serial.print('l');
            } else {
                Serial.print('d');   
            }
        } /*end for loop a*/
        for(b=0;b<25-i;b++){
            Serial.print('l');
        } /*end for loop b*/

        Serial.print('\n'); // CODE EDITED HERE
        delay(2000);
    }    
}

Und Ihr Python-Code mag so ...

ser = None
try:
    ser = serial.Serial('/dev/AMA0',9600,timeout=3)
    ser.open()

    while True:
        try:
            serial_data = ser.readline()
            print serial_data
        except:
            pass
except:
    pass    
finally:
    if ser:
        ser.close()
0
Farmer Joe