Anthias
mail
6 connectés     # # # # # #

Recherche de l’autonomie maximum d’une balise
basée sur un ESP32 minimum

Page en construction
Brouillon à 70%

w

Introduction
Alimentation du ESP32
Composants d’une balise
Cycles de consommation
Consommation en phase sommeil
ESP32 + DS3231 (RTC)
ESP32 + AHT21 (temp + hum)
ESP32 + BME280 (press + temp + hum)
ESP32 + DS18B20 (temp)
ESP32 + TSL25611 (light)
Afficheur Oled SSD 1306
Configuration de la carte
Mesure de la tension batterie
Consommation en latence pendant le réveil
Consommation en phase active réveil
Envoi données : Choix des technologies
Conclusion

Maj : 22/06/21

Abstract :
The purpose of this page is to find the best solutions to operate a transmitter beacon with a small battery for the longest periods of time, sending data to a home automation system. It is not easy to trap the many details that increase consumption.
Obsession is "energy saving" to protect polar bears.
Consult this preliminary page showing 18650 status at low currents : Décharge lente d'une LiPo 18650

Résumé :
Le but de cette page est de trouver les meilleures solutions pour faire fonctionner une balise émettrice avec une petite batterie pendant les périodes les plus longues, en envoyant des données à un système domotique. Il n'est pas facile de piéger les nombreux détails qui augmentent les consommations.
L’obsession est "économies d'énergie" pour protéger les ours polaires.
Voir cette page préparatoire qui montre le comportement d'une 18650 à faibles courants : Décharge lente d'une LiPo 18650

bezier  Introduction

Dans un dispositif de domotique comme celui décrit par exemple ici Domotique via Internet arduino, un certain nombre de balises envoient les indications de leurs capteurs vers un système central qui les traite.
Nous aborderons ici les manières d’économiser l’énergie sur les balises autonomes. Il faut réduire drastiquement la consommation moyenne, l'ambition folle serait de tenir un an avec une 18650 sur une balise radio ou WiFi., ce qui nous donnerait une consommation moyenne, pour une très bonne LiPo de :
2000 mAh / (360*24) = 0.23 mA
Nous allons voir que cela pose bien des problèmes en pratique...
Cette page montre le comportement d'une 18650 à faibles courants : Décharge lente d'une LiPo 18650

Divers modèles de LiPo 18650

Pour commencer, voici le circuit de base des balises indépendantes qui dialoguent avec le maitre en ESPNow ou WiFi. La plupart des périphériques BMP280, DS3231, AHT41, OLED, etc.. , sont en I2C, les autres OneWire, SPI, radio, etc.. seront rajoutés à la demande et prévus sur le circuit imprimé final mais ne figurent pas ici pour simplifier.

Attention aux charges I2C de SDA/SCL qui doivent être de 4.7 à 10 kOhms en tout, mais les divers modules que l’on rajoute sont déjà chargés avec parfois des 4.7 KOhms (exemple DS3231). Il faut s’assurer d’enlever ces résistances inutiles pour respecter les impédances d'entrées de l’ESP32.

Schéma de la carte balise

Le circuit choisi est le ESP32 monté sur platine carrée et non le classique DevKit, car en fonctionnement il faut supprimer le circuit FTDI très gourmand en énergie et que l’on ne peut pas passer en sommeil.

Vous voyez sur l'image quelques périphériques I2C cités au dessus en tests de consommation.

Vue du premier prototype avant production du circuit

La recharge annuelle de la LiPo se fait par un module à TP4056 indépendant.
Il se trouve à 0.5 € chez les chinois.


La programmation se fera avec le petit module rouge FTDI, plus sa carte intermédiaire à deux transistors, comme décrit dans la documentation Expressif, pour fournir les IO0 et Enable pendant la programmation, depuis RTS et DTR. Cela permet le démarrage automatique sans passer par la séquence des poussoirs.
Cette carte ne sera branchée que pendant la phase de programmation et d’auto-démarrage, ou en debug pour utiliser le terminal, puis débranchée sinon.

Voici les oscillogrammes autour des signaux DTR et RTS qui commandent les deux transistors pour produire <EN> et <IO0> afin de passer en programmation et démarrage automatique.
Attention à ne pas faire l’erreur, il s’agit bien de DTR présent sur le coté de la carte, et pas de CTS en bout de carte !

Vous vérifiez que les signaux sont bien conformes à la table de vérité que j'ai indiquée sur le schéma.

Timings ESP32 FTDI : RTS _ DTR _ Enable (reset) _ IO0

Une autre manière de voir les mêmes signaux (plus TX et RX), avec l’excellent analyseur Salae qui permet de capturer en une seule fois huit voies, alors que l’oscilloscope ne peut en capturer que deux.
L’oscilloscope permet de bien voir le détail des fronts, ce que l’analyseur ne permet pas.

Timings ESP32 FTDI : RTS _ DTR _ Enable (reset) _ IO0

 Haut de page

bezier  Alimentation du ESP32

L'alimentation du ESP32 est très critique, les valeurs données par Expressif sont de 3.3 +/- 0.3V.
Il continue à fonctionner à 2.9 V mais devient instable surtout par temps froid il conviendra de rester dans les spécifications.
La tension basse n'est pas un problème, car nous sommes dans le coude de décharge complète de la LiPo que l'on considère comme vide en dessous de 3V.
Il ne peut pas être alimenté directement par une batterie LiPo chargée à bloc à 4.2 V
C'est pour cela qu'un régulateur linéaire à "faibles pertes" est installé. Le choix s'est porté sur le MCP1700 330E, qui accepte jusqu'à 6V en entrée.

Cette page montre le comportement d'une 18650 à faibles courants : Décharge lente d'une LiPo 18650

 Mesures sur le MCP1700 330e

