Neste tutorial, vais aprender a monitorizar os níveis de carga de uma bateria LiPo usando o MAX1704X. Os exemplos de hardware e código são para um ESP32, mas funcionam da mesma forma para um ESP8266 ou Arduino.
As baterias LiPo são ótimas para projetos alimentados por bateria e são frequentemente usadas em aplicações exteriores ou móveis, como monitorização meteorológica, vigilância ou robótica. Mas funcionar a bateria significa que precisas de saber quando recarregar.
Estimar a carga de uma bateria LiPo e o seu tempo de funcionamento restante é, no entanto, surpreendentemente difícil. As baterias LiPo têm curvas de descarga altamente não lineares com uma queda muito súbita no final. Vê a seguinte curva de descarga.

Ainda pior, a curva de descarga depende da temperatura ambiente e da corrente que retiras da bateria. Isto torna muito difícil obter boas estimativas da carga relativa e do tempo de funcionamento restante de uma bateria LiPo.
O MAX17043 é um avançado indicador de carga de bateria desenvolvido para resolver este problema. Neste tutorial, vais aprender a usar o MAX17043 para medir a tensão e a carga relativa de uma bateria LiPo com um ESP32. Também te vou mostrar como configurar e gerir alertas de bateria fraca.
Mas vamos começar pelas peças necessárias.
Peças Necessárias
Para este tutorial, estou a usar uma placa ESP32 mais antiga (ESP32 lite), que já foi descontinuada, mas ainda podes encontrá-la a um preço baixo. É a que está listada abaixo. Existe um modelo sucessor com especificações melhoradas, que podes encontrar here .
Mas a maioria das placas ESP8266 e outras ESP32 também devem funcionar. Gosto do ESP32 lite pelo preço baixo e pelo conector de bateria com capacidade de recarga integrada. Isto significa que podes usar o ESP32 a bateria e carregar a LiPo via porta USB – muito prático.
Se quiseres usar um Arduino, deves usar uma placa que funcione a 3.3V, como o Arduino Pro Mini (ATmega328-3.3V ), já que vamos usar uma única bateria LiPo (3.7V) aqui. Também listei um OLED, mas qualquer ecrã que suporte comunicação I2C e funcione a 3.3V serve.
Existem duas versões do MAX1704X. O MAX1704 3 listado aqui é para uma única célula LiPo, enquanto o MAX1704 4 é para duas células LiPo (em série). No entanto, não consegui encontrar uma placa breakout para o MAX1704 4 em lado nenhum, por isso vamos usar o MAX1704 3 . Mas isso significa que precisas de um microcontrolador que funcione a 3.3V ou de um buck booster para gerar tensões mais altas.

MAX17043 LiPo Fuel Gauge

ESP32 lite

Cabo de Dados USB

Conjunto de Fios Dupont

Breadboard

Kit de Resistores & LED

Ecrã 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.
Especificações do MAX1704X Fuel Gauge
O MAX17043/MAX17044 é um sistema ultra-compacto de indicador de carga para baterias de iões de lítio (Li+). O IC em si é muito pequeno e a imagem abaixo mostra uma placa breakout típica para o chip, o que facilita muito a ligação.

Existem duas versões do chip. O MAX17043 está configurado para medir a carga de uma única célula de lítio, enquanto o MAX17044 é configurado para um pack de duas células 2S. O chip usa um esquema de modelação de bateria LiPo, chamado ModelGauge, para acompanhar continuamente o estado relativo de carga (SOC) da bateria ao longo de um perfil de carga/descarga muito variável.
Aqui estão as especificações segundo o Datasheet do MAX17043/MAX17044 :
- Tipo de Bateria: bateria Li-polímero/Li-íon de 3.7V
- 1 Célula (MAX17043) ou 2 Células (MAX17044)
- Medição de Tensão Precisa
- Precisão de ±12.5mV para 5V (MAX17043)
- Precisão de ±30mV para 10V (MAX17044)
- Capacidade Relativa Precisa (RSOC)
- Sem Acumulação de Offset na Medição
- Sem Necessidade de Reaprendizagem Completa da Bateria
- Alarme/Interrupção Externa para Aviso de Bateria Fraca
- Interface I2C
- Corrente de Operação: 50 µA
- Tensão de Entrada (VCC): 3.3V~6.0V
Pinout
Como mencionado acima, o MAX1704X é um IC muito pequeno e por isso usamos a placa breakout listada nas peças necessárias. Podes encontrar o pinout desta placa abaixo:

