When you are debugging a microcontroller on the bench, you rarely get to look at clean decimal numbers. Raw sensor data lives in hardware registers as strings of ones and zeros. If you are reading an exam question or a raw serial dump, you need to fluently translate that raw data into real-world physical units. This walkthrough tackles a realistic binary number system example involving a 12-bit Analog-to-Digital Converter (ADC) on an ESP32-S3, showing every algebraic step from raw register bits to a final voltage reading.
The Problem Statement: ESP32 12-Bit ADC Register Read
Problem Statement:
You are reading the raw output register of a 12-bit Successive Approximation Register (SAR) ADC on an ESP32-S3 microcontroller. The ADC is configured with a reference voltage ($V_{ref}$) of exactly 3.300 V. The hardware register outputs the following 12-bit binary number:
101100101101
Tasks:
- Convert the binary register value to its base-10 decimal equivalent.
- Calculate the actual analog input voltage ($V_{in}$) that produced this reading.
- Identify the most common mathematical trap in this conversion and verify your answer independently.
Step-by-Step Solution: Base-2 Positional Notation
The method that applies here is base-2 positional notation. In any positional numeral system, the value of a digit is determined by its face value multiplied by the base raised to the power of its position index. For binary, the base is 2, and the position index starts at 0 on the far right (the Least Significant Bit, or LSB) and increments as you move left toward the Most Significant Bit (MSB).
Step 1: Map the Bit Positions
Our binary string is 101100101101. Let us assign the power of 2 to each bit, starting from $2^0$ on the right:
| Bit Index | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Bit Value | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 |
| Weight | 2048 | 1024 | 512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
Step 2: Execute the Algebraic Summation
We multiply each bit by its positional weight and sum the results. Zeros contribute nothing, so we only sum the weights where the bit is 1:
$D_{10} = (1 \times 2048) + (0 \times 1024) + (1 \times 512) + (1 \times 256) + (0 \times 128) + (0 \times 64) + (1 \times 32) + (0 \times 16) + (1 \times 8) + (1 \times 4) + (0 \times 2) + (1 \times 1)$
$D_{10} = 2048 + 512 + 256 + 32 + 8 + 4 + 1$
$D_{10} = 2861$
The decimal equivalent of the register value is 2861.
Step 3: Apply the ADC Transfer Function
To find the analog voltage, we use the standard ADC transfer equation:
$V_{in} = \frac{D_{10} \times V_{ref}}{2^n - 1}$
Where $n$ is the bit-resolution (12).
⚠️ The Trap: $2^n$ vs $2^n - 1$
The most common mistake in this binary number system example is dividing by $2^{12}$ (4096) instead of $2^{12} - 1$ (4095). A 12-bit ADC has 4096 possible states (from 0 to 4095), but it only has 4095 intervals or steps between 0V and $V_{ref}$. Dividing by 4096 introduces a 'fencepost error' that slightly skews your voltage calculation, which matters in precision instrumentation. For a deep dive into ADC architecture, refer to the All About Circuits Digital Textbook.
Plugging in our exact numbers:
$V_{in} = \frac{2861 \times 3.300}{4095}$
$V_{in} = \frac{9441.3}{4095}$
$V_{in} \approx 2.305567... \text{ V}$
Rounding to a realistic 3 decimal places for a standard bench multimeter, the input voltage is 2.306 V.
Sanity Check and Independent Hexadecimal Verification
Never trust a raw calculation on an exam or in firmware without a sanity check. We will use two methods to verify our result.
Method 1: Order of Magnitude and Bounding
Look at the MSB (Bit 11). It is a 1. This means the decimal value must be at least 2048. Half of our maximum decimal value (4095) is roughly 2047.5. Therefore, the voltage must be greater than half of $V_{ref}$ (1.65 V).
Next, look at Bit 10. It is a 0. This means the value is strictly less than $2048 + 1024 = 3072$. The voltage corresponding to 3072 is roughly 2.47 V.
Our calculated answer, 2.306 V, sits comfortably between 1.65 V and 2.47 V. The order of magnitude and bounds check out perfectly.
Method 2: Independent Hexadecimal Conversion
To verify the decimal conversion without re-doing the base-2 addition, group the binary string into nibbles (4-bit chunks) from right to left and convert to hexadecimal:
1011= $8 + 2 + 1 = 11$ = B0010= $2$ = 21101= $8 + 4 + 1 = 13$ = D
The hex value is 0xB2D. Converting hex to decimal:
$D_{10} = (11 \times 16^2) + (2 \times 16^1) + (13 \times 16^0)$
$D_{10} = (11 \times 256) + 32 + 13$
$D_{10} = 2816 + 32 + 13 = 2861$
The decimal value matches our initial summation exactly. For more on ESP32-S3 specific ADC hardware registers and oneshot reading APIs, consult the official Espressif ESP-IDF ADC Documentation.
Binary Number System Example FAQ
How do I handle a binary number system example with a fractional part?
If your binary string includes a radix point (e.g., 101.11), the positional notation method remains exactly the same, but the powers of 2 become negative to the right of the radix point. The first digit right of the point is $2^{-1}$ (0.5), the next is $2^{-2}$ (0.25), and so on. For 101.11, the math is: $(1 \times 4) + (0 \times 2) + (1 \times 1) + (1 \times 0.5) + (1 \times 0.25) = 5.75$ in decimal. This format is foundational for understanding IEEE 754 floating-point representations used in microcontroller math libraries.
Why do we use $2^n - 1$ instead of $2^n$ in ADC binary conversions?
This is a classic 'fencepost error'. Think of a ruler that is 12 inches long. It has 13 marks on it (0 through 12). An $n$-bit ADC has $2^n$ total marks (states), starting from 0 up to $2^n - 1$. However, the full-scale voltage ($V_{ref}$) corresponds to the final mark, which is $2^n - 1$. If you divide by $2^n$, you are effectively assuming the ADC can reach a value of 4096 on a 12-bit system, which is physically impossible since 4096 requires a 13th bit (1000000000000). Always divide by the maximum possible digital output code.
What is the fastest way to decode a binary number system example on the bench?
When you are staring at a logic analyzer trace or a raw serial terminal, doing base-2 algebra in your head is slow and error-prone. The fastest manual method is the hex-nibble grouping trick demonstrated in the verification step above. Memorize the binary-to-hex mappings for the numbers 0 through 15. Group the binary string into blocks of four, translate each block to a hex character, and then use your calculator's HEX-to-DEC function. This cuts a 16-bit binary addition problem down to four simple lookups and a single base-16 calculation.