Tests sous Vin = 3.6 V
Première mesure à vide  Iout = 0, Iin = 4.5 µA : C’est très décevant, la moitie de la consommation de l'ESP32 en sommeil, alors que le datasheet annonçait 1.6 µA
Deuxième mesure :  Iout = 6 µA, Iin = 10µA, rendement 60%
, c'est le cas de l'ESP32 nu (sans périphérique) en sommeil, ce" qui représente la quasi totalité du temps....
Troisième mesure:  Iout = 959 µA, Iin = 992 µA, rendement 97%
Quatrième mesure :  Iout = 82.6 mA, Iin = 82.7mA, rendement presque 100%
Donc, pour résumer :
 Le dropout de 250 mV est bien plus important que prévu, le datasheet annonçait 128 mV à 250 mA.
 Le rendement est bon à fort courant, mais la perte à très faible courant est trop importante, la moitié de la consommation de l’ESP32 en sommeil (pas de courbe constructeur disponible).

Pourquoi ce composant est-il aussi loin des spécifications ?
Faut-il estimer que les composants chinois sont de mauvais clones ?... Il faudrait en tester un vrai.


 Alternative douteuse
On peut remplacer ce régulateur problématique par une simple diode Schottky qui étalera le surplus quand la batterie est à pleine charge, mais qu’il faudra court-circuiter par un interrupteur quand la batterie tombera en dessous de 3.6 V
Une SS4 chutera de 200 mV à courant quasi nul, mais de 350 mV à 150 mA. Ce n’est pas encore l’idéal  car en pleine charge, les spécifications sont dépassées en sommeil.

Créer ce court-circuit par un MosFet dont la gate est commandée par le programme est risqué car l’état des GPIOs est indéterminé au démarrage.

 Haut de page

bezier  Composants d’une balise

Autour du microcontrôleur, divers périphériques sont nécessaires pour mesurer l’environnement, les valeurs principales seront :
Le temps : Une horloge temps réel donnera le top précis d’émission de la trame de données (sans qu’il soit utile de connaitre l’heure complète).
La tension batterie : Par un convertisseur Analogique –Digital externe ou interne, indispensable pour savoir quand recharger.
La température : AHT21, BMP ou BME280...
La pression : AHT21, BMP ou BME280...

L’humidité éventuellement : AHT21, BME280, et tout autre facteur : GPS, accéléromètre, luxmètre, courant, vent, hauteur de liquide, comptage, bruit, intrusions, etc.

La partie émission est soit interne (WiFi) soit externe avec un module radio supplémentaire.

Les capteurs I2C sont privilégiés et il faudra prendre en compte la consommation en sommeil, le temps de réveil et de réponse à une demande de mesure (certains ont une longue phase d’initialisation), donc le bilan en énergie.
Quelques exemples sont détaillés pour voir les temps machine et les bilans énergétiques.

 Haut de page

bezier  Cycles de consommation

La valeur typique pour une balise est d’émettre brièvement sa trame à un moment précis toutes les deux minutes et passer en sommeil le reste du temps pour ne pas interférer avec les autres.
Elle n’écoutera pas, car cela consomme trop de temps machine et ruine l’autonomie.

Premier exemple du bilan énergétique qui sera affinée par la suite, pour fixer les ordres de grandeurs :
1) Phase de réveil très critique, pendant
3 secondes, consommation moyenne 150 mA: Consommation maximale de l'énergie.
2) En sommeil presque 2 minutes, prenons une base de 10 µA.

Les chapitres suivants détailleront chacune des phases avec leur bilan énergétique.

 

 Moyen trivial pour économiser l'énergie

Evidement, si l'on augmente la période, la consommation moyenne diminuera d'autant, mais ce n'est pas vraiment jouable car trop peu de données dégradent les courbes.
La période de 2 minutes, qui donne 720 points de mesure par jour s'avère bien adaptée pour de la domotique.
Le nombre de cycles annuel sera de 365 * 24 * 30 = 262800, chiffre que nous retrouverons par la suite.


 Calcul du bilan énergétique sur l'année:

Pour calculer la dépense énergétique d'une phase sur une année
il suffit de multiplier :
Courant en mA * Temps d'activation en mS par cycle * 10-3 *262800 /3600 =
mA * mS * 73 * 10
-3 en mAh
 Lecture du courant
Il faudra étudier soigneusement les paliers de courant en phase réveil pour tenter de tout réduire. Nous pourrons faire les mesures avec un oscilloscope, en mettant en série une résistance dans l’alimentation négative 3.3 V. Avec une consommation de 150 mA, une résistance de 1 Ohm donnerait une chute beaucoup trop importante de  150 mV,
Le problème est qu’il y a deux grandeurs de magnitude très différente à mesurer, il faudra délicatement  commuter la résistance de charge pour alterner les deux mesures.
Pour les mesures en phases travail est préférable d'utiliser une résistance de charge de 0.1 Ohm avec un amplificateur d'instrumentation de gain 500 pour un courant en réveil de 150 mA, une chute acceptable de 15 mV, avec une sortie oscilloscope de 7.5 V, ce qui montrera parfaitement les paliers de courant.
En phase sommeil, la sortie serait bien trop faible pour s’extraire du bruit, on commutera provisoirement sur une résistance de charge de 100 Ohms ; on retrouvera les valeurs ci-dessus pour un courant en sommeil de 15 µA,
Evidement si l’on oublie de court-circuiter la 100 Ohms avant la fin du sommeil, l’ESP32 ne pourra pas redémarrer.
Il est préférable d’utiliser un ampli d’instrumentation moderne avec résistance de gain fixe interne calibrée, et de soigner l’alimentation.
Deux batteries LR22 de 9V rechargeables sont un excellent choix d'alimentation à faible bruit.


 Alternative pour la lecture du courant sans oscilloscope.
 L’INA219 est un amplificateur différentiel qui sort en pleine échelle en 12 bits (0…4095) sur un shunt à 40 mV, décrit comme « Bidirectional Current / Power Monitor With I2C Interface » (Si l’on veut mesurer trois courants d’un coup, s’orienter vers le INA3221).
