In questo tutorial imparerai come monitorare i livelli di carica di una batteria LiPo usando il MAX1704X. Gli esempi hardware e di codice sono per un ESP32 ma funzionano allo stesso modo per ESP8266 o Arduino.
Le batterie LiPo sono ottime per progetti alimentati a batteria e sono comunemente usate in applicazioni esterne o mobili come monitoraggio meteo, sorveglianza o robotica. Ma usare batterie significa dover sapere quando ricaricarle.
Stimare la carica di una batteria LiPo e il tempo di funzionamento residuo è però sorprendentemente difficile. Le batterie LiPo hanno curve di scarica altamente non lineari con un calo molto improvviso alla fine. Dai un’occhiata alla seguente curva di scarica.

Peggio ancora, la curva di scarica dipende dalla temperatura ambiente e dalla corrente prelevata dalla batteria. Questo rende molto difficile ottenere stime accurate sulla carica relativa e sul tempo di funzionamento residuo di una batteria LiPo.
Il MAX17043 è un avanzato fuel gauge per batterie sviluppato per risolvere questo problema. In questo tutorial imparerai come usare il MAX17043 per misurare la tensione e la carica relativa di una batteria LiPo con un ESP32. Ti mostrerò anche come configurare e gestire gli avvisi di batteria scarica.
Ma iniziamo con i componenti necessari.
Componenti necessari
Per questo tutorial uso una vecchia scheda ESP32 (ESP32 lite), ormai deprecata ma ancora reperibile a basso costo. È quella elencata qui sotto. Esiste un modello successore con specifiche migliorate, che puoi trovare here .
Ma la maggior parte delle schede ESP8266 e altre ESP32 dovrebbe funzionare ugualmente. Mi piace l’ESP32 lite per il prezzo basso e il connettore batteria con capacità di ricarica integrata. Questo significa che puoi alimentare l’ESP32 a batteria e ricaricare la LiPo tramite la porta USB – molto comodo.
Se vuoi usare un Arduino, dovresti scegliere una scheda che funzioni a 3.3V come la Arduino Pro Mini (ATmega328-3.3V ), dato che useremo una singola batteria LiPo (3.7V). Ho anche elencato un OLED ma qualsiasi display che supporti la comunicazione I2C e funzioni a 3.3V andrà bene.
Esistono due versioni del MAX1704X. Il MAX1704 3 elencato qui è per una singola cella LiPo, mentre il MAX1704 4 è per due celle LiPo (in serie). Tuttavia, non sono riuscito a trovare una breakout board per il MAX1704 4 da nessuna parte e useremo quindi il MAX1704 3 . Ma questo significa che ti serve un microcontrollore che funzioni a 3.3V o un buck booster per generare tensioni più alte.

MAX17043 LiPo Fuel Gauge

ESP32 lite

Cavo dati USB

Set di fili Dupont

Breadboard

Kit resistori & LED

Display 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.
Specifiche del Fuel Gauge MAX1704X
Il MAX17043/MAX17044 è un sistema fuel gauge ultra-compatto per batterie al litio (Li+). Il chip vero e proprio è minuscolo e l’immagine sotto mostra una tipica breakout board per il chip, che rende molto più semplice il collegamento.

Esistono due versioni del chip. Il MAX17043 è configurato per misurare la carica di una singola cella al litio, mentre il MAX17044 è configurato per un pacco a due celle 2S. Il chip usa uno schema di modellazione della batteria LiPo, chiamato ModelGauge, per tracciare continuamente lo stato relativo di carica (SOC) della batteria su un profilo di carica/scarica molto variabile.
Ecco le specifiche secondo il datasheet del MAX17043/MAX17044 :
- Tipo di batteria: batteria Li-polimeri/Li-ion 3.7V
- 1 cella (MAX17043) o 2 celle (MAX17044)
- Misurazione precisa della tensione
- Precisione ±12.5mV per 5V (MAX17043)
- Precisione ±30mV per 10V (MAX17044)
- Capacità relativa accurata (RSOC)
- Nessuna accumulazione di offset nella misurazione
- Nessuna necessità di ricalibrazione da pieno a vuoto della batteria
- Allarme/interrupt esterno per avviso batteria scarica
- Interfaccia I2C
- Corrente operativa: 50 µA
- Tensione di ingresso (VCC): 3.3V~6.0V
Pinout
Come detto, il MAX1704X è un IC molto piccolo e usiamo quindi la breakout board elencata tra i componenti necessari. Qui sotto trovi il pinout di questa scheda:

