Why ADC/1024 is correct, and ADC/1023 is just plain wrong!
It's common to need to scale a microcontroller ADC result to give a value in some other scale. One example is to scale the ADC to read in actual volts like read from 0.00v -> 5.00v.
People sometimes use ADC *500 /1023 as this gives a reading of 500 (5.00v) for the top ADC value of 1023.
Doing that math; *x/(n-1) or *x/1023 does perform a kind of rounding function, but it "fudges" the rounding and gives both scaling and rounding errors.
The correct scaling math; *x/n or *x/1024 correctly scales all the output data in size, but gives an average rounding error of 0.5 ADC counts (always rounding down).
To magnify and show the errors caused by *x/(n-1) this table shows a simple ADC that has 5 values. (This is just like a PIC ADC but has 5 possible ADC values, not 1024).
People sometimes use ADC *500 /1023 as this gives a reading of 500 (5.00v) for the top ADC value of 1023.
Doing that math; *x/(n-1) or *x/1023 does perform a kind of rounding function, but it "fudges" the rounding and gives both scaling and rounding errors.
The correct scaling math; *x/n or *x/1024 correctly scales all the output data in size, but gives an average rounding error of 0.5 ADC counts (always rounding down).
To magnify and show the errors caused by *x/(n-1) this table shows a simple ADC that has 5 values. (This is just like a PIC ADC but has 5 possible ADC values, not 1024).
Code ( (Unknown Language)):
- [b]First the incorrect *x/(n-1) math;[/b]
- input ADC math result average output
- voltage value ADC*x/(n-1) error result
- 4.00-4.99 4 *5 /4 5.00 +0.50 5
- 3.00-3.99 3 *5 /4 3.75 +0.25 3
- 2.00-2.99 2 *5 /4 2.50 0.00 2
- 1.00-1.99 1 *5 /4 1.25 -0.25 1
- 0.00-0.99 0 *5 /4 0.00 -0.50 0
Note that for the 5 possible ADC values, the output scale now has 6 values (0-5) and the value 4 can never occur! And although the average error might look to be nicely distributed +/- the centre of scale, the actual output result proves to be much uglier.
So if you had a slowly increasing voltage, the ADC would read; 0, 1, 2, 3, 5!!
The maximum error in real world use is 2v, because that very tiny change of 3.999v - 4.001v would cause an output change of 3v -> 5v or a change of 2v!
All output values are properly scaled and all are represented. The average error is never greater than 0.5 (no more average error than the /(n-1) example), and the average error is always one fixed value (-0.5) making it very easy to compensate (see below).
The maximum error at any time is 1v, this is half the max error of the /(n-1) example, which can introduce extra error up to 1 in high value ADC readings.
So if you had a slowly increasing voltage, the ADC would read; 0, 1, 2, 3, 5!!
The maximum error in real world use is 2v, because that very tiny change of 3.999v - 4.001v would cause an output change of 3v -> 5v or a change of 2v!
Code ( (Unknown Language)):
- [b]Here is the correct scaling math *x/n;[/b]
- input ADC math result average output
- voltage value ADC*x/n error result
- 4.00-4.99 4 *5 /5 4.00 -0.50 4
- 3.00-3.99 3 *5 /5 3.00 -0.50 3
- 2.00-2.99 2 *5 /5 2.00 -0.50 2
- 1.00-1.99 1 *5 /5 1.00 -0.50 1
- 0.00-0.99 0 *5 /5 0.00 -0.50 0
The maximum error at any time is 1v, this is half the max error of the /(n-1) example, which can introduce extra error up to 1 in high value ADC readings.