0
\$\begingroup\$

For example, suppose I have an AREF of 2.5 V and a voltage of 0.3V at the A0 input of the microcontroller. How would one calculate the resulting 10-bit binary number at the output

\$\endgroup\$
3
  • \$\begingroup\$ 0 means 0 volts. 1023 means a voltage the same as VREF. And in-between means in-between. \$\endgroup\$ Commented Aug 16, 2022 at 22:01
  • \$\begingroup\$ I edited the question. \$\endgroup\$ Commented Aug 16, 2022 at 22:07
  • \$\begingroup\$ The formula is in the datasheet. What research have you done about the subject? \$\endgroup\$
    – Justme
    Commented Aug 16, 2022 at 22:16

1 Answer 1

2
\$\begingroup\$

When working with ADCs, you basically just need to know the following formula:

$$ \text{LSB} = \frac{\text{FSR}}{2^N} $$

where:

  • "LSB" = "least significant bit", or, essentially, the "step size" of the digital outputs,
  • "FSR" = "full scale resolution", which is the maximum possible input voltage value (in your case, VREF), and
  • "2N" = two-to-the-power-of-N, where N is the number of bits of resolution supported by your ADC.

This tells you everything you need to know about how your ADC performs. (There are generally other formulae that you can find in the datasheet, online tutorials, etc. for ADC conversions, but they can all be derived from this.)

Substituting the values given in the question, we get the following specific version of the equation for your case:

$$ \begin{aligned} \text{LSB} &= \frac{2.5\ \text{V}}{2^{10}}\\ \text{LSB} &\approx 0.00244\ \text{V} \end{aligned} $$

Once you have calculated the LSB (step size between digital measurements, which is a constant for your ADC configuration), you can easily interconvert between voltage input and digital output based on this proportionality. For example, if the input voltage is 0.3 V, then the converted digital output will be ≈123:

$$ \begin{aligned} \text{result} &= \frac{\text{V}_\text{input}}{\text{LSB}}\\ \text{result} &= \frac{0.3\ \text{V}}{0.00244\ \text{V}}\\ \text{result} &\approx 122.88 \end{aligned} $$

A decimal-to-binary calculator will tell you that decimal 123 is 0b1111011 in binary. You can find decimal-to-binary conversion tools online, as well as in the "programmer" mode of the calculator utility included with virtually all desktop operating systems.

Similarly, when you get ready to write the code that converts the digital output value into a voltage, it's as simple as multiplying the conversion value by the LSB. Say, for example, that you read a value of 0b110011010 (which is decimal 410):

$$ \begin{aligned} \text{V}_\text{input} &= \text{result}\times{\text{LSB}}\\ \text{V}_\text{input} &= 410\times{0.00244\ \text{V}}\\ \text{V}_\text{input} &\approx 1.0001\ \text{V}\\ \end{aligned} $$

Because the LSB is a compile-time constant, obtaining the actual voltage from the ADC conversion value requires only that you perform a multiplication at run-time. What could be simpler? :-)

(Of course, that assumes you have a floating-point unit available in your microcontroller and/or are willing to use it. If you don't have an FPU, then you will probably want to do the voltage conversion as an integer operation, which requires a bit more creativity—but not much.)

\$\endgroup\$
4
  • \$\begingroup\$ ATmega328P has no hardware floating point. Integer multiply is fast though. \$\endgroup\$
    – Justme
    Commented Aug 16, 2022 at 22:36
  • \$\begingroup\$ \$LSB = FSR / (2^N - 1)\$. \$ADC_{MAX} = 2^N - 1 = FSR\$. \$\endgroup\$
    – Velvet
    Commented Aug 17, 2022 at 9:46
  • \$\begingroup\$ @Seir Please see electronics.stackexchange.com/q/258490. While this is admittedly somewhat of an opinion-based perspective, my take on it is that the subtraction of 1 is not correct, and the answers given in that thread mostly summarize the reasons why, including it being defined by the IEEE standard. 2^N is the number of distinct codes, whereas 2^(N -1) is the step size between codes. In this case, the number of distinct codes is correct, because you're dividing it by the maximum value. \$\endgroup\$ Commented Aug 17, 2022 at 16:05
  • \$\begingroup\$ It is an interesting read. But the formula \$result = V_{input}/LSB\$ still doesn't make sense to me @\$V_{input} = 2.5V\$ and \$N = 10\$: \$result = 2.5V/ 0.00244140625 = 1024\$. 1024 is out of scope of a 10-bit value. Where am I wrong? \$\endgroup\$
    – Velvet
    Commented Aug 17, 2022 at 19:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.