Gray code, BCD and parity
Plain binary is not always the best way to encode a value. Gray code changes one bit per step, so a position sensor cannot be misread. BCD keeps decimal digits readable, and a parity bit lets a receiver notice a flipped bit.
Gray code: one bit per step
In binary, counting from 7 to 8 changes 0111 to 1000: four bits flip. Real hardware never flips them at exactly the same instant, so a sensor read in the middle can return a wrong value such as 1111. Gray code orders the values so that neighbours differ in exactly one bit, and a mid-transition read is off by at most one step.
That is why absolute rotary encoders output Gray code. To convert in C, xor the value with itself shifted right by one:
uint8_t gray = bin ^ (bin >> 1); // 7 (0111) -> 0100
uint8_t back = gray; // and back again:
while (gray >>= 1) back ^= gray; // 0100 -> 0111
| Decimal | Binary | Gray |
|---|---|---|
| 0 | 000 | 000 |
| 1 | 001 | 001 |
| 2 | 010 | 011 |
| 3 | 011 | 010 |
| 4 | 100 | 110 |
| 5 | 101 | 111 |
| 6 | 110 | 101 |
| 7 | 111 | 100 |
BCD: decimal digits in nibbles
Binary-coded decimal stores each decimal digit in its own four bits. The number 59 is 0101 1001, or 0x59 read as hex. Hex and decimal line up digit by digit, which is why many real-time clock chips keep seconds and minutes in BCD and why seven-segment displays are easy to drive. The cost is waste: four bits could hold 16 values, but BCD uses only 10. Check the datasheet of your RTC for its register format.
Parity: catching one flipped bit
A parity bit is one extra bit that makes the count of 1s even (even parity) or odd. The ASCII letter A is 0x41, 01000001, with two 1s, so its even-parity bit is 0. C is 0x43, 01000011, with three, so its even-parity bit is 1. If the receiver counts the wrong parity, one bit flipped on the wire. Parity cannot tell which bit, and two flips cancel out, so it is a cheap alarm, not a repair. UARTs can add it to every character.