Zweierkomplement Dezimal zu Hexadezimal?

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
hl68fx
User
Beiträge: 4
Registriert: Freitag 1. Juni 2018, 12:48

Hallo zusammen,

ich habe vor kurzem begonnen mich mit Python zu beschäftigen. Seit zwei Tagen versuche ich nun einen E-Motor anzusteuern. Diesem sende ich via RS485 einen Befehl der aus 16 Bytes besteht.
Byte 1 ist das Kommando.
Byte 2 bis 5 sind die Anzahl der Inkremente die der Motor verfahren soll. Der Wertebereich geht laut Hersteller von -2140000000 bis 2140000000 bzw. Hex F80723100 bis 7F8DCF00

Ich habe es mittlerweile geschafft in die positive Richtung zu verfahren. Leider klappt es in die negative Richtung überhaupt nicht und ich bin mit meinem Latein am Ende.
Folgender Code erzeugt mir mit positiven Dezimalzahlen das richtige Ergebnis in Hexadezimal:

Code: Alles auswählen

import struct
x = struct.pack('>l', 2140000000)
print(x)
\x7f\x8d\xcf\x00'
setze ich jedoch -2140000000 ein, so erhalte ich:
\x80r1\x00' <-- man beachte das r1

Ich wäre euch sehr dankbar, wenn ihr mir weiterhelfen könntet dieses Problem zu lösen :)

LG
Tom
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

Moin,

wie kommst du denn bei einem 4 Byte langen Wert auf neun Hexziffern?

Die Stringrepräsentation von `bytes`-Objekten stellt Bytes, die in ASCII darstellbar sind, als ihren ASCII-Wert dar. Und da 0x72 (bzw. dezimal 114) für das kleine R steht, wird ein „r“ angezeigt. Das Objekt enthält also die richtigen Bytes.
hl68fx
User
Beiträge: 4
Registriert: Freitag 1. Juni 2018, 12:48

Falls du F80723100 meinst, dies steht so im Handbuch vom Motorhersteller. Habe es kopiert und nicht abgetippt. Ich nehme an das F an erster Stelle soll dem Motor signalisieren, dass es sich um eine negative Zahl handelt.
Ebenso steht im Handbuch, dass Byte 2 bis 5 für die Anzahl der Inkremente reserviert ist.
Wie das also mit 4 Bytes aber 9 hexziffern funktionieren soll weiß ich selbst nicht :(
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

Und was genau ist jetzt dein Problem?

Zum F80723100: Ich würde eher sagen, dass das ein Fehler im Handbuch ist, weil diese Zahl nicht in 4 Bytes darstellbar ist. Allerdings kann man negative Zweierkomplementzahlen beliebig nach links mit 1-Bits erweitern, ohne dass sich der Wert ändert (genauso wie man positive Zahlen mit 0 nach links erweitern kann). Es kann also auch um eine eigenartige Notation handeln.
hl68fx
User
Beiträge: 4
Registriert: Freitag 1. Juni 2018, 12:48

Ich hätte gerne negative Dezimalzahlen "korrekt" ins Hexadezimal umgewandelt. Also so, dass nicht der ASCII Wert dargestellt wird :)
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

Um Zahlen in Hexadezimaldarstellung darzustellen, gibt es die `hex`-Funktion. Das wird dir aber nicht helfen, die korrekten Bytes über die serielle Schnittstelle zu senden, denn du willst ja die Bytes mit den Werten (dezimal) 128, 114, 49 und 0 übertragen. Und die werden, wenn ein `bytes`-Objekt in seine Stringdarstellung umgewandelt wird, eben als `"b'\x80r1\x00'"` dargestellt.

Es gibt übrigens genau genommen keine Dezimal- oder Hexadezimalzahlen. 42 und 0x2a sind genau das selbe, nur eben in einer anderen Darstellung.
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

hl68fx hat geschrieben: Freitag 1. Juni 2018, 14:51 Ich hätte gerne negative Dezimalzahlen "korrekt" ins Hexadezimal umgewandelt. Also so, dass nicht der ASCII Wert dargestellt wird :)
Ich erkläre es vielleicht nochmal, weil es wirklich verwirren kann.

Es gibt einen Unterschied zwischen der internen Datenhaltung und der Darstellung (zum Beispiel auf dem Bildschirm)

Letzteres meint narpfel und das ist auch der Grund, wieso du da plötzlich ein r siehst, wo du keins erwartest.

Von der seltsamen Darstellung im Handbuch mal abgesehen. Was passiert denn, wenn du die Bytes an den Motor schickst?
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
hl68fx
User
Beiträge: 4
Registriert: Freitag 1. Juni 2018, 12:48

Ich glaube ich habe es jetzt verstanden. Es wird mir durch print zwar "falsch" angezeigt, das bedeutet aber nicht, dass es auch so mit write() beim Gerät ankommt. Werde es am Montag ausprobieren und bescheid geben :)
Antworten