Skip to Content

Surveillez le niveau de batterie avec le MAX1704X

Surveillez le niveau de batterie avec le MAX1704X

Dans ce tutoriel, vous allez apprendre à surveiller le niveau de charge d’une batterie LiPo à l’aide du MAX1704X. Le matériel et les exemples de code sont prévus pour un ESP32, mais fonctionnent aussi bien avec un ESP8266 ou un Arduino.

Les batteries LiPo sont idéales pour les projets alimentés sur batterie et sont couramment utilisées pour des applications extérieures ou mobiles comme la surveillance météo, la vidéosurveillance ou la robotique. Mais utiliser des batteries signifie qu’il faut savoir quand les recharger.

Estimer la charge restante d’une batterie LiPo et son autonomie est pourtant étonnamment difficile. Les batteries LiPo ont des courbes de décharge très non linéaires, avec une chute très brutale en fin de cycle. Regardez la courbe de décharge suivante.

Discharge Curve LiPo battery
Courbe de décharge d’une batterie LiPo

Pire encore, la courbe de décharge dépend de la température ambiante et du courant consommé par la batterie. Cela rend l’estimation de la charge restante et de l’autonomie d’une batterie LiPo très difficile.

Le MAX17043 est un jauge de batterie avancée développée pour résoudre ce problème. Dans ce tutoriel, vous apprendrez à utiliser le MAX17043 pour mesurer la tension et la charge relative d’une batterie LiPo avec un ESP32. Je vous montrerai aussi comment configurer et gérer les alertes de batterie faible.

Mais commençons par la liste du matériel nécessaire.

Overview

Matériel nécessaire

Pour ce tutoriel, j’utilise une ancienne carte ESP32 (ESP32 lite), qui n’est plus produite mais que l’on peut encore trouver à petit prix. C’est celle listée ci-dessous. Il existe un modèle successeur avec de meilleures spécifications, que vous pouvez trouver here .

Mais la plupart des cartes ESP8266 et autres ESP32 devraient aussi fonctionner. J’aime l’ESP32 lite pour son prix bas et son connecteur batterie avec recharge intégrée. Cela permet d’alimenter l’ESP32 sur batterie et de recharger la LiPo via le port USB – très pratique.

Si vous souhaitez utiliser un Arduino, choisissez une carte fonctionnant en 3,3V comme la Arduino Pro Mini (ATmega328-3.3V ), car nous allons utiliser ici une seule batterie LiPo (3,7V). J’ai aussi listé un écran OLED, mais tout écran compatible I2C et fonctionnant en 3,3V conviendra.

Il existe deux versions du MAX1704X. Le MAX1704 3 listé ici est prévu pour une seule cellule LiPo, tandis que le MAX1704 4 est pour deux cellules LiPo (en série). Cependant, je n’ai pas trouvé de breakout board pour le MAX1704 4 nulle part, nous allons donc utiliser le MAX1704 3 . Cela signifie qu’il vous faut un microcontrôleur fonctionnant en 3,3V ou un convertisseur pour générer des tensions plus élevées.

MAX17043 Jauge de batterie LiPo

ESP32 lite Lolin32

ESP32 lite

USB data cable

Câble USB de données

Dupont wire set

Jeu de fils Dupont

Half_breadboard56a

Breadboard

Kit de résistances & LED

OLED display

Écran OLED

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.

Spécifications du MAX1704X Fuel Gauge

Le MAX17043/MAX17044 est un système jauge de batterie ultra-compact pour batteries lithium-ion (Li+). Le circuit intégré est minuscule et la photo ci-dessous montre un breakout board typique pour cette puce, ce qui facilite grandement les connexions.

MAX1704X breakout board (Front and Back)
Breakout board MAX1704X (avant et arrière)

Il existe deux versions de la puce. Le MAX17043 est configuré pour mesurer la charge d’une seule cellule lithium, tandis que le MAX17044 est prévu pour un pack double cellule 2S. La puce utilise un modèle de batterie LiPo, appelé ModelGauge, pour suivre en continu l’état de charge relatif (SOC) de la batterie, même lors de profils de charge/décharge très variables.