La scheda ha un connettore JST a 2 pin per collegare la batteria LiPo. Ci sono anche due pin (BAT+ e BAT-) dove puoi collegare la batteria. L’intervallo di tensione in ingresso è tra 2.5V e 4.5V . La tensione nominale di una singola cella LiPo è circa 3.7V. Completamente carica, la tensione è intorno a 4.2V. Quindi una singola cella LiPo rientra nell’intervallo di tensione in ingresso.
L’alimentazione della scheda è fornita tramite i pin VCC e GND. Il massimo VCC è 5.5V ma si raccomanda 3.3V. Nota che esistono diverse versioni della scheda con opzioni diverse (batteria o MCU) su come fornire VCC. Ti consiglio di usare i 3.3V del tuo microcontrollore.
Il pin ALT è il pin di allarme. Questo pin è normalmente HIGH ma diventa LOW se la carica relativa della batteria scende sotto una soglia percentuale configurabile, ad esempio il 10%. Puoi collegare questo pin a un pin di interrupt del microcontrollore per reagire a livelli di batteria bassi.
Il pin QST è per l’input quick-start. Permette di resettare il MAX17043 via hardware. Un fronte di salita su questo pin avvia un reset hardware. Ma puoi anche resettare via software, ed è quello che faremo.
Interfaccia I2C
SDA e SCL sono i pin per l’interfaccia I2C. L’indirizzo I2C del MAX17043 è 0x36 . La breakout board ha due resistenze di pull-up da 2.2kΩ collegate alle linee SDA e SCL, quindi non servono resistenze di pull-up separate.
Nota che c’è un jumper a 3 pad nella parte inferiore della scheda. Puoi tagliare i jumper per disabilitare le resistenze di pull-up, se colleghi più dispositivi I2C. Per maggiori dettagli dai un’occhiata al max1704 Guide .

E questo è tutto sul MAX17043. Ora diamo un’occhiata alle librerie disponibili per leggere i dati dal chip MAX170X.
Librerie MAX170X
Esistono molte librerie per usare il MAX17043 con ESP32/ESP8266 o Arduino. In particolare, ci sono le librerie di Porrey , Lucadentella , Sparkfun , Adafruit e Nlamprian . Sono tutte essenzialmente wrapper attorno alle funzionalità del chip MAX1704X e molto simili.
Ho provato la libreria Sparkfun e quella di Porrey. Entrambe funzionano ma in questo tutorial ti mostrerò esclusivamente codice basato sulla libreria di Porrey. Comunque, se preferisci un’altra, dovrebbe essere abbastanza semplice sostituirla.
Funzioni della libreria MAX170X
Ecco una rapida panoramica delle funzioni che trovi nella libreria MAX170X di Porrey:
| begin(TwoWire*) | Crea un’istanza FuelGauge. |
| uint8_t address(); | Restituisce l’indirizzo I2C del chip. |
| float voltage(); | Restituisce la misura della tensione della batteria in millivolt |
| float percent(); | Restituisce lo stato di carica (SOC) della batteria in percentuale. |
| uint16_t version(); | Restituisce la versione del chip MAX170X. |
| uint8_t compensation(); | Restituisce un valore usato per ottimizzare le prestazioni del chip in diverse condizioni operative |
| void compensation(uint8_t); | Imposta un valore per ottimizzare le prestazioni del chip in diverse condizioni operative |
| bool sleep(); | Mette il chip MAX170X in modalità sleep. Tutte le operazioni sono sospese |
| bool isSleeping(); | Restituisce se il chip MAX170X è in modalità sleep |
| bool wake(); | Riattiva il chip MAX170X dalla modalità sleep |
| void reset(); | Resetta il chip MAX170X |
| void quickstart(); | Riavvia i calcoli della carica della batteria |
| bool alertIsActive(); | Restituisce se un avviso di batteria scarica è attivo |
| void clearAlert(); | Cancella l’avviso di batteria scarica |
| uint8_t threshold(); | Restituisce la soglia corrente per l’avviso, es. 20% |
| void threshold(uint8_t); | Imposta la soglia per l’avviso, es. 20% |
Installazione della libreria MAX170X
Per install la libreria MAX170X di Porrey apri il Library Manager e digita “MAX1704X” nella casella di ricerca. Troverai “MAX1704X by Daniel Porrey”. Vedi sotto:

