falsche Daten im Hex-Wert

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
dusg
User
Beiträge: 3
Registriert: Donnerstag 29. Oktober 2020, 16:03

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
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Benutzeravatar
__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
dusg
User
Beiträge: 3
Registriert: Donnerstag 29. Oktober 2020, 16:03

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
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

dusg hat geschrieben: Donnerstag 29. Oktober 2020, 22:26 Ich dachte immer das Hex-Werte bis max. 0xFF gehen und nicht Zeichen wie ? und # in den Werten stehen.
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'.
Benutzeravatar
__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
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

dusg hat geschrieben: Donnerstag 29. Oktober 2020, 22:26 Was ist dann ein ? oder eine #. Wenige Werte sind ja auch dreistellig 0x123. Das ist doch auch komisch.
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?'
Ist es jetzt klarer?

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
dusg
User
Beiträge: 3
Registriert: Donnerstag 29. Oktober 2020, 16:03

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
jnkws
User
Beiträge: 8
Registriert: Dienstag 15. Dezember 2020, 11:47

Hallo,

kann man die "automatische" Umwandlung deaktivieren?
Ich brauche die Hexzahlen als Dezimalzahlen und nicht als Zeichen des Unicodes.

Freu mich auf eure Hilfe.

Grüße
Jan
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und noch ein Nachtrag: wenn es dir um Ausgabe geht, dann gibt es sowohl String-Formatting als auch die hex-Funktion.
Antworten