Simple battery monitoring: not simple as it seems

Hey guys from the Arduino community, again. :slight_smile:

I have one question, about Arduinos (mine's Arduino Pro Mini), batteries and boost converters.

I was trying to read the battery voltage, and it was very accurate. I used a 100K-10Kohm voltage div. resistor pair, user the internal reference, used the VoltageReference library and the LowPower library for the ADC noise reduction mode. I also incorporated some concept using a calibration value from the secret voltmeter site-tutorial-something. My calculation for the calibration value is (battery multimeter reading/((raw analog reading*calibrated internal ref. value)/1024). I dunno, 1024 gives much more exact value than 1023.

Setting that aside, whenever I power the Arduino using the USB port and read thebattery voltage, the readings are accurate. However, if I use a boost converter from the battery to the Arduino, readings become awfully inaccurate, regardless if the Arduino is still powered by the USB or not (I dunno if powering the Arduino two way would be a good practice, but yeah making mistakes is my thing lol). One thing I also noticed the battery voltage drops from the original value (3.76 V to 3.50-3.30 V) when I connect the boost converter to it. Pulling the wire again, the battery reading bounces back to 3.76 V.

Is it just hopeless to get good results on this method of monitoring the battery voltage?

rayrayrayyourboat:
I dunno, 1024 gives much more exact value than 1023.

That's because 1024 is correct and 1023 is BS :wink: You do have 1024 steps :slight_smile:

Pro Mini's / Nano's can be powered via programming header / USB and the Vin/RAW/5V/Vcc pin at the same time just fine.

But can you share a bit more details? Let's start off by a schematic (NO Fritzing breakboard mess!) and details on the converter. But (MCVE / SSCCE) code would be appreciated as well.

Here it is. These are the usual, cheap ones readily available here in our area, as well as the country. Haven't seen any circuit schematic about them, but they seem to bery handy. Only perhaps for simple applications :confused:

boost converter

And what about the rest of your setup? :wink:

rayrayrayyourboat:
Setting that aside, whenever I power the Arduino using the USB port and read thebattery voltage, the readings are accurate. However, if I use a boost converter from the battery to the Arduino, readings become awfully inaccurate, regardless if the Arduino is still powered by the USB or not (I dunno if powering the Arduino two way would be a good practice, but yeah making mistakes is my thing lol). One thing I also noticed the battery voltage drops from the original value (3.76 V to 3.50-3.30 V) when I connect the boost converter to it. Pulling the wire again, the battery reading bounces back to 3.76 V.

Is it just hopeless to get good results on this method of monitoring the battery voltage?

Two things to tease out here. Firstly when you impose a load on a battery, its voltage will drop. How much
depends on the load and the internal resistance of the battery (which itself depends on the state of charge).

Secondly when you power the Arduino from a different supply, you will change the Vcc voltage itself, which
is the reference for analog measurements.

The Arduino automatically switches supply if you supply USB and Vin, I can't recall which has precedence, but
you can look this up, or measure the Vcc with a multimeter - that way you'll know if the measurement is real.

For best results with analog measurement you should be using the built-in linear regulator for the Arduino board
by feeding 7--12V to Vin or the barrel jack - that way the reference voltage is free of switch-mode supply noise and consistent for that Arduino across time (calibrate only once).

The ultimate would be to use a precision 4.096V reference chip to drive AREF pin and select
analogReference (EXTERNAL) in setup().

@MarkT, he said he's using the internal reference which would be a good thing. External ref can be even more precise but at least it's supply voltage independent.

On a Pro Mini / Nano there is no precedence. Vusb is just linked to Vcc via a diode. So as long as Vusb < Vsupply + 0,5V you're fine.

There's a good chance that the boost converter is drawing current from the battery in pulses (at the converter's switching frequency), causing the voltage to fluctuate rapidly. If you have scope, you might want to take a look at that.

If you don't have a scope, trying hanging a big (like 10,000uf or so) capacitor on the battery (observe polarity!) and see if your readings are still bad.

If it's indeed the pulses from the converter I think a lower value cap already does a significant job. But get one with a low ESR.

Or, easier, low pass filter the signal to the ADC.

Here it is. I'm sorry I can't access my paper with the drawing on it. I'm somewhere else. But here it is in general.

I actually kind of messed up with my pic after editing it on my phone. Sorry. Hahahaha. The second pis a detailed view of my simple power state detection (checks USB that powers the TP4056 has current, if yes, normal power conditions. Otherwise if cord is removed or no power is present, power interruption). Readings are also weird if I charge the battery while reading it with the said circuit. As soon as I get my hands on a scope and have my multimeter fuses replaced, I'd be so glad to work this out day and night. :cry:

Just found the booster's schematic. I'll be including the other parts of the circuit as well (pics and links).

Adjustable boost converter image link

TP4056 with specs, component datasheet and image

0.9-5V to 5V boost converter specs, image and components datasheet

Couple of things I'm lost about:

  • I'm lost how the second image fits in the first...
  • What the heck is all that stuff on the left?

The MT3608 at least has a common GND so should work. But you might made a nice ground loop.

If it's indeed the load of the boost converter on the battery a filter cap on the battery voltage feedback (aka A2) should do the trick.

PS Buttons are easier if you just use the internal pull up :wink:

@Septillion.

Okay, I promise to draw my schematic all over again this time. I'll upload them later. Thank you for going this far. :slight_smile:

I was trying an RC filter of different combinations on the analog pin which checks the battery voltage and the boost converter output. Nothing good still comes out. Hahahaha. I'll be looking for extra help too but if you have more to say, please do. I'd appreciate it.

Sorry guys. Are you still there? Was also too busy the past days and internet isn't really mucj available around in here.

Here it is.

Is it wrong to ask any further questions?

I've also noticed that when the Arduino Pro Mini is powered via USB (using USB to UART adapter) it reads battery voltage accurately and battery voltage is around 3.74.

However, when I connect the battery to the booster to power the Pro Mini which reads battery voltage, the multimeter reads an instantaneous decrease in voltage at around 3.50-3.40 V. I know the water pressure analogy and some like the ESR which produces this phenomenon, but how is voltage monitoring going to be possible with these issues at hand? It seems like checking the voltage of the battery accurately is impossible unless you don't connect any load to it. :confused:

23.6.1 of the datasheet for the ATmega328P states, "The ADC is optimized for analog signals with an output impedance of approximately 10 kΩ or less. If such a source is used, the sampling time will be negligible. If a source with higher impedance is used, the sampling time will depend on how long time the source needs to charge the S/H capacitor, with can vary widely. The user is recommended to only use low impedance sources with slowly varying signals, since this minimizes the required charge transfer to the S/H capacitor." To overcome this, you will want to put a decoupling capacitor of 0.1 µF between the analog pin where you are reading the battery voltage and ground.

Hi @Perehama.

Okay, I'll try to reduce my voltage divider values from 100K-10K to 10K-1K for the 1.1 V voltage reference at the pin. But isn't that going to consume a lot more current?

I dunno if this is cray cray or pathetic, but is it possible to use a transistor to control when will voltage and current flow into the voltage divider when I'm going to perform an analog read? Like this:

  1. Digital write high to transistor base (with base resistor)
  2. Analog read at voltage divider connected at collector.
  3. Digital write low to close the circuit.

?????

rayrayrayyourboat:
Hi @Perehama.

Okay, I'll try to reduce my voltage divider values from 100K-10K to 10K-1K for the 1.1 V voltage reference at the pin. But isn't that going to consume a lot more current?

Don't do that. Yes, it will consume too much current. Just put a 0.1 µF low ESR ceramic capacitor between the pin and ground to solve your problem. This has been done with values as high as 10 MΩ.
See a similar discussion on this thread.
P.S. You want to put the capacitor as close to the input pin as possible.

I may be a little late to the game ( I only see ?? for the dates).

It is absolutely possible to get a good reading in a noisy environment. It is common to read millivolt thermocouples it such an environment. The suggested filtering should work, you must keep the divider and capacitors near the arduino input.

Curious, the Pro Mini I have has no USB input.

@Perehama
Okay. I'll try and do as what you suggested. Perhaps I'll be needing to rearrange all the components on a seemingly small breadboard. Again. :frowning:

@JohnRob
No there's no USB input. What I meant was, I used a USB to UART adapter that has male pins. I connected female-female jumper pins to connect it with the Arduino Pro Mini's uhh FTDI header pins.

rayrayrayyourboat:
I used a 100K-10Kohm voltage div. resistor pair, user the internal reference, used the VoltageReference library and the LowPower library for the ADC noise reduction mode.

I also incorporated some concept using a calibration value from the secret voltmeter site-tutorial-something. My calculation for the calibration value is (battery multimeter reading/((raw analog reading*calibrated internal ref. value)/1024). I dunno, 1024 gives much more exact value than 1023.

100k:10k is for voltages up to 11volt (with 1.1volt Aref).
Not very good for measuring a 4.2volt LiPo battery (I think you're measuring a single LiPo).
With that ratio you loose more than one bit (measuring with <= 9bits resolution).
Pick a ratio that is close to 3.2:1, like 100k:33k (= 1.042volt out at 4.2volt in).
No need to use libraries. Converting A/D value to voltage is only one line of code.

float voltage = analogRead(A0) * 0.0042317; // calibrate by changing the last digit(s)

Nooo. secret voltmeter is for measuring VCC against 1.1volt Aref.
When you switch to 1.1volt Aref, VCC is out of the picture.
Adding that could make the result depedent on VCC of the Arduino again.
Leo..