Si l’on veut enregistrer des impulsions de 200 mA le shunt sera R = V/I = 40 * 10-3 / 200 * 10-3  = 0.2 Ohm.

Autre solution, l' INA250A4, capteur de courant sort en tension, 2 volts par ampère. avec shunt intégré 0.002 Ohm.
Pour des mesures vers 200 mA, il faut rajouter un amplificateur de gain 20 qui donnera 4V et un bon convertisseur Analogique-Numérique.

Il sera câblé sur un petit Arduino indépendant qui enverra ces mesures sur une carte SD, qu’il sera ensuite facile d’exploiter sur un PC dans une feuille Excel.
Le plus simple est d’enregistrer une trame sur un peu plus de 2 minutes afin d’avoir le réveil de l’ESP32 jusqu’au sommeil.
On éliminera du fichier la longue période sommeil dont la consommation est bien connue et constante.
Si l’on prend une mesure toutes les 10 mS, en 2 min 10s, il y aura 130*100 = 13000 données (de 2 octets), et après élimination du sommeil pour 3 secondes utiles seulement 300 données à traiter.

 A suivre :
Carte Arduino avec INA250A4 et support µSd en enregistreur de courant (C'est le circuit imprimé de Déchargeur de batteries arduino)


INA250A4

 Haut de page

bezier  Consommation en phase sommeil

Commençons par le plus facile, chercher à réduire le plus possible à consommation en sommeil bien  que nous ayons vu qu'elle était faible par rapport au réveil, mais c’est un exercice de style.
Pour les modes de sommeil, il y a de très bonnes pages sur le Net, cherchez dans votre moteur
«esp32 sommeil», je ne le reprendrai pas ici.
A titre indicatif, l'ESP32 avec un programme vide consomme 75 mA.


 ESP32 nu

Les tests seront faits sur un ESP32-S nu, monté sur la carte carrée blanche. Il faut simplement câbler les deux résistances et le condensateur indispensables à repérer sur le schéma.
Pour le programmer, il faut 4 fils fournis par la carte FTDI, l’alimentation et RX/TX (à croiser !), plus DTR/RTS avec le démarrage automatique, comme le montre le schéma Eagle.
Pour se faire une première idée, commençons par lancer le petit programme dans les exemples ESP32
"TimerWakeUp.ino" ou "Beacon_sleep.ino" dans mes fichiers joints, directorie "LowPower".
Il utilise le mode
UART wakeup (light sleep only) avec la commande esp_sleep_enable_timer_wakeup().

Pour les premiers tests, et établir une base, regardons uniquement le mode sommeil.

 La carte FTDI reste branchée, mais débranchée coté USB. L’alimentation est en 3.3 V. Un milliampèremètre en série montre un courant de
12 mA, c’est énorme.

 Maintenant débranchons la carte FTDI et passons en mode microampère.
La consommation en sommeil tombe à 6 µA, cela fait gagner facilement un facteur 2000 !
Attention, c'est la consommation brute de l'ESP32, mais derrière le régulateur la consommation passe à 10 µA.
Cela montre qu’il serait impossible de continuer en laissant le circuit FTDI branché, comme par exemple en utilisant un DevKit.

Il ne faut donc pas monter les éléments de démarrage directement sur le circuit de la balise, mais ajouter les deux transistors+résistances (R1 ,R2,T1,T2) sur une petite carte intermédiaire amovible et de rentrer directement avec EN/IO0 à la place de DTR/RTS

Cette page montre le comportement d'une 18650 à faibles courants : Décharge lente d'une LiPo 18650

e

 ESP32 + circuit de charge de la batterie

On rajoute la carte du circuit de charge de la batterie, basée sur le TC4056A, qui permet de charger proprement la batterie LiPo sur une prise USB 5V.
En branchant cette petite carte (non alimentée) sur la batterie, la fuite est d'environ 0.6 µA.
Bien qu'elle ne devrait être alimentée qu'une fois par an, il serait possible de la laisser branchée, cette consommation du dixième de l'ESP32 nu est faible, mais l'alimentation externe par prises 3 pins l'isole de la batterie hors charge et il n'y a plus aucune perte.

 Haut de page

bezier  ESP32 + DS3231

 Note liminaire sur les cartes I2C : charge des bus

Dans les nombreuses cartes implantant un périphérique I2C, les résistances de tirages de 4.7 ou 10 kOhms sont systématiquement ajoutées sur SDA et SCL.
Le problème avec plusieurs périphériques est qu’il ne faut pas surcharger le bus. Nous éliminerons systématiquement toutes ces résistances pour n’en garder qu’un seul jeu.
Ce n’est pas toujours facile car les composants sont minuscules.

 

 On rajoute l'horloge DS3231 en I2C

La balise doit connaitre l'heure pour émettre à un moment précis du cycle afin d'éviter les collisions avec les autres balises. Sans cette RTC externe, l'heure glisse trop avec l'horloge incorporée et pourrait varier de quelques secondes par jour ce qui provoquerait un conflit aves les autres balises.
L'horloge DS3231 en I2C est extrêmement stable et il ne sera utile de la remettre à l'heure que tous les mois en prenant le temps en WiFi sur un serveur, opération couteuse en énergie.

Premier test avec la carte de base, DS3231 non initialisée, led rouge en place, la consommation en sommeil augmente de plus de
2 mA, c'est énorme.
Enlevons la led rouge inutile, la consommation passe à 957 µA, il n'y a aucun courant sur la diode de la pile CR2032, c'est encore bien trop.
D'après le datasheet des EEProms, le standby current est de à 0.1 µA, et en enlevant la AT24C02 de base, qui ne sera pas utilisée dans l'application balise, le gain est imperceptible.
Dessoudons les deux réseaux de résistances, et câblons en volant deux 10 kOhms de tirage SDA /SCL. La consommation en sommeil passe alors à 98 µA, c’est mieux, mais encore beaucoup trop.
Cela correspond bien au datasheet qui indique un standby current est de à 110 µA
Comme vous le voyez sur le montage, il faut alimenter les 3 Vcc par une sortie GPIO pendant le réveil pour désactiver la RTC en sommeil au lieu de tout tirer directement à Vcc.

Attention, il ne suffirait pas de commuter le Vcc, car les circuits I2C se réalimentent par SDA/SCL !

Première mauvaise méthode, isoler par le positif

Il faut prendre la précaution de laisser un temps entre la commande haute du GPIO et la lecture, car à très faible courants, les capacités parasites sont importantes et le signal met longtemps pour se stabiliser. C'est encore pire si l'on passe par un Mosfet (N ou P, coupure par le + ou le -), inutilisable pour des courants aussi faibles, sauf à le charger par une résistance supplémentaire pour consommer plus de quelques milliAmpères.
C'est jouable en termes d'énergie car on peut diminuer les temps de montée, en n'oubliant pas que l'ESP32 consomme une cinquantaine de millisAmpères en réveil (hors WiFi).

Ecran du haut, temporisation de 500 µS entre la commande GPIO et la lecture de l'horloge, écran du bas temporisation 1500 µS.
Séquencement de la lecture de l'horloge :
1) Montée GPIO
2) delayMicroseconds(500) ; // Delay necessary after GPIO gate High vor voltage increase
3) rtc.begin(); // Duration 1300 µS
4) dt = rtc.getDateTime(); // Duration 150 µS
5) Descente GPIO