Premi il pulsante INSTALL e hai finito. Come vedi nello screenshot sopra, ho già la libreria installata. Puoi installare anche le altre librerie, ad esempio Sparkfun o Adafruit, se vuoi. Non creano conflitti.
Nelle prossime due sezioni ti mostro prima come collegare il MAX17043 al microcontrollore e poi come usare la libreria per leggere i dati della batteria.
Collegare MAX17043 a ESP32
Collegare il MAX17043 a un microcontrollore è molto semplice. Prima collega 3.3V e GND del microcontrollore a VCC e GND del MAX17043 (fili rosso e blu). Se hai un Arduino a 5V, puoi anche collegare 5V a VCC.

Poi collega l’interfaccia I2C (SCL, SDA). I pin di default per I2C sull’ESP32 lite sono 23 (SDA) e 19 (SCL). Questo è mostrato sopra (fili verde e giallo). Nel caso di Arduino, collegheresti SDA -> A4 e SCL -> A5. Assicurati di collegarli correttamente, perché è facile confonderli e la scheda non funzionerà.
Infine colleghiamo la batteria LiPo. Il positivo e il negativo della batteria sono collegati ai connettori corrispondenti dell’ESP32 e del MAX17043. La cosa bella della scheda ESP32 è che puoi alimentarla dalla batteria e allo stesso tempo collegare la scheda al computer tramite cavo USB. Se è collegata, la batteria si ricarica. Il MAX17043 può rimanere connesso durante la ricarica e continuerà a riportare tensioni e livelli di carica.
Nota che ci sono segnalazioni che alcune schede MAX17043 di certi fornitori non funzionano. La mia scheda da AliExpress funziona bene e quella elencata tra i componenti dovrebbe andare bene. Però non ho testato quella specifica.
Lettura della carica della batteria dal MAX17043
Il seguente semplice esempio di codice ti mostra come leggere la tensione della batteria e la carica relativa usando il MAX17043. Dai un’occhiata veloce e poi discutiamo il codice più nel dettaglio.
#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);
}
Inclusione librerie
Iniziamo includendo la Wire e la MAX17043 libreria. La libreria Wire serve per configurare l’interfaccia I2C. Se hai un MAX17044, includeresti MAX17044.h invece di MAX17043.h . La libreria MAX170X di Porrey ha entrambi gli header file.
Funzione setup
Nella funzione setup() inizializziamo la comunicazione seriale a 115200 baud. Poi avviamo la comunicazione I2C usando la funzione Wire.begin(SDA, SCL) .
Definisco esplicitamente i pin per I2C usando Wire.begin(SDA, SCL) . Questo ti permette di usare pin diversi da quelli di default per I2C e sopprime anche un messaggio ” Wire.begin()" ” sul monitor seriale che altrimenti la libreria genera (vedi blog ).
Poi iniziamo il MAX17043 con FuelGauge.begin(&Wire) . Se il sensore FuelGauge non viene trovato, viene stampato un messaggio sul monitor seriale e il programma entra in un loop infinito.
Altrimenti resettiamo il FuelGauge seguito da un ritardo di 250ms e facciamo un quickstart seguito da un ritardo di 125ms. Questa sequenza è presa dal codice di esempio della libreria MAX17043. Non sono del tutto sicuro che questi ritardi siano necessari ma li ho lasciati.
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);
}
Funzione loop
La funzione loop() legge continuamente la tensione e la percentuale di carica della batteria LiPo. I valori di tensione e percentuale sono poi stampati sul monitor seriale usando Serial.printf() con un ritardo di 3 secondi tra ogni lettura.
void loop() {
float volts = FuelGauge.voltage();
float pcnt = FuelGauge.percent();
Serial.printf("%.0fmV (%.1f%%)\n", volts, pcnt);
delay(3000);
}
Se carichi ed esegui questo codice dovresti vedere il seguente output sul tuo Monitor Serial:

Nota che Arduino, a differenza dell’ESP32, non supporta la funzione printf . Dovrai usare una sequenza di istruzioni print() invece. Per evitare questo, useremo la libreria aprintf nei prossimi esempi di codice. Per maggiori dettagli dai un’occhiata al nostro tutorial How To Print To Serial Monitor On Arduino .
Stampare più dati con aprintf
Il seguente esempio di codice stampa tutte le informazioni che possiamo ottenere dal chip MAX17043 sul Monitor Serial. La struttura del codice è la stessa di prima, ma ci sono alcune piccole modifiche che voglio evidenziare.
#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);
}
Innanzitutto, invece di usare l’oggetto FuelGauge predefinito puoi creare il tuo oggetto monitor di carica:
MAX1704X monitor = MAX1704X(MAX17043_mV);
Nel costruttore puoi specificare se hai un MAX17043 o un MAX17044 e poi usare il nome “monitor” o qualsiasi altro nome ti piaccia per il resto del codice.
In secondo luogo, uso la libreria aprintf per stampare i dati sul Monitor Serial. La funzione aprint() fa la stessa cosa di Serial.printf() ma funziona allo stesso modo su Arduino, ESP32 e ESP8266. È anche utile per output formattati su display – come vedrai nella prossima sezione.
Tuttavia, devi installare la libreria aprintf da un file zip. Scarica il zip-file e poi installala tramite Sketch -> Include Library -> Install .ZIP Library ... .

Per maggiori dettagli su aprintf e il Monitor Serial dai un’occhiata al nostro tutorial How To Print To Serial Monitor On Arduino . Una volta installata dovresti poter eseguire il codice e vedere il seguente output sul Monitor Serial:

Come puoi dedurre dall’output, la scheda stava caricando la LiPo (Tensione = 4120mV), dato che per far funzionare il Monitor Serial l’ESP32 deve essere collegato via USB al computer. Nel caso dell’ESP32 lite, questo carica la batteria LiPo collegata.
Nella prossima sezione ti mostro come collegare un OLED e visualizzare lì le informazioni della batteria, invece che sul Monitor Serial.
Visualizzare la carica della batteria su OLED
Visualizzare il livello di carica della batteria sul Monitor Serial va bene per i test ma non è molto utile per un progetto alimentato a batteria. Di solito vogliamo mostrare il livello corrente della batteria in modo diretto. Può essere una barra LED o un display LCD. Ma in questo esempio uso un OLED, perché sono molto piccoli e funzionano bene a 3.3V.
Collegamenti per OLED
Il diagramma seguente mostra come collegare l’OLED (in aggiunta ai componenti già presenti) al progetto. Inizia collegando 3.3V e GND dal microcontrollore a VCC e GND dell’OLED (fili rosso e blu).

