Disclaimer:Thread title copied verbatim with no permission from owner.
Here is the link my post refers to: http://www.electro-tech-online.com/threads/why-adc-1024-is-correct-and-adc-1023-is-just-plain-wrong.132570/
I found the above post quite interesting, and not being a member of the above forum, I thought you may find it interesting and comment on it a bit.
I found it strange that anyone would divide by 1023 in the first place. Then in the second post I find this line.
Doing the incorrect math of ADC *5 /1023, gives ONE advantage, it means that the top ADC reading of 1023 will give an output result of "5v"
The disadvantages is also there. But the most interesting bit for me is the last heading at the end of the second post.
I'm quoting it all here highlighting what I what like to be lectured about.
Doing the ratio scaling math right!
First let's clear one thing up, the ratio scaling math of *x /n is perfect, it has no error.
But there are two rounding down errors that we need to deal with;
1. The ADC hardware itself causes a rounding down error. Every possible input voltage is reounded down to the nearest ADC unit. This error occurs BEFORE any ratio math is done, and can be compensated by adding 0.5 ADC counts to every ADC sample BEFORE any conversion.
Since it is impossible to add 0.5 in integer math the best way is to double the ADC value, and then just add 1, ie; (ADC*2)+1
2. The math *x /n does not introduce error with the *x but the /n operation using integer math causes a rounding down error to the nearest n unit. This integer division rounding down error can be compensated by adding half the divisor; +0.5n /n which in our case is +512 /1024.
However since we have the ADC value already doubled from the previous operation, we need to divide by double, or 2048. So it becomes; +1024 /2048.
Putting it all together.
To get a reading of 0.00v to 5.00v from the PIC ADC can be done using the correct data scaling of all samples, and properly compensated integer rounding on all samples, by the following integer math;
((ADC*2)+1) *500 +1024 /2048
Using *x of *500 means we are converting 1024 ADC units to 500 output units (which represent 0-500 ie 0.00v to 5.00v).
- The ADC causes rounding down .... I guess that is true for AVR as well as I suppose its the same type of ADC and nothing to be done about it, unless perhaps feed a slightly lower reference voltage?
- /n (divide by n) causes a rounding down in integer math .... true.
- And then the final result, i.e. the formula in turquoise... 1024/2048 should always return 0 in integer maths? I am not so sure if the formula is correctly printed there.
- I think it should read (((ADC*2) +1) * 500 + 1024) / 2048
Crickey, I've never even given it the slightest consideration when converting, and I doubt it will make a difference in most projects, but considering a perfect environment, will it actually make a difference?
Lets say your scale you convert to is like 100V, i.e. 25 times up, that could mean quite a bit of an error.
Or the other problem, with high resolution ADC's, I guess that would also cause inaccuracies if we go convert in the usual fashion.
What say ye? Is it something to consider?