Voici les spécifications selon la fiche technique du MAX17043/MAX17044 :

  • Type de batterie : batterie Li-polymère/Li-ion 3,7V
  • 1 cellule (MAX17043) ou 2 cellules (MAX17044)
  • Mesure de tension de haute précision
    • Précision ±12,5mV pour 5V (MAX17043)
    • Précision ±30mV pour 10V (MAX17044)
  • Capacité relative précise (RSOC)
  • Pas d’accumulation d’offset lors de la mesure
  • Pas besoin de réapprentissage batterie pleine/vide
  • Alarme/interruption externe pour avertissement batterie faible
  • Interface I2C
  • Courant de fonctionnement : 50 µA
  • Tension d’entrée (VCC) : 3,3V~6,0V

Brochage

Comme mentionné plus haut, le MAX1704X est un petit circuit intégré, c’est pourquoi nous utilisons le breakout board listé dans le matériel nécessaire. Vous trouverez le brochage de cette carte ci-dessous :

Pinout for MAX17043 breakout board
Brochage du breakout board MAX17043

La carte dispose d’un connecteur JST 2 broches pour brancher la batterie LiPo. Mais il y a aussi deux broches (BAT+ et BAT-) où vous pouvez connecter la batterie. La plage de tension d’entrée est comprise entre  2,5V  et  4,5V . La tension nominale d’une cellule LiPo est d’environ 3,7V. Une fois chargée à bloc, la tension atteint environ 4,2V. Donc une cellule LiPo entre bien dans la plage de tension d’entrée.

L’alimentation de la carte se fait via les broches VCC et GND. La tension maximale pour VCC est de 5,5V mais il est recommandé d’utiliser 3,3V. Notez qu’il existe différentes versions de la carte avec différentes options (batterie ou MCU) pour fournir le VCC. Je vous conseille d’utiliser le 3,3V de votre microcontrôleur.

La broche ALT est la broche d’alerte. Cette broche est normalement à l’état HAUT mais passe à l’état BAS si la charge relative de la batterie descend sous un seuil configurable, par exemple 10%. Vous pouvez connecter cette broche à une broche d’interruption de votre microcontrôleur pour réagir à un niveau de batterie faible.

La broche QST sert à l’entrée de démarrage rapide (quick-start). Elle permet de réinitialiser le MAX17043 par le matériel. Un front montant sur cette broche déclenchera une réinitialisation matérielle. Mais vous pouvez aussi réinitialiser par logiciel, ce que nous allons faire ici.

Interface I2C

SDA et SCL sont les broches de l’interface I2C. L’adresse I2C du MAX17043 est  0x36 . Le breakout board possède deux résistances de tirage de 2,2kΩ connectées aux lignes SDA et SCL, donc vous n’avez pas besoin d’ajouter de résistances de tirage externes.

Notez qu’il y a un jumper à 3 pastilles en bas de la carte. Vous pouvez couper ce jumper pour désactiver les résistances de tirage si vous connectez plusieurs périphériques I2C. Pour plus de détails, consultez le max1704 Guide .

3-pad jumper to disconnect I2C pullup resistors
Jumper à 3 pastilles pour déconnecter les résistances de tirage I2C

Voilà pour le MAX17043. Passons maintenant aux bibliothèques disponibles pour lire les données du circuit MAX170X.

Bibliothèques MAX170X

Il existe de nombreuses bibliothèques pour utiliser le MAX17043 avec un ESP32/ESP8266 ou un Arduino. Notamment, il y a les bibliothèques de  PorreyLucadentellaSparkfun , Adafruit et  Nlamprian . Toutes sont en fait des wrappers autour des fonctionnalités de la puce MAX1704X et sont très similaires.

J’ai testé la bibliothèque Sparkfun et celle de Porrey. Les deux fonctionnent, mais dans ce tutoriel, je vous montre uniquement du code basé sur la bibliothèque de Porrey. Cependant, si vous préférez une autre, il est assez simple de la remplacer.

Fonctions de la bibliothèque MAX170X

Voici un aperçu rapide des fonctions que vous trouverez dans la bibliothèque MAX170X de Porrey :

