Hallo, es geht um eine Umsetzung von HEX nach Float.
Kann mir bitte jemand behilflich sein?
Das Beispiel
C++, nicht C
In C kann man keine Funktionen oder gar Methoden überladen.
Macht aus float speed = 100.0 zwei HEX Werte HIGH(0x42C8) LOW(0x0000) oder float speed = 82.6 High(0x42A5) Low (0x3333).
Wie geht das? Ich komme einfach nicht dahinter.
Hat jemand eine Idee wie ich es bewerkstelligen kann, den umgekehrten Weg?
Also Ich benötige den float Wert.
Ich bekomme z.B. die Werte 0x42CF + 0x0333 und möchte als Ergebnis den passenden float 103.6 bekommen.
Wenn der eine Weg geht, muss es ja auch eine Möglichkeit für den Weg rückwärtigen geben.
Für Hilfestellung wäre ich Dankbar.
Mit HEX meinst du die Darstellung eines Bitmusters.
Wenn du weißt, wie eine float-Zahl in deiner Hardware gespeichert wird, insbesondere die Reihenfolge und Anzahl der Bytes, kannst du C++ überlisten.
Gerne kann man da das (formal) undefinierte Verhalten einer union missbrauchen, oder einen Zeiger auf ein float als einen Zeiger auf ein uint32_t oder ein Array von zwei uint16 uminterpretieren.
Und umgekehrt.
float f = 103.6;
uint16_t * ip = (uint16_t*) & f;
Serial.print( ip[0], HEX);
Serial.println( ip[1], HEX);
float* fp = (float*) ip;
Serial.println(*fp);
Rintin
February 13, 2024, 12:23am
3
Floats werden nach IEEE-754 im Speicher abgelegt.
Schau dir mal IEEE-754 Floating Point Converter an.
Danke,
der rückwärts Weg im Beispiel funktioniert aber nur weil float f = 103.6 schon angegeben wurde.
Und das nur mit angegebenen f Werten.
Habe ich z.B. meine uint16_t Wert in result
uint16_t result = node.readHoldingRegisters(0x3001, 2); //Register Daten Lesen
float* fp = (float*) result;
funktioniert es Rückwärts nicht.
Irgendetwas fehlt, wegen dem fehlenden f Parameter.
uint16_t * result = (uint16_t*) & f ; ????
Nur wenn wie in deinem Beispiel f angegeben wurde funktioniert es.
Ich möchte aber aus result welches sich immer ändert f bekommen.
combie
February 13, 2024, 9:41am
5
Mein Rat: Lerne die Sprache die du verwendest!
Du brauchst aber 32 Bit um ein float zu bauen
noiasca
February 13, 2024, 10:50am
6
herbert9910:
result
result ist kein Ergebnis der ausgelesenen Register sondern nur ein OK oder Fehlercode aus dem Modbus Zugriff.
Du musst getResponseBuffer verwenden.
Schau dir mal die Beispiele der Library an.
1 Like
combie
February 13, 2024, 11:19am
7
noiasca:
Beispiele der Library an
Sehe kein Lib.
Ja!
Sehe aber bisher noch nicht mal den einen Weg.
Wie soll ich da den Weg zurück finden?
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
float u2fA(uint16_t a, uint16_t b)
{
float result = NAN;
*(((uint16_t*)&result)+0) = a;
*(((uint16_t*)&result)+1) = b;
return result;
}
#pragma GCC diagnostic pop
float u2fB(uint16_t a,uint16_t b)
{
union{float f;uint16_t u[2];} konverter;
konverter.u[0] = a;
konverter.u[1] = b;
return konverter.f;
}
void setup()
{
Serial.begin(9600);
Serial.println(u2fA(0x0333,0x42CF));
Serial.println(u2fB(0x0333,0x42CF));
}
void loop() {}
node.readHoldingRegisters(0x3001, 2);
Kann doch bestimmt auch 4 Byte in einem Schlag. Oder?
combie:
Sehe kein Lib.
Irgendwo muss ja die Methode readHoldingRegisters definiert sein. Und die Klasse, die diese Methode enthält.
Oder was anderes, das ein Bitmuster erzeugt von dem man annimmt, es sei eine float Zahl.
combie
February 13, 2024, 12:12pm
9
Ja!
Wir sehen hier ein Problem, welches (mir) gruselig erscheint.
Vermutlich würde es sich leichter lösen lassen, wenn der Kontext offen liegen würde.
Quelle, Ziel und verwendete Komponenten.
Für mich ist es wieder Zeit:
"Ein dreifach Hoch auf die Salami!"
Danke für eure Antworten.
combie
February 13, 2024, 3:13pm
12
Ja, so ähnlich meinte ich das.
system
Closed
August 11, 2024, 3:14pm
13
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.