Measuring voltage , and not loosing current..

Hi.

We need to inform a user when the battery is going to die .

Our pcb has a 3.7V battery , that goes into a regulator (LD6806) of 3.6V to drive the atmega328p.

Our board mostly in sleep mode, and consume only 50-100uA while sleep .

We need to measure current only when the MCU is awake and to detect if its about to end.

Using 2 resistors to divide the voltage and input that to the ADC sounds great, but the problem with it, is that it has a hell of a leakage (current ).

We cant afford putting 2 of 10k resistors .

  1. i was thinking of putting 2- 100k resistors, to divided the voltage and into the ADC, but i have heard the MCU cant have this resistors in the input ? why ?

  2. I have read here about software only solution that measures the atmega's own voltage . but in our case its voltage is from regulator . can we use that to determine when battery going to die ?

Thank you

1) Why do you need the LD6806? Why not simply powering the Arduino from the battery? If you choose to get rid of the regulator, this link will be useful: https://code.google.com/p/tinkerit/wiki/SecretVoltmeter

2) Check this link: https://startingelectronics.org/articles/arduino/measuring-voltage-with-arduino/

3) You can have 100k resistors in the input. You can even have 1M resistors if you want. It is not the value of the resistors that matter (although that might drain your battery), but the ratio between the 2 resistors.

If your fully-charged battery is 3.7V and your regulated output is 3.6V, what is the end-of-discharge voltage that you would like to inform the user? I'm guessing it's less than 3.66V. So that means your regulated voltage will drop a little when the battery is nearly flat and you can just simply measure the ATMega's supply voltage.

Note the dropout voltage of the regulator is dependent on current. Make sure that the chip takes the battery reading at a time when all the other inputs and outputs are in a known state- that way you should always be measuring with the same current draw and the dropout voltage will be consistent.

A voltage divider of 2*100K can work, but you should add a small capacitor like 4.7pF so that when the analog input takes its sample, it has a little reservoir of charge to draw on.

Thank .

First , i dont connect battery directly to the board for 1000 reasons, one of them is that i have another parts which are very sensitive to change, the other is that a loaded cell li-po can be at 4.2v when fully charged .

Anyway , regarding the capacity problem ,can i add a delay between the reading and the setting the mux ? for example 1ms delay between the read and the adc input switch ?

i dont care about accuracy , even 10% is good. just want to know a few days before battery is going to die . So 2 100k is good ? or even 50k and 100k where the 50k is parallel to the atmega ?

BenStlr:
Our board mostly in sleep mode, and consume only 50-100uA while sleep.

Did you add the 155uA of the LDO to that.
Maybe you can run the micro straight off the battery, and other modules off the LDO (sleep pin).

BenStlr:
We cant afford putting 2 of 10k resistors.

Not needed. A cap to ground can give you the required low impedance.
You have to use the internal 1.1volt Aref, because the MCU can’t measure it’s own supply with default Aref.
You need a 1:3 divider for a LiPo cell.
3.3Meg (to ground) and 10Meg (to battery) is ideal (<300nA).
You must use a 100n cap from analogue in if you use these high values.
http://jeelabs.org/2013/05/16/measuring-the-battery-without-draining-it/
Never tried the software solution. It might work.

MorganS:
A voltage divider of 2*100K can work, but you should add a small capacitor like 4.7pF so that when the analog input takes its sample, it has a little reservoir of charge to draw on.

You might want to revise that.
A 4.7pF cap is not much of a reservoir cap compared to the 12pF or so sample cap of the micro.

BenStlr:
Anyway , regarding the capacity problem ,can i add a delay between the reading and the setting the mux ? for example 1ms delay between the read and the adc input switch ?

No delays.
If you want higher accuracy, just read the A/D twice and use the second reading.
Leo…

Sorry, yes, I was thinking 47pF but wrote 4.7.

Bigger is better and doesn’t hurt this circuit until you get to really big caps like 1000uF which have a higher leakage. 1nF, 1uF; whatever you have lying around.

MorganS: Bigger is better and doesn't hurt this circuit until you get to really big caps like 1000uF which have a higher leakage. 1nF, 1uF; whatever you have lying around.

Best to keep it 100n (10-100n). Pin caps have to be discharged through the pin protection diodes when you power down your Arduino. Leo..

Thanks a lot both !

@wawa ,thanks, you gave us so many ideas. Why should it be 1:3 ? the ratio makes any difference ? what about 200k and 100k ? its a 10uA leakage which is good . and just to understand , what would happen without capacitor ?

The analog system on the chip needs to charge up an internal capacitor. Then it has a number of steps to carry out to measure the voltage on that capacitor. This is one of the reasons why analogRead() is slower than digitalRead().

You need that capacitor to charge very quickly - microseconds or even nanoseconds. So the peak current going into the capacitor is relatively high, even though the total energy transferred is small. If you have a big 100K resistor divider feeding the analog input, then it's like having another resistor connected - the voltage will be divided by the two resistors you control AND the resistance of the analog input. So by adding a capacitor that's charged 'all the time' by the two resistors you control, then you are adding a store of energy that can be used to charge up the internal analogRead capacitor.

Ok that i already know thanks, but this is a capacitor, so why cant a delay solve all of this ? i saw that a 1ms delay for every 10k resistance is good .

Also @wawa said i must use internal reference of 1.1V . why ? why not just measuring the voltage (with/without external capacitor) via analogRead(x) ?

Delay? You can't delay the analogRead() process. It has its own clock. You can change the speed of the clock but that is generally a bad idea.

You must use the fixed voltage reference because the normal analog reference is the supply voltage. It's like you have a measuring tape that you can use to measure everything except itself. You need a different reference to measure the supply.

have not thought about this, but maybe someone can tell us why it will not work.

battery through a voltage divider to a digital pin.
connect analog pin to voltage divider

wake, bring pin to ground, measure voltage
bring digital pin high.

Because then the digital pin is powered when the Arduino is off. If the thing is permanently connected to power and only using sleep mode, this can work.

BenStlr: Also @wawa said i must use internal reference of 1.1V . why ? why not just measuring the voltage (with/without external capacitor) via analogRead(x) ?

Arduino uses the battery as a reference to measure the battery. When the battery voltage drops, the reference voltage also drops. So with a 10k/10k divider, and default Aref, the A/D ALWAYS outputs ~512, independent of battery voltage.

A 1:3 divider outputs 1/4 of the battery voltage to the analogue pin. 1/4 of 4.2volt is 1.05 volt. Perfect to use the whole A/D range with 1.1volt Aref.

A divider with high value resistors cannot charge/discharge the A/D's internal sample cap fast enough. An external cap on the pin maintains a constant "solid" voltage on the divider tap. Like a small battery connected directly to the analogue pin. During sampling time, the voltage on the 100n cap remains constant. Important if other analogue inputs are used (ghost charge). Leo..