Hi, looking for some help with a simple battery voltage monitor on a Arduino Mini Pro 3.3V 8Hz. The battery I am trying to measure is 4 x 1.5V AA batteries which my multimeter tells me are outputting around 7.1V. I have a voltage divider with 2 resistors to knock this down to around 2.1V (again proved by my multimeter). I am feeding this 2.1V to an analog pin on the Arduino. I should note at this point I am actually powering the Arduino via USB so I can debug the output, but eventually it will be battery powered and hence my need for a voltage monitor. However, I believe the analog pin should still read the 2.1V from the battery/voltage divider correctly. My meter shows current out of the divider as 0.07mA.
I have a simple sketch doing an analogRead of the pin and outputting the resultant value. I've put in a delay of 500ms to slow down the output. I would've expected this to be a fairly stable value, moving up and down slightly around a certain point. Ignore the maths that I then need to employ to get actual voltage for now. However, what I actually see if weird fluctuating readings such as: 359, 983, 187, 0, 849, 947, 12, 21, 940, 932, 7, 28, 950 etc.
To prove the pin is not faulty I have tried several. In addition I have temporarily fed the pin with the Arduino ground and I get a nice reading of near 0, then if I feed it Arduino Vcc I get a nice clean reading of near 1023, so the pin is working for this regulated voltage from the Arduino.
Please can someone give me some ideas why it might not be working? Thanks in advance.
No it doesn't, it shows 2.1v you told us earlier. (or did you perhaps mean 0.07 milliAmps here?
Oops, I corrected that a few mins after original post when I re-read it. Yep I of course meant mA.
Your suggestions were indeed spot on, I had missed a connection between battery ground and Arduino ground. My basic knowledge of electronics did not realise this was required.
I'd appreciate your input on a two final question about voltage monitoring. My readings don't have to be super precise, maybe accurate to something like 0.5V. Is it worth doing the complicated register stuff to get a true Vcc (by reference to 1.1V internal) or would assuming 3.3V be ok for my needs?
Lastly, as battery voltage decays over time, I was wondering how much that impacts the accuracy?
Boardburner2:
You have a problem there.
Try changing the battery on your multimeter first.
Nope I don't. It is quite common for brand new (especially good quality batteries) to output higher than advertised voltage. This is also common with re-chargeable batteries.
I'd appreciate your input on a two final question about voltage monitoring. My readings don't have to be super precise, maybe accurate to something like 0.5V. Is it worth doing the complicated register stuff to get a true Vcc (by reference to 1.1V internal) or would assuming 3.3V be ok for my needs?
I with Ken and I assume you're missing a ground connection.
With the meter, are you measuring 2.1V at the Arduino's input with the meter's "ground" lead connected to the Arduino's ground?
My meter shows current out of the divider as 0.07mA.
Current is not important unless you've got too much current through the voltage divider and that's draining your battery. And, there's no reason to measure it since you know the voltage & resistance values.
It's kind-of a pain to measure current because you have to break the circuit to insert the meter. Then, you accidentally leave the meter setup to read current, and you blow the fuse in the meter when you try measuring a voltage. Or worse, you fry a component in your circuit! :o
The Arduino's input impedance is on the order of 100 meghoms, so there's no measurable current into the Arduino (unless you go over 3.3V or negative).
Is it worth doing the complicated register stuff to get a true Vcc (by reference to 1.1V internal)
That won't help in your situation. With the 1.1V reference you can't measure higher than 1.1V. It would just require a different voltage divider and a different ratio in your sketch and you'd have the same resolution in the end.
Urm that only sets the reference voltage to use to be internal 1.1V and doesn't give you the actual Vcc being output by the Arduino (it is not always the advertised 3.3V, often slightly less). I don't want to use 1.1V as my reference as I am measuring higher than that. I could use a constant 3.3V (probably good enough for my needs) but by using the following code you can get actual Vcc (which for me reads about 3.19V):
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
infaddict:
Lastly, as battery voltage decays over time, I was wondering how much that impacts the accuracy?
If you're using the default reference voltage, Yes it does. If you were to put a voltage divider from 5v to GND and then measure it's mid point, the value returned would never change. As the 5v changes, so does the voltage measured. Since the relationship between these two values is maintained (by the passive voltage divider), so your reading will remain constant. (thereby hiding the decay that you're looking for)
Using an alternative reference voltage therefore becomes essential. (as suggested by Crossroads). Just make sure your voltage divider is setup to give you less than the voltage reference being used.
KenF:
If you're using the default reference voltage, Yes it does. If you were to put a voltage divider from 5v to GND and then measure it's mid point, the value returned would never change.
I presume you mean 5V battery (as my Arduino is 3.3V) . I agree that referencing the thing that is changing (the battery) wouldn't work.
I was proposing referencing to the 3.3V Vcc of the Arduino which should remain constant as long as the Arduino is receiving enough power to operate. So knowing my resistor values and ohms law I can do something like the code below (where R1 and R2 are the resistor values). My understanding is this will monitor battery decay and would only fail (as would whole Arduino) if voltage dropped below 3.3V input minimum:
infaddict:
I presume you mean 5V battery (as my Arduino is 3.3V) . I agree that referencing the thing that is changing (the battery) wouldn't work.
...
This works and shows me around 7.1V which is exactly what I am looking for. Please let me know if my theory is flawed.
Your logic is sound. You can expect your readings to plateau when they drop below that required by the voltage regulator though. This may be significantly higher than 3.3v maybe 4.8 ish.
infaddict:
Nope I don't. It is quite common for brand new (especially good quality batteries) to output higher than advertised voltage. This is also common with re-chargeable batteries.
Eh ?
4 x 1.5 = 6 v not 7.2.
Those are dry or alkaline cell values dictated by laws of physics.
5 x 1.2 yes which would imply nicad batteries or nimh which you have not specified.
For brand new batteries I might accept 6.5 v from a cheap meter but 7.1 or 7.2 is not particularly believable.