A placa tem um conector JST de 2 pinos para ligar a bateria LiPo. Mas também há dois pinos (BAT+ e BAT-) onde podes ligar a bateria. A faixa de tensão de entrada está entre 2.5V e 4.5V . A tensão nominal de uma bateria LiPo de célula única é cerca de 3.7V. Totalmente carregada, a tensão é cerca de 4.2V. Portanto, uma célula única LiPo está dentro da faixa de tensão de entrada.
A alimentação da placa é fornecida via os pinos VCC e GND. O máximo VCC é 5.5V, mas o recomendado é 3.3V. Note que existem diferentes versões da placa com opções diferentes (bateria ou MCU) para fornecer VCC. Recomendo que uses os 3.3V do teu microcontrolador.
O pino ALT é o pino de alerta. Este pino está normalmente em HIGH, mas passa para LOW se a carga relativa da bateria cair abaixo de um limiar percentual configurável, por exemplo 10%. Podes ligar este pino a um pino de interrupção do teu microcontrolador para reagir a níveis baixos de bateria.
O pino QST é para entrada de arranque rápido. Permite reiniciar o MAX17043 por hardware. Uma transição de subida neste pino inicia um reset por hardware. Mas também podes reiniciar via software, que é o que vamos fazer.
Interface I2C
SDA e SCL são os pinos para a interface I2C. O endereço I2C do MAX17043 é 0x36 . A placa breakout tem dois resistores pull-up de 2.2kΩ ligados às linhas SDA e SCL, por isso não precisas de resistores pull-up separados.
Note que há um jumper de 3 pads na parte inferior da placa. Podes cortar os jumpers para desativar os resistores pull-up, se ligares múltiplos dispositivos I2C. Para mais detalhes vê o max1704 Guide .

E é tudo sobre o MAX17043. A seguir, vamos ver as bibliotecas disponíveis para ler dados do IC MAX170X.
Bibliotecas MAX170X
Existem muitas bibliotecas para usar o MAX17043 com ESP32/ESP8266 ou Arduino. Nomeadamente, as bibliotecas de Porrey , Lucadentella , Sparkfun , Adafruit e Nlamprian . Todas são essencialmente wrappers em torno da funcionalidade do chip MAX1704X e são muito semelhantes.
Experimentei a biblioteca da Sparkfun e a biblioteca do Porrey. Ambas funcionaram, mas neste tutorial vou mostrar código exclusivamente baseado na biblioteca do Porrey. No entanto, se preferires outra, deve ser bastante simples trocar.
Funções da biblioteca MAX170X
Aqui está uma visão rápida das funções que vais encontrar na biblioteca MAX170X do Porrey:
| begin(TwoWire*) | Cria uma instância FuelGauge. |
| uint8_t address(); | Devolve o endereço I2C do IC. |
| float voltage(); | Devolve uma medição da tensão da bateria em milivolts |
| float percent(); | Devolve o estado de carga (SOC) da bateria em percentagem. |
| uint16_t version(); | Devolve a versão do IC MAX170X. |
| uint8_t compensation(); | Devolve um valor usado para otimizar o desempenho do IC em diferentes condições de operação |
| void compensation(uint8_t); | Define um valor para otimizar o desempenho do IC em diferentes condições de operação |
| bool sleep(); | Força o IC MAX170X a modo de suspensão. Todas as operações são interrompidas |
| bool isSleeping(); | Devolve se o IC MAX170X está ou não em modo de suspensão |
| bool wake(); | Desperta o IC MAX170X do modo de suspensão |
| void reset(); | Reinicia o IC MAX170X |
| void quickstart(); | Reinicia os cálculos de carga da bateria |
| bool alertIsActive(); | Devolve se um alerta de bateria fraca está ativo |
| void clearAlert(); | Limpa o alerta de bateria fraca |
| uint8_t threshold(); | Devolve o limiar atual para o alerta, por exemplo 20% |
| void threshold(uint8_t); | Define o limiar para o alerta, por exemplo 20% |
Instalação da biblioteca MAX170X
Para install a biblioteca MAX170X do Porrey, abre o Library Manager e escreve “MAX1704X” na caixa de pesquisa. Vais encontrar a “MAX1704X by Daniel Porrey”. Vê abaixo:

Pressiona o botão INSTALL e está feito. Como podes ver na captura de ecrã acima, já tenho a biblioteca instalada. Podes instalar as outras bibliotecas, por exemplo a da Sparkfun ou Adafruit, se quiseres. Não entram em conflito.
Nas próximas duas secções, mostro primeiro como ligar o MAX17043 ao teu microcontrolador e depois como usar a biblioteca para ler dados da bateria.
Ligação do MAX17043 ao ESP32
Ligar o MAX17043 a um microcontrolador é muito simples. Primeiro liga 3.3V e GND do microcontrolador a VCC e GND do MAX17043 (fios vermelho e azul). Se tiveres um Arduino a 5V, também podes ligar 5V a VCC.

Depois liga a interface I2C (SCL, SDA). Os pinos padrão para I2C no ESP32 lite são 23 (SDA) e 19 (SCL). É o que está representado acima (fios verde e amarelo). No caso do Arduino, ligarias SDA -> A4 e SCL -> A5. Certifica-te de fazer estas ligações corretamente, pois é fácil confundi-las e a placa não funcionará.
Finalmente, ligamos a bateria LiPo. O positivo e o negativo da bateria são ligados aos conectores correspondentes do ESP32 e do MAX17043. O bom da placa ESP32 é que podes usá-la a bateria e ao mesmo tempo ligar a placa via cabo USB ao computador. Se estiver ligada, a bateria é carregada. O MAX17043 pode permanecer ligado durante a carga e continuará a reportar tensões e níveis de carga.
Note que houve relatos de que as placas MAX17043 de alguns fornecedores não funcionam. A minha placa do AliExpress funciona bem e a que está listada nas peças necessárias também deve funcionar. Contudo, não testei essa placa específica.
Ler a Carga da Bateria do MAX17043
O seguinte exemplo simples de código mostra como ler a tensão da bateria e a carga relativa usando o MAX17043. Dá uma vista rápida primeiro e depois discutimos o código em mais detalhe.
#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 Bibliotecas
Começamos por incluir a Wire e a MAX17043 biblioteca. A biblioteca Wire é necessária para configurar a interface I2C. Se tiveres um MAX17044, incluirias MAX17044.h em vez de MAX17043.h . A biblioteca MAX170X do Porrey tem ambos os ficheiros header.
Função Setup
Na função setup() , inicializamos a comunicação serial a 115200 baud. Depois iniciamos a comunicação I2C usando a função Wire.begin(SDA, SCL) .
Defino explicitamente os pinos para I2C usando Wire.begin(SDA, SCL) . Isto permite usar pinos diferentes dos pinos padrão para I2C e também suprime uma mensagem ” Wire.begin()" no monitor serial que a biblioteca normalmente cria (ver blog ).
De seguida, iniciamos o MAX17043 via FuelGauge.begin(&Wire) . Se o sensor FuelGauge não for encontrado, uma mensagem é impressa no monitor serial e o programa entra num ciclo infinito.
Caso contrário, reiniciamos o FuelGauge seguido de um atraso de 250ms e fazemos um quickstart seguido de um atraso de 125ms. Esta sequência vem do código de exemplo que acompanha a biblioteca MAX17043. Não tenho a certeza se estes atrasos são necessários, mas deixei-os.
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);
}
Função Loop
A função loop() lê continuamente a tensão e a percentagem de carga da bateria LiPo. Os valores de tensão e percentagem são depois impressos no monitor serial usando Serial.printf() com um atraso de 3 segundos entre cada leitura.
void loop() {
float volts = FuelGauge.voltage();
float pcnt = FuelGauge.percent();
Serial.printf("%.0fmV (%.1f%%)\n", volts, pcnt);
delay(3000);
}
Se carregares e executares este código, deverás ver a seguinte saída no teu Monitor Serial:

Note que o Arduino, ao contrário do ESP32, não suporta a função printf . Terás de usar uma sequência de instruções print() em vez disso. Para evitar isso, vamos usar a biblioteca aprintf nos exemplos de código seguintes. Para mais detalhes, vê o nosso tutorial How To Print To Serial Monitor On Arduino .
Imprimir mais Dados com aprintf
O seguinte exemplo de código imprime toda a informação que podemos obter do chip MAX17043 no Monitor Serial. A estrutura do código é igual à anterior, mas há algumas pequenas alterações que quero 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);
}
Primeiro, em vez de usar o objeto FuelGauge predefinido, podes criar o teu próprio objeto de monitorização de carga:
MAX1704X monitor = MAX1704X(MAX17043_mV);
No construtor podes especificar se tens um MAX17043 ou um MAX17044 e depois usar o nome “monitor” ou outro que prefiras no resto do código.
Em segundo lugar, estou a usar a biblioteca aprintf para imprimir os dados no Monitor Serial. A função aprint() faz o mesmo que Serial.printf() mas funciona da mesma forma no Arduino, ESP32 e ESP8266. Também é útil para saída formatada para ecrãs – como vais ver na próxima secção.
No entanto, tens de instalar a biblioteca aprintf a partir de um ficheiro zip. Descarrega o zip-file e depois instala via Sketch -> Include Library -> Install .ZIP Library ... .

Para mais detalhes sobre aprintf e o Monitor Serial, vê o nosso tutorial How To Print To Serial Monitor On Arduino . Uma vez instalada, deverás conseguir executar o código e ver a seguinte saída no teu Monitor Serial:

Como podes inferir pela saída, a placa estava a carregar a LiPo (Tensão = 4120mV), já que para o Monitor Serial funcionar, o ESP32 precisa estar ligado via USB ao computador. No caso do ESP32 lite, isto carrega a bateria LiPo ligada.
Na próxima secção, vou mostrar como ligar um OLED e mostrar a informação da bateria lá, em vez do Monitor Serial.
Mostrar Carga da Bateria no OLED
Mostrar o nível de carga da bateria no Monitor Serial é bom para testes, mas não muito útil para um projeto alimentado a bateria. Normalmente queremos mostrar o nível atual da bateria diretamente. Isso pode ser uma barra de LEDs ou um ecrã LCD. Mas neste exemplo estou a usar um OLED, pois são muito pequenos e funcionam bem a 3.3V.
Ligação para OLED
O diagrama seguinte mostra como ligar o OLED (para além das peças já existentes) ao projeto. Começa por ligar 3.3V e GND do microcontrolador a VCC e GND do OLED (fios vermelho e azul).