Les courbes montrent qu'avec 500 µS, c'est très limite, l'I2C se déclenche à 1.3 V, gros risque d'instabilité en batterie basse, avec 1500 µS ce n'est que 1.8 V.
Toutefois ce n'est pas la bonne solution. car la tension est trop limite.


coupure par Vcc

Violet: commande GPIO
Jaune : SCL

Deuxième bonne méthode, isoler par le négatif qui sera seul commandé par un GPIO (voir mesure tension batterie) . SDA/SCLA sont déjà au Vcc, ce qui est moins critique.

Il faudra toutefois ajouter une temporisation d'au moins 1000 µS après l'état bas du GPIO pour stabiliser. Evidement, sur le firmware balise, cette temporisation sera utilisée pour traiter les autres périphériques avant de passer à l'envoi de la trame, gros consommateur d'énergie.

Résultats des tests : L'opération dure moins de 2.43 mS, plus la temporisation.
On retrouve bien en sommeil nos 10 µA avec la RTC en l'air et 98 µA en activité.

En ne comptant pas la temporisation qui dera utilisée pour les autres fonctions, le bilan énergétique de la lecture RTC serait :.

50 mA * 2.43 mS * 73 * 10-3 = 9 mAh, mais il est très facile de réduire fortement cette consommation, par exemple en ne lisant l'horloge qu'une fois sur dix.

La consommation de la RTC en lecture est quasi nulle.

 coupure par négatif

 Première initialisation de la RTC

