Dividing by 1023 or 1024? The final verdict on analogRead

J-M-L:
2. dividing by 1023 statistically minimizes the maximum absolute error and thus it's fair then to assume that you get statistically a better approximation of your true original input value [color=blue]V[/color] if you use 1023

The "statistical minimum" is obtained when the value is assumed to be in the middle of the bucket: VEST = (x + 0.5) * VREF / 1024

Yes that could be another formula :slight_smile:

The whole idea that people might have uses for hardware that don't completely match the hardware to the full set of not just significant digits but the insignificant digits as well simply never occurs to datasheet fetishists.

Robin2:
I agree with that, and we established that way back when.

And, assuming that is also your view I don't understand the purpose of your Reply #102

...R

Thread TL:DR?

J-M-L:

The figure is wrong because the datasheet says that 1023 is obtained for a value that is not Vref (Vcc in your figure) but Vref-Vref/1024, so the last segment, the one that has Vcc as upper limit, doesn't exist.

J-M-L:
THIS IS WHY I THINK 1023 IS BETTER THAN 1024 (and you get a nice 5V for 1023)

Same reason, the ADC range never reach Vcc if Vcc=Vref, Vref is ever outside ADC range.

Give the ADC 5V and it cannot measure all the way to 5V.

In some people's heads the world is perfect and only one answer can right.

In the real world I can read the same signal with the same ADC several times and average the yes-they-are different values to arrive at a closer to real value than one read is likely to give. It's called oversampling and it works because the real world is not as diagram-simple as people's notions.

The truest you can get on a single read is "center of the bucket" and to realize that and this has been noted here since YEARS ago that the error margin is more than a "bucket" wide.

In the real world we build to tolerances. That's what the band on the resistors is there to tell you. That's what tolerances in specs are there for. The measure and the cut are never perfect, only ever within acceptable range (what will be tolerated by the design, hence the term "tolerance") that since you CAN'T measure perfectly, you CAN'T tell if anything happens to be so.

In the real world, when someone takes a procedural convenience that is within tolerance, you have to get UNREAL to object.

zoomx:
The figure is wrong because the datasheet says that 1023 is obtained for a value that is not Vref (Vcc in your figure) but Vref-Vref/1024, so the last segment, the one that has Vcc as upper limit, doesn't exist.

The figure is correct - that’s the start point, the left side of the last (top) horizontal red line - what do you get if you feed 5V ? (Answer is 1023 too - and I think the pin will safely take up to 5.5V if the ref is 5V - returning 1023 as you saturated the ADC)

This way the last segment has not the same length of the others, for sure is longer, and you don't know how is long because you can get the same value, 1023, also for 5.5V, maybe more, maybe less.
In other words 1023 mean a value that is bigger than Vref-Vref/1024 (not Vref!) but you don't know how many is bigger.

zoomx:
This way the last segment has not the same length of the others, for sure is longer, and you don't know how is long because you can get the same value, 1023, also for 5.5V, maybe more, maybe less.
In other words 1023 mean a value that is bigger than Vref-Vref/1024 (not Vref!) but you don't know how many is bigger.

Yes... this does not mean the estimated voltage you get by dividing by 1023 or 1024 is not a possible value, right?

you could even argue that given it's not at the beginning of the interval, if your setup allows going beyond 5V (not recommended though) then you'll be closer to the truth by saying 5 versus (5 - 5/1024) and statistically in the case lower the max potential error.

but as said above as well it does not matter compared to all the other imperfections of the hardware and likely your Vref

