Go Down

Topic: Dividing by 1023 or 1024? The final verdict on analogRead (Read 8071 times) previous topic - next topic

GoForSmoke

If you want your results to read 0 to Vref and are willing to live with less error than you can measure, divide by 1023.

If you want to be a pedantic-retentive obsessed with correctness you can never show or use, divide by 1024 and feel superior.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

Whandall

If you want your results to read 0 to Vref and are willing to live with less error than you can measure, divide by 1023.

If you want to be a pedantic-retentive obsessed with correctness you can never show or use, divide by 1024 and feel superior.
Doing things deliberately wrong/incorrect would make me feel dumb, how about you?
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

TolpuddleSartre

Doing things deliberately wrong/incorrect would make me feel dumb, how about you?
Can I give you a hug?
Would that be awkward?

GoForSmoke

Doing things deliberately wrong/incorrect would make me feel dumb, how about you?
First I make sure it's actually "wrong", noting that slavishness to one form of error is not "right".

When the error is below the noise level of somebody's idea of "right", that's how insubstantially small their claim is.

I'd feel dumb claiming either way to be right when both ways yield errors when used to convert ADC to analog values.
I'd feel even more dumb if I couldn't see that as fact and then decide which one serves my app best.

If you want your results to read 0 to Vref and are willing to live with less error than you can measure, divide by 1023.

If you can't stand knowing that the hardware has 1024 steps and you have a need to keep that from abstraction then you should know that you have not improved accuracy and now can't get any result showing signal in either the 1st Vref/1024 or the last Vref/1024 part of the range regardless of the voltage measured, which seems a bit funny for "right" doesn't it?

When I compare the two, I prefer the first since the error is less than noise and at least near 0 gives me 0 and near Vref gives me Vref.

Purity to hardware that is supposed to be approximating something else, it's the something else that I want. If the way I get that does not cause actual as opposed to supposed bad data and that way covers a GAP in the supposed right way at the same time, no I don't feel dumb taking that bit of win at all. I wonder at the ones who don't! Perhaps 3 factors at once confuse them?

PS -- I get a big laugh at people who go on about preserving the "purity" of what is not pure.

So my question for those is: Why does analog oversampling work?

1/1024 = 0.000976562
1/1023 = 0.000977517
Difference when Vref is 5V is less than 5 microvolts.

THINK
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

Robin2

PS -- I get a big laugh at people who go on about preserving the "purity" of what is not pure.
Reminds me of the story about the engineer, the mathematician and the economist who were at the door to a room with an attractive woman (or man, I guess) in the room at the opposite wall. They were told that they could kiss the woman if they could get to her by following a simple rule.

They could start to cross the room with the longest step they could make, but each subsequent step would have to half the distance of the previous step.

The engineer asked how would he know what direction to go.

The mathematician said it was impossible.

The economist said that after 4 steps he would be close enough.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

TolpuddleSartre

#20
Mar 28, 2018, 12:40 pm Last Edit: Mar 28, 2018, 06:10 pm by TolpuddleSartre
In real life, we all bodge things, but I still think it is better if you know the underlying principles, for those edge cases where it will matter.

I guess I'll just have to live with my feelings of being superior correct and literate.

Robin2

Now that my interest has been awoken sufficiently to read the Atmega328 datasheet ...

The data sheet clearly states what is in Reply #2
ADC = (VIN * 1024) / VREF

However if you imagine a very crude ADC that can only report the values 0, 1, 2, 3, 4 and 5 for a range of 0v to 5v you can easily see that the only sensible calculation is
ADC = VIN * number of intervals / VREF

For example, if Vref is 5v and Vin is 3v the calculation will be 3 * 5 / 5 = 3

For the Atmega 328 the number of intervals is 1023, not 1024. And if the crude ADC was to mimic the Atmega datasheet the calculation would be 3 * 6 / 5  = 3.6 which should round to 4 and which would be incorrect. Of course an integer only system would report 3 (rounding down) so the error would not appear.

All of which leads me to believe that the Atmega 328 ADC is not sufficiently precise for it to matter whether you use 1023 or 1024. And that the assertion that started this Thread has no basis in theory and (as the OP acknowledged) does not matter in reality.