Depois ligamos os fios I2C (SDA, SCL) em paralelo ao MAX17043 (fios amarelo e verde). O OLED e o MAX17043 partilham o mesmo barramento I2C e devem ter endereços I2C diferentes. Se tiveres problemas, verifica os endereços I2C. O meu OLED tem o endereço I2C 0x3C e o MAX17043 normalmente tem o endereço 0x36 . Também os resistores pull-up podem ser um problema. Lembra-te do jumper de 3 pads no MAX17043 que podes usar para desativar os resistores pull-up.
Se precisares de mais detalhes sobre como usar um ecrã OLED, vê o nosso tutorial sobre How to Interface the SSD1306 I2C OLED Graphic Display With Arduino .
Código para OLED
O código seguinte mostra a tensão da bateria e a carga relativa no OLED. Como sempre, dá uma vista rápida ao código completo antes de o analisarmos mais a fundo.
#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);
}
Bibliotecas e Configuração do Ecrã
O código inclui bibliotecas necessárias como Wire.h , aprintf.h , MAX17043.h , e Adafruit_SSD1306.h . Depois inicializa uma instância da classe Adafruit_SSD1306 para um ecrã OLED com dimensões específicas. Estou a usar um OLED 128×64 aqui. Se o teu OLED for de tamanho diferente, terás de ajustar os valores.
Adafruit_SSD1306 disp(128, 64, &Wire, -1);
Função Setup
Na função setup() , a comunicação serial é iniciada a 115200 baud. A comunicação I2C é iniciada usando a função Wire.begin(SDA, SCL) . O código verifica se o IC MAX17043 é detetado e, se não, imprime uma mensagem e entra num ciclo infinito. Depois o indicador de carga é reiniciado e é feito um quick start.
Também definimos um limiar para aviso de bateria fraca chamando FuelGauge.threshold(20) . Isto significa que o limiar para o alerta de bateria fraca está definido para 20%. O nível máximo que podes definir é 32% e o mínimo é 1%. Depois limpamos todos os alertas existentes.
FuelGauge.threshold(20); FuelGauge.clearAlert();
Finalmente, inicializamos o ecrã OLED. Certifica-te de usar o endereço I2C do teu OLED aqui. O meu é 0x3C e tenho um OLED a preto e branco, por isso defini a cor do texto para WHITE.
disp.begin(SSD1306_SWITCHCAPVCC, 0x3C); disp.setTextSize(2); disp.setTextColor(WHITE);
Função Loop
A função loop() lê continuamente a tensão da bateria e o nível percentual usando as funções FuelGauge.voltage() e FuelGauge.percent() . Também verifica se algum alerta está ativo usando FuelGauge.alertIsActive() .
float volts = FuelGauge.voltage() / 1000; float pcnt = FuelGauge.percent(); bool alrt = FuelGauge.alertIsActive();
A informação da bateria é impressa no OLED usando a função fmt() da biblioteca aprintf e a função display() da biblioteca Adafruit_SSD1306 .
A função fmt() funciona como Serial.printf() mas imprime para um buffer de string que é depois retornado. A função disp.print() do OLED usa esse buffer de string e mostra o conteúdo no OLED.
disp.clearDisplay();
disp.setCursor(20, 10);
disp.print(fmt("%.1f%% %c", pcnt, alrt ? '!' : ' '));
disp.setCursor(20, 30);
disp.print(fmt("%.3fV", volts));
disp.display();
Com a função fmt() podes usar a mesma formatação e imprimir convenientemente para dispositivos que não suportam uma função tipo printf() . No entanto, para o OLED não te esqueças do disp.display() no final, caso contrário nada será mostrado.
O OLED vai mostrar a percentagem da bateria, a tensão e um indicador de alerta (!) se um alerta estiver ativo. Se tudo estiver ligado e implementado corretamente, deverás ver a seguinte saída:

Neste exemplo mostramos um alerta de bateria fraca no OLED ao verificar o estado do pino de alerta a cada 3 segundos. Alternativamente, podemos usar um handler de interrupção para reagir imediatamente a um alerta de bateria fraca. Este é o tema da próxima secção.
Gestão de Alertas de Bateria Fraca do MAX17043
Para demonstrar a gestão do evento de bateria fraca, vamos adicionar um LED ao circuito. Este LED acenderá se a carga da bateria cair abaixo de um limiar pré-definido.
Ligamos o lado positivo (pino longo) do LED ao GPIO 25 do ESP32. Podes escolher outro GPIO que queiras – só não te esqueças de alterar o código abaixo em conformidade. O lado negativo do LED é ligado ao GND (G) através de um resistor limitador de corrente de 68Ω.