Pour initialiser l'horloge sur le serveur de temps, sans se préoccuper des consommations pour le moment, lancez une seule fois, "Beacon_RTC_init.ino". Il faudra auparavant rentrer le SSID et le mot de passe de votre box.
Si vous avez le message "Brownout detector was triggered", cela signifie que l'alimentation s'écroule lors du violent appel de courant du WiFi, revoir l'impédance des fils, de l'alimentation, supprimer le milliampèremètre, vérifier es condensateurs (10µF + 100 nF sur l'alimentation), la qualité des soudures...
Plus grave, cela peut être dû à un mauvais clone à bas prix de l’ESP32, il faut re-tester avec un authentique. Vous devez obtenir sur le terminal :! _ Connecting to myBox _ ..... CONNECTED _ Monday, April 04 2022 13:50:12 _ ...
L'horloge est initialisée, par la suite, les appels au serveur de temps se feront automatiquement par le programme.

 Recalage de la RTC sur un serveur de temps Internet.
Très longue séquence de connexion en WiFi, de 2550 milliSecondes, environ 150 mA,
Energie pour un appel : 2.55 * 150 = 282 mAs. Avec 12 appels par an, 282*12/3600 = 0.2 mAh, ce qui est absolument négligeable. Les longs appels WiFi vers le serveur de temps consommeront beaucoup, il faudra les limiter à quelques uns dans l'année. Le passage heure été/hiver n'intervient pas car la balise n'a à connaitre que les minutes et secondes pour se déclencher par interruption.


 Elimination des  temporisations

Il existe une solution un peu tordue pour supprimer cette temporisation d’au moins 1 mS, coûteuse en temps CPU (qui consomme inutilement 50 mA), c’est de déclencher la commande au début, mais ne lire la RTC qu’après la longue séquence d’émission de la trame.
Ce n’est pas un problème car la seule chose qui nous intéresse est le calage précis au top 2 minutes pour synchroniser la balise avec les autres, la trame n’envoie pas l’heure qui est connue par le Master.

 Haut de page

bezier ESP32 + AHT21

Remarque préalable

Il existe deux versions de cette carte à schéma identique, l’une avec le chip dessus, l’autre dessous.
Le composant 3 pattes est le Sumron XC6006P333MR (662k), régulateur 3.3V parfaitement inutile ici en 3.3V
Le bloc central est un réseau de 4 résistances de 8.2 k, deux en tirage I2C, les deux autres vers le circuit 6 pattes K2736 qui est un double Fet prévu pour la conversion 5V ->3.3V inutile ici.
Il est possible de supprimer aussi les inutiles blocs de résistances  +  K2736 (en le remplaçant par deux straps SDA SCL), mais cela ne joue pas sur la consommation.
L’ensemble est complété par 3 condensateurs de découplage, mais cette disposition curieuse n’est pas conforme aux spécifications. Voir ICI le schéma de la carte AHT21

Sans rien modifier, la comsommation permanente de cette carte AHT21 est du même ordre que la consommation de l’ESP32 en sommeil, 6.8 µA, alors que le datasheet donne 0.25µA !
En remplaçant ce régulateur inutile par une 330 Ohms comme le spécifie le constructeur, la consommation en sommeil retombe à quasi zéro comme indiqué.
Il est donc inutile de chercher à couper l’alimentation en sommeil.

Consommation réveil

L’appel des lectures température + humidité dure 2 fois 80 mS ce qui est très long.
L’oscillogramme suivant montre la consommation du circuit I2C pendant l’appel d’une mesure (un seul paramètre).
Trace jaune, 1 carreau = 500 mV en sortie de l’amplificateur d’instrumentation de gain 500 sur 1 Ohm.

Le courant du AHT21 est donc d'environ 1 mA pendant la demi-période soit 40 mS, comme l'indique le datasheet, mais il faut tenir compte de la consommation de l'ESP32 de 50 mA sur tout le cycle, soit une dépense énergétique annuelle pour une seule mesure de (temp ou hum) :
((1 mA * 40 mS ) +( 50 mA *80 mS) ) * 73 * 10-3  = 300 mAh, soit 15 % de la capacité batterie pour le réveil.

Malgré la réduction drastique de consommation en enlevant le régulateur, l'AHT21 est donc peu adapté pour une balise à faible consommation.


AHT21

 

 Haut de page

bezier ESP32 + BME280

Remarque préalable

Attention sur les sites chinois lors de la commande, à la confusion BMP/BME ! Si le composant n’est pas cher, c’est un BMP malgré qu’il ait été commandé comme BME280.
En principe, mais ce n’est pas toujours vrai, mais un trou = BME, deux trous = BMP. Vérifiez que votre soit disant BME280 peut bien lire l’humidité.

Le montage est ici beaucoup plus simple que pour l'AHT21 : 4 résistances de 10 kOhms, 3 en tirage SDA, SCL une pour CSB (seulement pour mode SPI), l'autre à la masse pour SDO (Bit d'adresse).
Il est ici très facile de supprimer les deux tirages I2C.

Le BMP280 lit la pression + la température
Le BME280 lit en plus l’humidité, mais est moins bon pour cette mesure que le AHT21, voir les comparaisons sur : Domotique via Internet arduino

Consommation du BME280

Pour les tests de consommation à l’oscilloscope, une résistance de 1 kOhm est provisoirement insérée dans le négatif du BME280, moyenne sur 16 cycles.
La consommation du BME280 en sommeil est quasi nulle, il n’est pas utile de chercher à le commander par un créneau de tension comme pour la RTC.
La trace  GPIO violette est le créneau déclenché à la fin du réveil, il dure le temps de « Wire.begin + bme.begin » soit 10 mS
Ensuite pendant les 15 mS suivantes, acquisition des trois paramètres, Temp, Hum et Press.
Les courants sont très variables, nous prendrons en moyenne 300mv sur 1 kOhm, soit 0.3 mA, ce qui est négligeable devant la consommation de l’ESP32 de 50 mA pendant ce temps total de 25 mS.

Le bilan énergétique annuel de la lecture du BME280 est :

(50 + 0.3 mA) * 25 mS * 73 * 10-3 = 98 mAh, soit 2 % de la capacité batterie, ce qui est très acceptable.


BMP280

 Haut de page

bezier ESP32 + DS18B20

Ce capteur de température très répandu n’est pas un composant I2C, il utilise le bus One Wire de Dallas. Son inconvénient est de nécessiter un long intervalle entre la commande et la lecture.
Le circuit utilise le mode d’alimentation parasite, avec une 4.7 kOhms entre Vcc et DQ.

Pour les tests de consommation à l’oscilloscope, une résistance de 1 kOhm est provisoirement insérée dans le négatif du DS18B20.

Utilisation de la librairie de base Arduino et modifications des exemples pour le mode sommeil
Hors activité la consommation est de 40µA ce qui demandera la coupure du négatif

Premier test simple monobloc

Séquence unique de 500mS avec une consommation moyenne de 500 µA.

 

Deuxième test : WaitForConversion

Ici l’interprétation des courants est moins évidente
Premier créneau d’initialisation de 500 mS, comme précédemment
Ensuite longue attente de quelques secondes (ici 1 sur l’oscillogramme), destinée à simuler le temps d’envoi de la trame, mais en début de ce temps, consommation de 350 µA pendant encore 500 mS
puis lecture des résultats pendant 30 mS, à faible consommation de 100µA.
Contrairement à ce qui était espéré, cette méthode consomme beaucoup plus que la basique précédente et n’offre aucun intérêt.

Le bilan énergétique annuel (hors sommeil) de la lecture du DS18b20 en monobloc est :
(50 + 0.5 mA) * 500 mS * 73 * 10-3 = 2000 mAh, soit  la capacité totale batterie, ce qui est évidement inacceptable

Le DS18B20 ne peut pas être envisagé pour une balise faible consommation.

 Haut de page

bezier ESP32 + TSL2561

Le TSL2561 est un circuit I2C de conversion digitale de l’éclairement. Un étalonnage délicat permettrait d’en faire un luxmètre, sinon les valeurs lues ne seront que relatives.
Il est très sensible et pour mesurer l’intensité lumineuse extérieure, il faut le laisser à l’ombre, pointé vers le ciel au Nord, ce qui évite la saturation et permet de mesurer les faibles fumières au lever et coucher du soleil.
Le montage directement exposé au soleil doit être protégé par un dépoli, mais est moins performant aux faibles lumières et chauffe trop.
Comme pour le DS18B20, ce TSL2561 a un temps d’intégration très long, mais une fois la commande lancée, il est possible d’envoyer la trame pendant quelques secondes, puis de lire le résultat et le stocker pour le cycle suivant avant de s’endormir. Evidement il y aura toujours un retard de 2 minutes sur les courbes de luminosité.
On utilise pour cela les registres conservés en sommeil : RTC_NOINIT_ATTR uint16_t  mydata ; // In permanent 16k RTC memory

Comme pour l’AHT21, en 3.3V, il faut enlever le régulateur inutile qui consomme beaucoup, mais la consommation permanente reste encore de 650 µA, il est donc indispensable de couper l’alimentation en sommeil, la fuite tombe alors à 0.7µA ce qui est quasi nul.
Il est facile de supprimer aussi les résistances de tirages I2C de 10 kOhms, s’il y en a déjà dans la balise.

La trace violette est la porte d’alimentation du négatif.
La trace est la ligne SCL active pendant l’initialisation de 52 µS, puis la longue attente interne du temps d’intégration de 420 µS, puis une très rapide activité à la lecture des registres de quelques mS, puis la fin du cycle ce qui est normal, en tout 470 mS
Il faut modifier la bibliothèque pour sortir la longue attente comme décrit précédemment afin de n’utiliser que 55 mS de temps machine et réduire ainsi la consommation d'un facteur 8.5..

Le bilan énergétique annuel (incluant l'attente) de la lecture du TSL2561 est :
(50 + 0.65 mA) * 470 mS * 73 * 10-3 = 1740 mAh, soit la quasi capacité totale batterie, ce qui est évidement inacceptable.

Le TSL2561 ne peut pas être envisagé pour une balise faible consommation sans éliminer l'attente.

 Haut de page

bezier ESP32 + Option afficheur Oled SSD 1306

Cas particulier : Le Oled est branché, sans être initialisé, en mode sommeil, la consommation augmente de 7 µA.
S’il est initialisé, suivant le texte affiché, la consommation passe à 7 mA, et en effaçant l’écran retombe à 0.7 mA.
Pour revenir au 7µA non initialisé, il faut le débrancher puis le rebrancher.
Ce bilan énergétique montre qu’il sera impossible de le laisser branché en permanence sur la balise.

Solution : Isoler par le négatif (voir mesure tension batterie) pendant le réveil pour désactiver l'Oled hors debug.

 Haut de page

bezier Configuration de la carte

La balise à besoin d’un mot de configuration pour régler divers paramètres de fonctionnement. (Configurateur à zéro, mode normal d’exploitation)

Première approche, lire l’état de quatre dip switches à glissières, soit 4 bits (1 = fermé) donnant 16 possibilités de configuration.
Alternative :
- Ou lecture à chaque cycle pour modifier le comportement en dynamique.
- Ou une seule lecture après le reset à froid pour modifier le comportement en statique.

Voici 4 solutions différentes pour obtenir ce résultat (extrait du schéma complet)

Dans tous les cas, la commande sera effectuée par un GPIO qui sera tiré à la masse un temps très bref, au positif le reste du temps.

 Mauvaise solution 1 inutilisable :
Réseau R/2R. Une seule lecture analogique de 55 µS (16 pas de tension). N'utilise que 2 GPIOs.
Attention, ce n’est pas un réseau R-2R classique, car la commutation n’est pas Vcc (bit =1) à Zéro (bit =0) mais Zéro (bit =1) à infini (bit =0) !
La sortie n'est pas monotone, c'est à dire que l'incrémentation du mot de commande n'implique pas l'augmentation de la sortie.
Le réseau R /2R ne fonctionne QUE si l'on commute les résistances 2R à la masse OU au Vcc, il n'est pas possible de les laisser en l'air comme ici.

 Solution 2 :
Utilise 4 GPIOs en entrées tirés au positif par les résistances internes (pullup 10 kOhms). Les résistances de 1 ko en série dans les switches sont une sécurité pour éviter que si d’autres programmes mettaient par erreur ces GIPO au niveau haut et d’autres au niveau bas avec switches fermés, il n’y ait un court-circuit.
Quatre lectures digitales en moins d'une µS. C'est très performant et très rapide mais gaspille 4+1 GPIOs.


3 solutions configurateurs


Schéma de la carte balise

 Solution 3 :
Echelle de résistances en progression géométrique (pas = 2). Une seule lecture analogique de 55 µS (16 pas de tension). N'utilise que 2 GPIOs.
Nous pouvons prendre R33 = 1.2 kOhms et les valeurs approchées : 1.2 _ 2.,4 _ 4.8 (2*2.4 en série) _ 9.6 (9.1 + 470 en série)
La valeur de la résistance de tête n'est pas très critique, elle détermine la tension maximale et la concavité de la courbe, par exemple facteur 8.3 -> R35 = 10 kOhms

Cette feuille Excel montre les calculs et la courbe résultante
Inconvénient : La courbe est bien monotone mais non linéaire ce qui complique la lecture des tensions

Pour tester « en vrai » ce type de réseau simple, j’ai remplacé provisoirement les 4 switches par les relais d’une platine Arduino, avec un petit programme qui compte de 0 à 15, chaque bit commandant un relais (alimentation 5 V).
Vous voyez sur l’oscillogramme que les pas sont bien distincts pour les valeurs faibles du mot de commande, mais compressées pour vers le haut. Il vaudrait mieux se limiter à 3 bits.

Ces solutions avec interrupteurs à glissières sont abandonnées.


Réseau géométrique


 Alternative choisie : Le bouton poussoir

Autre solution statique complètement différente, qui a été retenue après avoir exploré toutes les autres. Un bouton poussoir sur une seule entrée GPIO (avec filtre RC + firmware anti rebond) déclenche une interruption qui réveille la balise. La led clignote visiblement rapidement pendant quelques secondes, et le firmware attend d’autres appuis sur le poussoir puis se rendort. Le nombre d’appuis détermine les nouveaux paramètres, Par exemple :
 Aucun nouvel appui = Remise à zéro des paramètres, mode normal.
 Un appui = Active l’écran Oled pendant un cycle.
 Deux appuis = Active la liaison série (qui peut alors recevoir des commandes au clavier).
Consommation quasi nulle car l’évènement est exceptionnel.


 Haut de page

bezier Mesure de la tension batterie

 La led

Cette led qui semble montée un peu bizarrement commandée par GPIO2 (impulsion à zéro) est très utile, et ne sert pas qu'à faire joli.
Sous 3.3 V, sa tension à ses bornes est de 1.764 Volts et aux bornes de la 3.9 ko de 1.5 volts. Le courant est de I = V/R =1.5/3.9 * 10-3 = 0.4 mA.
Il est évident qu’elle ne sera pas allumée en permanence, un cycle de 10 milliSecondes est parfaitement visible si l'on veut montrer un petit flash toutes les deux minutes.
 Il faut toutefois ajouter que pendant ce temps le CPU travaille, avec une consommation moyenne de 50 mA, la consommation rajoutée par cette la led est négligeable, mais le courant à considérer n'est pas de 0.4 mA mais de 50 mA,
Dépense énergétique annuelle liée au flash d'allumage de la led : mA * mS * 73 * 10-3 = 50 * 10 * (73 *10-3) = 36.5 mAh, soit 2% de la capacité de la batterie.
Cela est significatif et ne se justifie pas.

Cette led à sa pleine utilisation maintenant. Il est difficile d'obtenir une valeur stable de la tension batterie en dépensant peu d'énergie, et le sur-échantillonnage prend beaucoup trop de temps. C'est un gros problème, car les convertisseurs Analog-digital de l'EP32 de 12 bits sont très bruyants, i
La tentation est grande d'utiliser un ADC de course comme le ADS1115, qui consomme 150 µA, mais c'est prendre une masse pour écraser une mouche...
Le schéma montre la disposition choisie pour contourner ces problèmes !
Cette led n'est pas placée pour flasher visiblement, elle sert le temps d'une impulsion pour calculer la tension batterie en décalant la valeur dans la meilleure zone sans consommer hors mesure.
C'est très bref et elle n'est quasiment pas visible.

 

 Principe de la mesure de la tension batterie

L'anode de la led rouge est directement reliée au positif de la batterie (jusqu'à 4.2v). En période de sommeil, IO2 en sortie est au niveau haut, la tension aux bornes est au maximum de 4.2-3.3V = 0.9, dans la zone de non-conduction de la led, quasi aucun courant ne passe, la led est éteinte, La tension aux bornes de IO32 est flottante, et pour éviter tout risque de tension statique ou induite (effet d'antenne), une résistance Rstat de 100 kOhms est tirée au positif, donc avec courant nul. Si le tirage était à la masse, il y aurait une fuite via la led d'au maximum : 0.9/(100 103) = 9 µA.
Rvolt et Cvolt constituent un filtre pour atténuer le bruit de conversion.
Pour chaque cycle, une impulsion à la masse sur IO2 fait conduire la led au travers de R5, la led flashe.
Le courant maximum est de de 4.2-1.764 * 3.9 * 10-3 = soit
1 mA, en en fin de décharge, 2.9-1.764 * 3.9 * 10-3 = 0.3 mA, soit un courant moyen de (1 + 0.3)/2 = 0.65 mA.
La tension vers IO32 est alors pour Vbat = 4.2 V de 2.4 V et pour Vbat = 3V de 1.2V, ce qui se situe dans la meilleure zone de conversion linéaire, loin du pied et de la tète de courbe.

Le filtre RC introduit un léger retard exponentiel de quelques dizaines de µS, c'est pour cela que nous allons d'abord faire une lecture du pont R/2R des configurateurs pendant les premières 50 µS, puis une fois la tension stabilisée sur IO32, la lecture de la tension batterie.
Ce créneau de commande dure deux fois le temps d'une conversion analogique, soit 104.4 µSecondes,
avec un courant moyen de (1 + 0.3)/2 = 0.65 mA.

Violet: entrée ADC sur IO32
Jaune : gate IO2

 Il faut toutefois ajouter que pendant ce temps le CPU travaille, avec une consommation moyenne de 50 mA, la consommation rajoutée par cette mesure est néglige able, mais le courant à considérer n'est pas de 0.65 mA mais de 50 mA,
Dépense énergétique annuelle liée à la mesure de tension batterie : mA * mS * 73 * 10-3 = 50 * (104.4* 10-3) * (73 *10-3) =
0.4 mAh soit 0.2%, ce qui est absolument négligeable.

 Etalonnage :
Pour étalonner en tension, il suffit de remplacer la batterie par une alimentation variable et de relever les valeurs.
Un petit programme joint, "etalonnage_batterie.ino" fait cela.
La lecture est très précise et cette feuille Excel montre plusieurs courbes très intéressantes.

1) La relation lecture CAN / tension d'entrée est rigoureusement linéaire !

2) La relation Vout -> Vin. C'est parfait entre 4.2 V et 3.5 V mais ensuite cela descend vite et à 3.1 V, la tension de sortie tombe à 2.86 V ce qui est limite pour la stabilité de l'ESP32. Cela n'est pas gênant car comme le montrent les courbes de décharges suivantes, la batterie peut être considérée comme totalement vide à 3.1V.
Considérez la courbe orange à C/10, soit une décharge en 10h, en réalité pour cette application la décharge se fera en quelques milliers d'heures, la courbe correspondante sera légèrement au dessus.

3) La perte de tension Vin -Volt = "dropout", qui est de 350 mV dans la zone utile, ce qui est beaucoup moins bon que nous le laissait penser la lecture du datasheet !

 <
