View Single Post
Estel's Avatar
Posts: 5,029 | Thanked: 8,597 times | Joined on Mar 2011
[Announce] bqCapacity - measure real mAh capacity of Your battery using only N900.

OK, jokes-aside (cause it's not a program), thanks to Pali's work on Kernel-Power, research about internal working of bq chip done by many people (most notably, joerg_rw, shadowjk, 412b), priceless help of shadowjk (via PM discussion including war-and-peace class long messages) which made me understand chip calibration process, + my very small part summing this all up, testing, writing this tutorial...

...finally it's possible to accurate measure capacity of Your battery, that N900 can use (from full charged, to ~3.0 V - thats it, not 3.3V, but 3.0!). All that using only N900 and it's integrated charging chip - we're able to measure discharged mAh - just like professional RC chargers do. Now, everyone can contribute to this thread - I hope that this will give dr_frost_dk's finances a little rest

Ho ever, process is little delicate - it's 100% safe, (ho ever, usual warnings apply, may blown up your coffee cup, blabla), but getting 100% certain results need processing with care, especially when we want to measure battery with capacity different from our last one by value of >=1000 mAh (for example, switching from regular Nokia battery to dual-scud, or reverse). So, before posting results here, please be 100% sure that Your results are correct. "Important background info" after instructions will help you understand how this process works, and it's must-read for every serious tester. So, let's start!

Pre-Requirements: script by shadowjk - place it wherever You want (i suggest /usr/bin, this way You may execute it by typing just "", without quotes - no need for full path), and chmod +x it.
i2cget from shadowjk's website - place it in ./ (root - *not* MyDocs, or any other place)

kp47, with bq27x00 module enabled (it's enabled by default in kp47). [b]*WARNING* - In KP48 (and, probably, all higher versions), bq27200 isn't enabled by default, furthernore, path allowing it to co-exist with bme was disabled. So, it's not possible to have both working at once. Still, You can get every needed info via script, so calibrating is still possible. Thus, as shadowjk correctly mentioned, bq27x00 module is in fact purely optional for calibration. by shadowjk or his - delete .txt from it's name, and place it inside /usr/bin/
Difference is, that charge with 1050 mAh max, and with 950 mAh max + log errors, so may help with debugging. Also, 950 mAh may be less stressful for battery (actually, bme tends to charge @ 1050 anyway...), for dual battery mod it doesn't matter. and may be used to charge N900 with bme disabled. Should be used only with any kind of wall charger - using it when connected to any real USB port (notebook, desktop...) may result in OS complaining about overcurrent in said USB port, and shutting it temporally - at best - or frying mentioned USB port/it's fuse, at worst case (depends on motherboard design). Remember that regular USB ports current limit is 500 mAh, and use 1050 mA ( 950 mA).


Charge your battery fully, de-attach charger plug. Then, as root, execute:

You will get detailed info collected from charging chip. Look for VDQ one - it should be "VDQ: 1". It's located almost at output end, just before "eeprom data:" line. If it's 1, you're good to go. If it's 0 just after charging, for some reasons chip doesn't consider your last charging "valid", and You must wait with measuring until another full charge (most unlikely to happen).

Discharge to almost empty - you don't need to do it quickly, You can use phone normally, except that You must not turn off/reboot Your phone before finishing measuring, or results will be scratched.

3. When approaching battery empty state, run as root: again and check if VDQ is still 1. Better safe than sorry.

If true, run (still as root): 5

This will start special mode of, done in loop in 5 seconds interval. Wou will have a glance on battery voltage and other important data - especially EDV1 state. Now, really keep an eye on discharging process and script output.

4. When voltage will stay under 3248 mV for 15 seconds, EDV1 will turn from 0 to 1. This means, mission accomplished. Now You may wait for bme to turn your device off (will happen in 15-60 seconds, 2x longer with dual-scuds setup), turn it off Yourself, or plug charger in. Close terminal window with looping

Run as root:
...and check for "Last measured discharge" line. It will contain measured mAh value.

Positive side effects:
You not only achieved info about your battery capacity. Your charging chip also get this knowledge This means, all programs using bq27x00 module data (dr_frost_dk QBW script version for KP, 412b's pyBattery, and many others) will finally start giving You true data about Your battery capacity. In fact, we performed "calibration" of charging chip, and knowing exact battery capacity is very desired side-effect.

Important background info (In most cases, not necessary to measure, ho ever please read it, if you're willing to do accurate measuring and submitting results here):
N900 build-in bq chip is capable of measuring real discharge mAh value (amongst other things). Ho ever, bme doesn't use this functionality Chip doesn't care about it too much, and still store collected data. Thanks to bq27200 module, we can get read-only access to stored values. Talking in much simplified way (actual procedure is more complicated and involves many data, like chip internal voltage drop - irrelevant for us now), chip monitor current flowing though it when charging/discharging, and use special procedure to distinguish between full discharge/charge, and charging/discharging only partially.

The thing is, that when chip detect fully charged battery (by it's measurement - this may be totally unrelated to real state of charge [SoC]), it tells to himself "I can start learning capacity" - by switching special eeprom value "vdq" from 0 to 1 (valid discharge quality, probably). Then, if during discharge, a condition - that may render learned value wrong - occur (like excessive low/high temperature, very strange voltage difference in short time, rebooting/turning off phone), it immediately switch "vdq" to 0, scratching all learned capacity data, and still using old one (if any present). Next vdq=1 may be achieved only, by charging again to 100%.

Then, there is another important for us value stored in chip's eeprom - "edv1". It's hardcoded to 3248 mV. When battery voltage reach (down) this value, and remain 3248 or low for 15 seconds, edv1=1 is set. If (and only) "vdq" also remained 1 to that time, measured capacity is stored, and full_charge (last measured valid discharge) updated to that value.

Here bme kicks in - just around ~3198 mV it shutdown device. Without bme, our bellowed N900 would turn off unconditionally @ 3000 mV, which is "edvf" stored in chip's eeprom. Chip think that between 3000 and 3248 is 6% difference in SoC, so it adds 1/16 of measured discharge value to data stored as charge_full. This value is accurate enough for us - that's why we get charge from full to 3.0V, not to ~3198 mV when bme shut down device, or 3248 when learned capacity is confirmed. Side info - for some reasons, shutting device down @ 3000 mV (when bme is disabled) is not present - We can get to as low as ~2850 mV, when phone just turn off due to lack of real power. Keep in mind, that this may be harmful to filesystem.

Ho ever, there is some hatch, that may prevent recalibration from happening at all, or give inaccurate results. First of all, Chip doesn't allow to store instant capacity drop higher than 1/8 = 12,5% (thanks magick777 for measuring it accurately!) just by one learning cycle. So, if You used 1300 mAh battery, and measured crappy 400 mAh one, after first learning cycle you'll get ~1300-162,5= 1137,5 mAh result. This will drop continuously during next learning cycles, until it reach real capacity.

So, it's very important to perform 3-5 learning cycles (measuring), when You test unknown capacity battery - you may stop doing so, when learned value isn't changing very much from one measuring discharge to another. Without doing so, measured value may be totally wrong.

When switching from weaker battery to better one (regular to dual-scud) chip is much more forgiving, but also has limitations. I wasn't able to recalibrate from 1370 mAh to 3000mAh - ho ever, doing so in 2 steps (from 1370 mAh to 2300 mAh, and then to 3000 mAh) worked. So, it requires less cycles to get accurate results, ho ever if done wrong, will fail to update measured capacity at all. So, in my case, it was stuck @ ~1370 mAh until I've done it properly with shadowjk's help.

So, measuring battery of suspected capacity much (more than 1000 mAh) higher (than last one), special approach is needed. You must charge battery to RSOC 100% = last stored learned capacity (RSOC is amongst data output of, then charge battery for no longer than 1 hour (can be done normally, via bme - that's it, you don't charge it to full), and after that, you start discharging and follow regular measuring procedure. Chip will learn higher value and store it. During next measuring cycle, You charge battery to full, and continue normally. By the way, if during 1 hour from RSOC hitting 100%, Your unknown battery is fully charged (green diode - means that charging is finished/almost finished), it means that it's capacity is not higher than last one by more than 1000 mAh, and special 2-step procedure is not needed - you can proceed normally.

Last, not very important thing, that fanatics of accurate measurement (like me ;P ) should consider - when charging before measuring discharge, and You're close to finishing charge, turn offline mode on, lock screen, and don't use phone until charge is finished. This way - keeping current used for operational low - you're charging battery to 100%. More current use by phone (system load, wifi, GSM, playing game, whatever), the less close to 100% battery will charge - this is valid always, not only during measuring. This is way charging chip work, it can't distinguish current used by phone from current provided by charger, it just use total current flowing from/to battery. Also keep in mind that diode turning green doesn't mean that charge finished - it mean "I'm almost done". Then, charge may continue very slowly, or never stop if system draw too much energy - whatever madness bme decide to perform.

Still, difference gained by lowering power load isn't more than 50 mAh, at worst case.

// Troubleshotting

In some cases (including my initial attempts), vdq switch to "0" immediately after turning bme off. Most likely You won't experience this problem - it happened to me few times, then, sudden of nothing, I can't reproduce it anymore (so, it's piece of cake to reach edv=1, with disabled bme).

Ho ever, if You get this problem, you still can calibrate chip and measure battery. To successfully end calibration (i.e. achieve 15 seconds uptime below 3248 mAh, without bme kicking in and shutting device down), You need to:

From the point of 3300 mV, turn off-line mode on. Then, voltage jump a little higher (due to less charge used) - when it reaches 3300 mV again, turn brightness to min (with constant backlight *enabled* - switching it off and on on touch, may cause temporary, yet huge voltage drop = bme can kick in and shutdown phone).

At this point, total power usage should be ~100 mA (" 5" - loop mode - helps a lot in monitoring). Going down so slowly, I'ts now perfectly able to have < 3248 mV for 15 seconds, to turn edv1=1. After that, for another unknown reasons, BME shutdown the phone in 5 seconds (IDK, maybe this is only case in my device, lol), even that it's still ~3235 mV - 3240 mV range. Thankfully, at this point fuel gauge already recorded edv1=1 and saved new "last measured discharge"

Background info for consideration:
I don't know why it's working like that - at least in my case - Normally, BME turns phone @ around 3190 mV. I saw it personally, when not calibrating = higher current used. Maybe it's some time-trigger, so with higher power usage, we're able to go down to less than 3200 mV?

I even tried it with screen turned off, which resulted in ~40 mAh power usage, and results were the same. So, if we're approaching lower limit slower (for example, due to fact that we want to stay below 3248 for full 15 seconds), BME turn phone off @ little higher voltage.
N900's aluminum backcover / body replacement
N900's HDMI-Out
Camera cover MOD
Measure battery's real capacity on-device
TrueCrypt 7.1 | ereswap | bnf
Hardware's mods research is costly. To support my work, please consider donating. Thank You!

Last edited by Estel; 2011-09-15 at 04:13.

The Following 71 Users Say Thank You to Estel For This Useful Post: