FuelGauge vs System Battery Level Race Condition?

I ran into an odd problem when working with a boron running on solar power. I wanted the device to automatically sleep without connecting on startup if the battery was under a certain cutoff value, to prevent the device from getting stuck in a loop attempting to connect and failing because of low power, keeping the battery from recharging.

However, when using System.batteryCharge() immediately upon calling setup() to determine whether to sleep, it would always sleep even with a fully charged battery, because the call would return -1 as if the battery were disconnected. Instantiating a FuelGauge object and calling getNormalizedSoC() did not have this issue at all. Also, naively delaying a few seconds before checking the battery resolved the issue, but this is not ideal.

Is there some sort of race condition at play with System.batteryCharge() on startup? The docs say that function internally calls getNormalizedSoC(), so I'm not sure what's going on here.

Also, when creating an instance of FuelGauge, does calling its methods always return the current value of battery charge/voltage/etc., or does a new instance need to be instantiated each time a reading is taken?

The fuel gauge is powered off during sleep, and it takes time for it to start up and be able to return a value. That's why the delay worked for you.

You don't have to delay, you can just keep calling it until it returns a valid value, waiting between tests, with some sort of reasonable upper bound of retry, just in case.

You don't need to create a new object to real the value again, it's not cached.

The Boron uses very little power with cellular off, so the few seconds of being powered on will be negligible.

1 Like

That makes sense, thanks; I'm still not sure why reading it with FuelGauge doesn't have that issue then, does that block until the reading can be taken?

Also, if I keep calling it until I get a valid reading, I still want the device to connect normally if the battery is disconnected but it is being powered by USB for debugging; is there a way to check if the -1 being returned is because the fuel gauge hasn't restarted or if the battery can't be read?