Problem mit serieller Schnittstelle

  • Hallo zusammen ich habe ein Problem mit der seriellen Schnittstelle und komme nicht mehr weiter.
    An ein externes Gerät sende ich einen Request-String und erhalte darauf einen Antwort String.

    Das Problem ist, wenn ich einen Request-String sende, welcher als Antwort nur ein Byte liefert funktioniert es.
    Ich erhalte jede Sekunde eine Antwort.

    Wenn ich nun einen anderen Request-String sende, welcher als Antwort ca. 22 Byte liefern soll,
    so kann es bis 3 Minuten dauern, bis ich eine Antwort erhalte.
    In der Antwort ist der Antwort-String dann zu allem Übel 4-fach enthalten.

    Ich vermute, dass es am Timing bei der Schnittstellenabfrage liegt.
    Hat von Euch noch irgend eine Idee?

    Vielen Dank
    Gruss Thomas

  • HellsternQeuelltext und andere Texte bitte als Text und nicht als Bilder zeigen. Bilder verbrauchen mehr Bandbreite, sind umständlicher zu lesen, man kann keinen Text daraus kopieren… Jetzt hat zum Beispiel sicher keiner Bock nachzuschauen wie viele Bytes da empfangen und ausgeben werden, weil man das auf einem Bild manuell auszählen müsste.

    Es gibt keinen Code der irgendwie sinnvoll mit dem timeout umgehen würde. Entweder das machen, oder den timeout weglassen.

    Ist das ein binäres Protokoll oder ein Textprotokoll? In den Daten scheint ja kein Zeilenende vorzukommen, also wartet readline() ”ewig” bzw. bis zum timeout und bricht dann den Lesevorgang ab.

    Nächste Frage wäre ob das Protokoll überhaupt halbduplex ist. Falls vollduplex, dann ist der Code da nicht geeignet/zu simpel.

    Edit: Beim schreiben sollte man auch sicherstellen, dass der Puffer komplett raus ist.

    “Don't put your trust in revolutions. They always come around again. That's why they're called revolutions. People die, and nothing changes.” — Terry Pratchett, Night Watch

    Edited once, last by __blackjack__ (August 31, 2024 at 6:56 PM).

  • read() und zwar so das Du da alles liest. Was ”alles” ist, entscheidet sich ja durch den Inhalt, denn die Anzahl der Datenpunkte steht ja in den Daten selbst und dann auch die Länge jedes einzelnen Datenpunkts.

    “Don't put your trust in revolutions. They always come around again. That's why they're called revolutions. People die, and nothing changes.” — Terry Pratchett, Night Watch

  • Mir sind diese Fragen eingefallen:

    1) Um welches Gerät handelt es sich denn, mit dem der Pi Kontakt per serieller Schnittstelle Kontakt aufnehmen soll?

    2) Hast Du mal versucht, mittels Monitor-Programmen die serielle Schnittstelle des anderen Gerätes z. Bsp. von einem PC aus mit Daten zu beschicken? Mit einem solchen Programm kann man schauen, welche Antworten von dem Gerät zurückkommen. Vielleicht gibt es ein solches Programm auch schon für den Raspberry, evtl. sogar eine darauf abgestimmte Distribution.

  • Hellstern Ist das überhaupt die passende Dokumentation? Wir können ja nur raten was Du da als Gerät hast, aber der Name „kBerry“ im Quelltext und das „BAOS“ in der Dokumentation, kombiniert mit einer Suchmaschine meines Misstrauens deutet auf so etwas wie „KNX BAOS Module 838 kBerry“ hin.

    Wenn man dort in die Dokumentation schaut ist Deine Abfrage falsch, weil die meisten Nachrichten in einem Rahmen verpackt werden müssen. Und auch die Anwendung muss Datenpakete mit einem 0xE5 bestätigen, was Dein Code auch nicht machen würde. Und falls ich das richtig sehe ist in der Anfrage auch wenn sie in einem entsprechenden Rahmen verpackt wäre, nicht genug Information drin — da fehlt ein Bytewert für den Filter.

    Das was Du da vom Gerät bekommst sieht nach DatapointValue.Ind Nachrichten aus, und die versendet der ObjectServer asynchron wenn sich Datenpunkte geändert haben. Wenn man also Nachrichten liest, darf man nicht einfach die Erste, die man bekommt als Antwort auf die konkrete Anfrage hernehmen, sondern muss erst einmal schauen ob das tatsächlich die Antwort ist auf die man gewartet hat.

    “Don't put your trust in revolutions. They always come around again. That's why they're called revolutions. People die, and nothing changes.” — Terry Pratchett, Night Watch

  • Hellstern Ist das überhaupt die passende Dokumentation? Wir können ja nur raten was Du da als Gerät hast, aber der Name „kBerry“ im Quelltext und das „BAOS“ in der Dokumentation, kombiniert mit einer Suchmaschine meines Misstrauens deutet auf so etwas wie „KNX BAOS Module 838 kBerry“ hin.

    Dieser Beitrag von ihm deutet auch darauf hin:

    Hellstern
    August 23, 2024 at 10:54 AM
  • Ich bin jetzt in UART mit Python nicht so tief drin, aber ich weiß aus der Vergangenheit, dass serielle Schnittstellen oftmals einen Pufferspeicher haben (oder hatten), der erst übertragen wurde, wenn ein Zeilenumbruch/Enter kam oder der Puffer überlief. Die Puffergröße war gerne mal 2048 oder gar 4096 Bytes. Gerade unter Windows artete das seinerzeit bei bestimmten Libraries schnell in ein furchtbares Gefrett aus.

    In der Library mal nach Funktionen wie flush suchen. Diese Methode veranlasst, ausstehende Bytes sofort zu übertragen, egal wie es im Pufferspeicher aussieht. Es gibt bisweilen auch count oder sowas, womit man die Anzahl der anstehenden Bytes im Empfangspuffer ermitteln kann.

    Ich weiß aber nicht, ob das bei Deiner Python-Lib überhaupt zutrifft.

  • Es müssen gemäss Dokumentation nicht alle Nachrichten mit einem 0x05 quittiert werden. (siehe Beispiel oben)
    Das Filter Byte ist im Request-String enthalten (0x00)

    Bezüglich Auswertung der empfangenen Stings:
    Die Auswertung der empfangenen Strings erfolgt später, wäre nur schon mal froh, wenn überhaupt etwas ankommt.

    Guss
    Thomas

  • Quittieren ist 0xE5 und wo sehe ich in dem Beispiel das Du das nicht quittieren musst?

    Erst einmal kommt ja etwas an. Hör am besten mal gleich auf das “Strings“ zu nennen, denn das ist kein Text sondern es sind Binärdaten. Und da, wie schon gesagt, der ObjectServer auch asynchron Nachrichten senden kann und das wie man in Deinem Beispiel sehen kann auch tut! musst Du Dich jetzt mit dem empfangen von beliebigen Nachrichten beschäftigen. Die kommen ganz offensichtlich über die Schnittstelle. Und zwar sendet der ObjektServer da immer die selbe Nachricht, weil Du die nicht quittierst. Würde ich mal behaupten. Denn wenn das unterschiedliche Nachrichten mit zufällig den gleichen Daten wären, würde sich mindestens das Controlbyte des Rahmens ändern, denn der Wert alterniert bei geraden und ungeraden Nachrichten zwischen zwei Werten.

    Genau wie beim Senden dieser Bytewert auch zwischen zwei (anderen) Werten alternieren muss. Das müsstest Du auch machen, denn Deine Anfrage muss ja auch in so einen Rahmen verpackt werden, mit Längenangabe, dem alternierenden Controlbyte und einer (sehr einfachen) Prüfsumme.

    Du musst die Nachrichten ja nur in soweit auswerten, dass Du unbekannte einfach verwirfst. Oder vielleicht zumindest mal irgendwo protokollierst, damit man so eine Kommunikation im Nachhinein noch mal analysieren kann.

    Die alternierenden Controlbyte-Werte sind ein Grund das ganze in einer Klasse zu verpacken, denn das ist ja Zustand den man sich über Aufrufe von Funktionen, also dann Methoden, hinweg merken muss. Da könnte man dann auch die serielle Verbindung drin kapseln und nach aussen verständliche Methodennamen das ganze schön lesbar machen lassen. Also beispielsweise reset() zum verschicken eines Reset.

    “Don't put your trust in revolutions. They always come around again. That's why they're called revolutions. People die, and nothing changes.” — Terry Pratchett, Night Watch

  • Hellstern Das beschreibt ja nur den allgemeinen Teil des Protokolls der für alle Wege gleich ist (Seriell, USB, TCP/IP). Du verwendest seriell, also musst Du auch den Teil der nur dafür gilt beachten, also die FT1.2-Rahmen und so weiter, was ab Seite 29 beschrieben ist. In Abbildung 4 auf Seite 30 sieht man, dass man Daten auch quittieren muss. Auf Seite 32 dann ein konkretes Beispiel mit den Bytes die hin und her geschickt werden, wo man das auch noch mal deutlich sieht.

    “Don't put your trust in revolutions. They always come around again. That's why they're called revolutions. People die, and nothing changes.” — Terry Pratchett, Night Watch

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!