Seite 1 von 1

Zweierkomplement Dezimal zu Hexadezimal?

Verfasst: Freitag 1. Juni 2018, 13:00
von hl68fx
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

Re: Zweierkomplement Dezimal zu Hexadezimal?

Verfasst: Freitag 1. Juni 2018, 13:29
von narpfel
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.

Re: Zweierkomplement Dezimal zu Hexadezimal?

Verfasst: Freitag 1. Juni 2018, 14:12
von hl68fx
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 :(

Re: Zweierkomplement Dezimal zu Hexadezimal?

Verfasst: Freitag 1. Juni 2018, 14:42
von narpfel
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.

Re: Zweierkomplement Dezimal zu Hexadezimal?

Verfasst: Freitag 1. Juni 2018, 14:51
von hl68fx
Ich hätte gerne negative Dezimalzahlen "korrekt" ins Hexadezimal umgewandelt. Also so, dass nicht der ASCII Wert dargestellt wird :)

Re: Zweierkomplement Dezimal zu Hexadezimal?

Verfasst: Freitag 1. Juni 2018, 15:03
von narpfel
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.

Re: Zweierkomplement Dezimal zu Hexadezimal?

Verfasst: Freitag 1. Juni 2018, 15:37
von Kebap
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?

Re: Zweierkomplement Dezimal zu Hexadezimal?

Verfasst: Samstag 2. Juni 2018, 16:12
von hl68fx
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 :)