birdyb
Goto Top

Arduino: long in HEX-String konvertieren

Hallo zusammen,

ich habe hier ein kleines Arduino-Bastelprojekt, welches RFID-Transponder einlesen soll und den Wert als HEX-String ausgeben soll. Der Arduino wird dann als HID(Tastatur) agieren.
Leider hängt es bei mir bei der Konvertierung des eingehenden Strings in einen HEX-String. Die Umwandlung des Strings in eine LONG funktioniert, danach hakt es.
Hier ist mein Code:
String str;
int test = 1;
char out[20];
long strlint;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  if(test == 1){
  		str="0004572516";  
    	Serial.print("str: ");  
    	Serial.println(str);
    	strlint = atol(str.c_str());
    	Serial.print("strlint: ");  
    	Serial.println(strlint);
    	Serial.print("String(strlint, HEX): ");  
    	Serial.println(String(strlint, HEX));
    	Serial.print("sprintf(out,\"%08X\",strlint): ");  
		sprintf(out,"%08X",strlint);  
    	Serial.println(out);
  		test = 0;
  }  
}

Und hier die Ausgabe:

str: 0004572516 
strlint: 4572516 
String(strlint, HEX): 455555 
sprintf(out,"%08X",strlint): 0000C564   

Eigentlich müsste aber 45C564 herauskommen... Wo habe ich den Fehler gemacht?

Danke für die Hilfe und beste Grüße!


Berthold

Content-Key: 308698

Url: https://administrator.de/contentid/308698

Printed on: April 25, 2024 at 15:04 o'clock

Member: miniversum
miniversum Jul 01, 2016 at 13:13:52 (UTC)
Goto Top
Hallo,

Das sieht ja so aus als ob er dir nur die niedrigsten 16 Bit raushaut.
Ich weiß jetzt grade nicht was der Controller des Arduino so kann und macht, aber wenn Du es schon im Long richtig hast kann kannst du ja, im Zweifelsfall, die unteren 16 Bit berechnen, die Zahl um 16 Bit nach rechts shiften und dann die oberen 16 Bit berechnen. Dann hängst Du die beiden Strings zusammen und fertig.
Member: BirdyB
BirdyB Jul 01, 2016 at 13:19:53 (UTC)
Goto Top
Also spannenderweise tritt dieser Fehler nur bei der Arduino-Simulation von circuits.io auf. Um mal kurz zu verschnaufen habe ich jetzt mal einen echten Arduino Uno angeklemmt und den Code hochgeladen. Das Ergebnis ist nun folgendes:
str: 0004572516
strlint: 4572516
String(strlint, HEX): 45c564
sprintf(out,"%08X",strlint): 0000C564  

Also scheinbar scheint "String(strlint, HEX): 45c564" wohl doch das richtige Ergebnis zu produzieren...
Member: rubberman
rubberman Jul 01, 2016 updated at 15:41:21 (UTC)
Goto Top
Hallo BirdyB,

was dein String Constructor in deinem ursprünglichen Beispiel verkehrt macht, kann ich auch nicht sagen. Bei sprintf sollte aber klar sein, dass du bei einem long auch ein "%lX" und nicht nur ein "%X" als Formatbezeichner benötigst.
Und nutze eine vernünftige Funktion/Methode für die Konvertierung zum long. So ziemlich jede Funktionsreferenz weist mittlerweile darauf hin, dass alles was mit ato... anfängt in die Tonne gehört face-wink

Grüße
rubberman
Member: BirdyB
BirdyB Jul 01, 2016 at 20:06:56 (UTC)
Goto Top
Hallo rubberman,

was dein String Constructor in deinem ursprünglichen Beispiel verkehrt macht, kann ich auch nicht sagen. Bei sprintf sollte aber klar sein, dass du bei einem long auch ein "%lX" und nicht nur ein "%X" als Formatbezeichner benötigst.
Ich habe es ja jetzt per String(eingabe, HEX) gelöst, daher kommt sprintf garnicht mehr zum Einsatz. Trotzdem vielen Dank für den Hinweis.
Und nutze eine vernünftige Funktion/Methode für die Konvertierung zum long. So ziemlich jede Funktionsreferenz weist mittlerweile darauf hin, dass alles was mit ato... anfängt in die Tonne gehört face-wink
Was würdest du denn empfehlen? Ich bin wahrlich kein C++-Experte, ich wollte nur eine kleine Problemstellung kostengünstig lösen...
Grüße
rubberman

Danke für die Unterstützung und beste Grüße!


Berthold
Member: rubberman
rubberman Jul 01, 2016 updated at 21:17:37 (UTC)
Goto Top
Zitat von @BirdyB:
Was würdest du denn empfehlen?
Ich habe überhaupt keine Ahnung von Arduino, aber Google sagt es gibt eine toInt() Methode für die Arduino-eigene Stringklasse, die ein long zurückgibt.

Zitat von @BirdyB:
Ich bin wahrlich kein C++-Experte
Als Experte kann ich mich auch nicht bezeichnen, aber so viel:
Funktion atol() ist nicht C++ sondern C. Lediglich die Tatsache, dass C fast vollständig in C++ aufgeht, ist dafür verantwortlich dass du diese Funktion nutzen kannst. In C++ würde man sich ggf. des stol() Funktionstemplates bedienen. Das erwartet aber einen std::string oder std::wstring. Das Arbeiten mit Streamklassen ist zu diesem Zweck ebenfalls üblich (siehe >>Operatorüberladungen der stringstream Klasse).
Bei C gibt es strtol() als bessere Alternative für atol(). Hier lassen sich mit dem endptr und errno Fehler bei der Konvertierung erkennen.

Grüße
rubberman