Portable_ReadBMUVariable 10 (flags) and failing battery
Charles Ferguson (8243) 427 posts |
Hiya, I’m improving the Pyromaniac Portable module to provide more information about the state of the system. Of course, to test this you plug and unplug your power a bunch of times to check that the system is reporting the right things, and that you’re extracting the data properly from the host. So… before all this, my MacBook’s battery was reporting ‘Condition: Good’, and now it’s reporting ‘Condition: Service Battery’ (or ‘Check Battery’ in the plist version). So that’s annoying. Or great news – I now know another state that the system can report! But… what do I do with it? The Portable module’s flags don’t indicate any additional information about the battery other than ‘Charging fault’. My feeling is that I should report any non-‘Good’ state as a charging fault in these flags, and that’s what I’m going to do for now. However, if there’s a better way to report more specific information, that would be useful to know so that the battery state can be reported more usefully. My example code for reading the state of the BMU variables (which can be found here: https://github.com/gerph/riscos-examples/blob/master/hardware/ReadPortable%2Cfd1 ) is currently returning: charles@laputa ~/projects/RO/pyromaniac (portable-implementations)> pyrodev --load-internal-modules --config portable.implementation=osx --command /ReadPortable Program renumbered Var Variable name Value 0 Version BMU variable 0 cannot be read for unit 0 1 NominalCharge 5909 mAh 2 MeasuredCharge 5849 mAh 3 UsedCharge BMU variable 3 cannot be read for unit 0 4 UsableCharge BMU variable 4 cannot be read for unit 0 6 ChargeEstimate BMU variable 6 cannot be read for unit 0 7 InstVoltage 12868 mV 8 InstCurrent 513 mA 9 InstTemperature 357.3 K 10 Flags 496 AtThreshold3 LidOpen BatteryFlat BatteryLow + ChargingFault + ChargeStateKnown + BatteryPresent + ChargerConnected + BatteryCharging 11 ChargeRate BMU variable 11 cannot be read for unit 0 21 BatteryTimeRemaining 2.14748365E9 s 22 BatteryTimeMax BMU variable 22 cannot be read for unit 0 23 BatteryPercentage 100 % 24 BatteryChargeTimeRemaining 0 s 25 ChargeCount 925 26 SmoothedVoltage 12868 mV 27 SmoothedCurrent 513 mA 28 SmoothedNominalCapacity 5909 mAh 29 SmoothedCompensatedCapacity BMU variable 29 cannot be read for unit 0 Does this look reasonable? It feels to me that ‘ChargingFault’ is the wrong thing, because a charging fault makes me think that it’s going to catch fire, whilst it’s actually just telling me that the battery is dying. It’s not that the charger is faulty, but that it’s doing what it’s expected to do and detecting a problem with the battery. Presumably such a state must also be detected by modern portable systems – how is such a state reported for them? I can easily report an extra flag for a failing battery, but it needs to match up with what other users are using. I’ve not yet implemented the lid state – the Portable module really is a mess of different types of information, which is really frustrating. |
Jeffrey Lee (213) 6048 posts |
At the moment, I don’t think any of them do report that info. For the modern BMUs I’m aware of, a quick skim through the manuals suggests the Portable API is currently missing out on the following important info:
So although none of them appear to be able to report a battery fault, it looks like the BQ27200 & BQ27500 could be used to generate a “replace me!” warning once the battery gets sufficiently worn.
Adding an extra flag bit sounds fine to me. |
Charles Ferguson (8243) 427 posts |
I have added the following to my constant definitions: # Portable_BMUFlags Portable_BMUBatteryCharged = (1<<0) Portable_BMUAtThreshold3 = (1<<0) # Alias for BatteryCharged Portable_BMULidOpen = (1<<1) Portable_BMUBatteryFlat = (1<<2) Portable_BMUAtThreshold2 = (1<<2) # Alias for BatteryFlat Portable_BMUBatteryLow = (1<<3) Portable_BMUAtThreshold1 = (1<<3) # Alias for BatteryLow Portable_BMUChargingFault = (1<<4) Portable_BMUChargeStateKnown = (1<<5) Portable_BMUBatteryPresent = (1<<6) Portable_BMUChargerConnected = (1<<7) Portable_BMUBatteryCharging = (1<<8) Portable_BMUBatteryFailing = (1<<9) And this gives me: charles@laputa ~/projects/RO/pyromaniac (portable-implementations)> pyrodev --load-internal-modules --config portable.implementation=osx --command /ReadPortable Program renumbered Var Variable name Value 0 Version BMU variable 0 cannot be read for unit 0 1 NominalCharge 5967 mAh 2 MeasuredCharge 5908 mAh 3 UsedCharge BMU variable 3 cannot be read for unit 0 4 UsableCharge BMU variable 4 cannot be read for unit 0 6 ChargeEstimate BMU variable 6 cannot be read for unit 0 7 InstVoltage 12721 mV 8 InstCurrent 0 mA 9 InstTemperature 344.1 K 10 Flags 755 + BatteryCharged + LidOpen BatteryFlat BatteryLow + ChargingFault + ChargeStateKnown + BatteryPresent + ChargerConnected BatteryCharging + BatteryFailing 11 ChargeRate BMU variable 11 cannot be read for unit 0 21 BatteryTimeRemaining 2.14748365E9 s 22 BatteryTimeMax BMU variable 22 cannot be read for unit 0 23 BatteryPercentage 100 % 24 BatteryChargeTimeRemaining 0 s 25 ChargeCount 925 26 SmoothedVoltage 12721 mV 27 SmoothedCurrent 0 mA 28 SmoothedNominalCapacity 5967 mAh 29 SmoothedCompensatedCapacity BMU variable 29 cannot be read for unit 0 … for my laptop. If that name (‘BMUBatteryFailing’) seems good to you, I’ll go with that? (Sorry, I’m taking Jeffery’s word as gospel for this… maybe that’s not right, but I suspect few people will be playing with this). It might be useful to have a `BatteryFailed` as well, but you didn’t mention that in your overview of the possible conditions, so I assume that’s just not something that can be explicitly detected. |
Jeffrey Lee (213) 6048 posts |
BatteryFailing sounds good to me.
Chances are that as long as you update the wiki to document the new flag (1, 2), and maybe the PortableHAL header, it’ll be fine. Or at least, I never got into trouble when I decided that bit 8 should be used to indicate that the battery is charging! |
Rick Murray (539) 13840 posts |
Yes, I wonder if a failed battery would present as “battery flat” or maybe even not “battery present”? It might be something that needs to be detected by noting the charge percentage not incrementing as it should? That, coupled with discharge time vs %ge, might also be a way to detect battery aging? |
Charles Ferguson (8243) 427 posts |
From Jeffrey:
… and my own PRM documentation, and notify the OSLib people, and probably update my own skeleton Portable module code… So many things :-) Actually, I was in the process of updating the Big Scary Compatibility Table with the Pyromaniac Portable module’s features, so that’s easy. Ok that’s the two wiki pages updated. I don’t have an account on the site; so I shall leave it to others to update the headers. I don’t know whether anyone else would be interested, but in the dim dim dim past, back when I expected portable systems to be coming much sooner, I created a skeleton Portable module so that people could just plug in their implementations as necessary. This was at the same time as the improved roaming capabilities for the Internet stack, touchscreen support, bluetooth investigations, stateful firewalling, NMEA GPS support and the other things that all went by the way side… but anyhow… the skeleton portable module is really quite simple and just has a bunch of plug in points where you stick your supporting code. It can be made available relatively easily, if it would actually be useful – although I suspect that if you’ve already reimplemented Portable for PortableHAL, there’s very little reason for anyone to need such a thing. From Rick:
If the battery controller can detect that the battery is not going to charge, then it can report that explicitly, rather than reporting the symptoms. It might do the sorts of checks that you suggest, but… that’s the micro controller’s job to monitor that, not the driver’s, I would expect. Unless the controllers are dumb, in which case, yeah, you might monitor it like that. |
Chris Hall (132) 3554 posts |
Using the Adafruit Powerboost 1000C to use a lithium battery (3V to 4.2V) to provide 5.1V and allow any input from a powerbank or a mains adapter to float charge the battery, it offers a ‘low battery’ input that warns that the Lithium battery is below about 3V and therefore less than 5%/10% cvapacity capacity remaining. This can be read using a GPIO line to force a software power off request which would remove power on a ROM reset. So ‘battery low’ is a good parameter. |
Theo Markettos (89) 919 posts |
One thing some systems report is ‘battery health’ as a percentage. I think that is typically calculated as the usable capacity of the battery divided by the nominal capacity, and where a ‘Service Battery’ is reported as below (for example) 80%. But the battery health could be calculated by a more complex algorithm than that and it may help to present that percentage directly rather than guess the algorithm. |
Colin Ferris (399) 1814 posts |
Do these latest Laptop batteries get nackerd – if left discharged? And is there a way of bringing them back? |
Alan Adams (2486) 1149 posts |
It doesn’t seem that they suffer in the same way as Ni-Cd when left discharged, nor do they have the memory effect that meant you needed to run them flat regularly before recharging. However my experience with a few (in schools) is that they fail abruptly, sometimes as soon as three years from new. |
Stuart Swales (8827) 1357 posts |
Batteries with too much ‘intelligence’. I have one that claims to have been failing for five years, yet still manages a full discharge (11h running for this laptop). |
Dave Higton (1515) 3525 posts |
As I understand it, all types of battery suffer degradation when fully discharged. |
David J. Ruck (33) 1635 posts |
But unless you run it down to what it claims is empty, then leave it a few months, it’s not actually fully discharged. |