Poi colleghiamo i fili I2C (SDA, SCL) in parallelo al MAX17043 (fili giallo e verde). L’OLED e il MAX17043 condividono lo stesso bus I2C e devono avere indirizzi I2C diversi. Se hai problemi, controlla gli indirizzi I2C. Il mio OLED ha indirizzo I2C 0x3C e il MAX17043 tipicamente ha indirizzo 0x36 . Anche le resistenze di pull-up potrebbero essere un problema. Ricorda il jumper a 3 pad sul MAX17043 che puoi usare per disabilitare le resistenze di pull-up.
Se ti servono più dettagli su come usare un display OLED dai un’occhiata al nostro tutorial su How to Interface the SSD1306 I2C OLED Graphic Display With Arduino .
Codice per OLED
Il codice seguente mostra la tensione della batteria e la carica relativa sull’OLED. Come al solito, dai prima un’occhiata al codice completo prima di analizzarlo più nel dettaglio.
#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);
}
Librerie e configurazione display
Il codice include le librerie necessarie come Wire.h , aprintf.h , MAX17043.h , e Adafruit_SSD1306.h . Inizializza poi un’istanza della classe Adafruit_SSD1306 per un display OLED con dimensioni specifiche. Io uso un OLED 128×64. Se il tuo OLED ha dimensioni diverse, dovrai adattare i valori.
Adafruit_SSD1306 disp(128, 64, &Wire, -1);
Funzione setup
Nella funzione setup() la comunicazione seriale è avviata a 115200 baud. La comunicazione I2C è iniziata usando la funzione Wire.begin(SDA, SCL) . Il codice verifica se il chip MAX17043 è rilevato, altrimenti stampa un messaggio ed entra in un loop infinito. Poi il fuel gauge è resettato e viene fatto un quick start.
Impostiamo anche una soglia per l’avviso di batteria scarica chiamando FuelGauge.threshold(20) . Questo significa che la soglia per l’avviso batteria scarica è impostata al 20%. Il livello massimo impostabile è 32% e il minimo 1%. Dopo puliamo tutti gli avvisi esistenti.
FuelGauge.threshold(20); FuelGauge.clearAlert();
Infine inizializziamo il display OLED. Assicurati di usare l’indirizzo I2C del tuo OLED qui. Il mio è 0x3C e ho un OLED bianco e nero, quindi imposto il colore del testo su WHITE.
disp.begin(SSD1306_SWITCHCAPVCC, 0x3C); disp.setTextSize(2); disp.setTextColor(WHITE);
Funzione loop
La funzione loop() legge continuamente la tensione della batteria e la percentuale usando le funzioni FuelGauge.voltage() e FuelGauge.percent() . Controlla anche se ci sono avvisi attivi usando FuelGauge.alertIsActive() .
float volts = FuelGauge.voltage() / 1000; float pcnt = FuelGauge.percent(); bool alrt = FuelGauge.alertIsActive();
Le informazioni della batteria sono stampate sull’OLED usando la funzione fmt() della libreria aprintf e la funzione display() della libreria Adafruit_SSD1306 .
La funzione fmt() funziona come Serial.printf() ma stampa su un buffer stringa che viene poi restituito. La funzione disp.print() dell’OLED prende questo buffer stringa e mostra il contenuto sull’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();
Con la funzione fmt() puoi usare la stessa formattazione e stampare comodamente su dispositivi che non supportano una funzione simile a printf() . Però, per l’OLED non dimenticare il disp.display() alla fine, altrimenti non verrà mostrato nulla.
L’OLED mostrerà la percentuale di batteria, la tensione e un indicatore di allarme (!) se un avviso è attivo. Se tutto è collegato e implementato correttamente dovresti vedere il seguente output:

In questo esempio abbiamo mostrato un avviso di batteria scarica sull’OLED interrogando lo stato del pin di allarme ogni 3 secondi. In alternativa, possiamo usare un gestore di interrupt per reagire immediatamente a un avviso di batteria scarica. Questo è l’argomento della prossima sezione.
Gestione degli avvisi di batteria scarica del MAX17043
Per dimostrare la gestione dell’evento batteria scarica aggiungiamo un LED al circuito. Questo LED si accenderà se la carica della batteria scende sotto una soglia predefinita.
Colleghiamo il lato positivo (pin lungo) del LED al GPIO 25 dell’ESP32. Puoi scegliere qualsiasi altro GPIO ti piaccia – basta che cambi il codice di conseguenza. Il lato negativo del LED è collegato a GND (G) tramite una resistenza di limitazione corrente da 68Ω.

