If you need to convert the binary number to decimal for standard 8-bit microcontroller registers, the direct answer for the common byte 11010110 is 214. Whether you are parsing a GPIO port mask on an Arduino or reading an 8-bit I2C sensor register, base-2 to base-10 conversion is the foundational step before scaling that value to real-world electrical units. Below is the exact mathematical substitution, the assumptions that dictate your final integer, and how this math shifts when mapping binary ADC reads to AC mains voltages.
The Core Formula and Neighboring Values
The standard positional notation formula for converting an 8-bit unsigned binary string to decimal is:
D = (b7×128) + (b6×64) + (b5×32) + (b4×16) + (b3×8) + (b2×4) + (b1×2) + (b0×1)
Substituting our target values for 11010110:
- (1×128) + (1×64) + (0×32) + (1×16) + (0×8) + (1×4) + (1×2) + (0×1)
- 128 + 64 + 0 + 16 + 0 + 4 + 2 + 0 = 214
When debugging embedded systems, you rarely look at a single value in isolation. Here is a spec-sheet-table of neighboring values within a ±20% range (171 to 255) to help you spot off-by-one errors or bit-shift mistakes in your serial monitor output.
| Binary (8-bit) | Decimal | Hex | Common Use Case |
|---|---|---|---|
| 10101011 | 171 | 0xAB | Lower threshold limit |
| 10111001 | 185 | 0xB9 | PWM duty cycle (~72%) |
| 11010110 | 214 | 0xD6 | Target GPIO mask / ADC byte |
| 11110000 | 240 | 0xF0 | Upper nibble mask |
| 11111111 | 255 | 0xFF | Max 8-bit unsigned / All HIGH |
What Assumptions Fix Your Decimal Answer?
Raw base-2 math assumes an unsigned integer. In embedded C++, the assumption that fixes your final decimal answer is the data type cast. If your compiler interprets 11010110 as a signed 8-bit integer (int8_t), the most significant bit (MSB) acts as a sign flag. Using Two's Complement, the decimal answer instantly shifts from 214 to -42.
uint8_t or bitwise-ANDing it with 0xFF before printing.
Furthermore, endianness fixes the answer when dealing with 16-bit or 32-bit registers (like reading a 12-bit ADC value split across two 8-bit I2C bytes). If the sensor sends the Least Significant Byte (LSB) first, swapping the byte order will completely change your decimal output.
Scaling Binary to Mains: 120V vs 230V vs 3-Phase ADC Reads
In power electronics, converting a binary ADC read to a meaningful decimal voltage requires physical assumptions. The assumption that fixes your final real-world answer is the nominal voltage, the power factor (pf), and whether you are measuring single-phase vs 3-phase systems.
Let's look at how the decimal answer shifts when using an ESP32-WROOM-32's 12-bit ADC (0-4095 binary range) paired with a ZMPT101B voltage transformer module to measure AC mains.
- 120V Nominal (North America): The peak voltage is ~170V. Your voltage divider scales this to the ESP32's 3.3V logic limit. A peak binary read of
111111111111(4095) maps to 170V. A mid-point RMS calculation requires sampling the sine wave and converting the binary array to decimal to find the True RMS True RMS measurement. - 230V Nominal (EU/UK/AU): The peak voltage is ~325V. If you use the exact same hardware voltage divider without changing the scaling factor in your code, a binary read of
111111111111(4095) now represents 325V. The decimal conversion math remains identical, but the multiplier applied to the decimal output shifts by a factor of 1.91. - 3-Phase Systems: When measuring phase-to-phase (e.g., L1 to L2) instead of phase-to-neutral, the voltage is multiplied by √3 (1.732). A 230V phase-to-neutral system yields 400V phase-to-phase. Your binary-to-decimal scaling constant must be updated to account for this phase shift, or your decimal output will read 73% lower than the actual line voltage.
Decision Tree: When Standard Conversion is Meaningless
Blindly applying the base-2 positional formula is meaningless if the binary string is not a standard integer. Use this decision-tree-table to determine the correct parsing method before attempting to convert the binary number to decimal.
| Data Source / Protocol | Binary Format | Why Standard Math Fails | Concrete C++ Fix |
|---|---|---|---|
| DS3231 RTC Module (I2C) | BCD (Binary Coded Decimal) | Each nibble is 0-9, not 0-15. 0001 0101 is 15 in decimal, not 21. | Use Wire.read() - 6 * (Wire.read() >> 4) |
| IEEE 754 Sensor (Modbus) | 32-bit Float | Bits represent sign, exponent, and mantissa, not a linear integer. | Use memcpy(&floatVar, &byteArray, 4) |
| UART Text String | ASCII Encoded | The string "101" is three bytes (0x31 0x30 0x31), not the number five. | Use strtol(charBuffer, NULL, 2) |
| Raw GPIO / I2C Register | Standard Unsigned Int | N/A - Standard math applies perfectly. | Cast to uint8_t or uint16_t |
Final Pick: If you are reading raw sensor registers or GPIO masks, always terminate your decision path by explicitly casting to uint8_t (for 8-bit) or uint16_t (for 12-bit ADC reads) to prevent the compiler from applying unwanted Two's Complement sign extensions.
FAQ: Edge Cases in Embedded Binary Math
Why does my ESP32 ADC binary read max out at 4095 even when I increase the voltage?
The ESP32's ADC is 12-bit, meaning the absolute maximum binary value is 111111111111 (4095 in decimal). If your input voltage exceeds the 3.3V VCC reference (or ~1.1V on some older WROOM revisions due to internal attenuation), the ADC saturates. You must add a hardware voltage divider to scale the input down before it hits the GPIO pin ESP32 ADC Oneshot Driver.
How do I handle the non-linearity of the ESP32 ADC near 0V and 3.3V?
Converting the binary number to decimal is mathematically perfect, but the physical silicon is not. The ESP32 ADC exhibits non-linearity at the extreme low and high ends of its range. To get accurate decimal voltage readings, avoid using the bottom 100 and top 100 decimal values. Design your voltage divider so your expected AC peak sits squarely in the 500 to 3500 decimal range.
What happens if I read a 12-bit ADC value into an 8-bit variable?
Truncation. If the ADC returns 101011001110 (2766 in decimal) and you store it in a uint8_t, the compiler chops off the top 4 bits. You are left with 11001110 (206 in decimal). Always use uint16_t for any ADC with a resolution higher than 8 bits.






