Hallo,
ich nutze folgende Funktion um mit die Hexwerte auszugeben.
Grund das ich diese Variante nutze und keine sprinntf sind die Größeneinsparungen beim Sketch.
void printHex(unsigned int numberToPrint) {
if (numberToPrint >= 16)
printHex(numberToPrint / 16);
/* line is needed, no line - no output !!! */
Serial.print("0123456789ABCDEF"[numberToPrint % 16]);
}
Nun würde ich gern das selbe Prinzip nutzen aber da brauche ich die führende Null mit in der Ausgabe.
Somit möchte ich anstatt
Bsp: F ein 0F erhalten.
Kann ich diese Funktion modifizieren, das ich dies hinbekommen?
Leider erhielt ich noch keine Erfolge.
Du musst erst mal checken, wieviele Hexzeichen raus kommen sollen und dann die fehlenden mit if (wert < ...) mit 0 ausgeben.
Oder Du gibst die erwartete Zeichenzahl als Parameter mit.
void printHex(byte actual) // helper function to print out hex values with pre-zero
{
Serial.print(" 0x");
if (actual < 0x10) Serial.print("0");
Serial.print(actual, HEX);
}
ArduNewBee:
ich nutze folgende Funktion um mit die Hexwerte auszugeben.
void printHex(unsigned int numberToPrint) {
if (numberToPrint >= 16)
printHex(numberToPrint / 16);
Serial.print("0123456789ABCDEF"[numberToPrint % 16]);
Nun würde ich gern das selbe Prinzip nutzen aber da brauche ich die führende Null mit in der Ausgabe.
In welchem Bereich bewegst Du Dich denn? Arduino unsigned int wäre uint16_t somit 0-65535 dec bzw. FFFF hex.
Willst Du dann eine Ausgabe 0F 0F 0F 0F für 65535?
Was mir Sorgen macht ist, dass die Funktionsüberladung nicht funktioniert wenn ich es auf 16Bit limitiere aber der Testwert noch 16Bit groß ist. Folgendes erzeugt ein
Serial_HEX_Formatierung_02.ino: In function 'void setup()':
Serial_HEX_Formatierung_02:5:16: error: call of overloaded 'drucken(long int)' is ambiguous
5 | drucken(65535);
| ^
Serial_HEX_Formatierung_02.ino:27:6: note: candidate: 'void drucken(int16_t)'
27 | void drucken(const int16_t var)
| ^~~~~~~
Serial_HEX_Formatierung_02.ino:32:6: note: candidate: 'void drucken(uint16_t)'
32 | void drucken(const uint16_t var)
| ^~~~~~~
exit status 1
call of overloaded 'drucken(long int)' is ambiguous
Was mir Sorgen macht ist, dass die Funktionsüberladung nicht funktioniert wenn ich es auf 16Bit limitiere aber der Testwert noch 16Bit groß ist. Folgendes erzeugt ein
Das kann ich dir sagen...
drucken(65535);
Die Zahl passt nicht in int16_t
Wird deswegen auf long erweitert.
Dafür gibts aber keine Funktion
drucken(65535U);
Dann passt sie in uint16_t
Und darum keine Meldung
Vorschlag aus meiner Wühlkiste:
(ganz andere Richtung)
class PrintStr: public String, public Print
{
public:
using String::String;
using String::operator=;
virtual size_t write(byte value) override
{
*this += (char)value;
return 1;
}
void format(char fueller, size_t stellen)
{
size_t strLen = length();
if(strLen >= stellen) return;
char temp[strLen+1];
toCharArray(temp, strLen+1);
*this = "";
for(unsigned i = 0; i <= stellen - strLen; i++) *this += fueller;
*this += temp;
}
};
PrintStr test;
void setup()
{
Serial.begin(9600);
test.reserve(30);
test.print(32767,HEX);
test.format('#',12); // String wird mit vorlaufenden Lattenkreuzen aufgefüllt
Serial.println(test);
// rechtsbuendige Ausgabe
unsigned long array[] {345,56565,3333,66,1,676766,3534342};
for(auto &d:array)
{
test = d;
test.format(' ',12);
Serial.println(test);
}
}
void loop()
{
}
Übrigens, die Ursprungsfunktion würde auch arbeite mit führender Null wenn man einfach
das if ausbaut :-).
Allerdings für so etwas Rekursion zu nutzen ist schon gewagt
void printHex(unsigned int numberToPrint) {
printHex(numberToPrint / 16); // vordere Ziffer < 16 ist die Division halt 0 wie gewollt
/* line is needed, no line - no output !!! */
Serial.print("0123456789ABCDEF"[numberToPrint % 16]);
}
Allerdings für so etwas Rekursion zu nutzen ist schon gewagt
Insbesondere bei Rekursionen mit fehlerhafter (oder wie hier, ganz ohne) Abbruchbedingung. Da versagt nicht nur ein kleiner Arduino, das kann der größte Großrechner nicht.
ist allerdings heftig. Danke dafür.
Kommt so allein auf 26 byte Flash weniger alsSerial.print(numberToPrint & 0x0F, HEX);durch den Verzicht auf die Standard print(int,HEX) Funktionalität. ( Für einen 328 kompiliert )
Ein Byte RAM ist wertvoller als FLASH, daher geb ich dir Recht.
Außerdem muss man aufpassen, dass der superschlaue Compiler beim Test nicht "0123456789ABCDEF"[numberToPrint % 16] schon zur CompileZeit ausrechnet (und den 17 Byte Text gar nicht speichert), weil er den Wert von numberToPrint beim Aufruf kennt.
Ich habe mal eine Funktion zusammengezimmert, die von Byte bis long long alles mit führenden Nullen für die jeweilige Größe des Typs ausgibt.
Ein Problem habe ich damit allerdings noch. Print-Routinen sollen ja die Anzahl der ausgegebenen Zeichen zurückgeben. Das macht sie nicht. Intern wird die Anzahl richtig ermittelt.
Tommy56:
Ein Problem habe ich damit allerdings noch. Print-Routinen sollen ja die Anzahl der ausgegebenen Zeichen zurückgeben. Das macht sie nicht. Intern wird die Anzahl richtig ermittelt.
Kann mir da jemand auf die Sprünge helfen?
// keine negativen Zahlen und max. 8 Byte groß
if (value < 0 || len > 8) {
return 0;
}
Das ist doch wieder so ein Ding, was irgendwo versteckt mit den Typen verbastelt ist.
Wenn Du den Codeschnipsel oben auskommentierst, bekommst Du 24 und ne Zeile vorher nur Kauderwelsch.
return len; statt return count; wäre auch richtig.
Dein Problem scheint irgendwas mit size_t zu tun zu haben.
Nimmt man den Datentyp byte als Rückgabetyp, und liefert len zurück, scheint es immer zu funktionieren.
Da du ja gleich nach out ausgibst, brauchst du eigentlich den char puffer[9] garnicht, oder?
Und wie du das Ganze auf Arrays erweitern willst, wäre meine nächste Frage