If you need to know how to convert binary numbers to denary (the standard base-10 number system we use daily), the direct answer depends on your specific bit-string. For our anchor example, the 8-bit binary number 10110100 converts exactly to 180 in denary. Microcontrollers like the Arduino Uno or ESP32 process data in base-2 (binary), but humans debug and display data in base-10 (denary/decimal). Bridging this gap requires a precise mathematical formula and a clear understanding of your hardware's data registers.

The Core Formula and Step-by-Step Substitution

The denary value ($D$) of any binary number is calculated by multiplying each bit ($b$) by 2 raised to the power of its positional index ($i$), starting from 0 on the far right (the Least Significant Bit, or LSB) and moving left to the Most Significant Bit (MSB).

The Formula:
$D = (b_n \times 2^n) + ... + (b_2 \times 2^2) + (b_1 \times 2^1) + (b_0 \times 2^0)$

Substituting our anchor value (10110100):

  • Bit 7 (MSB): $1 \times 2^7 = 1 \times 128 = 128$
  • Bit 6: $0 \times 2^6 = 0 \times 64 = 0$
  • Bit 5: $1 \times 2^5 = 1 \times 32 = 32$
  • Bit 4: $1 \times 2^4 = 1 \times 16 = 16$
  • Bit 3: $0 \times 2^3 = 0 \times 8 = 0$
  • Bit 2: $1 \times 2^2 = 1 \times 4 = 4$
  • Bit 1: $0 \times 2^1 = 0 \times 2 = 0$
  • Bit 0 (LSB): $0 \times 2^0 = 0 \times 1 = 0$

Total Sum: $128 + 0 + 32 + 16 + 0 + 4 + 0 + 0 =$ 180.

What Assumptions Fix the Answer? (Beyond Voltage and Phase)

In AC power theory, conversions (like calculating Amps from Watts) shift drastically for 120V vs 230V vs 3-phase systems, and become entirely meaningless if the power factor (pf) is unknown. Binary-to-denary math does not use voltage, phase, or power factor. However, just as you shouldn't present a single-voltage ampacity answer as universal without specifying the system voltage, you cannot present a binary conversion as universal without specifying three digital assumptions:

1. Bit-Width (The Digital "Voltage"): An 8-bit shift register reading 10110100 is 180. But if that same bit pattern is the lower byte of a 16-bit register (e.g., 00000000 10110100), it is still 180. If it is the upper byte (10110100 00000000), the denary value shifts to 46,080. Always confirm if you are reading an 8-bit, 10-bit (common in older Arduino ADCs), 12-bit (ESP32 ADC), or 16-bit register.

2. Signed vs. Unsigned (Two's Complement): If your microcontroller treats 10110100 as an unsigned 8-bit integer, the answer is 180. If it is a signed 8-bit integer (using Two's Complement), the leading '1' indicates a negative number. Inverting the bits and adding 1 reveals the denary value is actually -76. Ignoring the sign format is the digital equivalent of ignoring AC phase angles.

3. Endianness: When reading multi-byte sensors over I2C or SPI, you must know if the device sends data Big-Endian (MSB first) or Little-Endian (LSB first). Swapping the bytes will completely alter your denary output.

Reference Table: Neighboring Values (±20% Range)

When debugging sensor drift or ADC noise on a workbench, it helps to recognize the binary patterns of values surrounding your target. Below is a spec-sheet-table showing the denary, binary, and hexadecimal equivalents for a ±20% range around our anchor value of 180.

Denary (Base-10) Binary (Base-2, 8-bit) Hex (Base-16) Variance from Anchor
144 10010000 0x90 -20%
162 10100010 0xA2 -10%
180 10110100 0xB4 Anchor (0%)
198 11000110 0xC6 +10%
216 11011000 0xD8 +20%

Practical Application: Parsing Binary in C++

When writing firmware for an ESP32 or Arduino, you rarely calculate the powers of 2 manually. Instead, you rely on built-in C++ functions to parse binary strings from serial monitors or shift bitwise registers. According to the official Arduino language reference, the most robust way to convert a binary string to a denary integer is using strtol().

// Converting a binary string to a denary integer in C++
char binaryString[] = "10110100";

// strtol parameters: (string, endptr, base)
// Base 2 tells the compiler to interpret the string as binary
long denaryValue = strtol(binaryString, NULL, 2);

Serial.print("The denary value is: ");
Serial.println(denaryValue); // Outputs: 180

For raw hardware registers (like reading an ESP32 ADC peripheral), you use bitwise shifting rather than string parsing:

uint16_t raw_adc_register = 0xB400; // Hex representation
// Shift right by 8 bits to isolate the upper byte
uint8_t upper_byte = (raw_adc_register >> 8); 
// upper_byte now holds 180 in denary

Frequently Asked Questions

How to convert binary numbers to denary with a fractional part?

Microcontrollers do not natively process floating-point binary; they use "fixed-point" math. To convert a binary number with a fractional part (e.g., 101.10), the bits to the right of the radix point use negative exponents. The formula extends as: $(1 \times 2^{-1}) + (0 \times 2^{-2})$. For 101.10, the denary calculation is $4 + 0 + 1 + 0.5 + 0 = 5.5$. In embedded C++, this is usually handled by defining a scaling factor (like Q8.8 format) and dividing the final integer by 256.

How to convert binary numbers to denary using Python for data logging?

If you are logging I2C sensor data via a Raspberry Pi or serial port, Python makes this trivial. Use the built-in int() function and specify the base. For example, int('10110100', 2) immediately returns 180. If you are dealing with Two's Complement signed data from a sensor like the MPU6050 accelerometer, use the ctypes library to cast the 16-bit unsigned integer to a signed 16-bit integer before printing.

When is a binary-to-denary conversion meaningless in embedded systems?

Just as calculating real power (Watts) is meaningless in AC theory if the power factor is unknown, converting a raw binary register to denary is meaningless under three conditions: 1) Reading an uninitialized I2C/SPI register that defaults to 0xFF or 0x00 before the sensor wakes up. 2) Reading a floating (unconnected) GPIO or ADC pin, which will yield random binary noise dictated by electromagnetic interference rather than a physical measurement. 3) Attempting to parse a denary value from a data stream without knowing the byte-order (endianness) of the transmitting device.