En este tutorial aprenderás cómo monitorizar los niveles de carga de una batería LiPo usando el MAX1704X. Los ejemplos de hardware y código son para un ESP32, pero funcionan igual para un ESP8266 o Arduino.
Las baterías LiPo son ideales para proyectos alimentados por batería y se usan comúnmente en aplicaciones móviles o al aire libre, como monitorización meteorológica, vigilancia o robótica. Pero usar baterías implica que necesitas saber cuándo recargarlas.
Sin embargo, estimar la carga de una batería LiPo y su tiempo de funcionamiento restante es sorprendentemente difícil. Las baterías LiPo tienen curvas de descarga altamente no lineales con una caída muy abrupta al final. Observa la siguiente curva de descarga.

Peor aún, la curva de descarga depende de la temperatura ambiente y de la corriente que extraes de la batería. Esto hace muy difícil obtener buenas estimaciones sobre la carga relativa y el tiempo de funcionamiento restante de una batería LiPo.
El MAX17043 es un avanzado medidor de carga de batería desarrollado para resolver este problema. En este tutorial aprenderás a usar el MAX17043 para medir el voltaje y la carga relativa de una batería LiPo con un ESP32. También te mostraré cómo configurar y manejar alertas de batería baja.
Pero empecemos con las piezas necesarias.
Piezas necesarias
Para este tutorial, estoy usando una placa ESP32 antigua (ESP32 lite), que ha sido descontinuada pero aún puedes conseguirla a bajo precio. Es la que aparece listada abajo. Hay un modelo sucesor con mejores especificaciones, que puedes encontrar here .
Pero la mayoría de las placas ESP8266 y otras ESP32 también deberían funcionar. Me gusta el ESP32 lite por su bajo precio y el conector de batería con capacidad de recarga integrada. Esto significa que puedes alimentar el ESP32 con batería y recargar la LiPo vía el puerto USB, muy práctico.
Si quieres usar un Arduino, deberías usar una placa que funcione a 3.3V como el Arduino Pro Mini (ATmega328-3.3V ), ya que aquí usaremos una sola batería LiPo (3.7V). También he listado un OLED, pero cualquier pantalla que soporte comunicación I2C y funcione a 3.3V servirá.
Hay dos versiones del MAX1704X. El MAX1704 3 listado aquí es para una sola celda LiPo, mientras que el MAX1704 4 es para dos celdas LiPo (en serie). Sin embargo, no pude encontrar un breakout para el MAX1704 4 en ningún lado, por lo que usaremos el MAX1704 3 . Pero eso significa que necesitas un microcontrolador que funcione a 3.3V o un convertidor buck para generar voltajes más altos.

MAX17043 Medidor de carga para LiPo

ESP32 lite

Cable USB de datos

Juego de cables Dupont

Protoboard

Kit de resistencias y LEDs

Pantalla OLED

Arduino IDE
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Especificaciones del medidor de carga MAX1704X
El MAX17043/MAX17044 es un sistema ultra compacto de medidor de carga para baterías de ion-litio (Li+). El IC es muy pequeño y la imagen abajo muestra un breakout típico para el chip, que facilita mucho la conexión.

Hay dos versiones del chip. El MAX17043 está configurado para medir la carga de una sola celda de litio, mientras que el MAX17044 está configurado para un pack de dos celdas 2S. El chip usa un esquema de modelado de batería LiPo llamado ModelGauge para seguir continuamente el estado relativo de carga (SOC) de la batería sobre un perfil de carga/descarga muy variable.
Aquí están las especificaciones según la hoja de datos del MAX17043/MAX17044 :
- Tipo de batería: batería Li-polímero/Li-ion de 3.7V
- 1 celda (MAX17043) o 2 celdas (MAX17044)
- Medición precisa de voltaje
- Precisión ±12.5mV para 5V (MAX17043)
- Precisión ±30mV para 10V (MAX17044)
- Capacidad relativa precisa (RSOC)
- Sin acumulación de offset en la medición
- No es necesaria recalibración de batería de lleno a vacío
- Alarma/Interrupción externa para aviso de batería baja
- Interfaz I2C
- Corriente de operación: 50 µA
- Voltaje de entrada (VCC): 3.3V~6.0V
Pinout
Como se mencionó, el MAX1704X es un IC muy pequeño, por lo que usamos el breakout listado en las piezas necesarias. Puedes ver el pinout para esta placa abajo:

