I'm trying to calculate the "drained" capacity from the battery each second so I can get the nearest possible capacity used.

This is how I'm getting this.

  • dischargingCurrentSum - Is the sum of the "current" which I get every second, milliamps-second

For example

  • 1s = 300mA
  • 2s = 380mA
  • 3s = 540mA

When I sum this it's 1220mAs

  • dischargingUpdateCount - Is the count of entries, to be precise each second is one entry, in this case, it will be 3, it helps me to determine the arithmetic mean.

  • currentTimeUnix - This is the current time, it the exact same time of calculation in milliseconds (each second)

  • dischargingStartTime - This is the time when discharging started also in milliseconds

  • /1000 - is to convert milliseconds to seconds

  • /3600 - is to get the mAh


drainedMah = dischargingCurrentSum / dischargingUpdateCount * (currentTimeUnix - dischargingStartTime) / 1000 / 3600

I'm not sure what I have missed here, at the first time it counts normally, but after a while, it became way more than the actual battery capacity is.

  • \$\begingroup\$ Isn't dischargingCurrentSum already the mAh value? In which case, you should not be summing it. \$\endgroup\$ Commented Jun 25, 2021 at 16:37
  • \$\begingroup\$ @AndrewMorton no, here I'm getting the current every second then divides it with each entry there so I can get arithmetic mean (average), then multiply it with the discharging time. \$\endgroup\$ Commented Jun 25, 2021 at 16:54
  • \$\begingroup\$ Don't be so clever in your formula. Write out each binomial as a separate line and output the result. Then you'll know the compiler is doing what you think it's doing.$$$$ ex. Calculate "CurrentTimeUnix - DischargingStartTime" as a separate line, verify it's right, and use the result in further equations. Jamming everything into one equation isn't really going to improve computing efficiency since the compiler will break down your formula into pieces as I describe anyhow. You are smarter than it is. – \$\endgroup\$
    – Kyle B
    Commented Jun 25, 2021 at 17:28
  • \$\begingroup\$ Useful search term : coulomb counting \$\endgroup\$
    – user16324
    Commented Jun 25, 2021 at 18:24
  • \$\begingroup\$ @Kyle B, everything is counted normally. I already have monitoring it for a longer time, and it always became way more than actual battery capacity. Thing I want to do is calculate how much capacity was taken from the battery based on the current. \$\endgroup\$ Commented Jun 25, 2021 at 19:38

2 Answers 2


And when I sum this it's 1220mA

More precisely, since you are taking the measurement every second you have 1220 mA seconds. Capacity is measured in units of current times time -- for instance, milliamp hours. A typical AA battery has a capacity of around 2000 mA hours.

1220 mA seconds equals 0.34 mA hours.

drainedMah = dischargingCurrentSum / dischargingUpdateCount * (currentTimeUnix - dischargingStartTime) / 1000 / 3600

I'm not sure what's going on in the formula.

Suppose you take a current reading in milliamps every second and let \$S\$ be that sum of all of the current readings. Then

  • \$S\$ is the total charge extracted from the battery in milliamp-seconds
  • \$S/3600\$ is that value in millamp-hours
  • \$S/3600/1000\$ is that value in amp-hours

In response to your comment...

If you take one reading per second, the average discharge current is either:

  • sumOfAllReadings / timeElapsedInSeconds, or
  • sumOfAllReadings / numberOfReadings

The formula, as it is written, is multiplying by elapsed time, not dividing by it.

Note this will produce a current which has units of amps, not a capacity.

  • \$\begingroup\$ To short it a bit, average miliamp-second / discharging time in seconds / 3600 \$\endgroup\$ Commented Jun 25, 2021 at 16:30
  • \$\begingroup\$ Answer updated. \$\endgroup\$
    – ErikR
    Commented Jun 25, 2021 at 16:59
  • \$\begingroup\$ You are alright those two things are actually the same, the only difference is that first approach you mentioned is more precise. \$\endgroup\$ Commented Jun 25, 2021 at 19:27

When you take a current sample each second, and plot the sample on a graph against time, then the area under that sample is the current measured times one second. This is a rectangle and all you are doing is adding up the area in each sample rectangle which approximates the discharge of the battery in terms of ampere seconds. If you know the sample time is one second then you don't need a timestamp to find the discharge time - the length of records in a file is the elapsed time in seconds.

In comment the time change is not constant so the area approximation depends on the difference between respective timestamp values.

Scroll down and review this reference which describes the use of finite difference methods to approximate the area under a curve:


Approximating Area Under a Curve

In your application the most accurate approximation would be to calculate a rectangular area for each current sample and timestamp difference and then add up those areas and then convert to ampere hour. You could take an average over any span of time, however, it will be no more accurate than the sum of actual sample data unless you think there is noise in the samples that must be compensated by averaging. Taking an average over any time window you choose may be useful for statistical analysis but would not improve precision of the area approximation. Accuracy and precision are determined by the sample equipment and sample rate and presence or absence of errors in measurement.

  • \$\begingroup\$ The time here is not exact. it's always +100-300ms for each run. In the short run, it's not a big deal tho but after few hours it makes a huge difference as I explained in one of the comments above. I would rather going to include the runtime in the calculation average mA * runtime(s) / 3600. I hope I'm not wrong here. \$\endgroup\$ Commented Jun 26, 2021 at 17:24
  • \$\begingroup\$ In real time the data stream produces a series of current samples with timestamps. If the data stream is stored it will be an array of current samples and an array of timestamps. If data are available in series then just take a difference operation on the timestamp array which gives the width of each rectangle in the series and then multiply this by the current sample for that period (this assumes current is constant for a short period) so this is the width (time) times height (current) in your sample data. Then sum all these products to get the measured area and then convert to other units. \$\endgroup\$ Commented Jun 26, 2021 at 20:11
  • \$\begingroup\$ Okay, got it. Thanks I'm going to make changes then do a test. If you want to check the thing, it's called Battery Guru, and it's on PlayStore \$\endgroup\$ Commented Jun 26, 2021 at 20:23

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.