how to read correctly from a voltage divider

Hello everyone,

I’m building a device with a simple battery level indicator. There is a voltage divider bound to analog input 8.
I do several readings from Arduino and averaging them.

And now the strange thing: the averaged value varies significantly by the number of readings.

Here it is the (simpliefied) source:

int   battMeasureCount = 0;
float battVolts = 0;
float battVoltsMedian = 0;
int   battSamples = 10;

void batteryUpdate() { // called at every cycle
  
 if (battMeasureCount <= battSamples) { // we do battSamples readings...
  battVolts = battVolts + 12.10 * analogRead(8) / 1024; // empirical formula
  battMeasureCount++;
 }
 else
   { // we reached the desired samples count...
   battVoltsMedian = battVolts / battSamples; // computing the mean value

    Serial.print("battVoltsMedian="); Serial.println(battVoltsMedian); 

    // resetting the variables
    battMeasureCount = 0;
    battVolts = 0;
   }

}

void setup() {
 pinMode(8, INPUT);
}

void loop() {
batteryUpdate();
}

and the results:

with battSamples=10 → battVoltsMedian=9.82
with battSamples=500 → battVoltsMedian=8.90

With a higher number of readings (500 or more), the value is stabilising. Measured with a multimeter, it gave the same value (approx. 8.90 V).

I cannot understand, since the device is fed by a stabilised power source, why it reads that high value (9.92) with 10 samples.

Is it any other way to better compute the mean value, something statistical ?
Maybe to combine the last computed mean value with the current reading.
So there won’t be series anymore, but a continuous reading and average computing.

Regards,
Ciprian

You should post your code between code tags, </> in the ‘Post’ window, rather than inline in your post. It’s not a bad idea to read the “How to use this forum” post at the top of the section’s index page for posting guidelines.

Before anything else, which Arduino are you using?

The code is calculating the mean, not the median.

If there is a lot of variation in the voltage you may have noise, or a noisey supply to the Arduino
or there may be a large fluctuation in the load on the battery of course.

One thing to try is add a 100nF capacitor between the analog pin and ground, that will kill a lot
of noise.

If you use a Mega (A8 ??), you could use the 2.56volt Aref.
Default Aref (supply) is usually not very stable.
Other Arduinos might have a 1.1volt Aref.
What are the values of the voltage divider.
100n from A8 to ground is needed if resistors are >10k.
+12.10 ? what battery are you trying to measure.
Leo..

I think that the problem is in this line:

if (battMeasureCount <= battSamples)

It is true for all values of battMeasureCount between 0 and 10, i.e. 11 different values.

So you take 11 readings, add them together and then divide by 10.
This will give you a 10% error, which is easily noticeable.

You are always taking one more reading than you think.

When you increase the number of readings to (500+1), and divide by 500, the error is now only 0.2%.
This is less easily noticed, so you believe it to be correct.

If you look at your results:

and the results:

with battSamples=10 → battVoltsMedian=9.82
with battSamples=500 → battVoltsMedian=8.90

9.82 is 10% higher than 8.90

I rest my case.

Many thanks JohnLincoln :slight_smile:

I spent a lot of hours, even dug out my old statististics courses, to find another way to calculate the mean. I could not believe the answer was so straightforward.

Thanks for all answers - indeed, I meant the mean, not median, the board is a genuine Mega2560, and for now on I’ll use the </> tag ( I thought it is for HTML, not source code). I did not use a capacitor, because i needed just an (more or less) approximative estimation for the battery voltage while the device is working.

Regards,
Ciprian

pisicaverde:
and for now on I’ll use the </> tag ( I thought it is for HTML, not source code).

No, just go back to your first post, choose the “More” option and “Modify”, and fix that one.