Skript für Datenübertragung zwischen RasPi und Arduino Nano

  • Hallo an alle,

    ich versuche mich seit einiger Zeit ein wenig mit Programmierung.

    Aktuell erfasse ich die Vor/Rücklauftemperatur des Heizkessels mittels DS18B20/Arduino Nano

    und sende die Daten mittels CAN-Bus-Modul zu einem RasPi(Kellerhost). Der Nano sendet alle 5min.

    die Daten und auf dem Raspi läuft in einer screen-Session ein Python-Skript.

    Das Skript liefert die Daten weiter an eine RRD Datenbank. Es läuft soweit erstmal...

    Es geht aber sicher besser, ich möchte z.B. dass der Raspi die Daten vom Nano anfordert.

    Ich hänge das Python-Skript mal hier an, bei Bedarf kann ich den Nano-Sketch auch posten.

    Es ist noch einiges überflüssige mit im Skript, ein laufender Entwicklungsprozess quasi...

    mfg

  • Skript für Datenübertragung zwischen RasPi und Arduino Nano? Schau mal ob du hier fündig wirst!

  • Danke für die Antwort. Ich fahre hier allerdings kein CANOpen-Protokoll.

    Das ist alles etwas Low-Level bei mir. Ich habe das Skript etwas angepasst.

    Den Nano natürlich auch. Somit antwortet der Nano auf ein Datenpaket

    vom "Kellerhost".

    Funktioniert soweit erstmal...

    Edit: ...wenn man "vcan0" durch "can0" ersetzt...Schreibfehler...

    2 Mal editiert, zuletzt von f91w (2. Januar 2022 um 16:12)

  • f91w Anmerkungen zum Quelltext: Zeichenkettenliterale sind keine Kommentare. Die haben an bestimmten Stellen für die Sprache selbst eine Bedeutung, als Docstrings, und an anderen Stellen werden sie darüber hinaus von Werkzeugen wie Sphinx ebenfalls in dieser Funktion erkannt. Kommentare fangen mit einem # an.

    Die erste "sinnlose" Zeichenkette gehört an den Anfang des Moduls, vor die Importe, denn dort hat sie dann tatsächlich für die Sprache die Bedeutung eines Docstrings für das gesamte Modul. Dort wo sie jetzt steht, dokumentiert sie `can0` und passt da nicht so recht zu.

    Und die andere Zeichenkette wurde zum auskommentieren von Code missbraucht. Wie gesagt: # ist das Kommentarzeichen.

    Warum ist das Erzeugen vom Bus-Objekt nicht mit im ``try``-Block?

    Der Bus wird beim Programmabbruch nicht sauber runtergefahren. Die `Bus`-Objekte sind netterweise Kontextmanager, die man mit der ``with``-Anweisung verwenden kann.

    Die `format()`-Methode würde ich nicht mehr verwenden wenn man es auch als f-Zeichenkettenliteral schreiben kann. ``%`` auf Zeichenketten ist veraltet und bei Pfadangaben auch nicht geeignet. Da ist `os.path.join()` für vorgesehen. Oder in neuem Code das `pathlib`-Modul.

    Eine Zeichenkette mit `str()` in eine Zeichenkette umzuwandeln macht keinen Sinn.

    Der Test ob die Nachricht `None` ist, steht an der falschen Stelle, weil zu dem Zeitpunkt das Programm schon über den Test im ``if`` davor mit einem `AttributeError` auf die Nase gefallen wäre. Kann aber nicht passieren weil die Nachricht nur `None` sein kann, wenn ein `timeout` angegeben wird.

    Ungetestet:

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • __blackjack__:

    Zunächst Vielen Dank für Deine Antwort. Warum der Code so ist wie er ist: Ich wusste es nicht besser...

    Ich habe hier Python3.8.10 auf dem Rechner und die dazugehörige Doku verwendet. Ausserdem python-can

    von readthedocs.io und einiges von https://www.kompf.de/weather  . Die CAN-Schnittstelle wird vom

    System in den Netzwerkeinstellungen konfiguriert. "sleep(30)" ist eigentlich auch nur eine Notlösung.

    Hatte nach "python repeated tasks" gesucht und mehr gefunden als ich anwenden konnte. Vermutlich wäre

    es besser das Skript regelmässig von der crontab aufrufen zu lassen. Allerdings will ich noch einige

    Teilnehmer hinzufügen, z.B. mit BME 280.

    mfg

    gtfn

  • Hallo,

    ich habe mal ein wenig an meinem Skript weitergebastelt.

    Funktioniert gut. Ich hatte was gesucht um die Abfrage periodisch im Hintergrund zu machen.

    Bei https://python-can.readthedocs.io/en/3.3.4/ bin ich fündig geworden. Der Broadcastmanager

    war genau das was ich suchte. Ich habe mir etwas aus dem "examples.cyclic" rausgenommen.

    mfg

    f91w

  • f91w: Was soll denn das `periodic_started`? Vergiss bitte gleich wieder das es ``global`` gibt.

    Man vergleicht nicht mit literalen Wahrheitswerten. Da kommt ja nur wieder ein Wahrheitswert bei heraus. Entweder der, denn man sowieso schon hatte, oder dessen Gegenteil. Wenn man den Wert sowieso schon hatte, kann man ihn gleich verwenden. Für den anderen Fall gibt es ``not``. Also statt ``if irgendwas == False:`` schreibt man ``if not irgendwas:``.

    Letztlich ist dieses Flag aber auch unsinnig wenn das nur dazu verwendet wird am Anfang des allerersten Schleifendurchlaufs *einmal* etwas auszuführen. Das macht man einfach *vor* der Schleife.

    `task_id` wird nirgends verwendet und der Name ist auch ein bisschen irreführend, denn das Objekt ist mehr als einfach nur eine ID.

    Ungetestet:

    Das `print()` und `strftime()` legt nahe, dass da eigentlich eine Logging-Bibliothek verwendet werden sollte. Zum Beispiel `logging` aus der Standardbibliothek oder das externe `loguru`.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Hallo,

    Danke für die Antwort.

    Ursprünglich hatte ich den "simple_periodic_send" am Anfang gestartet. Ich wollte aber die Möglichkeit haben

    den Task im Programm zu ändern oder zu stoppen. Daher auch "task_id". Hätte wohl besser "task_objekt" geheissen.

    print() und strftime() sind nur für mich um zu sehen was läuft, sollen kein Bestandteil des fertigen Programmes sein.

    mfg

    f91w

  • Einfach nur `task` denn alles was man an einen Namen binden kann ist in Python ein Objekt, das heisst ein `_objekt`-Zusatz im Namen sagt letztlich nichts aus, weil es keinen zusätzlichen Informationswert hat.

    Das mit `print()` und `strftime()` ist eigentlich ein Grund mehr Logging zu betreiben, denn da kann man zum Beispiel über Loglevel einstellen ob/wann/was ausgegeben wird und wann nicht. Oder man verwendet eine Bibliothek für Debuggingausgaben wie `icecream`, `q`, oder `snoop`. Da kann man auch Zeitstempel ”umsonst” bekommen, plus zusätzliche Informationen wie Modulname, Funktions-/Methodenname, Zeilennummer, der Ausdruck im Code der zum Ausgabewert geführt hat, …

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Kurze Rückmeldung:

    Das ungetestete Skript funktioniert. Wenn ich das richtig sehe ist die

    "while" Endlosschleife rausgefallen. "iter" und "object" muss ich mir mal genauer ansehen.

    Ich hatte an meinem Skript auch weitergearbeitet um mehrere Klienten abzufragen.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!