Ora arriva la parte interessante. Il MAX17043 genererà un segnale sul pin ALT quando la carica della batteria scende sotto la soglia. Più precisamente il pin ALT passerà da HIGH a LOW. Colleghiamo il pin ALT al GPIO 32 dell’ESP32 e un gestore di interrupt sarà chiamato se lo stato del pin ALT cambia.
Vediamo come si fa in codice!
Codice per gestore interrupt batteria scarica
La maggior parte dei microcontrollori, incluso l’ESP32, permette di associare una funzione gestore di interrupt a un pin. Questo fa sì che la funzione venga eseguita quando il pin cambia stato. Il codice sotto è quello di prima con l’aggiunta di una funzione gestore di interrupt lowBattery() . C’è anche una definizione aggiuntiva per un ledPin e un alrtPin , necessari per mostrare e rilevare un avviso di batteria scarica.
Qui sotto trovi il codice completo e ne discuteremo i dettagli nelle sezioni seguenti:
#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);
}
Costanti e variabili
Come detto, definiamo prima due nuove costanti, alrtPin e ledPin , che rappresentano i pin per il segnale di allarme e l’indicatore LED rispettivamente.
const int alrtPin = 32; const int ledPin = 25;
Funzione batteria scarica
La funzione lowBattery() viene chiamata quando la carica della batteria scende sotto una certa soglia. Semplicemente accende il LED collegato a ledPin . Nota che il LED rimarrà acceso finché l’ESP32 non viene resettato, anche se la carica della batteria torna sopra la soglia. Ma è facile cambiare questo comportamento, se ti serve qualcosa di diverso.
void lowBattery() {
digitalWrite(ledPin, HIGH);
}
Funzione setup
Nella funzione setup() il codice inizializza la comunicazione seriale, il bus I2C, il Fuel Gauge MAX17043, il display OLED e imposta le modalità pin per il LED e il segnale di allarme.
Soprattutto, configura l’interrupt per attivare la funzione lowBattery() su un fronte di discesa. Questo significa che se il pin ALT del MAX17043 va basso a causa di batteria scarica, rileviamo questo fronte di discesa su alrtPin e chiamiamo la funzione lowBattery() . Nota che la funzione lowBattery() viene chiamata indipendentemente dalla funzione loop() .
void setup() {
...
attachInterrupt(alrtPin, lowBattery, FALLING);
}
Se vuoi saperne di più sugli interrupt dai un’occhiata ai nostri tutorial Push-Button And Arduino e Build Arduino Tachometer Using A3144 Hall Effect Sensor che hanno più applicazioni e dettagli.
Funzione loop
La funzione loop() è la stessa di prima. Legge continuamente la tensione della batteria, la percentuale di carica e lo stato dell’allarme dal chip MAX17043. Aggiorna poi il display OLED con queste informazioni e controlla eventuali avvisi. Se un avviso è attivo, mostra un punto esclamativo accanto alla percentuale di batteria.
La differenza importante tra l’avviso mostrato sull’OLED e quello segnalato tramite il LED rosso è che l’OLED si aggiorna solo ogni 3 secondi, mentre il LED reagisce immediatamente.
E questo è tutto. Con questi circuiti e codice puoi monitorare accuratamente i livelli di carica della batteria e reagire rapidamente agli avvisi di batteria scarica.
Conclusioni
Il MAX1704X è un piccolo IC molto utile per monitorare i livelli di carica delle batterie in progetti alimentati a batteria. Le due versioni, MAX17043 e MAX17044, sono essenzialmente uguali. Il codice e i circuiti presentati sopra funzionano allo stesso modo per entrambi. L’unica differenza è che il MAX17043 è progettato per monitorare la carica di una singola LiPo (3.7V), mentre il MAX17044 è usato quando si usano due LiPo (7.4V) in serie.
Una caratteristica del MAX1704X di cui non abbiamo parlato in questo tutorial è la funzione di compensazione. Apparentemente può ottimizzare le prestazioni del chip per diverse chimiche al litio o diverse temperature operative. Ma non ci sono informazioni specifiche su come usarla nel datasheet.
Tuttavia, un’altra bella caratteristica documentata del MAX1704X è la modalità sleep. È utile in combinazione con la modalità deep sleep dell’ESP32 (o Arduino/ESP8266). Permette di mettere sia il microcontrollore che il monitor batteria in deep sleep per estendere la durata della batteria.
In alternativa al MAX1704X, potresti usare un partitore di tensione e misurare la tensione della batteria tramite un ingresso analogico per implementare un semplice sistema di avviso batteria scarica. Per maggiori dettagli vedi il nostro tutorial How to Monitor Battery Voltage for Battery Powered Projects . Questo è un approccio più economico ma molto meno affidabile, specialmente se vuoi stimare il tempo residuo e ricaricare in tempo.
E ora divertiti ; )
Link
Ecco alcuni link che ho trovato utili mentre scrivevo questo 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)
Domande frequenti
Quanto è accurato il Fuel Gauge MAX1704X nel monitorare i livelli di carica della batteria?
Il Fuel Gauge MAX1704X è molto accurato, con un errore tipico di solo ±1% su tutta la gamma di temperature.
Il MAX1704X può essere usato con altri microcontrollori oltre a ESP32 e Arduino?
Sì, il MAX1704X può essere usato con vari microcontrollori purché supportino la comunicazione I2C.
È possibile personalizzare la soglia di avviso batteria scarica sul MAX1704X?
Sì, la soglia di avviso batteria scarica può essere personalizzata per adattarsi alle tue esigenze specifiche modificando i valori del registro corrispondente. Tuttavia, la soglia massima è 32% e la minima 1%.
Il MAX1704X può essere usato con tipi di batterie diversi dalle LiPo?
Sebbene il MAX1704X sia ottimizzato per batterie LiPo, può essere usato anche con altri tipi di batterie con alcune regolazioni nelle impostazioni di configurazione.
Come è alimentato il Fuel Gauge MAX1704X?
Il Fuel Gauge MAX1704X può essere alimentato direttamente dalla batteria che monitora, ma consiglio di alimentarlo dal microcontrollore.
Il MAX1704X può monitorare più batterie contemporaneamente?
No, il MAX1704X è progettato per monitorare una sola batteria alla volta.
Qual è l’interfaccia di comunicazione usata dal Fuel Gauge MAX1704X?
Il Fuel Gauge MAX1704X comunica con il microcontrollore usando l’interfaccia I2C.
È possibile calibrare il MAX1704X per una precisione ancora maggiore?
Sì, il MAX1704X può essere calibrato usando comandi software per migliorare la precisione in base alle esigenze specifiche dell’applicazione. Vedi la funzione compensation() della libreria MAX1704X e il datasheet del MAX1704X .
Come gestisce il MAX1704X la protezione da sovraccarico della batteria?
Il MAX1704X non fornisce protezione da sovraccarico di per sé, ma può monitorare il livello di carica della batteria per aiutare a prevenire il sovraccarico se usato insieme a circuiti di ricarica appropriati.
Come gestisce il MAX1704X la protezione da scarica eccessiva della batteria?
Il MAX1704X non fornisce protezione da scarica eccessiva, ma può monitorare il livello di carica per aiutare a prevenire scariche profonde se integrato con sistemi di gestione dell’alimentazione adeguati.
Qual è l’intervallo di tensione operativa tipico del Fuel Gauge MAX1704X?
Il MAX1704X opera in un intervallo di tensione tipico da 2.7V a 5.5V; adatto a monitorare la tensione tipica di una batteria LiPo (3.7V).
Qual è il consumo di corrente tipico del Fuel Gauge MAX1704X?
Il consumo di corrente tipico del MAX1704X è di 50µA e ha una modalità sleep con consumo ancora più basso di 1µA.