The difference is not only near Vref. It changes also the angular coefficient of the straight line that you use as transfer function between the ADC values and the voltage values, if you use a linear fit. If you use a range of 0-5V you have an angular coefficient of 1/1023 but if you use a range of 0-Vref-Vref/1024 you get an angular coefficient of 1/1024
Also this values, using 10 bit, have very small difference. If bits are lesser (maybe 8, I didn't tested it) the difference is not negligible.
As I wrote before, if you have only 2 bits the range is only 0-4V ( if Vref is 5V) and the difference is a lot.

Your reasoning is "flawed" because there is no angle and there is no continuous transfer function from voltage to digital value

The math problem to solve is that you are looking at the reverse function of a surjective but non bijective piecewise affine function. (the steps)

You really lost information when the ADC converted the input Voltage into a digital representation, and the amount of information you lot is directly related to the number of bits (and hardware quality) of the representation and there is no way to get back to the original value.

All you can do is take an estimate, based on simple principle that it has to be a likely original value (ie within the interval). There is no good or bad estimate as long as they sit there in the interval. You can add extra personal constraints like "I want to see a nice 5V when the ADC tells me 1023" or "I want to minimize the max average error" or "I want a constant max error"... Those are arbitrary choices you can impose to yourself.

that means basically that any of the affine function crossing every "step" is legit to consider.

line.png

but it does not need to be an affine function either, you might want to compensate specific bias you have at specific steps so this would be a legit curve as well

altview.png

if you have 2 bits --> you have 4 possible values for the ADC. So it's exactly the same thing just with less precision... and in a perfect world, they would map this way:

[color=purple][sub]
0.00V to 1.25 V would map to 0
1.25V to 2.50V would map to 1
2.50V to 3.75V would map to 2
3.75V to 5.00V would map to 3 (and beyond 5V if the hardware does not burn)[/sub][/color]

so when you have a x value 0,1,2 or 3 you need to decide arbitrarily what voltage was the input. The point I make above is that dividing by 4 to get a possible estimate of the original voltage by using x * 5 / 4 always gives you the entry point of the interval (0 - 1.25, 2.50, 3.75) whereas dividing by 3 gives you a point somewhere within the interval (0, 1.66, 3.33, 5) which are not worse than the other values... they are just as likely possible estimates.

Now assuming you have input varying amongst the full scope and you do millions of reading, when the ADC tells you 1 the second approach (dividing by 3) will give you 1.6666 for something that was between 1.25 and 2.50 so the max error you are doing is 0.83 whereas when you divided by 4 the max error is 1.25V..

--> as said above, taking the middle of the interval (x + 0.5) * V[tt]ref / 1023 [/tt]is actually what minimizes this max error. You could decide to take always the min of the interval (divide by 1024), always take the max of the interval (same absolute max error), or shoot anywhere randomly within the interval... All are valid answers for an estimate.

zoomx:
This way the last segment has not the same length of the others, for sure is longer, and you don't know how is long because you can get the same value, 1023, also for 5.5V, maybe more, maybe less.
In other words 1023 mean a value that is bigger than Vref-Vref/1024 (not Vref!) but you don't know how many is bigger.

Same thing goes for > 5V when dividing by 1024. What's your point worth making?

When you start at zero what could be 1/2 you end at Vref - Vref/1024 rather than Vref = Vref/2048 which is More Real.

The hardware does this in 10 stages, not 1024.

Is it worse to play in shadows or to act like there are none?

Nobody that was shown properly successive approximation A/D conversion method will go down the wrong path of 5/1023, right? Do that in the online calculator and see how many decimal places the result has. It keeps going and going. But 5/1024 is different.

The way it works is... 10 bit... 1024 levels. Level 1 to level 1024. Voltage range is 5V for the analog range. 1024 levels (steps) contains 1023 individual gaps..... just as 2 steps has 1 gap. We don't divide the 5V range into 1023 portions. Instead, we divide it by the total number of levels (ie. 1024).

For later... the D/A will have a voltage res of 5/1024 volt. Why D/A? Because a successive approx A/D contains a D/A within it. Zero volt analog will convert to level 1.... all zeros binary... ie. decimal 0. And 2.5V converts to level 512... or binary 1000000000 or decimal 512.... which is 512*[5/1024] V. And level 1024 is all ones binary.... which is decimal 1023, which corresponds to 1023*[5/1024] volt. The highest analog voltage 5V rounds down to 1023*[5/1024]. This just means..... all binary ones 1111111111 (decimal 1023) represents (5V-5/1024) V, or 1023*[5/1024] V.

To avoid bias..... they use noise dithering, right?

It's true that for relatively large bit length.... the 5/1023 or 5/1024 thing give relatively close results. But should always be divide by Vrange/1024 for the voltage resolution. It's definitely not 5/1023.

Southpark:
The 5/1023 or 5/1024 thing give relatively close results. But should always be divide by Vrange/1024 for the voltage resolution. It's definitely not 5/1023.

Seems you have not read the above... see the graphs in post #123 you will see that dividing by 1023 is as legit as dividing by 1024 => it gives you one of the possible value

J-M-L:
Seems you have not read the above... see the graphs in post #123 you will see that dividing by 1023 is as legit as dividing by 1024 => it gives you one of the possible value

Thanks jml.... but the method used in successive approx is the method of halves...or halving. So what you wrote below shows method of halving.... where the input analog voltage is compared with exactly half the voltage range ... ie. compared with 2.5 volt.

J-M-L:
always gives you the entry point of the interval (0, 1.25, 2.50, 3.75) whereas dividing by 3 gives you a point somewhere within the interval (0, 1.66, 3.33, 5) which are not worse than the other values

The 0, 1.25, 2.5, 3.75 system does just that. ie. 2.5 is halfway between 0 and 5. And, 1.25 is exactly halfway between 0 and 2.5.....and 3.75 is halfway between 2.5 and 5. It's the divide and conquer method.... easily implemented. That's what they use, right? And when they apply the D/A, which is required in a A/D process.....the D/A constructs an analog level based on the 2 bit resolution of 5/(2^2) = 5/4 volt, right? It all ties up to the hardware link between the A/D and internal D/A, right?

But I do agree that if we use our own system, then we can define or specify own levels of quantisation, or customise the system to however we want. But if the arduino system is based on say successive approximation, then the calculations/math will be based on their system. So if the documentations/data sheet reckons 5/1024 as the voltage resolution, then that is what should be used.

There is no but...any voltage value in the interval corresponding to the digital value is as good as any other one... that’s it.

J-M-L:
There is no but...any voltage value in the interval corresponding to the digital value is as good as any other one... that’s it.

Let's take a look at what successive approximation A/D (including the D/A side of it) generally involves. Also, the hardware has a voltage resolution of 5/1024 volt..... not 5/1023 volt (for the 5V, 10 bit system). This is assuming the general internal D to A converter (inside the A to D) is based on a general R-2R system. The least significant bit being a '1' (and all the other bits being zero) will correspond to 5/1024 volt, not 5/1023.

If it's a 5V, 2 bit system, then the voltage resolution will be 5/4 volt. The very first test (of two tests) for a 2-bit system is where the reference voltage is first set to exactly half-way between 0 and 5, which is 2.5 volt. This corresponds to temporarily setting of the MSB to '1' (and the LSB remains '0'. This means the reference register is temporarily '10', or decimal 2, which converts (via a D/A) to 2*[5/4) = 2.5V. The first test will be to see if the input voltage is greater-than or equal-to that 2.5 level. If it is, then the MSB will permanently become a '1'. Then the system will know that the voltage will be in the top-half of the range (ie. above 2.5 volt and below 5 volt). And the system then proceeds to home in on the best binary representation for the input voltage....based on the 2-bit system. For the second (and final test), if the MSB is already determined to be '1', then the 2 bit register is then temporarily made to be '11' or decimal '3', which sets the new internal reference voltage (care of the internal D/A) to be 3 * 5/4 = 3.75 volt (which is exactly half-way between 2.5 and 5 volt). The comparison between the input voltage and that 3.75 volt will decide on the outcome of the LSB.

The general D/A circuit allows these internal 'half-voltages' to be generated easily. That is, voltages like 0, 1.25, 2.5, 3.75.

That other set of values you mentioned..... ie. [(0, 1.66, 3.33, 5)] ..... the 1.66 is actually 1.666666666666666666 etc. and the 3.33 is actually 3.33333333333333333 .... which isn't very good, because they just keep going, right? Maybe for a mathematical exercise it is all ok. But from a hardware implementation perspective, that's not what they do (or want to do), right?

I'm thinking that.... the main thing is ...the question of ... does 'divide by 1023' (for 10 bit) represent the system that the manufacturer aimed to achieve? I'm thinking... no, it does not. So if it doesn't, then it'll be best to just teach it as it should be ..... divide by 1024.

Southpark:
Do that in the online calculator and see how many decimal places the result has.

Do the math and see how quickly the digits reach insignificance in the face of noise alone.
Marvel at the number of places that a calculator can show that have already been shown to not matter.....

The way it works is... 10 bit... 1024 levels. Level 1 to level 1024. Voltage range is 5V for the analog range. 1024 levels (steps) contains 1023 individual gaps..... just as 2 steps has 1 gap. We don't divide the 5V range into 1023 portions. Instead, we divide it by the total number of levels (ie. 1024).

The way it really works is all that and error. You forgot the error that is bigger than your point.

Oversampling is how ADC accuracy gets improved. That or get a better ADC but by 12 bits the wiring gets real important.

It's not like there is only ONE WAY to treat analog reads. If you're a stickler for accuracy then first divide by 4 and then get upset over the divide by 255 or 256 because then the difference will be more significant than the noise. Sure you lose precision but that's not accuracy.

Southpark:
That other set of values you mentioned..... ie. [(0, 1.66, 3.33, 5)] ..... the 1.66 is actually 1.666666666666666666 etc. and the 3.33 is actually 3.33333333333333333 .... which isn't very good, because they just keep going, right? Maybe for a mathematical exercise it is all ok. But from a hardware implementation perspective, that's not what they do (or want to do), right?

This is not the point. The point is that if you know the Digital value is X what could be a likely original Analog voltage that generated that X?

What I am saying is if X=1 then 1.66 or 1.666666666666666 or 1.5 or 2 are as likely good guesses as 1.25 (in your example). the rest is litterature...