If you are reading an 8-bit unsigned register and capture the binary sequence 11010110, the direct decimal conversion is 214. If that exact same 8-bit register is configured for signed two's complement, the decimal value is -42. There is no universal base-2 answer without knowing the bit-width and signedness assumption dictated by your microcontroller's datasheet. Below is the exact formula, the substitution for this sequence, and the decision framework to know which interpretation your logic analyzer trace actually requires.
The Direct Answer: Converting 11010110 to Decimal
The standard formula for converting an unsigned binary number to decimal is the sum of each bit multiplied by 2 raised to the power of its positional index (starting from 0 on the right):
Formula: D = (bn × 2n) + ... + (b1 × 21) + (b0 × 20)
Substituting the 8-bit value 11010110 into the formula:
- (1 × 27) + (1 × 26) + (0 × 25) + (1 × 24) + (0 × 23) + (1 × 22) + (1 × 21) + (0 × 20)
- 128 + 64 + 0 + 16 + 0 + 4 + 2 + 0
- Sum = 214
This calculation assumes an unsigned 8-bit integer. If your ESP32 or STM32 datasheet specifies the register is signed, the most significant bit (MSB) acts as a negative weight (-128), shifting the result to -128 + 64 + 16 + 4 + 2 = -42.
Neighboring Values: Binary to Decimal Reference (±20% Range)
When debugging sensor thresholds on the bench, you rarely need just one number. You need the surrounding range to verify if a drifting analog-to-digital converter (ADC) is staying within tolerance. For our anchor value of 214, a ±20% range spans from roughly 171 to 255. Here is the spec-sheet-table for those boundary and intermediate values:
| Decimal | 8-Bit Binary | Hexadecimal | Context / Benchmark |
|---|---|---|---|
| 171 | 10101011 | 0xAB | -20% lower bound threshold |
| 192 | 11000000 | 0xC0 | Common I2C address base |
| 214 | 11010110 | 0xD6 | Target anchor value |
| 235 | 11101011 | 0xEB | +10% upper drift marker |
| 255 | 11111111 | 0xFF | 8-bit unsigned maximum (+20% cap) |
What Fixes the Answer: Bit-Width and Signedness Assumptions
Just as calculating AC power requires knowing if you are dealing with 120V single-phase or 480V 3-phase, converting binary requires knowing the bit-width and signedness. The binary string 11010110 means something entirely different depending on the register size it occupies.
Bench Tip: Always check the datasheet's register map. A 16-bit register reading 00000000 11010110 is still 214. But if the hardware left-pads with ones for a negative signed 16-bit integer (11111111 11010110), the decimal value becomes -42 in 16-bit two's complement, matching the 8-bit signed result.
- 8-bit context: Max unsigned value is 255. Used for standard GPIO states, 8-bit PWM duty cycles, and basic I2C payloads.
- 16-bit context: Max unsigned value is 65,535. Standard for ADC reads (e.g., a 16-bit ADS1115 module) and timer counters.
- 32-bit context: Max unsigned value is 4,294,967,295. Used for system tick timers (like Arduino
millis()) and 32-bit DMA memory addresses.
Decision Tree: How to Interpret Raw Binary Register Data
When you pull a raw hex or binary dump from a logic analyzer, use this decision-tree-table to determine exactly how to convert it to a usable decimal engineering value.
| Condition / Question | If YES | If NO |
|---|---|---|
| Does the datasheet label the data type as 'Float' or 'IEEE 754'? | Stop. Use an IEEE 754 hex-to-float converter. Base-2 integer math will yield garbage. | Proceed to next row. |
| Is the data packed as BCD (Binary Coded Decimal)? | Stop. Convert each 4-bit nibble separately (e.g., 1001 0110 = 96, not 150). | Proceed to next row. |
| Does the register map specify 'Signed' or 'Two's Complement'? | Action: Apply Two's Complement. If MSB is 1, invert bits, add 1, and make negative. | Action: Use standard unsigned base-2 conversion formula. |
Final Concrete Pick: For 90% of raw sensor and GPIO register debugging on platforms like the ESP32 or Arduino, unless the datasheet explicitly states 'signed' or 'float', assume unsigned base-2 integer conversion. Treat 11010110 as 214.
When Base-2 Conversion is Meaningless
Applying the standard base-2 positional formula is mathematically valid but practically meaningless in three common embedded scenarios:
- IEEE 754 Floating Point: If a 32-bit sensor (like a high-precision digital barometer) transmits
01000000 01001001 00001111 11011011, converting this via base-2 yields 1,078,523,867. The actual physical measurement is 3.14159. The bits represent sign, exponent, and mantissa, not positional integers. Refer to the Espressif ESP32 Technical Reference Manual for how hardware floating-point units (FPU) handle these registers natively. - Binary Coded Decimal (BCD): Real-time clock (RTC) modules like the DS3231 store time in BCD to simplify 7-segment display driving. The binary
00100011converted via base-2 is 35. But in BCD, it means 23 (as in 23:00 hours). - ASCII Text Encoding: If you are reading a serial UART buffer, the binary
01000001converts to 65 in decimal. But in the context of the serial stream, it represents the character 'A'. Converting it to a math variable will corrupt your string parsing.
FAQ: Binary to Decimal in Embedded Systems
How do I quickly convert binary to decimal in Arduino C++?
Use the strtol() function with base 2. For example: long val = strtol("11010110", NULL, 2); will output 214. Do not use atoi(), as it assumes base-10 and will fail on binary strings.
Why does my 8-bit signed calculation overflow at 127?
In an 8-bit signed two's complement system, the MSB is the sign bit. This leaves only 7 bits for the positive magnitude, capping the maximum positive decimal value at 127 (01111111). Adding 1 results in 10000000, which is -128. For values up to 255, you must declare your variable as uint8_t (unsigned) rather than int8_t. See All About Circuits' guide on signed binary numbers for a deeper breakdown of overflow mechanics.
Can I use bitwise shifts instead of the math formula?
Yes, and it is faster on the microcontroller. To extract the decimal value of a specific bit, use (register_value >> bit_position) & 1. To build a decimal from scratch in code, use decimal |= (1 << i) when the bit is high.