begin(TwoWire*) Crée une instance FuelGauge.
uint8_t address(); Retourne l’adresse I2C du circuit intégré.
float voltage(); Retourne une mesure de la tension de la batterie en millivolts
float percent(); Retourne l’état de charge (SOC) de la batterie en pourcentage.
uint16_t version(); Retourne la version du circuit MAX170X.
uint8_t compensation(); Retourne une valeur utilisée pour optimiser les performances du circuit selon les conditions d’utilisation
void compensation(uint8_t); Définit une valeur pour optimiser les performances du circuit selon les conditions d’utilisation
bool sleep(); Force le circuit MAX170X à passer en mode veille. Toutes les opérations sont arrêtées
bool isSleeping(); Indique si le circuit MAX170X est en mode veille ou non
bool wake(); Réveille le circuit MAX170X du mode veille
void reset(); Réinitialise le circuit MAX170X
void quickstart(); Redémarre le calcul de la charge de la batterie
bool alertIsActive(); Indique si une alerte batterie faible est active
void clearAlert(); Efface l’alerte batterie faible
uint8_t threshold(); Retourne le seuil actuel pour l’alerte, par exemple 20%
void threshold(uint8_t); Définit le seuil pour l’alerte, par exemple 20%

Installation de la bibliothèque MAX170X

Pour install installer la bibliothèque MAX170X de Porrey, ouvrez le Library Manager et tapez « MAX1704X » dans la barre de recherche. Vous trouverez « MAX1704X by Daniel Porrey ». Voir ci-dessous :

Install MAX1704X library by Porrey
Installer la bibliothèque MAX1704X de  Porrey

Appuyez sur le bouton INSTALLER et c’est terminé. Comme vous pouvez le voir sur la capture d’écran ci-dessus, j’ai déjà installé la bibliothèque. Vous pouvez aussi installer les autres bibliothèques, par exemple Sparkfun ou Adafruit, si vous le souhaitez. Elles ne sont pas en conflit.

Dans les deux prochaines sections, je vous montre d’abord comment connecter le MAX17043 à votre microcontrôleur puis comment utiliser la bibliothèque pour lire les données de la batterie.

Connexion du MAX17043 à l’ESP32

Connecter le MAX17043 à un microcontrôleur est très simple. Commencez par relier le 3,3V et le GND du microcontrôleur aux broches VCC et GND du MAX17043 (fils rouge et bleu). Si vous avez un Arduino 5V, vous pouvez aussi connecter le 5V à VCC.

Connecting MAX17043 to ESP32
Connexion du MAX17043 à l’ESP32

Ensuite, connectez l’interface I2C (SCL, SDA). Les broches par défaut pour l’I2C sur l’ESP32 lite sont 23 (SDA) et 19 (SCL). C’est ce qui est illustré ci-dessus (fils vert et jaune). Pour un Arduino, connectez SDA -> A4 et SCL -> A5. Faites bien attention à ces connexions, car il est facile de les inverser et la carte ne fonctionnera pas.

Enfin, connectez la batterie LiPo. Le plus et le moins de la batterie sont reliés aux connecteurs correspondants de l’ESP32 et du MAX17043. L’avantage de la carte ESP32 est que vous pouvez l’alimenter par la batterie et en même temps la connecter à votre ordinateur via le câble USB. Si elle est branchée, la batterie se recharge. Le MAX17043 peut rester connecté pendant la charge et continuera à indiquer la tension et le niveau de charge.

Notez qu’il y a eu des retours indiquant que certains modules MAX17043 de certains vendeurs ne fonctionnent pas. Mon module acheté sur AliExpress fonctionne bien et celui listé dans le matériel nécessaire devrait aussi convenir. Cependant, je n’ai pas testé ce modèle précis.

Lecture du niveau de charge de la batterie avec le MAX17043

L’exemple de code simple suivant vous montre comment lire la tension et la charge relative de la batterie avec le MAX17043. Jetez-y un œil rapidement, puis nous détaillerons le code.

#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);
}

Inclure les bibliothèques

On commence par inclure la bibliothèque Wire et la bibliothèque MAX17043 . La bibliothèque Wire est nécessaire pour configurer l’interface I2C. Si vous avez un MAX17044, il faudra inclure MAX17044.h à la place de MAX17043.h . La bibliothèque MAX170X de Porrey contient les deux fichiers d’en-tête.

Fonction Setup

Dans la fonction setup() , on initialise la communication série à un débit de 115200 bauds. On démarre ensuite la communication I2C avec la fonction Wire.begin(SDA, SCL) .

Je définis explicitement les broches pour l’I2C avec Wire.begin(SDA, SCL) . Cela permet d’utiliser d’autres broches que celles par défaut pour l’I2C et supprime aussi le message  » Wire.begin()"  » sur le moniteur série qui serait sinon généré par la bibliothèque (voir blog ).

