Mit Raspi vom Arduino Daten holen über serielle Schnittstelle

OP #7759440
Lesenswert?

Hallo Zusammen, bei mir läuft ein Arduino Nano, der einige Sachen zur Hausautomatisierung macht. Unter anderem erfasst er auch die Temperaturen von ca. 20 Stellen und schreibt sie mit folgendem Code (Ausschnitt) jede Minute an die serielle Schnittstelle:

1
   for (int i=0; i<PT1000_ANZAHL; i++) {
2
       Serial.print(istTemperatur[i]);
3
       // Serial.print(i);
4
       Serial.print(RS232_TRENNZ);    // Trennzeichen
5
    }

Der Arduino Nano ist über den USB-Anschluss mit einem Raspberry Pi verbunden. Mit dem möchte ich die Temperaturdaten abholen und dann in eine Datei sowie eine InfluxDB schreiben. Derzeit macht das ein Python-Script, hier die Funktion:

1
def readData():
2
    with serial.Serial(com_port, baud_rate, timeout=70) as s:
3
        serialmessage = s.readline()
4
        now = datetime.now()
5
        dtString = now.strftime("%Y-%m-%d-%H-%M-%S")
6
        kw = now.strftime("%W")
7
        year = now.strftime("%Y")
8
        dateiname = year + "-" + kw + "KW_Logfile.csv"
9
        datei = open(dateiname, "a")
10
        datei.write(dtString + "\t" + serialmessage)
11
        datei.close()
12
        writeInfluxDB(serialmessage)

Diese Funktion wird von der folgenden Main-Funktion aufgerufen. Falls ein Fehler auftritt, wird der COM-Port gewechselt:

1
while True:
2
    try:
3
        readData()
4

5
    except SerialException:
6
        time.sleep(3) # Waiting for 3 seconds
7
        print "Neuer Versuch, wechsle COM-Port"
8
        if com_port == '/dev/ttyUSB0':
9
            com_port = "/dev/ttyUSB1"
10
        else:
11
            com_port = "/dev/ttyUSB0"

Der Raspberry wird headless betrieben, ich greife also über die Konsole mit Putty darauf zu. Das funktioniert soweit auch alles. Damit das Python-Script auch nach dem Beenden der Konsolensitzung weiterläuft, wird es mit nohup aufgerufen.

Grundsätzlich läuft das alles so. Manchmal beendet sich aber leider das Skript. Wenn ich das dann merke, starte ich es wieder neu. Manch andere regelmäßig auszuführende Skripte habe ich in die crontab geschrieben. Hier habe ich aber Angst, dass es sich mit dem Timeout beisst. Gibt es andere Möglichkeiten, zuverlässig die Daten vom Arduino zu holen, auch nach einem Neustart des Raspberrys?

#7759447
Lesenswert?

Viele USB-Serial Adapter haben Seriennummern. Mit einer udev-Rule kannst Du also Deinen Arduino eindeutig identifizieren. z.B.

KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="ABCDEFGH",SYMLINK+="ttyARDUINO",MODE="0666",RUN+="/opt/ardu/script.sh"

Heißt also: Wenn ein USB-Serial Gerät mit Vendor ID 0403 (FTDI) und Product ID 6001 (also FT232) und Seriennummer ABCDEFGH detektiert wird, wird den wie gewohnt ein /dev/ttyUSBx zugewiesen, danach ein symbolischer Link /dev/ttyARDUINO auf das /dev/ttyUSBx angelegt, der Mode auf 0666 geändert, und das Skript /opt/ardu/script.sh gestartet. Egal, ob der Arduino bei Booten angesteckt ist oder nachträglich angesteckt wird.

Damit hat der über den symbolischen Link immer einen festen Devicenamen.

Warum sich Dein Skript beendet, kann ich jetzt nicht sagen. Das wäre zu debuggen.

fchk

#7759512
Lesenswert?

Andreas D. schrieb:

Gibt es andere Möglichkeiten, zuverlässig die Daten vom Arduino zu holen, auch nach einem Neustart des Raspberrys?

Ja, mit systemd. Allerdings erledigt das nur den Neustart des Scripts nach Neustart des RasPi oder nach Script-Crash.

Um zuverlässig Daten auszutauschen benötigst du darüber hinaus noch ein geeignetes Protokoll. Du grenzt ja zur Zeit eine Datenzeile von der Nächsten durch eine Zeitlücke ab. Das wäre mir zu fehleranfällig. Du verwendest auch keine Prüfsumme, um diw Speicherung von durch Übertragungsfehler korrumpierte Daten zu minimieren.

LG, Sebastian

#7764614
Lesenswert?

Vorschlag: Lass das USB weg, das ist einfach nicht zuverlässig zu bekommen.

Nimm das echte UART.

Der Nano hat echtes UART (an D0 und D1). Die werden jetzt schon verwendet und du brauchst da gar nix ändern in der SW.

Der RasPi kann anscheinend auch echtes UART. Direkt miteinender verbinden und schon ist die Zuverlässigkeit deutlich besser.

#7764660
Lesenswert?

beides kann so einfach sein

  1. direkt mit R und Schutzdioden verbinden siehe Bild

  2. mittels MAX3232 wichtig weil nur diese mit 3,3V vom Raspi arbeiten, andere 232 Chips brauchen mindesten 4,5V.

  3. über fertige USB-RS232 und da Raspi auf Linux basiert kann man auch die USB ID befragen und immer den richtigen USB/seriell Kanal öffnen

Benjamin K. schrieb:

Der RasPi kann anscheinend auch echtes UART.

nicht nur anscheinend!

Benjamin K. schrieb:

Direkt miteinender verbinden und schon ist die Zuverlässigkeit deutlich besser.

nana, gegen direkt kann die Spannungslage sprechen und daß im Arduino diese schon belegt sind oder mit 5V laufen, also Vorsicht mit den Aussagen.

Angehängte Dateien:
#7764843
Lesenswert?

Bauform B. schrieb:

Wenn der USB-Konverter sich abmeldet und gleich wieder anmeldet, ist /dev/ttyUSB0 noch busy und es wird ttyUSB1 benutzt. Offenbar ist das passiert und deshalb könnte man einen besseren Konverter probieren und/oder die Erdung kontrollieren.

Daher den Vorschlag vom Vorposter übernehmen, und einen Alias anlegen.

Im Gegensatz zum Vorposter (#7759447) würde ich an Deiner Stelle das Script als Service laufen lassen. Dann kümmert sich der Raspi von ganz alleine drum, dass ein abgestürztes Script auch wieder gestartet wird.

Z.B. https://github.com/torfsen/python-systemd-tutorial

(Firma: 1984now) #7765683
Lesenswert?

Harald K. schrieb:

Man könnte auch versuchen, herauszufinden, warum sich der USB-Seriell-Adapter "abmeldet", denn das ist nicht normal.

So isses.

Ich kenne das Phänomen eigentlich nur aus einer Anwendung: Da werden zu testende, frisch produzierte Geräte u.a. mit Tests bezüglich der elektrischen Sicherheit gequält und die Auswertungssoftware der Ergebnisse interagiert neben dem elektrischen Folterknecht auch mit dem Prüfling (über USB, denn was anderes hat der nicht). Oder eben plötzlich auch nicht mehr...

Aus dieser Erfahrung weiß ich, dass Windows mit dieser Situation garnicht gut klarkommt. Es kostet schon einigen Hirnschmalz, das Problem plötzlich verschwindender "serieller" USB-Geräte programmtechnisch sinnvoll in den Griff zu bekommen.

Aber ganz klar: das ist ein Extremszenario. Normalerweise passiert es nicht, dass so ein Gerät plötzlich "von allein" verschwindet. Nö, dafür muss schon der Vollhonk vor dem Rechner den USB-Stecker ziehen, während das Gerät noch in Benutzung ist.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren