Dividing by 1023 or 1024? The final verdict on analogRead

What would happen if a series if statements was written to do the conversion from A to D.

If (0 <= Vin < 2.441) then output = 0
If (2.441 <= Vin < 7.323) then output = 1
...
If (4997.559 <= Vin < 5) then output =1023

There are 1024 possible values.

But does 5/1023 or 5/1024 result in the same list of values the if statements would need?

I am using thresholds of 5/1024 in the if statements, only because I have not refreshed my memory on the internals of ADCs to know what the actual (correct?) threshold is.

For someone with the right equipment and environment (I used to have access at a previous job but don't now or in my basement), should be able to ramp the microvolt input into the ADC and see when it changes over. Is it at 1/2 of 4.88768 or at 1/2 of 4.88281?

Robin2:
The width of each "box" will be 5v / 1023 (or 5v / 1024 - take your pick)

There is no "take your pick". By design the cutoff points for the buckets are Vref / (2^bits). That is just the way a successive approximation converter works.

Is there agreement that from 0 to (Vref / (2^bits)) / 2 the output is 0 and the output changes to a 1 at (Vref / (2^bits)) / 2 + 1uV? Or does the output change to 1 at Vref / (2^bits) + 1uV

adwsystems:
Is there agreement that from 0 to (Vref / (2^bits)) / 2 the output is 0

That is not how they work. That is also not what I wrote.

I know that is not what you wrote. That would be what I wrote in the question. I also noticed you have skirted answering three times.

How the cutoffs are defined...
http://forum.arduino.cc/index.php?topic=537413.msg3670319#msg3670319

How the cutoffs are applied...
http://forum.arduino.cc/index.php?topic=537413.msg3668726#msg3668726

So your answer is B: The output changes to 1 at Vref / (2^bits) + 1uV.

Which make my thresholds in post #68 (very) wrong.

adwsystems:
So your answer is B: The output changes to 1 at Vref / (2^bits) + 1uV.

Ugh. Neither post includes "1uV". The answer is no, the output does not change to 1 at Vref / (2^bits) + 1uV.

Cutoff = Vref / (2^bits)

For your example...

Vref = 5 volts
bits = 10

So...

Cutoff = 5 / (2^10) = 0.0048828125

Which means...

For input voltages less than 1 * 0.0048828125 volts, a successive approximation analog-to-digital converter returns a zero.

For input voltages greater than or equal to 1 * 0.0048828125 volts and less than 2 * 0.0048828125 volts the ADC returns a one.

For input voltages greater than or equal to 2 * 0.0048828125 volts and less than 3 * 0.0048828125 volts the ADC returns a two.

Etcetera.

It would have been less typing to just say: C-neither - Vref / (2^bits)

Which I did not derive from either of the posts that you recently linked.

If you wanted to expound, the ADC stays 0 until Vref / (2^bits) -1uV.

You are welcome.

Oh. Wait. You don't appear to be grateful. Never mind.

Sure, transistor tolerances just like all manufacturing tolerances and standardization are my personal definition, uhuh.

added:
This must be why there's a thread on denying the utility of dividing by 1023. Because of me. Everyone else knows better. This just gets funnier.

added:
Just because your calculator spits out a string of digits, reality only matches so many in a row.
The ADC step is almost 5mV wide with 5Vref, you can stop at 2 decimal places.

That seems to be a very helpful way of expressing it, and I believe it is correct.

However, in one sense it is a lot more crude than I had expected, and in another way it answers a doubt that was in my mind when I wrote Reply #67.

If you imagine a 2-bit ADC - which can return values 0, 1, 2,and 3 and if you imagine that Vref is 4v. Then the cutoff will be 4 / (2^2) = 1. Which means that the changeover points will be 1, 2, and 3. The reason I see that as crude is that anything up to 0.999v will be reported as 0. And the answer to my doubt is that, by not having the changeover points at the half-way points there is no need to figure out how the first and last half divisions need to be figured (for example 0.5 and 3.5 in the simple example).

Now, what does that tell us about the process that started this Thread - how to convert the ADC value back to the voltage from which it was derived.

If the simple ADC produces a value of (say) 3 we can convert it back to a voltage either with Vref / 2^n * ADC (the equivalent to using 1024) or Vref / (2^n) - 1 (equivalent to using 1023 - the number of intervals)
4 / 2^2 * 3 = 3 and 4 / (2^2) - 1 = 4
Which is the correct answer?

The ADC would have produced 3 for an input voltage between 3v and 3.999v and we cannot know any closer than that what actually happened. So, in a sense, neither answer is correct and a better answer would the average of them - 3.5v.

Which I think can reasonably be extrapolated to the real 10bit ADC by saying that either calculation will be close enough.

...R

It's not like anyone is being forced to only convert to volts one way... yet. But the holy warriors have been triggered.

It is possible to know how to do something in practice without knowing the theory. The method by which aircraft wings generate lift is a good example.

The aircraft wings generate upward lift owing to the very universal law of the fluid mechanics. The technician was just lucky that the wings were fit together and the law worked well or the technician was highly intellect like the people of the Feroun's times who built the arches without knowing the geometry and the solid mechanics?

GolamMostafa:
The aircraft wings generate upward lift owing to the very universal law of the fluid mechanics.

Perhaps you would be good enough to start a new Thread (in Bar Sport) and explain how it works.

...R

I was planning to start a thread with similar title for a long time. Now I feel I must act now and support GoForSmoke against "1024 holy warriors".
Often when someone shows a code where 1023 divider is used to convert ADC reading to volts a "holy warrior" jumps up and tell them 1024 is the right divider and using 1023 is utterly wrong. I believe this advice is evil and should be punished with eternal torment. These are main reasons for this:

  1. The advice implies the ADC is so precise difference between 1023 and 1024 matters. A noob often expects to get 5mV resolution and accuracy from the Arduino's ADC. But since default reference is noisy and poorly regulated 5V from a USB port total accuracy of Arduino is very poor. And there is a lot of other sources of error much more important than 1023 vs 1024.

  2. Also it implies converting ADC reading to "real voltage" is the right way how to work with the result. In most applications there is no reason to convert the integer ADC result to float "real voltage". It only costs a lot of resources and adds nothing. Usually you want to compare the measured voltage to a threshold. "The right way" is to calculate (or find experimentaly) the threshold value directly in ADC "units".

2b) Only reason I can imagine to convert ADC result to "real voltage" is to show something to the user. For example you measure a wiper of a pot and show its position in %. When you use 100.0ADCResult/1024 formula I expect the user to be quite disappointed to have range of values from 0 to 99.9%. When you use 100.0ADCResult/1023 you get the expected range 0-100%.

  1. Supporters of the 1024 divisor claim it is "the correct number". Since one ADC value represents a whole interval of possible voltages - (uncountable!) infinity of values - there is no single correct voltage corresponding to given ADC result. You can define criteria how to choose "the best value" from the infinity of possibilities. But then "the best value" depends on the chosen criteria. And there are good reasons for both 1024 and 1023 divisors. Let alone many other possibilities how to choose the right value. (For example I often use ADCResult5 to show measured voltage in mV. Since my USB provides more than 5V it gives results closer to real value than "correct" ADCResult5.0/1024).