Comportement du
MCP1700 330e

Mais cela ne suffit pas ! Connaitre la tension est une indication, mais ce qui est plus utile est de connaitre l'autonomie restante.
Pour cela on utilise une courbe de décharge et l'on calcule sous Excel l'intégrale de la tension fonction du temps, ce qui donne exactement l'autonomie d'après la courbe de tension, car le courant moyen est constant.
Si la balise subit des écarts de température importants à l'extérieur, la capacité de la batterie variera beaucoup, et cela doit être intégré au calcul.
Cette page montre le comportement d'une 18650 à faibles courants : Décharge lente d'une LiPo 18650
C'est cette valeur de vraie capacité restante qu'enverra la balise.

 Haut de page

bezier  Consommation en latence pendant le réveil

C'est maintenant que les problèmes commencent, car tout consomme trop pendant trop longtemps.
Après avoir étudié le krill et les petits poissons, étudions maintenant les baleines.

 Latence du réveil de l'ESP32

Premier test, programme "LowPower_10.ino"

Allumage de la led 20 ms, extinction, sommeil une seconde, etc.. Le circuit FTDI est débranché, il n'y a que l'ESP32.
La courbe jaune est la tension de commande de la led (IO2).
La courbe violette le courant (résistance 1 ko, 1 carreau = 5 mA) en série sur le négatif de l'alimentation,
En horizontal, 1 carreau = 20 ms.