...R
(Runs for bomb shelter)
Two or three hours spent thinking and reading documentation solves most programming problems.

GoForSmoke

In real life, we all bodge things, but I still think it is better if you know the underlying principles, for those edge cases where it will matter
Knew this years ago. I understand what the device does and how precise it is not.

If I give it 5V and it tells me 1023 that really means 4.995V to 5V if I go by numbers alone.  That's a 5mV step.

The difference between 1/1023 and 1/1024 is less than a thousandth of that. Yeah... bodge... uhuh.

Let me know when you figure out the underlying realities including what the ADC is for.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

GoForSmoke

Now that my interest has been awoken sufficiently to read the Atmega328 datasheet ...

The data sheet clearly states what is in Reply #2
ADC = (VIN * 1024) / VREF

However if you imagine a very crude ADC that can only report the values 0, 1, 2, 3, 4 and 5 for a range of 0v to 5v you can easily see that the only sensible calculation is
ADC = VIN * number of intervals / VREF

For example, if Vref is 5v and Vin is 3v the calculation will be 3 * 5 / 5 = 3

For the Atmega 328 the number of intervals is 1023, not 1024. And if the crude ADC was to mimic the Atmega datasheet the calculation would be 3 * 6 / 5  = 3.6 which should round to 4 and which would be incorrect. Of course an integer only system would report 3 (rounding down) so the error would not appear.

All of which leads me to believe that the Atmega 328 ADC is not sufficiently precise for it to matter whether you use 1023 or 1024. And that the assertion that started this Thread has no basis in theory and (as the OP acknowledged) does not matter in reality.

...R
(Runs for bomb shelter)
The ADC does have 1024 steps.  The zero step covers 0V to Vref/1024 (just under 5mV whenVref is 5V) returning 0.

Quote
28.6.3.
ADC Accuracy Definitions
An n-bit single-ended ADC converts a voltage linearly between GND and V REF in 2 n steps (LSBs). The
lowest code is read as 0, and the highest code is read as 2 n -1.
2^0 to 2^(1024-1) and we get n as the return, 1024 possible values.

The fun comes when reducing a range of values to a number treated as volts. We measure a smudge and give it a number.
 
The most of time closest number would be in the middle of the range and never be either 0V or 5V.

By dividing by 1023, I cover both ends in the math with a calculated 1/1024 error, looking at less than 5 microvolts.
Unless I need to show or calculate down to 6 decimal places, it's not a problem. But if I do, I want a different ADC.

For more details on ADC, check with Nick;
 http://www.gammon.com.au/adc
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

larryd

This all needs to be in the 'Introductory tutorials' forum.   :(





No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

GoForSmoke

Perhaps the OP will consider replies, but seems pretty set from the start.

Most users want to be able to jumper 5V and see 5V displayed or jumper GND and see 0V displayed.

Now another person might make quicker and easier sense just viewing the ADC value, coding to it and never converting it to volts. And divide by what ceases to be an issue.
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

Robin2

The ADC does have 1024 steps.  The zero step covers 0V to Vref/1024 (just under 5mV whenVref is 5V) returning 0.
In the range 0 1 2 3 4 5 there are 5 intervals. 5 - 0 = 5

I am inclined to think that if I wrote out all of the numbers from 0 to 1023 I would have 1023 - 0 = 1023 intervals.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

GoForSmoke


char buff[ 1024 ]; // has how many elements and what is the high index?
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

Robin2

char buff[ 1024 ]; // has how many elements and what is the high index?
I agree there are 1024 numbers. But there are only 1023 intervals between those numbers.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

GoForSmoke

Do you mean?

Divide 1024 by 1024 and you can cover one end (0V to 4.995V) or the other (0.4883 to 5V) and either way the range is open-ended.

Divide by 1024 by 1023 and you have 1 extra that closes the end.

The error is 6 decimal places down, Arduino floats guarantee 6 places total and ... they're dirt-in-the-sand IEEE 32-bit FP.

At least work to the ADC value where possible, it's the conversion of ranges to values that forces errors.

1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

Go Up