I have an Arduino which is being powered by a battery. I would like to monitor the charge level of this battery. Normally, this is very easy, just check the voltage across the disconnected battery's + and - terminals and then use an appropriate comparison table to find out what % of charge this voltage corresponds to. I can easily measure voltage with the analog pin on the Arduino, but there is an obvious problem: The Arduino is powered by this very same battery I am trying to measure, which will throw off the readings.

So, how can I handle this?

thank you


5 Answers 5


To measure the battery properly you indeed should not be loading it at the time of measurement.

If you know that your Arduino will be in a low power/standby more at certain times, it will then be consuming only a very small current that should not load the battery so much that the voltage drop is significant. What you could then do is "remember" this voltage using a capacitor.

This is what you could try:


simulate this circuit – Schematic created using CircuitLab

The resistive divider will charge the capacitor to a certain fraction of the battery voltage, the capacitor will cause the voltage at Ain to change with a certain time constant (about 1 second in my example).

When a battery measurement is needed, it should be done first thing right after the Arduino has been sleep mode/standby for some time. As soon as the Arduino starts consuming current, the voltage at Ain will start to drop slowly so the longer you wait the larger the error will be. But if you can do the measurement quickly enough the voltage at Ain should not have changed yet so the "no load" battery voltage can be determined.

  • \$\begingroup\$ With the megaohm-range divider I'd be worried that the leakage current of the capacitor could skew the results; you can't place just any capacitor there (e.g. aluminium), it needs to be low-leakage. \$\endgroup\$
    – anrieff
    Nov 21, 2018 at 15:48
  • \$\begingroup\$ @anrieff Of course you'd have to use a low leakage capacitor like a proper ceramic one. If you use crappy electrolytic type then sure, they leak. \$\endgroup\$ Nov 21, 2018 at 15:49
  • \$\begingroup\$ +1 (Beat me to it) One source suggests that the "sleep" current is about 10mA, while "awake" current is 45mA (assuming no other peripherals are active). So your approach is a semi-load-test. \$\endgroup\$
    – glen_geek
    Nov 21, 2018 at 16:14
  • \$\begingroup\$ @glen_geek One source suggests that the "sleep" current is about 10mA If that is the case then in my opinion you would not be using the Arduino correctly. I have here on my desk an Arduino based device being active 24/7, blinking a LED every 30 seconds and transmitting a code at 433 MHz, this gadget runs for a year on 2 AA Alkaline batteries. A sleep current below 100 uA should be easy to do. Unless there's some regulator on the Arduino board messing things up of course (I removed a regulator on my design to save current). \$\endgroup\$ Nov 21, 2018 at 16:45
  • \$\begingroup\$ huh? what's VDD? \$\endgroup\$ Jan 16, 2021 at 11:30

The battery negative will be attached to the micro-controller common. No problem there.

The battery positive will generally be higher than the chip supply voltage due to the on-board voltage regulator. Therefore it will be greater than the maximum ADC input voltage.

You will need a voltage divider between the battery and the ADC. Set the ratio so that at maximum battery voltage the divider output is within the ADC range.

  • \$\begingroup\$ The voltage range is not a problem, the actual voltage reading is because it will be affected by the fact the battery is in use. \$\endgroup\$
    – Askerman
    Nov 21, 2018 at 15:23
  • \$\begingroup\$ The voltage divider could hand nanoamps-which has more noise, but the measure itself does not affect the battery even at 1% of total charge. I suppose you have cents of mAh. \$\endgroup\$ Nov 21, 2018 at 15:26
  • \$\begingroup\$ @Askerman: What is going to matter to the Arduino is the battery terminal voltage when loaded. I can't see the point of an unloaded measurement. \$\endgroup\$
    – Transistor
    Nov 21, 2018 at 18:47

Compensate for the internal resistance and get the unloaded battery voltage.

How you can do that?

Additionally you measure the current of your load with a high side current sense circuit.

If you know the internal resistance you can then just calculate the drop of voltage based on the current. But usually the internal resistance depends on several factors, so you don't know it very well.

Solution: Measure the internal resistance.

How you can do that?

Apply an additional known current and measure the difference in voltage. With that you get the internal resistance and with the measured current from above, you get the real battery voltage.


Besides what Transistor said, which is right, you shouldn't be worried by the Arduino consumption making the readings inaccurate.

It may shift the voltage to %charge relation a bit due to the battery internal resistance, but the comparison table can easily takes this into account since the arduino current consumption is stable. So it won't make it more inaccurate than other discrepancies due to battery ageing, environment temperature, and such other external factors.

So, unless your Arduino board is randomly and continuously switching between 5mA consumption to 1A, there is no reason to worry about this.


You can measure voltage battery with voltage reference. You need voltage reference with lower reference than you expect on battery (for example 1.235 V). Then you measure this voltage with your ADC. With this measurement you can now calculate ADC reference voltage, which should be equal to battery voltage.


For example if you measure 300 with your ADC and your reference voltage Vr is 1.235 V then your battery voltage Vb is 4.2 V.

Another similar, but more complex way is to use voltage divider on battery and use internal voltage of arduino for ADC reference.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.