Ensuite, on initialise le MAX17043 via FuelGauge.begin(&Wire) . Si le capteur FuelGauge n’est pas trouvé, un message s’affiche sur le moniteur série et le programme entre dans une boucle infinie.

Sinon, on réinitialise le FuelGauge, suivi d’un délai de 250ms, puis on effectue un quickstart avec un délai de 125ms. Cette séquence provient de l’exemple fourni avec la bibliothèque MAX17043. Je ne suis pas certain que ces délais soient indispensables, mais je les ai laissés.

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);
}

Fonction Loop

La fonction loop() lit en continu la tension et le pourcentage de charge de la batterie LiPo. Les valeurs de tension et de pourcentage sont ensuite affichées sur le moniteur série avec Serial.printf() , avec un délai de 3 secondes entre chaque lecture.

void loop() {
  float volts = FuelGauge.voltage();
  float pcnt = FuelGauge.percent();
  Serial.printf("%.0fmV (%.1f%%)\n", volts, pcnt);
  delay(3000);
}

Si vous téléversez et exécutez ce code, vous devriez voir la sortie suivante sur votre moniteur série :

Battery Voltage and Charge Level displayed on Serial Monitor
Tension et niveau de charge de la batterie affichés sur le moniteur série

Notez que l’Arduino, contrairement à l’ESP32, ne prend pas en charge la fonction printf . Vous devrez utiliser une suite d’instructions print() à la place. Pour éviter cela, nous utiliserons la bibliothèque aprintf dans les exemples de code suivants. Pour plus de détails, consultez notre tutoriel How To Print To Serial Monitor On Arduino .

Afficher plus de données avec aprintf

L’exemple de code suivant affiche toutes les informations récupérables depuis la puce MAX17043 sur le moniteur série. La structure du code est la même que précédemment, mais il y a quelques petites différences à noter.

#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);
}

Premièrement, au lieu d’utiliser l’objet FuelGage prédéfini, vous pouvez créer votre propre objet de surveillance de batterie :

MAX1704X monitor = MAX1704X(MAX17043_mV);

Dans le constructeur, vous pouvez spécifier si vous avez un MAX17043 ou un MAX17044, puis utiliser le nom « monitor » ou tout autre nom dans le reste du code.

Deuxièmement, j’utilise la bibliothèque aprintf pour afficher les données sur le moniteur série. La fonction aprint() fait la même chose que Serial.printf() mais fonctionne aussi bien sur Arduino, ESP32 et ESP8266. Elle est aussi très pratique pour l’affichage formaté sur des écrans – ce que vous verrez dans la section suivante.

Cependant, il faut installer la bibliothèque aprintf à partir d’un fichier zip. Téléchargez le zip-file puis installez-le via Sketch -> Include Library -> Install .ZIP Library ... .

Install ZIP Library
Installer une bibliothèque ZIP

Pour plus de détails sur aprintf et le moniteur série, consultez notre tutoriel How To Print To Serial Monitor On Arduino . Une fois installée, vous devriez pouvoir exécuter le code et voir la sortie suivante sur votre moniteur série :

MAX17044 data displayed on Serial Monitor
Données MAX17044 affichées sur le moniteur série

Comme vous pouvez le voir sur la sortie, la carte était en train de charger la LiPo (Tension = 4120mV), car pour que le moniteur série fonctionne, l’ESP32 doit être connecté en USB à l’ordinateur. Dans le cas de l’ESP32 lite, cela recharge la batterie LiPo connectée.

Dans la section suivante, je vous montre comment connecter un écran OLED et y afficher les informations de batterie, au lieu du moniteur série.

Afficher le niveau de batterie sur un OLED

Afficher le niveau de charge sur le moniteur série est pratique pour les tests, mais pas très utile pour un projet sur batterie. On souhaite généralement afficher le niveau de batterie directement. Cela peut être une barre de LED ou un écran LCD. Mais dans cet exemple, j’utilise un OLED, car ils sont très compacts et fonctionnent bien en 3,3V.

Câblage pour l’OLED

Le schéma suivant montre comment connecter l’OLED (en plus des autres composants déjà présents) au projet. Commencez par relier le 3,3V et le GND du microcontrôleur aux broches VCC et GND de l’OLED (fils rouge et bleu).

