[tutorial] LiFuelGauge

LiFuelGauge Tutorial from codebender on Vimeo.

This is a tutorial on the LiFuelGauge library. Let's say you decide to make your next project portable. So you need a battery, and you pick one of the popular Lithium Polymer single cell batteries. You take your battery, you connect it to a boost converter to receive the desired voltage, and you power your project from the output of the converter. But like all batteries, yours eventually will run out of juice, and it will do so unexpectedly, right when you need it the most. So, what if you could tell the state of charge of your battery? What if you could tell how much time your project has left, so it can perform any final procedures and save you from the disaster of losing your precious data?


Well, you can do that... with the LiPo Fuel Gauge module. This fuel gauge from Sparkfun incorporates a MAX17043G+U to do all the dirty work of figuring out the state of your battery and letting you know when the time has come to pack up your things and get ready for power down.

So, this is the module with which the LiFuelGauge library will try to communicate and provide you with a simple interface to use. Let's see that...

This is the schematic of our circuit. The module on the left is the LiPo Fuel Gauge and the module on the right is a LiPower Boost Converter.



This example retrieves data from the Fuel Gauge module and prints them on the Serial Monitor.

Let's look at the code. At the beginning we include the necessary libraries (lines 13-14). The LiFuelGauge library makes use of the Wire library to communicate with the IC on the Fuel Gauge module. Next, we create a LiFuelGauge instance (line 23) with the type of the IC on the module, it's either MAX17043 or MAX17044, and optionally we can provide an interrupt number and a function to attach on that interrupt. So, what is exactly the meaning of this interrupt? The Fuel Gauge module has an ALRT pin that goes LOW whenever the State Of Charge (SOC) of the battery falls below a certain threshold. So, we can use that to generate an interrupt on the Arduino and start closing any open files, saving any important data, or just sending a notification to the user that he, or she, needs to charge the battery.

Inside setup, we reset the module to get it to a known state (line 35), and then we call the setAlertThreshold method (line 39) to set the alert threshold of interest. We provide this threshold as a percentage of the cell's full capacity. The available range 1-32%. We can also receive the current alert threshold by calling the getAlertThreshold method (line 41).

Inside loop, we call the getSOC method (line 47) to learn the current state of the battery's charge. It comes as a percentage of the battery's full capacity with a resolution of 1/256%. Next, we call the getVoltage method (line 49) to get a measurement of the battery's voltage. For the MAX17043, that measurement is in the range of 0-5V with a resolution of 1.25mV.

Later, if an interrupt has been generated and the alert variable has been set, we call the clearAlertInterrupt method (line 56) to reset the ALRT pin. Just remember here that when being inside an Interrupt Service Routine, in our case the lowPower function, interrupts are disabled and so we can't communicate with the Fuel Gauge module unless we re-enable interrupts by calling the sei function. But this is not recommended at all, and that is why I'm using the alert flag here to condition and do all the necessary work inside the loop function.

So... we have been informed of the low power situation, we have saved our data and notified the user, and then we halt all operations to save power for emergency reasons. Specifically for the Fuel Gauge module, we can put it in sleep mode by calling the sleep method (line 61).

Other useful methods we can call are the wake method that gets the module out of sleep mode, the sleeping method (returns a boolean value) that checks if the module is in sleep mode, and the quickStart method that makes the module restart the fuel gauge calculations. We can call this last method possibly inside the setup function, if we believe that there is a lot of noise on the power line during the power on of our system that will cause the Fuel Gauge module to take erroneous measurements.

And finally, there is the matter of the time left before the boost converter cuts the power. The following calculation is a rough approximation of the remaining minutes.

MinutesLeft = 0.6 * SOC * Capacity / LoadCurrent

SOC is the state of charge reported by the Fuel Gauge module and is expressed as a percentage of the full capacity. Next is the Capacity of the battery expressed in mAh, and LoadCurrent is the current drawn by the whole system expressed in mA.

So, let's say we have a 2000mAh LiPo battery, the Fuel Gauge module reports a 12% SOC and we draw 200mA from the battery. Then it turns out that, at these conditions, our system will keep running for another hour MinutesLeft = 0.6 * 12 * 2000 / 200 = 72 mins.

That's all folks. We hope you enjoy this library, and if you have any comments or suggestions you can contact us at girder [at] codebender [dot] cc

Sounds are from freesound.org. Schematics were based on Fritzing.