Agora vem a parte interessante. O MAX17043 vai gerar um sinal no pino ALT quando a carga da bateria cair abaixo do limiar. Mais precisamente, o pino ALT vai passar de HIGH para LOW. Ligamos o pino ALT ao GPIO 32 do ESP32 e um handler de interrupção será chamado se o estado do pino ALT mudar.
Vamos ver como isso é feito no código!
Código para Handler de Interrupção de Bateria Fraca
A maioria dos microcontroladores, incluindo o ESP32, permite anexar uma função handler de interrupção a um pino. Isto faz com que a função seja executada quando o pino muda de estado. O código abaixo é o mesmo de antes com a adição de uma função handler de interrupção lowBattery() . Há também uma definição adicional para um ledPin e alrtPin , que precisamos para mostrar e detetar um alerta de bateria fraca.
Abaixo está o código completo e vamos discutir os seus detalhes nas secções seguintes:
#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 e Variáveis
Como mencionado acima, definimos primeiro duas novas constantes, alrtPin e ledPin , que representam os pinos para o sinal de alerta e o indicador LED respetivamente.
const int alrtPin = 32; const int ledPin = 25;
Função de Bateria Fraca
A função lowBattery() é chamada quando a carga da bateria cai abaixo de um certo limiar. Simplesmente liga o LED ligado ao pino ledPin . Note que o LED ficará ligado até o ESP32 ser reiniciado, mesmo que a carga da bateria volte a um nível acima do limiar. Mas é fácil mudar este comportamento, se precisares de algo diferente.
void lowBattery() {
digitalWrite(ledPin, HIGH);
}
Função Setup
Na função setup() , o código inicializa a comunicação serial, o barramento I2C, o Fuel Gauge MAX17043, o ecrã OLED e configura os modos dos pinos para o LED e o sinal de alerta.
Mais importante, também configura a interrupção para disparar a função lowBattery() na borda de descida. Isto significa que se o pino ALT do MAX17043 ficar baixo devido a uma carga baixa da bateria, detetamos essa borda de descida no pino alrtPin e chamamos a função lowBattery() . Note que a função lowBattery() é chamada independentemente da função loop() .
void setup() {
...
attachInterrupt(alrtPin, lowBattery, FALLING);
}
Se quiseres aprender mais sobre interrupções, vê os nossos tutoriais Push-Button And Arduino e Build Arduino Tachometer Using A3144 Hall Effect Sensor que têm mais aplicações e detalhes.
Função Loop
A função loop() é igual à anterior. Lê continuamente a tensão da bateria, a percentagem de carga e o estado do alerta do IC MAX17043. Depois atualiza o ecrã OLED com esta informação e verifica se há alertas. Se um alerta estiver ativo, mostra um ponto de exclamação ao lado da percentagem da bateria.
A diferença importante entre o alerta mostrado no OLED e o sinalizado pelo LED vermelho é que o OLED é atualizado apenas a cada 3 segundos, enquanto o LED reage imediatamente.
E é isso. Com estes circuitos e código podes monitorizar níveis de carga da bateria com precisão e reagir rapidamente a alertas de bateria fraca.
Conclusões
O MAX1704X é um pequeno IC muito útil para monitorizar níveis de carga de bateria em projetos alimentados a bateria. As duas versões, MAX17043 e MAX17044, são essencialmente iguais. O código e os circuitos apresentados acima funcionam da mesma forma para ambos. A única diferença é que o MAX17043 é desenhado para monitorizar níveis de carga de uma única LiPo (3.7V), enquanto o MAX17044 é usado quando duas LiPo (7.4V) são usadas em série.
Uma funcionalidade do MAX1704X que não abordámos neste tutorial é a função de compensação. Aparentemente, pode otimizar o desempenho do IC para diferentes químicas de lítio ou diferentes temperaturas de operação. Mas não há informação sobre os detalhes e que valores usar para compensação no datasheet.
No entanto, outra funcionalidade interessante do MAX1704X que está documentada é o modo de suspensão. Isto é útil em conjunto com o modo deep sleep do ESP32 (ou Arduino/ESP8266). Permite colocar tanto o microcontrolador como o monitor de bateria em deep sleep para prolongar a vida da bateria.
Como alternativa ao MAX1704X, podes usar um divisor de tensão e medir a tensão da bateria via uma entrada analógica para implementar um sistema simples de aviso de bateria fraca. Para mais detalhes sobre isso, vê o nosso tutorial How to Monitor Battery Voltage for Battery Powered Projects . Esta é uma abordagem mais barata, mas muito menos fiável, especialmente se quiseres estimar o tempo restante e recarregar a tempo.
E agora diverte-te ; )
Links
Aqui estão alguns links que achei úteis ao escrever 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)
Perguntas Frequentes
Quão preciso é o MAX1704X Fuel Gauge na monitorização dos níveis de carga da bateria?
O MAX1704X Fuel Gauge é altamente preciso, com um erro típico de apenas ±1% em toda a faixa de temperatura.
O MAX1704X pode ser usado com outros microcontroladores além do ESP32 e Arduino?
Sim, o MAX1704X pode ser usado com vários microcontroladores desde que suportem comunicação I2C.
É possível personalizar o limiar de alerta de bateria fraca no MAX1704X?
Sim, o limiar de alerta de bateria fraca pode ser personalizado para se adequar às tuas necessidades específicas ajustando os valores do registo correspondente. No entanto, o limiar máximo é 32% e o mínimo é 1%.
O MAX1704X pode ser usado com diferentes tipos de baterias além de LiPo?
Embora o MAX1704X seja otimizado para baterias LiPo, também pode ser usado com outros tipos de baterias com alguns ajustes nas configurações.
Como é alimentado o MAX1704X Fuel Gauge?
O MAX1704X Fuel Gauge pode ser alimentado diretamente pela bateria que está a monitorizar, mas recomendo alimentá-lo pelo microcontrolador.
O MAX1704X pode monitorizar várias baterias simultaneamente?
Não, o MAX1704X foi desenhado para monitorizar uma única bateria de cada vez.
Qual é a interface de comunicação usada pelo MAX1704X Fuel Gauge?
O MAX1704X Fuel Gauge comunica com o microcontrolador usando a interface I2C.
É possível calibrar o MAX1704X para maior precisão?
Sim, o MAX1704X pode ser calibrado usando comandos de software para melhorar a precisão com base nos requisitos específicos da aplicação. Vê a função compensation() da biblioteca MAX1704X e o datasheet do MAX1704X .
Como o MAX1704X lida com a proteção contra sobrecarga da bateria?
O MAX1704X não fornece proteção contra sobrecarga por si só, mas pode monitorizar o nível de carga da bateria para ajudar a evitar sobrecarga quando usado em conjunto com circuitos de carregamento apropriados.
Como o MAX1704X lida com a proteção contra descarga da bateria?
O MAX1704X não fornece proteção contra descarga da bateria, mas pode monitorizar o nível de carga para ajudar a evitar descarga profunda quando integrado com sistemas de gestão de energia adequados.
Qual é a faixa típica de tensão de operação do MAX1704X Fuel Gauge?
O MAX1704X opera numa faixa típica de tensão de 2.7V a 5.5V; adequado para monitorizar a tensão típica de uma bateria LiPo (3.7V).
Qual é o consumo de corrente do MAX1704X Fuel Gauge?
O consumo típico de corrente do MAX1704X é 50µA e tem um modo de suspensão com consumo ainda menor de 1µA.

