Hallo zusammen,
ich versuche gerade ein Projekt für mich umzusetzen. Möchte meine Heizung auslesen und grafisch darstellen. Das gibt es zwar schon oft, aber ich möchte es halt für mich machen um dabei auch das Programmieren mit Python zu erlernen.
Die Heizung wird über die serielle Schnittstelle ausgelesen, sprich ich verwende auch pyserial ( import serial). Meine Pythn Version ist die 3.9.0. Hab ich erst vor ein paar Wochen installiert. Auf Windows.
Die Abfrage bzw die Kommunikation mit der Heizung selber läuft auch. Die Heizung schickt mir ihre Daten als Hex_Werte. 59Byte lang. Das ist auch alles so gewollt.
Nur leider befindet sich in der Antwort komische werde in den einzelnen Bytes:
b'\x0?\x00#\'
Ist jetzt nur als Veranschaulichung. Die Antwort ist natürlich länger. Aber es schleichen sich da immer so Sonderzeichen ein. Oder manchmal die ein vereinzelter Byte in der Antwort selber auch zu lang '\x010'.
Möchte euch jetzt nicht mit meinem Code langweilen.
Besteht eigentlich hauptsächlich aus
ser.write()
ser.read()
Wollte nur mal wissen ob dieses Fehlerbild bekannt ist.
Ich habe mit der Heizung auch schon über Docklight (serielles Testprogramm) kommuniziert. Hier kommen immer schön sauberer Antworten.
Mein Projekt selber ist auch schon älter. Habe damals mit Pyhon 2.7 (glaube ich) begonnen. Hab es aber nie fertiggestellt. Mit 2.7 und pyserial hatte ich damals keine Probleme diesbezüglich.
Könnte es an den neuen Versionen von Python oder pyserial liegen?
Danke vorab für euer Feedback.
Gruß
dusg
falsche Daten im Hex-Wert
Das sind keine komischen Zeichen. Das sind eben normale Zeichen. Das Python die Hexdarstellung \xXX wählt kommt nur dann vor, wenn es sich um ein nicht-Druckbares Zeichen handelt. Wenn aber zb der Wert 65, Hex 0x41 über die Leitung kommt, dann macht Python daraus ein profanes ‘A’
Zum Zweck der Verarbeitung ist das aber alles irrelevant, das ist nur die Darstellung bei einer Ausgabe mit Print.
Zum Zweck der Verarbeitung ist das aber alles irrelevant, das ist nur die Darstellung bei einer Ausgabe mit Print.
- __blackjack__
- User
- Beiträge: 13117
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Nur so als Anmerkung: Das hat sich mit Python 3 auch nicht geändert. In Python 2 waren das halt noch ”Zeichenketten” ohne das b vor der literalen Darstellung, aber die Darstellung der Bytewerte als ASCII-Zeichen falls möglich und Escape-Sequenz sonst, war auch in Python 2 schon genau so.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Ok, danke für die Antwort.
Ich dachte immer das Hex-Werte bis max. 0xFF gehen und nicht Zeichen wie ? und # in den Werten stehen.
Wie wertet Python das dann richtig aus?
Was ist dann ein ? oder eine #. Wenige Werte sind ja auch dreistellig 0x123. Das ist doch auch komisch.
Gruß
dusg
Ich dachte immer das Hex-Werte bis max. 0xFF gehen und nicht Zeichen wie ? und # in den Werten stehen.
Wie wertet Python das dann richtig aus?
Was ist dann ein ? oder eine #. Wenige Werte sind ja auch dreistellig 0x123. Das ist doch auch komisch.
Gruß
dusg
Du hast Bytewerte. Dass bestimmte Zeichen bestimmten Byte-Werten entsprechen ist für Dein Problem irrelevant. Du mußt die Bytes decodieren. Dafür gibt es das struct-Modul. Was die Bytes bedeuten, muß Deine Schnittstellendokumentation sagen.
Der ASCII-Buchstabe A wird durch den Dezimal-Wert 64 und Hexadezimal 0x41 dargestellt. Also problemlos innerhalb des Wertebereiches von 0..255.
Ein Byte ist ein Byte ist ein Byte. Worauf es ankommt ist die Interpretation. Fuer die einen ist es
b'\x48\x41\x4c\x4c\x4f'
fuer die anderen das schoenste
b'HALLO'
der Welt. Und Python hat sich - zu Recht - dazu entschieden, aus einer Reihe von Bytes nach Moeglichkeit einen Buchstaben oder eine Zahl oder ein Sonderzeichen zu machen, weil es eben sehr oft genau diese sind, die auch uebertragen werden, und es darum fuer den Menschen viel hilfreicher ist, "HALLO" als Antwort vom Arduino & Co zu lesen, als '\x48\x41\x4c\x4c\x4f'.
- __blackjack__
- User
- Beiträge: 13117
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Und falls man tatsächlich nur eine Hexadezimaldarstellung sehen möchte, mit genau zwei Hex-Ziffern pro Byte, kann man das auch leicht erreichen:
Code: Alles auswählen
In [279]: data = b"HALLO"
In [280]: data.hex()
Out[280]: '48414c4c4f'
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Du hast das Prinzip noch nicht verstanden. Was dir da ausgegeben wird ist die Repräsentation der Bytes. Wenn es sich um ein druckbares Zeichen handelt wird das genommen, sonst die Darstellung mit \x...
Schau dir mal an, wie Python die eingegebenen Daten ausgibt.
Code: Alles auswählen
>>> b'\x61'
b'a'
>>> b'\x61 \x63'
b'a c'
>>> b'\x61b\x63'
b'abc'
>>> b'\x61#\x63?'
b'a#c?'
In deinem 0x123 Beispiel hast du keine dreistellige Hexadezimalzahl. Du hast eine Sequenz von zwei Bytes. Das erste Byte ist \x12, das zweite \x33. Da ein \x33 aber als druckbares Zeichen dargestellt werden kann, wird es einfach als 3 ausgegeben und gesamt ist das dann halt b'\x123'.
Code: Alles auswählen
'\x123'
>>> b'\x123'
b'\x123'
>>> b'\x12\x33'
b'\x123'
>>> b'\x123' == b'\x12\x33'
True
Hallo zusammen,
danke für eure zahlreichen und auch sehr hilfreichen Antworten.
Wie /me schon richtig angemerkt hat, habe ich das Prinzip nicht verstanden.
Das hat sich dank eurer Hilfe jetzt geändert.
Ich bin auf jeden Fall in meinem Projekt weiter gekommen und erhalte jetzt auch sinnvolle Werte.
Danke.
Gruß
dusg
danke für eure zahlreichen und auch sehr hilfreichen Antworten.
Wie /me schon richtig angemerkt hat, habe ich das Prinzip nicht verstanden.
Das hat sich dank eurer Hilfe jetzt geändert.
Ich bin auf jeden Fall in meinem Projekt weiter gekommen und erhalte jetzt auch sinnvolle Werte.
Danke.
Gruß
dusg
Du hast es immer noch nicht verstanden. Da wird nichts automatisch umgewandelt. Und erst recht ist das kein unicode. Das ist ein bytestring. Und nein, man kann die print-Ausgabe nicht beeinflussen.
Dir wurde schon das struct modul genannt. Damit kannst du deinen bytestring in einzelne Felder zerlegen.
Dir wurde schon das struct modul genannt. Damit kannst du deinen bytestring in einzelne Felder zerlegen.