Serial.print(char, HEX) a char with a negative value -1 ~ -128 displays a long value rather than the byte value. This took me for a whirl thinking I had a coding problem.
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
char C;
byte B;
Serial.println("Printing Chars");
for (int x = 0; x < 256 ; x++) {
Serial.print(C, DEC);
Serial.print(" = ");
Serial.println(C, HEX);
C++;
}
Serial.println("Printing Bytes");
for (int x = 0; x < 256 ; x++) {
Serial.print(B, DEC);
Serial.print(" = ");
Serial.println(B, HEX);
B++;
}
}
void loop() {
// put your main code here, to run repeatedly:
}
Is this purposefully intended? or is it an error?
Z
Optimization. All the integer Print() functions are defined to accept long variables, relying on the standard C/C++ type promotions to convert other sizes, and that means that signed "small" variables are sign-extended.
It'll work better if you declare C as "unsigned char." Probably.
westfw:
Optimization. All the integer Print() functions are defined to accept long variables, relying on the standard C/C++ type promotions to convert other sizes, and that means that signed "small" variables are sign-extended.
It'll work better if you declare C as "unsigned char." Probably.
Thanks for the explanation makes sense now but it need to come with a warning label :o I kept on getting all these FFFFFF7C etc. on my serial feed from the other UNO but I thought I was only trying to send 1 byte. I looked everywhere and it turned out I had the serial captured as a char! rather than a byte and all my values sent higher than 127 had lots of F's in front lol.
Z
johnwasser:
Like the automatic stripping of leading zeroes (even in HEX and BIN!), it is something you get to learn the hard way and work around.
I saw the Hex zero Stripping I added periods between hex numbers to clarify there placement even when nothing was there. and as for Binary numbers, This visual display shifting because of a bit changing drove me nuts lol so I tackled the binary zero stripping of Serial.print ( integer,BIN ) and made some macros for that:
#define DPRINTBL(Num,Digits) for (int i=0;i<Digits;i++) Serial.write(((Num >> i) & 1) == 1 ? '1' : '0'); // Prints a binary number with following Placeholder Zeros (Digits)
#define DPRINTB16(Num) for (unsigned int t = 0x8000; t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a 16 bit binary number with leading zeros
#define DPRINTB(Num,Digits) for (unsigned long t = (1UL<<Digits-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a binary number with leading zeros (Digits)
The above macros print the binary number in different ways (Leading or following Zeros) one is fixed width the others can handle printing long values (32 digits)
I hope this helps someone
Z
Added: Just came up with an Automatic version that handles data types automatically!!!
#define DPRINTBIN(Num) for (unsigned long t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a binary number with leading zeros (Digits)
#define DPRINTBINL(Num) for (int i=0;i<(sizeof(Num)*8);i++) Serial.write(((Num >> i) & 1) == 1 ? '1' : '0'); // Prints a binary number with following Placeholder Zeros (Digits)
Sample Code to try all of them out:
#define DPRINTBL(Num,Digits) for (int i=0;i<Digits;i++) Serial.write(((Num >> i) & 1) == 1 ? '1' : '0'); // Prints a binary number with following Placeholder Zeros (Digits)
#define DPRINTB16(Num) for (unsigned int t = 0x8000; t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a 16 bit binary number with leading zeros
#define DPRINTB(Num,Digits) for (unsigned long t = (1UL<<Digits-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a binary number with leading zeros (Digits)
#define DPRINTBIN(Num) for (unsigned long t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a binary number with leading zeros (Digits)
#define DPRINTBINL(Num) for (int i=0;i<(sizeof(Num)*8);i++) Serial.write(((Num >> i) & 1) == 1 ? '1' : '0'); // Prints a binary number with following Placeholder Zeros (Digits)
void setup() {
Serial.begin(115200);
byte A = 35;
int B = 503;
long C = 10203041;
Serial.println("byte");
DPRINTBL(A, 8);
Serial.println();
DPRINTB(A, 8);
Serial.println();
Serial.println("int");
DPRINTBL(B, 16);
Serial.println();
DPRINTB16(B);
Serial.println();
Serial.println("long");
DPRINTBL(C, 32);
Serial.println();
DPRINTB(C, 32);
Serial.println();
Serial.println("Auto Detect");
DPRINTBINL(A);
Serial.println();
DPRINTBIN(A);
Serial.println();
DPRINTBINL(B);
Serial.println();
DPRINTBIN(B);
Serial.println();
DPRINTBINL(C);
Serial.println();
DPRINTBIN(C);
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
}
zhomeslice:
... macros print the binary number in different ways (Leading or following Zeros) one is fixed width the others can handle printing long values (32 digits)
I hope this helps someone
Z
wouldn't it be a lot more useful to create a template that the user wouldn't have to know each data element's size?
BulldogLowell:
wouldn't it be a lot more useful to create a template that the user wouldn't have to know each data element's size?
Challenge!
beat you to it lol Just came up with it!
#define DPRINTBIN(Num) for (unsigned long t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a binary number with leading zeros (Digits)[color=#222222][/color]
#define DPRINTBINL(Num) for (int i=0;i<(sizeof(Num)*8);i++) Serial.write(((Num >> i) & 1) == 1 ? '1' : '0'); // Prints a binary number with following Placeholder Zeros (Digits)
Demo Code:
#define DPRINTBIN(Num) for (unsigned long t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a binary number with leading zeros (Digits)
#define DPRINTBINL(Num) for (int i=0;i<(sizeof(Num)*8);i++) Serial.write(((Num >> i) & 1) == 1 ? '1' : '0'); // Prints a binary number with following Placeholder Zeros (Digits)
void setup() {
Serial.begin(115200);
byte A = 35;
int B = 503;
long C = 10203041;
Serial.println("Auto Detect");
DPRINTBINL(A);
Serial.println();
DPRINTBIN(A);
Serial.println();
DPRINTBINL(B);
Serial.println();
DPRINTBIN(B);
Serial.println();
DPRINTBINL(C);
Serial.println();
DPRINTBIN(C);
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
}
Thank you! Challenge accepted! I Read your mind I was done with the update before your post suggestion! lol.
There are 2 versions depending if you would like to have the binary numbers Left (DPRINTBINL) Left to Right or not (DPRINTBIN) Right to Left
These handle the ( sizeof(NUM) * 8 ) automatically int the code to generate the Digits value of 8, 16, 32 for you!
Z