Mesure à l'oscilloscope du courant de la phase "morte" de démarrage pendant laquelle aucune commande ne peut être passée

En début de courbe, à gauche, phase sommeil, consommation non mesurable dans le bruit < 10µA
 Réveil deuxième case, consommation 7.5 mA pendant  30 mS
 Palier 23 mA pendant 75 mS
 Palier 28 mA pendant 8 mS
 Palier 75 mA  pendant 40 mS
Ensuite la phase active d’interprétation des commandes commence et allume la led pendant 40 mS, consommation de travail  20 mA (aucun périphérique n’est branché), puis repasse en sommeil.

Ce temps de latence est donc d'environ 150 mS pendant lequel on ne peut strictement rien faire.
L’intégrale du courant pendant la phase de démarrage donne la quantité d’énergie incompressible perdue par cycle, soit sur un an :
((7.5*30) + (23 *75) + (28*8) + (75*40)) * 73 * 10-3 = 380 mAh

C’est beaucoup pour un processeur qui ne fait encore rien, 20% de l’énergie disponible sur une 18650, mais il n'y a pas moyen de réduire simplement
Toutefois, les documents Expressif évoquent la possibilité de faire exécuter des commandes par le coprocesseur pendant le sommeil, mais cela demande des moyens lourds qui ne sont pas du niveau de cette page.