Ajout de l’OLED au circuit MAX17043

Ensuite, connectez les fils I2C (SDA, SCL) en parallèle avec le MAX17043 (fils jaune et vert). L’OLED et le MAX17043 partagent le même bus I2C et doivent avoir des adresses I2C différentes. Si vous avez des soucis, vérifiez les adresses I2C. Mon OLED a l’adresse I2C 0x3C et le MAX17043 a généralement l’adresse 0x36 . Les résistances de tirage peuvent aussi poser problème. Rappelez-vous du jumper à 3 pastilles sur le MAX17043 qui permet de désactiver les résistances de tirage.

Si vous avez besoin de plus de détails sur l’utilisation d’un écran OLED, consultez notre tutoriel sur How to Interface the SSD1306 I2C OLED Graphic Display With Arduino .

Code pour l’OLED

Le code suivant affiche la tension et la charge relative de la batterie sur l’OLED. Comme d’habitude, jetez un œil rapide au code complet avant de l’analyser plus en détail.

#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);
}

Bibliothèques et configuration de l’affichage

Le code inclut les bibliothèques nécessaires comme Wire.h , aprintf.h , MAX17043.h , et Adafruit_SSD1306.h . Il initialise ensuite une instance de la classe Adafruit_SSD1306 pour un écran OLED avec des dimensions spécifiques. J’utilise ici un OLED 128×64. Si votre OLED a une taille différente, il faudra ajuster les valeurs ici.

Adafruit_SSD1306 disp(128, 64, &Wire, -1);

Fonction Setup

Dans la fonction setup() , la communication série démarre à 115200 bauds. La communication I2C est lancée avec la fonction Wire.begin(SDA, SCL) . Le code vérifie si le circuit MAX17043 est détecté, sinon il affiche un message et entre dans une boucle infinie. Ensuite, la jauge de batterie est réinitialisée et un quick start est effectué.

On définit aussi un seuil d’alerte batterie faible avec l’appel à FuelGauge.threshold(20) . Cela signifie que le seuil d’alerte batterie faible est fixé à 20%. Le niveau maximal possible est 32% et le plus bas est 1%. Ensuite, on efface toutes les alertes existantes.

  FuelGauge.threshold(20);
  FuelGauge.clearAlert();

Enfin, on initialise l’écran OLED. Assurez-vous d’utiliser l’adresse I2C de votre OLED ici. Le mien est 0x3C et j’ai un OLED noir & blanc, donc je mets la couleur du texte sur WHITE.

  disp.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  disp.setTextSize(2);
  disp.setTextColor(WHITE);

Fonction Loop

La fonction loop() lit en continu la tension et le pourcentage de charge de la batterie avec les fonctions FuelGauge.voltage() et FuelGauge.percent() . Elle vérifie aussi si une alerte est active avec FuelGauge.alertIsActive() .

  float volts = FuelGauge.voltage() / 1000;
  float pcnt = FuelGauge.percent();
  bool alrt = FuelGauge.alertIsActive();

Les informations de batterie sont affichées sur l’OLED avec la fonction fmt() de la bibliothèque aprintf et la fonction display() de la bibliothèque Adafruit_SSD1306 .

La fonction fmt() fonctionne comme Serial.printf() mais écrit dans un buffer de chaîne qui est ensuite renvoyé. La fonction disp.print() de l’OLED prend ce buffer et affiche le contenu sur l’écran.

  disp.clearDisplay();
  disp.setCursor(20, 10);
  disp.print(fmt("%.1f%% %c", pcnt, alrt ? '!' : ' '));
  disp.setCursor(20, 30);
  disp.print(fmt("%.3fV", volts));
  disp.display();

Avec la fonction fmt() , vous pouvez utiliser le même formatage et afficher facilement sur des périphériques qui ne supportent pas une fonction de type printf() . Pour l’OLED, n’oubliez pas le disp.display() à la fin, sinon rien ne s’affichera.

L’OLED affichera le pourcentage de batterie, la tension et un indicateur d’alerte (!) si une alerte est active. Si tout est bien connecté et programmé, vous devriez voir la sortie suivante :

Displaying Battery Charge and Voltage on OLED
Affichage du niveau de charge et de la tension sur l’OLED

