A lot has been written on this topic and I think Ive read it all!!
However, I still have some problems with implementation and a few questions about reliability.
My setup is roughly as follows: (if anyone spots a setup mistake, please feel free to comment)
2 x AA Eneloop rechargeables connected in series (Output at full charge ~2.93V)
The booster is connected to the 5V pin of an Arduino Nano.
(Please let me know if more info is required)
Because my input to the Arduino is now regulated, I find that reading the internal 1.1V reference of the Arduino is no good to me, as it does not indicate the battery voltage at all. (Input to Arduino stays constant at 4.96V as the batteries drain).
So my approach is to read the direct battery voltage using an analog pin.
I believe that I can safely do this as the maximum voltage I am putting into the Analog pin is 2.9V and therefore safely below the max 5.0V as per specs.
So I have simply wired the + terminal of the two batteries into the A2 pin and use this code:
int V = analogRead(A2);
Now here is my problem:
The value returned for fully charged batteries is approximately 590 (and roughly what I expected), however the value changes constantly and varies by about +/- 40.
(I am monitoring it with a delay of 500ms between reads and every time the value changes.)
Question 1:
Is this setup safe? I know that the Booster will keep the input at 5V, but if for some reason it fails; I will be sending 2.9V into the A2 pin with no other power being supplied. Will this be a problem or will the Arduino simply stop working because 2.9V is too low?
Question 2:
Why is the voltage not constant? Is this just noise from the batteries?
Can I solve it with a 1uF capacitor in the line that goes to the A2 pin?
Regards and thank you in advance
CX15
Disclaimer:
This is my first project with Arduino (and electronics of this scale).
Please feel free to correct any terminology mistakes or misunderstood concepts on my part!!
Q1:
I'd put a resistor between the plus terminal and ground. I think its basically safe though. (make sure to connect the 5V power before you connect the ~2.9v to analog in though.)
Q2:
Maybe AREF is not constant? Have you considered comparing the battery voltage to the internal reference voltage? (It should be possible, I don't know how, but I'd like to find out. If you figure it out - let me know. I will give it a shot sometime next week.)
AREF? Not 100% sure which voltage you are referring to but if I measure the internal 1.1V reference of the Arduino I also get a varying result of ~5050 +/-150.
Not sure what it means though?
--Code:-------
long readVcc() {
long result;
// Read 1.1V reference against AVcc
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate AVcc in mV
return result;
}
Vint = readVcc();
Vint returns ~5050 +/-150 varying with every read at 500ms intervals.
That code is to read the 5V, using the internal voltage as reference. You don't need it for now. Perhaps later, when you want to know both the battery and the 5V voltage.
Use the resistor as fkeel wrote. From the batteries plus-side a resistor of 1k or 4k7 to the analog input of the Arduino Nano.
That MintyBoost is a switching booster. There are two 100uF capacitors at the output, but I assume that the switching frequency is still all over the circuit and the Arduino Nano.
You could use an extra capacitor to reduce the noise, but I would use the average of a few samples. For example 5 or 20 samples.
Using the internal reference of 1.1V is something I would do. In that case you would need a resistor divider to scale the battery voltage into the range of 0...1.1V. That resisitor divider will draw current from the battery, but with high values that current is only small. Perhaps 47k and 10k resistors.
Not using the 1.1V internal reference means you are using Vcc for the reference. So as it changes with load and noise, the readings will change, no matter how stable and noise free the incoming voltage is.
Use the 1.1V internal reference. It is not exact, but it is supposed to be reasonably stable with time and temperature. The Aref pin should always have both a 1nF or 0.01uF and 10uF capacitor (paralleled) on it to ground.
You will of course have to use a voltage divider from the battery. You should have some protection between the battery and the Analog pin anyway, this should provide it.A 22k from the battery to a 10k to ground will divide it down to just below 1V full charge. The analog pin should have something like a 0.01uF bypass to ground, too.
With 22k between the battery and the Arduino pin, the internal protection diodes should be able to handle the current, and of course only for the short time between turning the power on and the 5V regulator coming up.
polymorph explained what I had hinted on. (As I consider measuring AREF the way you are doing it as somewhat advanced, I assumed my comment would be enough. sorry. didn't mean to be cryptic.)
I have a similar application in which I do something (roughly) equivalent what CX15 wants to do. However I would prefer not to use a voltage divider. Does anyone know of a software method for using the voltage at an analog input as the reference voltage for measuring the internal reference voltage?
This here suggests there is not
A way of doing it could be like this:
The OP could connect his battery to AREF and the regulated power supply to VCC. He could then read both the voltage of the power supply (setting bit 7 & 6 of the ADMUX to 0 & 1) and of the Battery (0 & 0) as compared to the 1.1v internal reference.
@CX15 if all of this sounds confusing, its probably because I don't haven't tried this myself yet. I plan on testing this. Once I do I'll share my code. Feel free to follow up if I don't come back in a week or so.
Anyone else have thoughts on this?
EDIT:
Somewhat related: Does anyone know the max voltage I can supply to AREF relative to VCC? The documentation to AREF states that it can accept anything between 0v to 5v. I would assume however that for the 3.3v pro mini series the max actually is at 3.8? (3.3v + 0.5v tolerance?)
That sounds backwards. Measuring the 1.1V reference? But you have to have a reference to measure it against, and Vcc is not necessarily stable.
Set the Arduino to the internal 1.1V reference. Connect one Analog input through a voltage divider to Vcc, connect the other through another voltage divider to the battery. You need a resistor between the battery and the Analog pin anyway, or when the battery is turned on and Vcc has not come up, excess current will flow through the protection diodes on the port.
correct - you measure the reference. and because you know the reference is stable, but VCC is not, you can calculate VCC based on your measurement of the reference. (i.e. depending on what your VCC is, the reading of the inter 1.1v reference will be different, and from that reading you can directly calculate what VCC is. No external components required.)
I have to admit that I am now completely confused!!
(my knowledge level on this subject is clearly very insufficient!)
From polymorph:
You will of course have to use a voltage divider from the battery. You should have some protection between the battery and the Analog pin anyway, this should provide it.A 22k from the battery to a 10k to ground will divide it down to just below 1V full charge. The analog pin should have something like a 0.01uF bypass to ground, too.
This is how I see your post schematically: (please correct me if Im wrong)
From polymorph:
Use the 1.1V internal reference. It is not exact, but it is supposed to be reasonably stable with time and temperature. The Aref pin should always have both a 1nF or 0.01uF and 10uF capacitor (paralleled) on it to ground.
This bit makes no sense to me unfortunately.
Am I suppose to connect something to the REF pin? What? From where?
Why do I need to measure the 1.1V internal reference? If I hook up the battery to the A2 pin and read the value, would that not be enough to calculate the battery voltage.
In other words: what has the 1.1V ref to do with the value I get from A2? How / why are they related?
From fkeel:
The OP could connect his battery to AREF and the regulated power supply to VCC. He could then read both the voltage of the power supply (setting bit 7 & 6 of the ADMUX to 0 & 1) and of the Battery (0 & 0) as compared to the 1.1v internal reference.
Yes, more confusion!!
Where is Vcc? Is this the Vin / 5V pin?
From polymorph's next post:
Set the Arduino to the internal 1.1V reference.
Do you perhaps have a link to how to do this?
Connect one Analog input through a voltage divider to Vcc,
Where is Vcc? Vin / 5V pin?
Thanks for the help - I apologise for not following all the terms, but Im learning fast - very fast!!
No, if you are averaging it you might as well use the full voltage range.
You don't need a resistor between the battery and A2. However, I would put one there, because it would make me feel more comfortable (if you were to connect things in the wrong order, or if you changed the function of A2 to digital output you may damage your board.)
I don't think a capacitor would do much, as the input from your battery should be steady anyway. The reason your readings are unstable, is because it is comparing the 'stable' battery readings to the 'unstable' 5v source you have. Try it and let us know
No, if you are averaging it you might as well use the full voltage range.
You don't need a resistor between the battery and A2. However, I would put one there, because it would make me feel more comfortable (if you were to connect things in the wrong order, or if you changed the function of A2 to digital output you may damage your board.)
I don't think a capacitor would do much, as the input from your battery should be steady anyway. The reason your readings are unstable, is because it is comparing the 'stable' battery readings to the 'unstable' 5v source you have. Try it and let us know
The default analogRead uses the chips Vcc (the Avcc pin actually) as it's internal reference, so if the chip is being powered by the +5vdc tiny switching regulator the analog input range will be 0-5vdc = 0-1023 counts, so 2.8vdc fits nicely into that measurement range.
I had the Batery's + Terminal wired straight into the A2 pin now for over 24 hours (no resisteor) to see what the readings are.
The readings are jumping around constantly, but in a pretty predictable way.
It would read x for about 2 seconds, then jump to +10 for 1 sec then -40 for 1 sec an then back to x for 2 seconds.
Further the readings drops linear to the battery discharge. So I can fairly well predict battery voltage with averaging the reading.
@lefty: Yep, all of us are aware of that. We had however previously established that the voltage at his VCC was very noise, leading to noise readings and were discussing alternatives to the default analog read which might avoid that issue.
You don't need a resistor between the battery and A2. However, I would put one there, because it would make me feel more comfortable (if you were to connect things in the wrong order, or if you changed the function of A2 to digital output you may damage your board.)
Yes, you do. In normal operation, you turn on a switch that connects the battery. The MintyBoost takes a few moments to come up to 5V. While it is below about 2.5V, the battery is shorted to the Arduino's Vcc line via the protection diodes on A0. Bad idea.
I don't think a capacitor would do much, as the input from your battery should be steady anyway. The reason your readings are unstable, is because it is comparing the 'stable' battery readings to the 'unstable' 5v source you have. Try it and let us know
It isn't about the battery voltage, it is about noise being picked up on the wire between the battery and A0. With a 10k resistor and a 0.1uF capacitor (on the A0 side, close to it as possible), that should prevent just about any noise from being picked up.
I don't understand all this stuff about measuring the internal reference to calculate the 5V line and then using that correction on the measurement from the battery voltage. Why not just use the internal 1.1V as Vref? A lot less noisy, too.
I have connected a line from my battery in series with a 10k resistor and 0.1uF capacitor to A3.
I use an average of a 100 readings over 2 seconds. The result is pretty good and definately usable for my intended purposes.
Comparing averages every 2 seconds give readings that vary by no more than 5, but normally within 1 or 2.
As the battery starts at aboout 3V; this gives values of about 600.
Next I have to check when the batteries start failing and then test if it's a linear graph so I can extrapolate a Battery Percentage Remaining