An implementation function from the nice little Wiegand library YetAnotherArduinoWiegandLibrary prints a hexadecimal representation of a facility # & card # (8-bit facility #, 16-bit card #) — 24 bits of a 26-bit stream that comes across the wire.
Example encoded 24-bit number: 7111097 (decimal). Hex equivalent: 6C81B9. The 6C portion is the facility # (decimal: 108). 81B9 is card # (decimal 33209).
This function from the library's example usage serial prints the hexadecimal format of the number:
void receivedData(uint8_t* data, uint8_t bits, const char* message) {
Serial.print(message);
Serial.print(bits);
Serial.print("bits / ");
//Print value in HEX
uint8_t bytes = (bits+7)/8;
for (int i=0; i<bytes; i++) {
Serial.print(data[i] >> 4, 16); //1st, 3rd, 5th hex digit
Serial.print(data[i] & 0xF, 16); //2nd, 4th, 6th hex digit
}
Serial.println();
}
What I've tried to do unsuccessfully so far is to loop over the bits to also serial print the two decimal formatted numbers (facility:card) in the final output form: 108:33209
1 Answer 1
Your code loops from the high order byte to the low order byte, printing each byte as 2 hex digits.
If you want instead to print the first byte as a decimal value, and then the remaining bytes as another decimal value, then do this:
Print byte 0 in base 10:
Serial.print(data[0]); //first byte
Serial.print(":");
Then loop through the remaining bytes, building a result as a decimal value, and print that:
unsigned long total = 0;
for (int i=1; i<bytes; i++) //Skip the first byte
{
total = total << 8; //Shift the previous total by 8 bits.
//(The same as multiplying by 256, but faster)
total += data[i]; //Add in the new value
}
Serial.println(total);
The sample code you posted is written to handle a variable number of bytes. The code above does the same thing with decimal results. It's much simpler if you know you will always have 3 bytes or 4 bytes:
For 3 bytes:
Serial.print(data[0]); //first byte
Serial.print(":");
long total = long(data[1])*256 + data[2]);
Serial.println(long(total);
-
I wrote the second version of the code using long ints, since I started out with printing an 8-bit value followed by a 24 bit value. If the second value is only 2 bytes (16 bits) you could change the data type to
unsigned int
Duncan C– Duncan C2020年03月04日 01:43:55 +00:00Commented Mar 4, 2020 at 1:43 -
This is great and makes sense of it for me, thank you.micahwittman– micahwittman2020年03月04日 05:12:27 +00:00Commented Mar 4, 2020 at 5:12
loop over bits
? ... thefor
loop already manipulates bytes of dataSerial.print(255, 16);
outputFF
? So couldn't the inside of the for loop just readSerial.print(data[i], 16);