Overview
In this tutorial, we will be Interfacing MAX17043 LiPo Fuel Gauge IC with Arduino. The MAX17043/44 IC can be used to measure the Lithium-Ion or Lithium Polymer Battery’s correct percentage along with charging and discharging rate. LiPo batteries are a great way to power your projects. They’re small, lightweight, and pack a pretty good punch for their size. Unfortunately, even the best batteries eventually run low on power.
In the previous tutorial, we build an online Battery Monitoring System. This method uses a voltage divider to bring down the voltage so that an ADC can read it. But this method is not an ideal method to measure battery percentage. This is because, the Battery voltage drops off quickly in the beginning, stays very stable for a long time, and then suddenly drops low at the end of its life. And secondly, the voltage of Li-ion or LiPo batteries doesn’t drop linearly.
This is the reason why we need an accurate method to measure the battery percentage linearly. The MAX17043 LiPo Fuel Gauge connects your battery to your project and uses a sophisticated algorithm to detect the relative state of charge and direct the A/D measurement of battery voltage. In other words, it tells your microcontroller how much ‘fuel’ is left in the tank. The MAX17043 LiPo Fuel Gauge IC communicates with Arduino over I2C & tells Battery percentage and an alert pin also tells you when the charge has dropped below a certain percentage.
Bill of Materials
For measuring the Battery Voltage & percentage accurately, you need to have following components. You can purchase all the components from Amazon from the given links.
S.N. | Components | Quantity | Purchase Links |
---|---|---|---|
1 | Arduino Nano Board | 1 | Amazon | AliExpress |
2 | MAX17043 Fuel Gauge Module | 1 | Amazon | AliExpress |
3 | TP4056 Battery Charger Module | 1 | Amazon | AliExpress |
4 | 0.96" I2C OLED Display | 1 | Amazon | AliExpress |
5 | 3.7V, 1000mAh LiPo Battery | 1 | Amazon | AliExpress |
6 | Jumper Wires | 20 | Amazon | AliExpress |
7 | Breadboard | 1 | Amazon | AliExpress |
MAX17043 3.7V Li Battery Fuel Gauge
The 3.7V Lithium batteries are commonly used in many projects. However, the remaining power and voltage of these batteries are highly nonlinear. We can only estimate whether the battery is full or almost empty according to its voltage. Mapping the battery voltage into percentage function is highly inaccurate due to non-linear discharging.
The MAX17043 single-cell Lithium Battery Fuel Gauge employs an I2C interface for easy interfacing with microcontrollers. It features an ultra-low operating current with the real-time tracking of the relative state of charge (SOC) of the battery through Maxim’s patented algorithm. This eliminates the need for full-to-empty relearning and offset accumulation errors.
The module also features a low battery power alert interrupt function. When the battery power falls below a specified threshold, the ALR pin generates a falling pulse to trigger the external interrupt of the controller. You will find it a great help to estimate the battery life by learning the power consumption of the system with this module. Check the MAX17043 Datasheet for more detail information.
Features of MAX17043 IC
- Maxim‘s patented algorithm
- Accurate voltage & remaining power readings of lithium battery
- No charge-discharge relearning process,
- No offset accumulation errors
- Wide input voltage, compatible with 3.3V and 5V controllers
- Programmable low power alert interrupt threshold
- Battery reverse polarity protection
Specifications
- Input Voltage (VCC): 3.3V~6.0V
- Battery Input Voltage (BAT IN): 2.5V~4.2V
- Battery Type: 3.7V Li-polymer/Li-ion battery
- Operating Current: 50 uA
- Precision: ±12.5mV Accuracy to 5.00V
Applications
- Smartphones
- MP3 Players
- Digital Cameras
- GPS Systems
- Handheld and Portable
- Robotics
Interfacing MAX17043 LiPo Fuel Gauge IC with Arduino
Now let us interface MAX17043 LiPo Fuel Gauge IC with Arduino. The following is the circuit diagram for the project.
Instead of using Arduino UNO or Arduino Nano, it’s better to use Arduino Pro Mini as Arduino Pro Mini can work with lower voltages and with Lithium Batteries. The most popular MAX17043 Fuel Gauge Module is manufactured by Sparkfun. So it’s better to go with SparkFun LiPo Fuel Gauge Module. For charging the Battery TP4056 Battery Charging Module is the cheaper and the best alternative in the market. To display the Battery voltage and percentage, we need some display unit like 0.96″ SSD1306 I2C OLED Display. For testing applications, you can either use 500mAh or 1000mAh Lithium-ion/Polymer Battery.
The Sparkfun MAX17043 Module has 6 pins as VCC, GND, SDA, SCL, QST & ALT. Connect the SDA & SCL Pin of MAX17043 to Arduino Pro Mini A4 & A5 pin respectively. Connect the VCC, GND & ALT pin of MAX17043 to Arduino Pro Mini RAW, GND & D2 Pin. Connect 3.7V lithium Battery to Battery connector of Sparkfun MAX17043 Module. There are + & – Pin on the top of the Module which should be connected to TP4056 + & – input pins.
To show the battery status, we have used 0.96″ I2C OLED Display with SSD1306 OLED Driver. Connect the SDA & SCL pin of OLED Display to A4 & A5 of Arduino Pro Mini. Connect the VCC & GND pin of OLED to Arduino 3.3V & GND Pin.
Source Code/Program for Interfacing MAX17043 with Arduino
There are multiple arduino libraries for interfacing MAX17043 IC with Arduino. One of the library is written by porrey and other by lucadentella & even Sparkfun library is the popular one.
But I prefer the library by Nlamprian which is easy to use, rewrite and modify.
The code also requires two libraries for OLED Display. Download the libraries from the following link and add them to the Library Folder of the Arduino.
1. Adafruit GFX Library: https://github.com/adafruit/Adafruit-GFX-Library
2. Adafruit SSD1306 Library: https://github.com/adafruit/Adafruit_SSD1306
Copy the following code and upload it to the Arduino Pro Mini Board use USB-to-TTL Converter or any FTDI Module.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
#include <SPI.h> #include <Wire.h> #include <LiFuelGauge.h> //https://github.com/nlamprian/LiFuelGauge #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C // 0x3D for 128x64, 0x3C for 128x32 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); void lowPower(); LiFuelGauge gauge(MAX17043, 0, lowPower); volatile boolean alert = false; void setup() { Serial.begin(9600); // Initializes serial port if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } display.clearDisplay(); // Waits for serial port to connect. Needed for Leonardo only while ( !Serial ) ; gauge.reset(); // Resets MAX17043 delay(200); // Waits for the initial measurements to be made // Sets the Alert Threshold to 10% of full capacity gauge.setAlertThreshold(10); Serial.println(String("Alert Threshold is set to ") + gauge.getAlertThreshold() + '%'); } void loop() { Serial.print("SOC: "); Serial.print(gauge.getSOC()); // Gets the battery's state of charge Serial.print("%, VCELL: "); Serial.print(gauge.getVoltage()); // Gets the battery voltage Serial.println('V'); display.setCursor(0, 10); //oled display display.setTextSize(2); display.setTextColor(WHITE); display.print("SOC:"); display.print(gauge.getSOC()); display.print("%"); display.setCursor(0, 40); //oled display display.setTextSize(2); display.setTextColor(WHITE); display.print("VOL:"); display.print(gauge.getVoltage()); display.print("V"); display.display(); display.clearDisplay(); if ( alert ) { Serial.println("Beware, Low Power!"); Serial.println("Finalizing operations..."); gauge.clearAlertInterrupt(); // Resets the ALRT pin alert = false; Serial.println("Storing data..."); Serial.println("Sending notification..."); Serial.println("System operations are halted..."); gauge.sleep(); // Forces the MAX17043 into sleep mode while ( true ) ; } delay(2000); } void lowPower() { alert = true; } |
MAX17043 Testing & Results
After the code is uploaded to Arduino Pro Mini Board, the OLED Display will start showing the Battery voltage and the Soc in percentage.
Also open the Serial Monitor to check the Battery Voltage and Status incase if you don’t have the OLED Display.
After continuous use of the Lithium Battery the battery might get discharged, in that case, you can plug in a micro-USB cable to the TP4056 charging port to charge the battery.
In most Lithium-ion batteries, the maximum battery voltage is 4.2V. In order to achieve 100% of charging, you have to charge the battery to 4.2V. The battery charging becomes slower after the battery cross 4.0V.
When the Battery is critically low, there is an automatic shut down of the entire system functions. The threshold voltage is set to 10% in the code. You can change it to even lower or higher.
The OLED will still show the battery voltage & SOC in percentage. But when you check the Serial Monitor, you will get much more information.
So, this is how you can use MAX17043 Fuel Gauge Module with Arduino to calculate the correct Battery Percentage.
Libraries & Coding Explanation
The following is the list of the public interface of the LiFuelGauge class.
-
LiFuelGauge(gaugeType ic); Creates a LiFuelGauge instance. Takes as argument the type of the IC. Either MAX17043 or MAX17044
-
LiFuelGauge(gaugeType ic, uint8_t intr, func f); Same as above. Also attaches the user-defined function f to interrupt number intr. These arguments associate with the ALRT interrupt. The function f must take no arguments and return no values
-
double getVoltage(); Returns a measurement of the battery’s voltage. MAX17043: 0-5V w/ 1.25mV res. MAX17044: 0-10V w/ 2.5mV res.
-
double getSOC(); Returns the battery’s state of charge as a percentage of the full capacity. The resolution is 1/256%
-
uint16_t getVersion(); Returns the production version of the IC
-
uint8_t getCompensation(); Returns a value used to optimize IC performance to different operating conditions
-
uint8_t getAlertThreshold(); Returns the alert threshold as a percentage below which an alert interrupt is generated
-
uint8_t setCompensation(uint8_t comp); Sets a value useful for optimizing IC performance to different operating conditions
-
uint8_t setAlertThreshold(uint8_t thrd); Sets the alert threshold below which an alert interrupt is generated. The acceptable range is 1-32%. The default threshold is 4%
-
uint8_t clearAlertInterrupt(); After an alert interrupt has been generated, it resets the interrupt. No interrupt will be regenerated until the battery’s SOC rises above the alert threshold and then falls below that again.
-
uint8_t sleep(); Forces the IC to sleep mode. All operations are halted
-
uint8_t wake(); Exits the IC from sleep mode
-
boolean sleeping(); Returns whether or not the IC is in sleep mode
-
uint8_t quickStart(); Forces the IC to restart fuel-gauge calculations
-
uint8_t reset(); Forces the IC to completely reset
3 Comments
The best electronic website i found over internet is @how2electronics thak you sir…
How do you know where in the microcontroller to plug the SDA, SCL and ALT pins?
I used arduino UNO and i am getting SOC: -1.00%, VCELL: -0.02V as output and nothing else please help