Il est intéressant de voir quand démarre le timer. Ce début de programme nous montre que le compteur a démarré 27 milli secondes avant de rendre la main.

void setup()
{
long top = millis();
Serial.begin(115200);
while (!Serial);
Serial.println (top) ; // Affiche 27 mS

 Haut de page

bezier  Consommation en phase active réveil

Cette phase de latence incompressible de 150 mS est terminée, nous avons vu comment les périphériques s'activent pour fournir les données, pendant un temps et une consommation qui dépend des capteurs comme vu précédemment.

Maintenant tous les capteurs sont lus, la préparation de la charge utile prend un temps machine quasi nul. Pour chaque cycle, il y a très peu de données à envoyer pour relever toutes les balises, quelques octets dans la charge utile, mais cela prendra beaucoup de temps d'activité à fort courant.

Les balises communiquent toujours avec un maitre central qui centralise et traite toutes les données. Divers choix sont possibles, mais aucun n'est parfait.
C'est le produit <temps d'émission * courant moyen> qui sera le facteur clef. Les différentes consommations dans cette phase critique dépendent des choix technologiques pour l'envoi de cette charge utile.

Nous travaillerons en unidirectionnel, il n’y a pas d’handshake, la balise envoie mais n’écoute pas car cela prendrait beaucoup trop de temps machine

 Haut de page

bezier Envoi données : Choix des technologies ??????????? à compléter ????????????

 

 Infra rouge

C’est une technique simple et extrêmement performante sur le plan énergétique, comme le prouvent les télécommandes domestiques, mais elle n’est possible que pour des balises à vue du central, ce qui est très rarement le cas, aussi elle sera oubliée.

 Bluetooth

Nous ne le détaillerons pas pour le moment, malgré l'avantage de sa faible consommation, car la portée est limitée et l'exploitation beaucoup plus compliquée qu'avec les autres moyens.

 LoRa

??????????? à compléter ????????????

 Radio 432 MHz

??????????? à compléter ????????????

 ESPNow

Le système actuel tourne en ESPNow, mais n'exploite pas son avantage de pouvoir communiquer sur des grandes distances car tous les capteurs sont proches dans la maison.
Des solutions moins gourmandes sont à envisager.

??????????? à compléter ????????????

 WiFi

Très curieusement, la consommation varie peu en réduisant la puissance émise, ce qui change beaucoup de nos émetteurs radio traditionnels.
En champ proche, près d'une box, la puissance est surabondante.

??????????? à compléter ????????????

 Haut de page

bezier  Conclusion

Voir la page préparatoire qui montre le comportement d'une 18650 à faibles courants : Décharge lente d'une LiPo 18650
Cette page montre qu’il est difficile d’atteindre une grande autonomie avec des composants classiques, il faudra se tourner vers de nouveaux microcontrôleurs spécialement conçus pour cette problématique.

 

 Addendum

Programmes inclus dans la directorie <__lipo_Beacon> :
 Beacon_sleep.ino : Simple program to test ESP32 current deep sleep mode
 VoltToPercent.ino : Percent capacity calculation for a good 18650 at low dicharge current  from remaining voltage 
 PercentToVolt.ino : Remaining voltage for a good 18650 at low discharge current from percent capacity (only to verify table accuracy)

 dec_pourcent.xlsx : Master record of decreasing voltage  from time
 tendance.xlsx : Optimised curve of 18650 percent capacity from voltage

 Beacon_switches.ino : Very fast basic program to test availaible dip switches configurators from GPIO readings (bad solution)
 Beacon_sleep.ino : Basic program to test the sleep mode current of the ESP32 beacon with a microAmperemeter. First use, ESP32 alone without FTDI
 Beacon_RTC_init.ino : Simple test of time server and DS3231 RTC  for the very first checks of ESP32 beacon.

Tous les détails et logiciels sont dans cette page à jour au : 220511

eclate
 

Haut de page

© Christian Couderc 1999-2022     Toute reproduction interdite sans mon autorisation


* Page vue   340   fois       IP : 44.200.40.195

 Haut de page         Dernière retouche le 21 Juin 2022 à 14 h         Retour page précédente

   Collector