Digital Systems 3 min read

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.

Left, binary: 7 is 0111 and 8 is 1000, so four bits change at once and a read during the change can be wrong. Right, Gray code: 7 is 0100 and 8 is 1100, so only one bit changes and a read is at most one step off.
From 7 to 8, binary flips four bits at once; Gray code flips one.

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
DecimalBinaryGray
0000000
1001001
2010011
3011010
4100110
5101111
6110101
7111100

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.