La placa tiene un conector JST de 2 pines para conectar la batería LiPo. Pero también hay dos pines (BAT+ y BAT-) donde puedes conectar la batería. El rango de voltaje de entrada está entre 2.5V y 4.5V . El voltaje nominal de una batería LiPo de una sola celda es alrededor de 3.7V. Completamente cargada, el voltaje es cerca de 4.2V. Así que una LiPo de una celda entra dentro del rango de voltaje de entrada.
La alimentación a la placa se provee vía los pines VCC y GND. El máximo VCC es 5.5V pero se recomienda 3.3V. Nota que hay diferentes versiones de la placa con distintas opciones (batería o MCU) para proveer VCC. Recomiendo usar los 3.3V de tu microcontrolador.
El pin ALT es el pin de alerta. Este pin normalmente está en ALTO pero pasa a BAJO si la carga relativa de la batería cae por debajo de un umbral configurable, por ejemplo 10%. Puedes conectar este pin a un pin de interrupción de tu microcontrolador para reaccionar a niveles bajos de batería.
El pin QST es para inicio rápido. Permite resetear el MAX17043 por hardware. Un flanco ascendente en este pin inicia un reset por hardware. Pero también puedes resetear por software, que es lo que haremos.
Interfaz I2C
SDA y SCL son los pines para la interfaz I2C. La dirección I2C del MAX17043 es 0x36 . La placa breakout tiene dos resistencias pull-up de 2.2kΩ conectadas a las líneas SDA y SCL, por lo que no necesitas resistencias pull-up separadas.
Nota que hay un jumper de 3 pads en la parte inferior de la placa. Puedes cortar los jumpers para deshabilitar las resistencias pull-up si conectas múltiples dispositivos I2C. Para más detalles, consulta el max1704 Guide .

Y eso es todo sobre el MAX17043. Ahora veamos las librerías disponibles para leer datos del IC MAX170X.
Librerías MAX170X
Hay muchas librerías para usar el MAX17043 con ESP32/ESP8266 o Arduino. En particular, están las librerías de Porrey , Lucadentella , Sparkfun , Adafruit y Nlamprian . Todas son básicamente envoltorios de la funcionalidad del chip MAX1704X y son muy similares.
Probé la librería de Sparkfun y la de Porrey. Ambas funcionaron, pero en este tutorial mostraré código exclusivamente basado en la librería de Porrey. Sin embargo, si prefieres otra, debería ser bastante sencillo cambiarla.
Funciones de la librería MAX170X
Aquí tienes un resumen rápido de las funciones que encontrarás en la librería MAX170X de Porrey:
| begin(TwoWire*) | Crea una instancia FuelGauge. |
| uint8_t address(); | Devuelve la dirección I2C del IC. |
| float voltage(); | Devuelve una medición del voltaje de la batería en milivoltios |
| float percent(); | Devuelve el estado de carga (SOC) de la batería en porcentaje. |
| uint16_t version(); | Devuelve la versión del IC MAX170X. |
| uint8_t compensation(); | Devuelve un valor usado para optimizar el rendimiento del IC en diferentes condiciones de operación |
| void compensation(uint8_t); | Establece un valor para optimizar el rendimiento del IC en diferentes condiciones de operación |
| bool sleep(); | Forza al IC MAX170X a modo de suspensión. Todas las operaciones se detienen |
| bool isSleeping(); | Devuelve si el IC MAX170X está en modo suspensión |
| bool wake(); | Despierta al IC MAX170X del modo suspensión |
| void reset(); | Resetea el IC MAX170X |
| void quickstart(); | Reinicia los cálculos de carga de la batería |
| bool alertIsActive(); | Devuelve si una alerta de batería baja está activa |
| void clearAlert(); | Limpia la alerta de batería baja |
| uint8_t threshold(); | Devuelve el umbral actual para la alerta, por ejemplo 20% |
| void threshold(uint8_t); | Establece el umbral para la alerta, por ejemplo 20% |
Instalación de la librería MAX170X
Para install la librería MAX170X de Porrey abre el Library Manager y escribe «MAX1704X» en el cuadro de búsqueda. Encontrarás «MAX1704X by Daniel Porrey». Mira abajo:

