When writing firmware for microcontrollers like the ESP32 or Arduino, flipping between base-2 and base-16 is a constant requirement. This binary hex table provides an immediate, bookmark-friendly reference for 4-bit nibbles and common 8-bit byte masks used in digital logic, I2C addressing, and GPIO port manipulation. Unlike generic math charts, this reference is optimized for embedded systems engineering, mapping raw numbers directly to hardware register operations.
How to read this table: Read across the rows to find your target value. The Hex column is your primary identifier for memory and I2C addresses. The Binary column shows the exact bit-state for bitwise operations. The Decimal column is used for PWM and analog thresholds. Finally, the Logic Voltage Rating column (the digital equivalent of a temperature rating in wire ampacity tables) indicates whether the resulting pin state is safe for 3.3V logic (ESP32/Raspberry Pi Pico) or requires 5V tolerant hardware (classic Arduino Uno), assuming standard CMOS thresholds where a '1' requires roughly 70% of VCC to register reliably.
The Master Binary Hex Table and Quick-Jump Masks
The following data-dense tables are sourced from standard base-2/base-16 mathematical principles (ISO/IEC 80000-13) and cross-referenced with Arduino BitMath documentation for practical register application. Keep these quick-jump rows bookmarked for bench work.
Table 1: 4-Bit Nibble Binary Hex Table (0x0 to 0xF)
| Hex | Binary | Decimal | Bitwise Mask / Common Use Case | Logic Voltage Rating (VCC) |
|---|---|---|---|---|
| 0x0 | 0000 | 0 | Clear all bits (PORT &= ~0x0F) | 3.3V / 5V Safe |
| 0x1 | 0001 | 1 | Set bit 0 (LSB) | 3.3V / 5V Safe |
| 0x2 | 0010 | 2 | Set bit 1 | 3.3V / 5V Safe |
| 0x3 | 0011 | 3 | Lower 2 bits (UART stop bits) | 3.3V / 5V Safe |
| 0x4 | 0100 | 4 | Set bit 2 | 3.3V / 5V Safe |
| 0x5 | 0101 | 5 | Alternating low (0101) | 3.3V / 5V Safe |
| 0x7 | 0111 | 7 | Lower 3 bits (7-segment decode) | 3.3V / 5V Safe |
| 0x8 | 1000 | 8 | Set bit 3 (MSB of nibble) | 3.3V / 5V Safe |
| 0xA | 1010 | 10 | Alternating high (1010) | 3.3V / 5V Safe |
| 0xC | 1100 | 12 | Upper 2 bits of nibble | 3.3V / 5V Safe |
| 0xE | 1110 | 14 | Clear bit 0, set 1-3 | 3.3V / 5V Safe |
| 0xF | 1111 | 15 | Set all 4 bits (Mask = 0x0F) | 3.3V / 5V Safe |
Table 2: High-Frequency 8-Bit Byte Masks
| Hex Byte | Binary Byte | Decimal | Embedded Systems Application |
|---|---|---|---|
| 0xFF | 11111111 | 255 | Set all pins HIGH / Max 8-bit PWM duty cycle |
| 0x00 | 00000000 | 0 | Set all pins LOW / Clear register |
| 0x55 | 01010101 | 85 | Alternating bit pattern for memory bus testing |
| 0xAA | 10101010 | 170 | Inverted alternating pattern for signal integrity checks |
| 0x3C | 00111100 | 60 | Standard I2C address for SSD1306 OLED displays |
| 0x80 | 10000000 | 128 | Isolate MSB / Trigger hardware interrupt flag |
0x3C will appear on the wire as 0x78 (0x3C shifted left by 1 bit) because the least significant bit is reserved for the Read/Write flag. Always account for the R/W bit when decoding raw hex captures.
Which Column Applies to Your Firmware Task?
Knowing which column of the binary hex table to focus on depends entirely on the layer of hardware abstraction you are currently programming. Choosing the wrong representation leads to unreadable code and subtle timing bugs.
Use the Hex Column for Addresses and Memory: Whenever you are defining I2C peripheral addresses (like 0x68 for an MPU6050 IMU), SPI chip select lines, or direct memory-mapped register pointers, use hexadecimal. The ESP32 Technical Reference Manual exclusively uses hex for its 32-bit register maps because hex aligns perfectly with byte boundaries. Two hex characters equal exactly one byte; trying to read an 8-bit binary string like 01101000 to verify a memory address is cognitively exhausting and error-prone.
Use the Binary Column for GPIO and Bitwise Logic: When configuring pin directions, setting up port masks, or writing interrupt service routines (ISRs), binary is mandatory. If you need to clear pin 3 and pin 4 on a port register, writing PORTB &= ~(0b00011000) makes your intent visually obvious to the next developer. The physical layout of the 1s and 0s maps directly to the physical pins on the microcontroller die.
Use the Decimal Column for Analog and Timing Values: Microcontroller peripherals that deal with human-scale measurements—like PWM duty cycles, analogRead() thresholds, or baud rate divisors—should be written in decimal. Writing analogWrite(ledPin, 127) immediately communicates 'roughly 50% duty cycle' to the reader, whereas analogWrite(ledPin, 0x7F) forces the reader to do mental math to understand the physical output.
How Bit-Shifting Modifies Base Values in 32-Bit Registers
In electrical wiring tables, derating factors modify the base ampacity of a wire based on ambient temperature or conduit fill. In embedded systems, bit-shifting and register widths modify the base value from the binary hex table based on the target memory address or pin offset.
A base value of 0x01 (binary 00000001) only sets the 0th bit. But microcontrollers like the ESP32 use 32-bit registers for GPIO control. If you want to set GPIO pin 18 HIGH using direct register manipulation, you cannot simply write 0x01 to the register. You must shift the base value by the pin number:
REG_WRITE(GPIO_OUT_W1TS_REG, 1 << 18);
Here, the base value 1 (which is 0x01 in hex) is shifted left 18 times. The resulting hex value written to the hardware is 0x00040000. If you look up 0x04 in a standard table, it just says 'set bit 2'. But in the context of a 32-bit register shifted by 16 bits, it represents pin 18. This is why a static binary hex table is only the starting point; you must apply the shift operator (<<) to scale the base value to your specific hardware pin.
Similarly, when extracting data from a 16-bit sensor reading, you use the inverse operation. If an I2C sensor returns 0x1A4F, and the upper byte contains the temperature while the lower byte contains the humidity, you apply a bitwise AND mask from the table (0xFF) combined with a right shift (>> 8) to isolate the 0x1A temperature value without corrupting the data.
What This Binary Hex Table Cannot Tell You
While this binary hex table is exhaustive for raw unsigned integer conversions, it deliberately omits three critical hardware-level contexts that will brick your firmware if ignored.
1. Signed vs. Unsigned Integers (Two's Complement): The table lists 0xFF as decimal 255. This is true only if your variable is declared as an unsigned 8-bit integer (uint8_t). If you pass 0xFF into a signed 8-bit integer (int8_t), the microcontroller interprets the most significant bit as a sign flag. In two's complement arithmetic, 0xFF evaluates to -1. Always explicitly declare your variable types in C/C++ to prevent the compiler from silently flipping your hex values into negative decimals during math operations.
2. Endianness in Multi-Byte Registers: The table shows that 0x1234 is composed of 0x12 and 0x34. However, it cannot tell you which byte gets written to memory first. ARM-based microcontrollers (like the ESP32 and Raspberry Pi Pico) are typically little-endian, meaning the least significant byte (0x34) is stored at the lowest memory address. If you are casting a byte array to a 16-bit integer pointer to read sensor data, failing to account for little-endian byte swapping will result in reading 0x3412 instead of 0x1234, completely invalidating your sensor calibration.
3. Floating-Point Representations (IEEE 754): This table is strictly for integers. If you attempt to map a hex value to a floating-point number (e.g., float or double), standard base-16 conversion fails entirely. Floating-point numbers are encoded using the IEEE 754 standard, which splits the 32 bits into a sign bit, an 8-bit exponent, and a 23-bit mantissa. The hex value 0x41200000 does not equal 1,092,616,192 in decimal when cast as a float; it evaluates exactly to 10.0. For floating-point debugging, you must use a dedicated IEEE 754 hex converter rather than a standard binary hex table.