In short - telling a noob to use 1024 instead of 1023 will not help them to get better results but will support bad habits and wrong beliefs. And that is evil.

While we're here...
How many of your Arduinos are running at a rock-solid EXACTLY 5.00V (or 3.30V)

I doubt many at all.
So that lost resolution is fairly academic unless you're using an external precision AREF
Which is fair enough - but worth considering

Turning ADC 10 bit to voltage different ways, it's okay to use what fits your app.

mV = Vref * ADC / 1024

mV = Vref * ADC / 1023

mV = Vref * ( ADC / 1024 + 1/2 step ) ---- best guess

I see far more people use analog to check the rough position of a pot. They don't need to calculate volts but so many do!

If the analog read is to be processed with a fixed calculation or one from several then I would pre-calculate and table all the possibilities to look up. If the result is a float then think of the cycles saved. The result could as easily point to a function to run.

map(analogRead(A1),0,1023,0,5000)

I know that this topic is most academic but in my mind a question arise.
If I apply only a linear fit using data 0,0V 1023,5V it seems that I have to use 5/1023 (Vref is 5V)
The datasheet (and some other reasons) states that instead I have to use 1024

My question is: maybe the ADC is not able to recognise well values just below Vref, 5V in my example? If I use the bucket example there is a possibility that the last bucket is bigger than the previous, it is large 25/1024 instead of 15/1024?