Pulsa el botón INSTALL y listo. Como ves en la captura, ya tengo la librería instalada. Puedes instalar las otras librerías, por ejemplo la de Sparkfun o Adafruit, si quieres. No hay conflicto.
En las siguientes dos secciones te muestro primero cómo conectar el MAX17043 a tu microcontrolador y luego cómo usar la librería para leer datos de la batería.
Conectando MAX17043 al ESP32
Conectar el MAX17043 a un microcontrolador es muy sencillo. Primero conecta 3.3V y GND del microcontrolador a VCC y GND del MAX17043 (cables rojo y azul). Si tienes un Arduino de 5V, también puedes conectar 5V a VCC.

Luego conecta la interfaz I2C (SCL, SDA). Los pines por defecto para I2C en el ESP32 lite son 23 (SDA) y 19 (SCL). Eso es lo que se muestra arriba (cables verde y amarillo). En Arduino conectarías SDA -> A4 y SCL -> A5. Asegúrate de conectar bien estos pines, ya que es fácil confundirlos y la placa no funcionará.
Finalmente, conectamos la batería LiPo. El positivo y negativo de la batería se conectan a los conectores correspondientes del ESP32 y del MAX17043. Lo bueno de la placa ESP32 es que puedes alimentarla con la batería y al mismo tiempo conectar la placa vía USB a tu ordenador. Si está conectada, la batería se carga. El MAX17043 puede permanecer conectado mientras se carga y seguirá reportando voltajes y niveles de carga.
Ten en cuenta que hay reportes de que algunas placas MAX17043 de ciertos proveedores no funcionan. Mi placa de AliExpress funciona bien y la que aparece en las piezas necesarias debería funcionar también. Aunque no he probado esa placa específica.
Leyendo carga de batería con MAX17043
El siguiente ejemplo de código simple te muestra cómo leer el voltaje y la carga relativa de la batería usando el MAX17043. Échale un vistazo rápido primero y luego discutimos el código en detalle.
#include "Wire.h"
#include "MAX17043.h"
void setup() {
Serial.begin(115200);
Wire.begin(SDA, SCL);
if (!FuelGauge.begin(&Wire)) {
Serial.println("MAX17043 NOT found.\n");
while (true) {}
}
FuelGauge.reset();
delay(250);
FuelGauge.quickstart();
delay(125);
}
void loop() {
float volts = FuelGauge.voltage();
float pcnt = FuelGauge.percent();
Serial.printf("%.0fmV (%.1f%%)\n", volts, pcnt);
delay(3000);
}
Incluir librerías
Empezamos incluyendo la Wire y la MAX17043 librería. La librería Wire es necesaria para configurar la interfaz I2C. Si tienes un MAX17044, incluirías MAX17044.h en lugar de MAX17043.h . La librería MAX170X de Porrey tiene ambos archivos de cabecera.
Función setup
En la función setup() , inicializamos la comunicación serial a 115200 baudios. Luego iniciamos la comunicación I2C usando la función Wire.begin(SDA, SCL) .
Defino explícitamente los pines para I2C usando Wire.begin(SDA, SCL) . Esto te permite usar pines distintos a los predeterminados para I2C y también suprime un mensaje » Wire.begin()" en el monitor serial que la librería genera (ver blog ).
Luego iniciamos el MAX17043 con FuelGauge.begin(&Wire) . Si no se encuentra el sensor FuelGauge, se imprime un mensaje en el monitor serial y el programa entra en un bucle infinito.
De lo contrario, reseteamos el FuelGauge seguido de un retardo de 250ms y hacemos un quickstart seguido de un retardo de 125ms. Esta secuencia viene del código de ejemplo de la librería MAX17043. No estoy seguro si estos retardos son necesarios, pero los dejé.
void setup() {
Serial.begin(115200);
Wire.begin(SDA, SCL);
if (!FuelGauge.begin(&Wire)) {
Serial.println("MAX17043 NOT found.\n");
while (true) {}
}
FuelGauge.reset();
delay(250);
FuelGauge.quickstart();
delay(125);
}
Función loop
La función loop() lee continuamente el voltaje y el porcentaje de carga de la batería LiPo. Los valores de voltaje y porcentaje se imprimen en el monitor serial usando Serial.printf() con un retardo de 3 segundos entre cada lectura.
void loop() {
float volts = FuelGauge.voltage();
float pcnt = FuelGauge.percent();
Serial.printf("%.0fmV (%.1f%%)\n", volts, pcnt);
delay(3000);
}
Si subes y ejecutas este código deberías ver la siguiente salida en tu monitor serial:

Ten en cuenta que Arduino, a diferencia del ESP32, no soporta la función printf . Tendrás que usar una secuencia de sentencias print() en su lugar. Para evitar esto, usaremos la librería aprintf en los siguientes ejemplos de código. Para más detalles, consulta nuestro tutorial How To Print To Serial Monitor On Arduino .
Imprimir más datos con aprintf
El siguiente ejemplo imprime toda la información que podemos obtener del chip MAX17043 al monitor serial. La estructura del código es igual que antes, pero hay algunos cambios menores que quiero destacar.
#include "Wire.h"
#include "aprintf.h"
#include "MAX1704X.h"
MAX1704X monitor = MAX1704X(MAX17043_mV);
void setup() {
Serial.begin(115200);
Wire.begin(SDA, SCL);
if (!monitor.begin(&Wire)) {
aprintf("MAX1704X NOT found.\n");
while (true) {}
}
monitor.reset();
delay(250);
monitor.quickstart();
delay(125);
}
void loop() {
aprintf("---------------------------------\n");
aprintf("Voltage %.0fmV\n", monitor.voltage());
aprintf("Percent %.1f%%\n", monitor.percent());
aprintf("Address 0x%02x\n", monitor.address());
aprintf("Version %d\n", monitor.version());
aprintf("ADC %d\n", monitor.adc());
aprintf("Alert %d\n", monitor.alertIsActive());
aprintf("Sleeping %d\n", monitor.isSleeping());
aprintf("Compensation 0x%02x\n", monitor.compensation());
delay(3000);
}
Primero, en lugar de usar el objeto FuelGauge predefinido, puedes crear tu propio objeto monitor de carga:
MAX1704X monitor = MAX1704X(MAX17043_mV);
En el constructor puedes especificar si tienes un MAX17043 o un MAX17044 y luego usar el nombre «monitor» o cualquier otro que prefieras en el resto del código.
Segundo, uso la librería aprintf para imprimir los datos en el monitor serial. La función aprint() hace lo mismo que Serial.printf() pero funciona igual en Arduino, ESP32 y ESP8266. También es útil para salida formateada en pantallas, como verás en la siguiente sección.
Sin embargo, debes instalar la librería aprintf desde un archivo zip. Descarga el zip-file y luego instálala vía Sketch -> Include Library -> Install .ZIP Library ... .

Para más detalles sobre aprintf y el monitor serial, consulta nuestro tutorial How To Print To Serial Monitor On Arduino . Una vez instalada, deberías poder ejecutar el código y ver la siguiente salida en tu monitor serial:

Como puedes deducir de la salida, la placa estaba cargando la LiPo (Voltaje = 4120mV), ya que para que el monitor serial funcione, el ESP32 debe estar conectado vía USB al ordenador. En el caso del ESP32 lite, esto carga la batería LiPo conectada.
En la siguiente sección te mostraré cómo conectar un OLED y mostrar la información de la batería allí, en lugar de en el monitor serial.
Mostrar carga de batería en OLED
Mostrar el nivel de carga de la batería en el monitor serial está bien para pruebas, pero no es muy útil para un proyecto alimentado por batería. Normalmente queremos mostrar el nivel actual de batería directamente. Eso puede ser una barra de LEDs o una pantalla LCD. Pero en este ejemplo uso un OLED, porque son muy pequeños y funcionan bien a 3.3V.
Conexión para OLED
El siguiente diagrama muestra cómo conectar el OLED (además de las partes ya existentes) al proyecto. Empieza conectando 3.3V y GND del microcontrolador a VCC y GND del OLED (cables rojo y azul).

Luego conectamos los cables I2C (SDA, SCL) en paralelo al MAX17043 (cables amarillo y verde). El OLED y el MAX17043 comparten el mismo bus I2C y deben tener direcciones I2C diferentes. Si tienes problemas, revisa las direcciones I2C. Mi OLED tiene la dirección 0x3C y el MAX17043 típicamente tiene la dirección 0x36 . También las resistencias pull-up pueden ser un problema. Recuerda el jumper de 3 pads en el MAX17043 que puedes usar para deshabilitar las resistencias pull-up.
Si necesitas más detalles sobre cómo usar una pantalla OLED, consulta nuestro tutorial sobre How to Interface the SSD1306 I2C OLED Graphic Display With Arduino .
Código para OLED
El siguiente código muestra el voltaje y la carga relativa de la batería en el OLED. Como siempre, echa un vistazo rápido al código completo antes de analizarlo más a fondo.
#include "Wire.h"
#include "aprintf.h"
#include "MAX17043.h"
#include "Adafruit_SSD1306.h"
Adafruit_SSD1306 disp(128, 64, &Wire, -1);
void setup() {
Serial.begin(115200);
Wire.begin(SDA, SCL);
if (!FuelGauge.begin(&Wire)) {
aprintf("MAX17043 NOT found.\n");
while (true) {}
}
FuelGauge.reset();
delay(250);
FuelGauge.quickstart();
delay(125);
FuelGauge.threshold(20);
FuelGauge.clearAlert();
disp.begin(SSD1306_SWITCHCAPVCC, 0x3C);
disp.setTextSize(2);
disp.setTextColor(WHITE);
}
void loop() {
float volts = FuelGauge.voltage() / 1000;
float pcnt = FuelGauge.percent();
bool alrt = FuelGauge.alertIsActive();
disp.clearDisplay();
disp.setCursor(20, 10);
disp.print(fmt("%.1f%% %c", pcnt, alrt ? '!' : ' '));
disp.setCursor(20, 30);
disp.print(fmt("%.3fV", volts));
disp.display();
delay(3000);
}
Librerías y configuración de pantalla
El código incluye librerías necesarias como Wire.h , aprintf.h , MAX17043.h , y Adafruit_SSD1306.h . Luego inicializa una instancia de la clase Adafruit_SSD1306 para una pantalla OLED con dimensiones específicas. Aquí uso un OLED 128×64. Si tu OLED es de otro tamaño, tendrás que ajustar estos valores.
Adafruit_SSD1306 disp(128, 64, &Wire, -1);
Función setup
En la función setup() , se inicia la comunicación serial a 115200 baudios. Se inicia la comunicación I2C usando la función Wire.begin(SDA, SCL) . El código verifica si se detecta el IC MAX17043, y si no, imprime un mensaje y entra en un bucle infinito. Luego se resetea el medidor de carga y se realiza un inicio rápido.
También establecemos un umbral para la alerta de batería baja llamando a FuelGauge.threshold(20) . Esto significa que el umbral para la alerta de batería baja se fija en 20%. El nivel máximo que puedes establecer es 32% y el mínimo es 1%. Después limpiamos todas las alertas existentes.
FuelGauge.threshold(20); FuelGauge.clearAlert();
Finalmente, inicializamos la pantalla OLED. Asegúrate de usar la dirección I2C de tu OLED aquí. La mía es 0x3C y tengo un OLED en blanco y negro, así que establezco el color del texto en WHITE.
disp.begin(SSD1306_SWITCHCAPVCC, 0x3C); disp.setTextSize(2); disp.setTextColor(WHITE);
Función loop
La función loop() lee continuamente el voltaje y el porcentaje de batería usando las funciones FuelGauge.voltage() y FuelGauge.percent() . También verifica si hay alertas activas usando FuelGauge.alertIsActive() .
float volts = FuelGauge.voltage() / 1000; float pcnt = FuelGauge.percent(); bool alrt = FuelGauge.alertIsActive();
La información de la batería se imprime en el OLED usando la función fmt() de la librería aprintf y la función display() de la librería Adafruit_SSD1306 .
La función fmt() funciona como Serial.printf() pero imprime en un buffer de cadena que luego se devuelve. La función disp.print() del OLED toma este buffer y muestra el contenido en la pantalla.
disp.clearDisplay();
disp.setCursor(20, 10);
disp.print(fmt("%.1f%% %c", pcnt, alrt ? '!' : ' '));
disp.setCursor(20, 30);
disp.print(fmt("%.3fV", volts));
disp.display();
Con la función fmt() puedes usar el mismo formato y imprimir cómodamente en dispositivos que no soportan una función tipo printf() . Sin embargo, para el OLED no olvides llamar a disp.display() al final, de lo contrario no se mostrará nada.
El OLED mostrará el porcentaje de batería, el voltaje y un indicador de alerta (!) si hay una alerta activa. Si todo está conectado e implementado correctamente, deberías ver la siguiente salida:

En este ejemplo mostramos una alerta de batería baja en el OLED consultando el estado del pin de alerta cada 3 segundos. Alternativamente, podemos usar un manejador de interrupciones para reaccionar inmediatamente a una alerta de batería baja. Este es el tema de la siguiente sección.
Manejo de alertas de batería baja del MAX17043
Para demostrar el manejo del evento de batería baja, añadamos un LED al circuito. Este LED se encenderá si la carga de la batería cae por debajo de un umbral predefinido.
Conectamos el lado positivo (pin largo) del LED al GPIO 25 del ESP32. Puedes elegir cualquier otro GPIO que prefieras, solo no olvides cambiar el código abajo en consecuencia. El lado negativo del LED se conecta a GND (G) a través de una resistencia limitadora de corriente de 68Ω.

Ahora viene la parte interesante. El MAX17043 generará una señal en el pin ALT cuando la carga de la batería caiga por debajo del umbral. Más precisamente, el pin ALT pasará de ALTO a BAJO. Conectamos el pin ALT al GPIO 32 del ESP32 y se llamará a un manejador de interrupción si cambia el estado del pin ALT.
¡Veamos cómo se hace eso en código!
Código para manejador de interrupción de batería baja
La mayoría de los microcontroladores, incluido el ESP32, permiten adjuntar una función manejadora de interrupción a un pin. Esto hace que la función se ejecute cuando el pin cambia de estado. El código abajo es el mismo que antes con la adición de una función manejadora de interrupción lowBattery() . También hay definiciones adicionales para un ledPin y alrtPin , que necesitamos para mostrar y detectar una alerta de batería baja.
Abajo está el código completo y discutiremos sus detalles en las secciones siguientes:
#include "Wire.h"
#include "aprintf.h"
#include "MAX17043.h"
#include "Adafruit_SSD1306.h"
const int alrtPin = 32;
const int ledPin = 25;
Adafruit_SSD1306 disp(128, 64, &Wire, -1);
void lowBattery() {
digitalWrite(ledPin, HIGH);
}
void setup() {
Serial.begin(115200);
Wire.begin(SDA, SCL);
if (!FuelGauge.begin(&Wire)) {
aprintf("MAX17043 device was NOT found.\n");
while (true) {}
}
FuelGauge.reset();
delay(250);
FuelGauge.quickstart();
delay(125);
FuelGauge.threshold(20);
FuelGauge.clearAlert();
disp.begin(SSD1306_SWITCHCAPVCC, 0x3C);
disp.setTextSize(2);
disp.setTextColor(WHITE);
pinMode(ledPin, OUTPUT);
pinMode(alrtPin, INPUT_PULLUP);
digitalWrite(ledPin, LOW);
attachInterrupt(alrtPin, lowBattery, FALLING);
}
void loop() {
float volts = FuelGauge.voltage() / 1000;
float pcnt = FuelGauge.percent();
bool alrt = FuelGauge.alertIsActive();
disp.clearDisplay();
disp.setCursor(20, 10);
disp.print(fmt("%.1f%% %c", pcnt, alrt ? '!' : ' '));
disp.setCursor(20, 30);
disp.print(fmt("%.3fV", volts));
disp.display();
delay(3000);
}
Constantes y variables
Como se mencionó, primero definimos dos nuevas constantes, alrtPin y ledPin , que representan los pines para la señal de alerta y el indicador LED respectivamente.
const int alrtPin = 32; const int ledPin = 25;
Función de batería baja
La función lowBattery() se llama cuando la carga de la batería cae por debajo de cierto umbral. Simplemente enciende el LED conectado a ledPin . Ten en cuenta que el LED permanecerá encendido hasta que se reinicie el ESP32, incluso si la carga de la batería vuelve a un nivel superior al umbral. Pero es fácil cambiar este comportamiento si necesitas algo diferente.
void lowBattery() {
digitalWrite(ledPin, HIGH);
}
Función setup
En la función setup() , el código inicializa la comunicación serial, el bus I2C, el medidor de carga MAX17043, la pantalla OLED y configura los modos de pin para el LED y la señal de alerta.
Lo más importante, también configura la interrupción para disparar la función lowBattery() en un flanco descendente. Esto significa que si el pin ALT del MAX17043 baja debido a una carga baja, detectamos este flanco descendente en alrtPin y llamamos a la función lowBattery() . Ten en cuenta que la función lowBattery() se llama independientemente de la función loop() .
void setup() {
...
attachInterrupt(alrtPin, lowBattery, FALLING);
}
Si quieres aprender más sobre interrupciones, consulta nuestros tutoriales Push-Button And Arduino y Build Arduino Tachometer Using A3144 Hall Effect Sensor que tienen más aplicaciones y detalles.
Función loop
La función loop() es la misma que antes. Lee continuamente el voltaje, porcentaje de carga y estado de alerta del IC MAX17043. Luego actualiza la pantalla OLED con esta información y verifica si hay alertas. Si hay una alerta activa, muestra un signo de exclamación junto al porcentaje de batería.
La diferencia importante entre la alerta mostrada en el OLED y la señalada por el LED rojo es que el OLED se actualiza solo cada 3 segundos, mientras que el LED reacciona inmediatamente.
Y eso es todo. Con estos circuitos y código puedes monitorizar niveles de carga de batería con precisión y reaccionar rápidamente a alertas de batería baja.
Conclusiones
El MAX1704X es un IC muy útil para monitorizar niveles de carga en proyectos alimentados por batería. Las dos versiones, MAX17043 y MAX17044, son esencialmente iguales. El código y circuitos presentados funcionarán igual para ambas. La única diferencia es que el MAX17043 está diseñado para monitorizar una sola LiPo (3.7V), mientras que el MAX17044 se usa cuando hay dos LiPo (7.4V) en serie.
Una característica del MAX1704X que no hemos tratado en este tutorial es la función de compensación. Al parecer, puede optimizar el rendimiento del IC para diferentes químicas de litio o diferentes temperaturas de operación. Pero no hay información sobre los detalles ni qué valores usar para la compensación en la hoja de datos.
Sin embargo, otra característica interesante del MAX1704X que está documentada es el modo de suspensión. Esto es útil junto con el modo deep sleep del ESP32 (o Arduino/ESP8266). Permite poner tanto el microcontrolador como el monitor de batería en suspensión profunda para extender la vida de la batería.
Como alternativa al MAX1704X, podrías usar un divisor de voltaje y medir el voltaje de la batería vía una entrada analógica para implementar un sistema simple de aviso de batería baja. Para más detalles sobre eso, consulta nuestro tutorial How to Monitor Battery Voltage for Battery Powered Projects . Esta es una opción más barata pero mucho menos fiable, especialmente si quieres estimar el tiempo de funcionamiento restante y recargar a tiempo.
Y ahora, ¡diviértete! ; )
Enlaces
Aquí algunos enlaces que encontré útiles al escribir este tutorial:
- SparkFun MAX1704x Fuel Gauge Arduino Library
- LiPo Fuel Gauge (MAX1704X) Hookup Guide – SparkFun Learn
- ESP32 get data from max17043 | All About Circuits
- Battery Monitoring Done Right (Arduino & ESP32)
Preguntas frecuentes
¿Qué tan preciso es el medidor de carga MAX1704X para monitorizar niveles de batería?
El medidor MAX1704X es muy preciso, con un error típico de solo ±1% en todo el rango de temperatura.
¿Se puede usar el MAX1704X con otros microcontroladores además de ESP32 y Arduino?
Sí, el MAX1704X puede usarse con varios microcontroladores siempre que soporten comunicación I2C.
¿Es posible personalizar el umbral de alerta de batería baja en el MAX1704X?
Sí, el umbral de alerta de batería baja puede personalizarse ajustando los valores del registro correspondiente. Sin embargo, el umbral máximo es 32% y el mínimo 1%.
¿Se puede usar el MAX1704X con otros tipos de baterías además de LiPo?
Aunque el MAX1704X está optimizado para baterías LiPo, también puede usarse con otros tipos de baterías con algunos ajustes en la configuración.
¿Cómo se alimenta el medidor de carga MAX1704X?
El MAX1704X puede alimentarse directamente desde la batería que monitorea, pero recomiendo alimentarlo desde el microcontrolador.
¿Puede el MAX1704X monitorizar múltiples baterías simultáneamente?
No, el MAX1704X está diseñado para monitorizar una sola batería a la vez.
¿Cuál es la interfaz de comunicación usada por el medidor MAX1704X?
El MAX1704X se comunica con el microcontrolador usando la interfaz I2C.
¿Es posible calibrar el MAX1704X para mayor precisión?
Sí, el MAX1704X puede calibrarse mediante comandos de software para mejorar la precisión según los requisitos específicos de la aplicación. Consulta la función compensation() de la librería MAX1704X y la hoja de datos del MAX1704X .
¿Cómo maneja el MAX1704X la protección contra sobrecarga de batería?
El MAX1704X no proporciona protección contra sobrecarga por sí mismo, pero puede monitorizar el nivel de carga para ayudar a prevenir la sobrecarga cuando se usa junto con circuitos de carga adecuados.
¿Cómo maneja el MAX1704X la protección contra descarga excesiva de batería?
El MAX1704X no proporciona protección contra descarga excesiva, pero puede monitorizar el nivel de carga para ayudar a prevenir descargas profundas cuando se integra con sistemas adecuados de gestión de energía.
¿Cuál es el rango típico de voltaje de operación del medidor MAX1704X?
El MAX1704X opera en un rango típico de voltaje de 2.7V a 5.5V; adecuado para monitorizar el voltaje típico de una batería LiPo (3.7V).
¿Cuál es el consumo de corriente del medidor MAX1704X?
El consumo típico de corriente del MAX1704X es de 50µA y tiene un modo de suspensión con consumo aún menor de 1µA.

