CHecking battery voltage/level

Okay, the trick it to user the arduino's ADC to get the voltage of the battery that is running said arduino. I know you need an independant reference so this is the hard part. Assuming I am powering my arduino with 5v, can I use a 3V voltage regulator and feed that to the ref pin and use a voltage divider to cut the voltage I am measuring to below 3v?

Bob

Most Arduinos have a built in voltage reference, which can be used to measure the battery voltage. For an Uno and the like use this:

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;  //Vcc in mV
}

The constant needs to be individually recalibrated for each Arduino.

One of MANY forum threads on the topic: Measuring voltage of own battery - #6 by GreggTom

The "regular" Arduino has an optional internal 1.1V reference.

If you need to measure above 1.1V you'll need a voltage divider.

Note that although the 1.1V reference is very stable it's not necessarily super accurate (I think there's a 10% tolerance) so you may have to make a calibration-correction in your software.

Or, there's a "trick" but don't have the link handy.... There is a way to measure the internal 1.1V reference relative to the normal Vcc reference. By assuming Vcc is 5V and calculating the "error" (the difference from the expected 1.1V) you can get the actual Vcc voltage.

[EDIT] See jremington's post above. :wink:

I probably should have said that it is a nano... Also I will probably be checking the battery directly rather than the 5 volts, so I can see when the battery is about dead.

Bob

Which "nano"? There are several.

If you are using a battery of 7V or greater to supply Vin (and the on board regulator to supply 5V) then you need to use an external voltage divider.

If It's about dead the Arduino ain't gonna' run! :wink:

It is a nano clone. I am not sure who's clone exactly, have had them a while. I am using a single lipo with a voltage booster to get my 5V. If I put my voltage divider across the battery directly, I assume that counts as an external voltage divider, is that right?
As for searching, I did try, but my wording of my search didn't come back with anything.

As for "about dead", I am thinking 3.5 volts should give me time to kick off an alert...but that all depends on the size (Ah rating) of the batter.

Thanks for the quick replies!
Bob

You don't need a voltage divider if the battery voltage is less that the Arduino power supply voltage Vcc (and therefore, the default analog reference voltage AREF).

To measure the battery voltage directly, first make sure that battery negative is connected through the booster to Arduino ground (usually the case). Then simply connect the battery + terminal to an analog input. To be extra safe, use a 10K series resistor between battery + and analog in.

LiPo batteries are variously considered to be fully discharged when the terminal voltage is somewhere between about 3.0 and 3.2V.

2 Likes

It would be best if a vDivder is not used. A voltage divider network will draw current that will impact battery life.

1 Like

Thanks Jremington. I love it when I find an easier way. I was looking at discharge curves for lipo and figure 3.5v as a warning level should give me the time I need to alert that it is going dead. Is dead is too late and easily discernible by the nano not being on anymore. lol

Bob

How else are you going to measure battery voltage with a classic Nano.
All you have for absolute measurements is 1.1volt Aref, so you must use a voltage divider.
That divider can be made with high value resistors, so it doesn't impact battery life.

Could use 3.3Meg from analogue pin to ground and 10Meg from pin to battery(+)
That will give you 3.3/(10+3.3) * 4.2 = 1.042volt with 4.2volt battery.
With these high values you must also add a 100n ceramic cap from pin to ground.

Then add this in setup()

analogReference(INTERNAL); // switch to 1.1volt Aref

Leo..

I would not measure battery voltage with a classic Nano.

As Jremington pointed out, since I have a 5V supply, I should be able to get the 4.2 or less volts of the battery from the nano. I plan to test this tonight/this weekend.

As for the 1.1 internal reference, is that from the nano or the ATMega chip? After I breadboard this, I plan to make my final versions with the chip alone.

As for why the nano, because it is what I have.

Bob

Much better than a UNO to be sure. When asked

What was meant was not whether it was a clone or not, but there are various "Nano" derivatives with alternate hardware.

The Nano is an ATmega328 (or if unlucky, an ATmega168).

Bad idea to my mind. Just get a Pro Mini and it is already assembled.

Why? For what do you need the 5 V?

What are the different versions, how do I identify? thought a nano was a nano aside from knockoffs.

There are other components on the nano, but your answer did answer my question.

why do you think so? Yes the nano is almost as cheap as the chip and not much extra to it, but I also like the challenge

Good question... Mostly always used 5V. But the nano/atmega328 should work fine down to the lower ends of a lipo battery... and the sensors/rf transceiver work on 3V... so you may be on to something there, except if I am boosting my voltage it is easier to test battery voltage... I am not so sure I totally understand the use of the internal 1.1.

Bob

If you can power everything directly from the battery, then you can use the trick mentioned by DVDdoug in reply #3. You use Vcc as the reference voltage, but you measure the 1.1V internal reference. As the battery and Vcc voltage drops, the 1.1V reference will measure higher. I don't remember how you do this, but it's definitely an option, and of course requires no external parts or current draw.

The only thing you have to watch out for is that the Nano's default is to run at 16MHz, and if you run off the battery directly, you may have problems at that clock speed. An alternative would be to run off the internal 8MHz oscillator. But I think most people find that 16MHz still works ok at something like 3.5V, at which point the battery will be mostly discharged anyway. The nominal minimum voltage for 16MHz per the datasheet is 3.78V, but I think typical performance is somewhat better than that.

The Arduino A/D by default does not measure voltage. It measures ratio.
Each A/D step is 1/1024 of it's own supply,
which means that mV between steps is supply dependent.

This is what you want for ratiometric sensors like pots and most current and pressure sensors,
but it's not wise to use the A/D with default settings for absolute/voltage measurements.
Because the returned value then depends on input voltage and supply voltage (which is not stable).
For voltage measurements we have a stable (but not exact) internal 1.1volt reference available,
which can be enabled with code.

Never connect a battery directly to a pin. Always use a 10k resistor in between.
This is of course not needed if a voltage divider is used.

If you choose to power the Arduino directly from the battery (no boost converter), then only software is needed to read the MCU supply.
The code compares MCU supply against 1.1volt Aref internally. No external parts required.
Leo..

If you take a look at the Arduino Hardware page you will find the Nano, the "Nano Every", the "Nano 33 BLE", the "Nano 33 BLE Sense" and the "Nano 33 IoT". And a few other things of a similar format.

"Challenge" is fine, but the ready-built module for virtually the same price is far more practical. :roll_eyes:

Hardly a reason.

A 3.3 V Pro Mini runs reliably at 8 MHz down to substantially less than 3 V.

I do know how the ADC works and the whole ratio compared to the reference. And I understand voltage dividers. So to use the 1.1, I simply use the analogReference(AR_INTERNAL1V2) (this is a 1.2V from the page https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/) and divide my expected max voltage to below 1.1(with safety margin) and calculate the real voltage?
As I understand this internal voltage is very stable but not 100% accurate from chip to chip, so I will need to test to determine a calibration number. Is that pretty much all there is to it? The first post posted how but I don't understand it all... have never used a | in Arduino.

Also final question, if I set the nano to run at 8Mhz, this adjusts everything that gets timing from the nano? So for example, I am using an nfr24l01 transceiver. If I have tested it to transmit at 1Mbs for nano at 16Mhz, it will still function at 1Mhz, if I set the nano to run at 8Mhz?

Bob

Near as I can tell by looking, they are straight nano clones... but I am intrigued by the nano every!

Bob