Dans cet exemple, nous avons affiché une alerte batterie faible sur l’OLED en interrogeant l’état de la broche d’alerte toutes les 3 secondes. On peut aussi utiliser un gestionnaire d’interruption pour réagir immédiatement à une alerte batterie faible. C’est le sujet de la section suivante.

Gestion des alertes batterie faible du MAX17043

Pour illustrer la gestion d’un événement batterie faible, ajoutons une LED au circuit. Cette LED s’allumera si la charge de la batterie passe sous un seuil prédéfini.

On connecte la patte positive (longue) de la LED au GPIO 25 de l’ESP32. Vous pouvez choisir un autre GPIO si vous voulez – n’oubliez pas de modifier le code en conséquence. La patte négative de la LED est reliée à la masse (G) via une résistance de limitation de 68Ω.

Adding LED to MAX17043 circuit
Ajout d’une LED au circuit MAX17043

Maintenant, la partie intéressante. Le MAX17043 génère un signal sur la broche ALT lorsque la charge de la batterie passe sous le seuil. Plus précisément, la broche ALT passe de l’état HAUT à BAS. On connecte la broche ALT au GPIO 32 de l’ESP32 et un gestionnaire d’interruption sera appelé si l’état de la broche ALT change.

Voyons comment cela se fait en code !

Code pour le gestionnaire d’interruption batterie faible

La plupart des microcontrôleurs, y compris l’ESP32, permettent d’attacher une fonction d’interruption à une broche. Cela exécute la fonction lorsque la broche change d’état. Le code ci-dessous est le même que précédemment, avec en plus une fonction de gestion d’interruption lowBattery() . Il y a aussi une définition supplémentaire pour un ledPin et un alrtPin , nécessaires pour afficher et détecter une alerte batterie faible.

Voici le code complet, que nous détaillerons dans les sections suivantes :

#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 et variables

Comme mentionné plus haut, on définit d’abord deux nouvelles constantes, alrtPin et ledPin , qui représentent les broches pour le signal d’alerte et l’indicateur LED respectivement.

const int alrtPin = 32;
const int ledPin = 25;

Fonction batterie faible

La fonction lowBattery() est appelée lorsque la charge de la batterie passe sous un certain seuil. Elle allume simplement la LED connectée à ledPin . Notez que la LED restera allumée jusqu’à ce que l’ESP32 soit réinitialisé, même si la charge de la batterie repasse au-dessus du seuil. Mais il est facile de modifier ce comportement si besoin.

void lowBattery() {
  digitalWrite(ledPin, HIGH);
}

Fonction Setup

Dans la fonction setup() , le code initialise la communication série, le bus I2C, la jauge de batterie MAX17043, l’écran OLED, et configure les modes des broches pour la LED et le signal d’alerte.

Le plus important, c’est qu’il configure aussi l’interruption pour déclencher la fonction lowBattery() sur un front descendant. Cela signifie que si la broche ALT du MAX17043 passe à l’état bas à cause d’une batterie faible, on détecte ce front descendant sur le alrtPin et on appelle la fonction lowBattery() . Notez que la fonction lowBattery() est appelée indépendamment de la fonction loop() .

void setup() {
  ...
  attachInterrupt(alrtPin, lowBattery, FALLING);
}

Si vous voulez en savoir plus sur les interruptions, consultez nos tutoriels Push-Button And Arduino et Build Arduino Tachometer Using A3144 Hall Effect Sensor qui présentent d’autres applications et détails.

Fonction Loop

La fonction loop() est la même qu’avant. Elle lit en continu la tension, le pourcentage de charge et l’état d’alerte depuis le MAX17043. Elle met ensuite à jour l’affichage OLED avec ces informations et vérifie les alertes. Si une alerte est active, un point d’exclamation s’affiche à côté du pourcentage de batterie.

La différence importante entre l’alerte affichée sur l’OLED et celle signalée par la LED rouge est que l’OLED n’est mis à jour que toutes les 3 secondes, alors que la LED réagit immédiatement.

Et voilà ! Avec ces circuits et ce code, vous pouvez surveiller précisément le niveau de charge de la batterie et réagir rapidement aux alertes de batterie faible.

Conclusions

