Windrichtungssensor für Raspi 4 Wetterstation

  • Hallo DeaD_EyE !


    Diese Tipps waren sehr hilfreich, danke.

    Nun bekomme ich keine Fehlermeldung mehr, dass es gar nicht geht, sondern eine Fehlermeldung, dass etwas NICHT RICHTIG funktioniert.

    Was ja schon mal eine Steigerung ist. Konkret bekomme ich bei folgendem Code:

    Code
    value1 = client.read_input_registers(0, 2)
    value2 = client.read_holding_registers(0,2)
    
    print(value1)
    print(value2)

    Diese Ausgabe:

    Code
    Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)
    Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

    Die obere Meldung (für Value1) deutet für mich darauf hin, mein raspi an der Stelle nichts empfangen hat, aber min. zwei bytes erwartet hätte.

    Die untere Meldung (für Value2) sagt mir, dass am Rasbpy entweder gar nichts ankam oder er es nicht interpretieren konnte.


    Wie kann ich jetzt das Problem weiter eingrenzen?

    Mit dem Befehl Screen bekomme ich nur die Fehlermeldung screen: Befehl nicht gefunden.

    Wie kann ich denn feststellen, ob von dem Windsensor auch tatsächlich überhaupt etwas gesendet wird?


    Ich schließe aber auch daraus, dass der Code bis dahin OK ist.

    Siehst du das auch so?


    Danke und Gruß

    U32

  • Mit dem Befehl Screen bekomme ich nur die Fehlermeldung screen: Befehl nicht gefunden.


    Das Programm ist nicht standardmäßig installiert.


    Code
    sudo apt-get install screen




    Bezüglich der Ausgabe:

    Code
    Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)
    Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response


    Das ist etwas, worüber ich mich tierisch aufgeregt hatte. In der Regel werden Exceptions ausgelöst und nicht als Rückgabewert einer Funktion geliefert. Das ist auch der Grund, wieso du beide Meldungen sehen kannst.


    Den Fehler hatte ich auch ziemlich oft. Ursachen

    • falsche ID des Geräts. An RS485 kann mehr als ein Slave hängen. Jeder Slave hat eine ID.
      In der Doku steht: The default ModBusAddress : 1

      Also bei jeden client.read_holding.registers(address, count, unit=1)
    • es wird nur ein Funktionscode unterstützt. Laut Doku:
      SupportFunctioncode:03
      0x03 ist read_holding_registers
    • falsche Baudrate vielleicht. 4800 Baud laut der einen verlinkten Doku.
      bytessize, parity, stopbits ist Standard
    • falscher Framer oder das Argument method ist falsch geschrieben. Framer muss "rtu" sein.
    • den gpio4 nicht vergessen

    Es gibt den ascii_framer, binary_framer, rtu_framer und socket_framer.

    Damit sind die Klassen gemeint, die die Register (16 bit) und diskreten Bits serialisieren und

    in Bytes umwandeln, die dann von anderen Modulen via TCP oder UDP oder tty übertragen werden.


    Ich tippe mal auf die ID. Du kannst auch nur read_holding_registers verwenden.


  • Hallo DeaD_EyE !


    Wow, ich hätte nicht gedacht, dass das so problematisch ist.

    Zum Stand der Ding:

    Ich habe nun Screen installiert und ausprobiert.

    Das Fenster wird wie erwartet schwarz => Schlussfolgerung: Verbindung hat funktioniert.

    Zu den vermuteten Ursachen:

    - falsche ID:

    Hier bin ich etwas unsicher: Es heißt ModBusAddress : 1 im Code habe ich aber geschrieben unit=1

    Was bedeutet denn an die erste Stelle in der Klammer? Das Argument heißt doch auch Address. Welche Adresse ist hier gemeint?


    - Funktionscode: Ist so eingearbeitet => OK.


    - Baudrate: Habe von 1200 bis 115200 alles ausprobiert, ohne Auswirkung. Bleibe also bei 4800 (weil default).


    - Falscher Framer: Habe einen value3 eingeführt, um diesen Wert abzufragen. Sieht für mich aber so aus, also ob die gewünschte Methode rtu auch verwendet wird.


    Hier mal mein aktueller Code:

    Dieser Code erzeugt folgende Ausgabe:

    Code
    value1:  Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)
    value2:  Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response
    value3:  <bound method ModbusRtuFramer.checkFrame of <pymodbus.framer.rtu_framer.ModbusRtuFramer object at 0x74664510>>

    Mir ist beim testen folgendes aufgefallen:

    Lasse ich value1 UND value2 aktiv...

    Code
    # Daten von der RS485-Schnittstelle lesen
    value1 = client.read_input_registers(address=0, count=2, unit=1)
    value2 = client.read_holding_registers(address=0, count=2, unit=1)
    #value3 = client.framer.checkFrame
    
    #Ausgabe
    print()
    print('value1: ',value1)
    print('value2: ',value2)

    ...bekomme ich folgende Ausgabe:

    Code
    value1:  Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)
    value2:  Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

    Wenn ich value1 auskommentiere, ändert sich plötzlich die Ausgabe für value2 (obwohl ich wissentlich nicht daran geändert habe.).

    Code
    # Daten von der RS485-Schnittstelle lesen
    #value1 = client.read_input_registers(address=0, count=2, unit=1)
    value2 = client.read_holding_registers(address=0, count=2, unit=1)
    #value3 = client.framer.checkFrame
    
    #Ausgabe
    print()
    #print('value1: ',value1)
    print('value2: ',value2)
    Code
    value2:  Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)

    Hilft das bei der Eingrenzung des Problems?


    Deinen Code habe ich natürlich auch ausprobiert. Der liefert mir folgenden Output:

    Code
    <ModbusSerialClient at 0x75987f10 socket=None, method=rtu, timeout=3>
    Port erfolgreich geöffnet <ModbusSerialClient at 0x75987f10 socket=Serial<id=0x746809f0, open=True>(port='/dev/ttyS0', baudrate=4800, bytesize=8, parity='N', stopbits=1, timeout=3, xonxoff=False, rtscts=False, dsrdtr=False), method=rtu, timeout=3>
    Fehler:
    Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)
    Irgendein Fehler
    No Response received from the remote unit/Unable to decode response

    Einerseits sagt mir die Meldung "Port erfolgreich geöffnet" , dass eine Verbindung erfolgreich zustande gekommen ist (=> richtige Schlussfolgerung???).

    Andererseits zeigt ja der Weg durch die Fehlerbehandlung, dass es offenbar ein Problem mit der Instanz gibt (was auch immer an der Stelle mit "Instanz" gemeint ist.) (=> richtige Schlussfolgerung?)

    Was mache ich nun mit dieser Information?


    Ich bekomme ja mehr und mehr den Verdacht, dass der Sensor (sprich die Windfahne) nicht korrekt funktioniert.

    Bisher konnte ich aber nur die Eingangsspannung (12V) und die Ausgangsspannung zwischen den PINs A und B messen (3,3V).
    Da ich aber kein Oszi habe kann ich nicht feststellen, welche Form diese Spannung hat.

    Gibt es keinen Weg, den Ort des Problems einzugrenzen?

    a.) Prüfen, ob mein Code überhaupt etwas über RS485 erkennt.

    b.) Prüfen, ob ob der Sensor überhaupt irgendwelche RS485 konforme Werte abgibt.


    Hast du da vielleicht eine Idee?


    Vielen Dank schon Mal für deine Unterstützung!

    Beste Grüße

    U32

  • Hallo zusammen!


    Nochmal die Frage zurück an alle hier Forum:

    Kann mir jemand bei meinem (oben beschriebenen) Problem helfen?

    Oder vielleicht hat auch jemand "nur" eine Idee?

    Bin für jede Anregung dankbar!


    Besten Dank und viele Grüße

    U32

  • Hilft das bei der Eingrenzung des Problems?

    Nicht wirklich. Das sagt nur aus, dass modbus gar nichts empfängt und das ist nicht gut. Wenn er wenigstens etwas empfangen würde, dass er nicht versteht, wären wir schon weiter.

    Einerseits sagt mir die Meldung "Port erfolgreich geöffnet" , dass eine Verbindung erfolgreich zustande gekommen ist (=> richtige Schlussfolgerung???).

    Wenn der Port offen ist, heißt das nicht, dass eine Kommunikation und/oder elektrische Verbindung besteht.

    Der Port wird vom Linux-Kernel entsprechend konfiguriert (Baudrate, Stopbits, Bytesize. Parity) und geöffnet, mehr nicht.


    Wenn das fehlschlägt:

    • keine Berechtigung
    • nicht existierender Port
    • Port ist bereits von einem anderen Prozess geöffnet worden


    Die Umsetzung auf RS485 ist nur elektrisch.

    Es wird einfach das RS232 Protokoll genutzt und

    obendrauf ist dann das Modus-Protokoll.



    a.) Prüfen, ob mein Code überhaupt etwas über RS485 erkennt.

    b.) Prüfen, ob ob der Sensor überhaupt irgendwelche RS485 konforme Werte abgibt.


    Hast du eine SPS mit RS485? Alternativ könnte man auch den hier verwenden: usb-rs485-pcb-pcb-only


    Bevor du das machst, hätte ich noch zwei Ideen, woran es liegen könnte:

    • die 120 Ohm Widerstände zur Terminierung des Busses vergessen
    • GPIO4 muss auf High zum senden und auf Low zum Empfangen gezogen werden:

    Nicht definiert ist, wie die Treiberfreigabe erfolgt. Sehr weit verbreitet ist die Steuerung durch RTS, sowohl bei EIA-232–EIA-485–Konvertern als auch in der Firmware in USB–EIA-485–Konvertern auf der Basis von CDC.[1] Gängig ist auch die Aktivierung durch Sendedaten und Rückfall nach Zeitablauf. Da die korrekte Zeitspanne direkt von der Bitrate abhängt, ist deren Wert kritisch. USB–EIA-485–Konverter „kennen“ das Ende der Sendedaten und sind daher einfacher in ihrer Anwendung.


    Der RTS ist hardwaremäßig auf Pin 11 / GPIO 17

    Das ist das Signal, welches du auf den GPIO4 angeschlossen hast (falls ich das richtig in Erinnerung habe).


    Man kann rtscts (ready to send/ready to receive | clear to send) mit pyserial einfach aktivieren.

    Das Problem ist, dass eine Instanz von Serial durch die Methode connect der Klasse ModbusSerialClient initialisiert wird, ohne dieses Argument an die Klasse zu übergeben.


    Ich verstehe jetzt auch, wieso der Entwickler geschrieben hat, dass er keine reale Hardware zum Testen hat.

    Wahrscheinlich kennt er das Problem gar nicht.


    Du kannst mal die Holzhammer-Methode probieren:

    Python
    from pymodbus.client.sync import ModbusSerialClient
    
    
    client = ModbusSerialClient(method="rtu", port="/dev/ttyS0", baudrate=4800)
    client.connect()
    client.socket.rtscts = True
    
    print(client.read_holding_registers(0,2, unit=1)) # 2 register -> 4 byte
    print(client.read_holding_registers(0,1, unit=1)) # 1 register -> 2 byte


    Falls das funktioniert, ist das noch nicht die Endlösung.

    Da die Verbindung automatisch neu aufgebaut wird, geht die Einstellung von rtscts verloren.


    Mit Vererbung kann man das fixen.

    Edited 2 times, last by DeaD_EyE ().

  • Hallo DeaD_EyE !


    Die Fehlermeldung bleibt leider... :wallbash:


    Bevor du das machst, hätte ich noch zwei Ideen, woran es liegen könnte:

    • die 120 Ohm Widerstände zur Terminierung des Busses vergessen
    • GPIO4 muss auf High zum senden und auf Low zum Empfangen gezogen werden:

    Den 120 Ohm Widerstand habe ich nicht. Wie in meinem ersten Posting beschrieben, habe ich die beiden Leitungen RS485-A und RS485-B vom Sensor kommend direkt auf die dafür vorgesehene (gelbe) Stift-Leiste auf dem RS485-HAT und dort auf die Stifte A und B. Daher hatte es für mich den Anschein, dass dort kein zusätzlicher Widerstand erforderlich ist.


    GPIO4 auf "LOW":

    Oh, dass ist ein guter Hinweis! Bisher dachte ich der Pin/Port müsste auf "HIGH" sein, um den RS485-HAT zu aktivieren.

    Leider hat das Ändern auf "LOW" keine Verbesserung gebracht.


    Noch eine Frage zur "Holzhammer-Methode":

    Wenn ich diese CODE-Zeilen per copy-and-paste alleine ausführen lasse, bekomme ich die oben erwähnte Fehlermeldung.

    Wenn ich die Zeilen in mein Programm einbaue bekomme ich die gleiche Fehlermeldung.


    Ich zweifele langsam an mir selbst, irgenwas muss ich doch falsch machen...

    Ich habe doch irgendwo ein Denkfehler... ich komme nur nicht drauf! :@



    Der RTS ist hardwaremäßig auf Pin 11 / GPIO 17

    Das ist das Signal, welches du auf den GPIO4 angeschlossen hast (falls ich das richtig in Erinnerung habe).


    Man kann rtscts (ready to send/ready to receive | clear to send) mit pyserial einfach aktivieren.

    Das Problem ist, dass eine Instanz von Serial durch die Methode connect der Klasse ModbusSerialClient initialisiert wird, ohne dieses Argument an die Klasse zu übergeben.

    RTS auf PIN 11 / GPIO17???

    Wie soll ich denn GPIO 17 auf GPIO 4 anschließen? Soll ich ein Brückendraht von dem einem zum anderen ziehen?

    PIN 11 wird bei mir schon für einen anderen Sensor verwendet.


    Ich habe weder RTS noch RTSCTS bisher berücksichtigt.

    Es gab für mich auch keine Notwendigkeit. Der Sensor, der "sendet", hat genau zwei Drähte RS485-A und RS485-B und der HAT für den Raspi, der empfangen soll hat die entsprechenden zwei Stifte A und B auf die man die beiden Drähte aufsteckt. Ich dachte bisher, damit sei "die Messe gelesen".


    Was ist denn piserial ? Und was soll ich damit machen?

  • Hallo zusammen!

    Mir ist leider der dümmste Fehler passiert, dem ein Entwickler passieren kann...
    Ich habe beim Löschen der "Fehlversuche" versehtlich die funktionierende Version meines Codes zu dem in diesem Thema beschriebenen Projekt gelöscht. :wallbash:

    Und natürlich kann ich den Code leider nicht mehr aus der Erinnerung wieder herstellen.


    Ich bin mir aber ziemlich sicher sicher, das dieses "Grundgerüst" nicht völlig falsch ist.

    Ich vermute den Fehler in der Kombination aus GPIO-setup und/oder Konfiguration des holding_registers (genauer: die Werte für address, count und unit).

    Weiß jemand zufällig, wie die Werte für das register sein müssen?

    (Oder ist am Ende gar das holding register falsch???).


    Besten Dank für euer Feedback!


    Viele Grüße
    U32

  • Hallo,


    vorweg ich habe mir das ganze Thema nicht mehr durchgelesen, nur kurz durch gescrollt. Dabei sind mir sehr viele Code's aufgefallen, darin findest du nicht die fehlenden Infos?


    Ich vermute den Fehler

    Welchen Fehler denn? Was funktioniert denn nicht?


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Hallo Dennis89!


    die Kurzform:

    Das ist mein Programm...

    und das ist die Fehlermeldung...

    Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)


    Es sollte aber ein Wert angezeigt werden, der der Windrichtung entspricht.


    Vielen Dank für dein Feedback und beste Grüße

    U32

  • Hallo Dennis89 !


    Konntest du mit meinem Hinweis etwas anfangen?

    Ich vermute den Fehler in der Kombination aus GPIO-Setup und/oder Konfiguration des holding_registers, da mit dieser Kombi das entsprechende Register (mit dem gewünschten Wert) ausgelesen werden können sollte.

    Tut es aber leider nicht und ich bekomme die erwähnte Fehlermeldung, statt eines Wertes (z.b. 270, 60, etc.).

    Daher also meine Vermutung.


    Beste Grüße

    Michael

  • Hallo,


    tut mir leid, leider kann ich dir nicht weiterhelfen.

    Hoffe du findest hier noch Hilfe.


    Grüße

    Dennis


    PS: Falls ich am Wochenende noch Langeweile habe schau ichs mir nochmals an.

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Hallo liebe Raspi-Freunde!


    Ich möchte mit diesem Posting nochmal um eure Hilfe bitten.

    Zur Erinnerung:

    Ich betreibe einen Raspberry Pi 3B als Wetterstation. Ein Sensor dieser Wetterstation soll dieser Windrichtungssensor sein:


    30565-pasted-from-clipboard-png


    Da dieser seine Daten über das RS485-Protokoll sendet, habe ich mir noch diesen RS485-HAT für den Raspi gekauft:


    30566-pasted-from-clipboard-png


    Weiterhin benötigt der Sensor eine Betriebsspannung von 12 V, weshalb er ein eigenes Netzteil hat.


    Für mein Python-Programm habe ich mir zunächst mit


    sudo pip3 install pymodbus


    die pimodbus-Library installiert.


    Danach habe ich für das eigentliche Script recherchiert.



    Das der Port 4 zum umschalten des Berriebsmodus (senden/empfangen) verwendet werden soll habe ich aus dem Handbuch des RS485-HATs von Waveshare

    (Siehe Seite 2 letzte Zeile in der Tabelle)

    Das der Port dann zum Empfangen auf "LOW" gesetzt werden muss habe ich von DeaD_EyE.


    Die Verbindungsparameter habe ich aus der Doku für den Sensor (Seite 4 Punkt 1.3 Communication Interface).

    Bezüglich des auszulesenden Registers steht in der Doku zwar nur, dass ausschließlich der Funktionscode 0x03 verwendet wird

    (und dieser wird dann mit "Read Data register" erklärt), aber sowohl DeaD_EyE als auch dieses Youtube-Video

    weisen auf den Typ "read_holding_registers" hin.



    Zu den Parametern dieses Registers:

    Adress: Laut Doku Seite 9 Punkt 4.3 gibt es zwei Register. 0x00 und 0x01.

    Wenn ich nun die Windrichtung in ° haben möchte, müsste ich demnach die Adresse 0x01 auswählen.


    Count: Anschließend bleibt noch der Wert für Count, dieser ist in dem YT-Clip so erklärt, dass dieser die Anzahl der auszulesenden Register angibt.

    Da ich nur den Wert für für die Windrichtung haben möchte, müsste dieser Wert also auch auf 0x01 stehen.


    Unit: In der Doku zum Sensor steht auf Seite 9 Punkt 4.2 das die Adresse des Transmitters 0x01 ist (factory default).

    Weiterhin entnehme ich sowohl der Doku, als auch dem YT-Clip, dass wenn nur ein Device im Netz ist, der Wert für Unit auf 0x01 gesetzt werden muss.


    Kurzum: Wenn ich die Logik richtig verstanden habe, müsste in meinem Fall überall eine 1 stehen.


    Und trotzdem funktioniert der Sch... nicht!

    Ich habe dann aus purer Verzweifelung anhand dieser Matrix...


    EN_485 address count unit Checked
    LOW 0 0 0 X
    LOW 0 0 1 X
    LOW 0 0 2 X
    LOW 0 1 0 X
    LOW 0 1 1 X
    LOW 0 1 2 X
    LOW 0 2 0 X
    LOW 0 2 1 X
    LOW 0 2 2 X
    LOW 1 0 0 X
    LOW 1 0 1 X
    LOW 1 0 2 X
    LOW 1 1 0 X
    LOW 1 1 1 X
    LOW 1 1 2 X
    LOW 1 2 0 X
    LOW 1 2 1 X
    LOW 1 2 2 X
    LOW 2 0 0 X
    LOW 2 0 1 X
    LOW 2 0 2 X
    LOW 2 1 0 X
    LOW 2 1 1 X
    LOW 2 1 2 X
    LOW 2 2 0 X
    LOW 2 2 1 X
    LOW 2 2 2 X
    HIGH 0 0 0 X
    HIGH 0 0 1 X
    HIGH 0 0 2 X
    HIGH 0 1 0 X
    HIGH 0 1 1 X
    HIGH 0 1 2 X
    HIGH 0 2 0 X
    HIGH 0 2 1 X
    HIGH 0 2 2 X
    HIGH 1 0 0 X
    HIGH 1 0 1 X
    HIGH 1 0 2 X
    HIGH 1 1 0 X
    HIGH 1 1 1 X
    HIGH 1 1 2 X
    HIGH 1 2 0 X
    HIGH 1 2 1 X
    HIGH 1 2 2 X
    HIGH 2 0 0 X
    HIGH 2 0 1 X
    HIGH 2 0 2 X
    HIGH 2 1 0 X
    HIGH 2 1 1 X
    HIGH 2 1 2 X
    HIGH 2 2 0 X
    HIGH 2 2 1 X
    HIGH 2 2 2 X


    ...alle möglichen Kombinationen ausprobiert.

    Leider immer mit der selben Fehlermeldung als Ergebnis. :(


    Das schlimme daran ist ja, dass es es schon Mal funktioniert hat und ich Vollpfosten die falsche Datei gelöscht habe (nämlich die mit dem richtigen CODE).


    Hat vielleicht irgendjemand noch eine Idee woran es liegen könnte?

    Oder hat jemand vielleicht im Netz noch jemand anderes gesehen, der die gleiche Konstellation verwendet?


    Ich bin für jeden Hinweis dankbar!!!


    Beste Grüße und ein schönes Wochenende!

    U32