Le MAX1704X est un petit circuit très pratique pour surveiller le niveau de charge des batteries dans les projets sur batterie. Les deux versions, MAX17043 et MAX17044, sont quasiment identiques. Les schémas et codes présentés ci-dessus fonctionnent pour les deux. La seule différence est que le MAX17043 est conçu pour surveiller une seule LiPo (3,7V), tandis que le MAX17044 s’utilise avec deux LiPo (7,4V) en série.

Une fonctionnalité du MAX1704X dont nous n’avons pas parlé dans ce tutoriel est la compensation. Apparemment, elle permet d’optimiser les performances du circuit pour différentes chimies lithium ou températures de fonctionnement. Mais il n’y a pas d’informations précises sur les valeurs à utiliser dans la fiche technique.

Une autre fonctionnalité intéressante du MAX1704X, bien documentée, est le mode veille. C’est pratique en combinaison avec le mode deep sleep de l’ESP32 (ou Arduino/ESP8266). Cela permet de mettre en veille profonde à la fois le microcontrôleur et le moniteur de batterie pour prolonger l’autonomie.

En alternative au MAX1704X, vous pouvez utiliser un pont diviseur de tension et mesurer la tension de la batterie via une entrée analogique pour réaliser un système d’alerte batterie faible simple. Pour plus de détails, consultez notre tutoriel How to Monitor Battery Voltage for Battery Powered Projects . C’est une solution moins chère mais beaucoup moins fiable, surtout si vous souhaitez estimer l’autonomie restante et recharger à temps.

Et maintenant, amusez-vous bien ; )

Liens

Voici quelques liens que j’ai trouvés utiles lors de la rédaction de ce tutoriel :

Questions fréquentes

Quelle est la précision du MAX1704X pour surveiller le niveau de charge de la batterie ?

Le MAX1704X est très précis, avec une erreur typique de seulement ±1% sur toute la plage de température.

Le MAX1704X peut-il être utilisé avec d’autres microcontrôleurs que l’ESP32 et l’Arduino ?

Oui, le MAX1704X peut être utilisé avec de nombreux microcontrôleurs, tant qu’ils supportent la communication I2C.

Peut-on personnaliser le seuil d’alerte batterie faible sur le MAX1704X ?

Oui, le seuil d’alerte batterie faible peut être personnalisé selon vos besoins en ajustant les valeurs de registre correspondantes. Cependant, le seuil maximal est de 32% et le minimum de 1%.

Le MAX1704X peut-il être utilisé avec d’autres types de batteries que les LiPo ?

Bien que le MAX1704X soit optimisé pour les batteries LiPo, il peut aussi être utilisé avec d’autres types de batteries en ajustant certains paramètres de configuration.

Comment le MAX1704X est-il alimenté ?

Le MAX1704X peut être alimenté directement par la batterie qu’il surveille, mais je recommande de l’alimenter via le microcontrôleur.

Le MAX1704X peut-il surveiller plusieurs batteries en même temps ?

Non, le MAX1704X est conçu pour surveiller une seule batterie à la fois.

Quelle interface de communication est utilisée par le MAX1704X ?

Le MAX1704X communique avec le microcontrôleur via l’interface I2C.

Peut-on calibrer le MAX1704X pour une précision encore meilleure ?

Oui, le MAX1704X peut être calibré par des commandes logicielles pour améliorer la précision selon les besoins de votre application. Voir la fonction compensation() de la bibliothèque MAX1704X et la fiche technique du MAX1704X .

Comment le MAX1704X gère-t-il la protection contre la surcharge de la batterie ?

Le MAX1704X n’assure pas lui-même la protection contre la surcharge, mais il peut surveiller le niveau de charge pour aider à éviter la surcharge lorsqu’il est utilisé avec un circuit de charge adapté.

Comment le MAX1704X gère-t-il la protection contre la décharge profonde ?

Le MAX1704X n’assure pas la protection contre la décharge profonde, mais il peut surveiller le niveau de charge pour éviter une décharge excessive lorsqu’il est intégré à un système de gestion d’alimentation approprié.

Quelle est la plage de tension de fonctionnement typique du MAX1704X ?

Le MAX1704X fonctionne dans une plage de tension typique de 2,7V à 5,5V ; ce qui convient pour surveiller la tension d’une LiPo classique (3,7V).

Quelle est la consommation de courant du MAX1704X ?

La consommation typique du MAX1704X est de 50µA et il dispose d’un mode veille avec une consommation encore plus faible de 1µA.