samedi 23 février 2019

ESP8266 et ESP32 sur batterie

ESP8266 et ESP32 sur batterie


Vous connaissez certainement ces petits modules WIFI et je ne vais pas vous les décrire une Nième fois.

Dans cet article nous allons plutôt nous intéresser à l'élaboration d'une solution à base d'ESP8266 ou ESP32 alimentée par batterie.

Nous en profiterons pour explorer aussi certains sujets pour les plus ou moins débutants :
  • les cartes de prototypage
  • le câblage
  • le chargement par l'IDE ARDUINO 
  • le sommeil profond ou deep-sleep
  • le réveil périodique
  • le réveil par une entrée digitale
  • envoyer un mail
Avant tout, il est important de savoir que le sommeil profond entraîne la coupure du modem WIFI, et donc l'ESP8266 ou l'ESP32 se retrouvera dans l'incapacité de communiquer.
Les montages réalisés dans une optique serveur WEB ne pourront bénéficier de cette technique d'économie d'énergie. Si vous envisagez la réalisation d'un serveur WEB alimenté par batterie, orientez-vous plutôt sur une alimentation secteur ou une alimentation par batterie + recharge solaire.

1. Alimentation sur batterie

1.1. Tension de service

Avant d'aller plus loin, il faut savoir que :
  • la tension d'alimentation de l'ESP8266 ne peut dépasser 3.6V
  • il ne peut fonctionner en dessous de 2.5V
  • la tension d'alimentation de l'ESP32 ne peut dépasser 3.6V
  • il ne peut fonctionner en dessous de 2.3V.
L'alimentation par batterie passera de préférence par les solutions suivantes :
  • 2 batteries NIMH en série
  • 1 batterie LifePo4 (l'idéal)
  • 3 batteries NIMH en série + 1 régulateur 3.3V ou 3V
  • 1 batterie LITHIUM-ION ou LIPO + 1 régulateur 3.3V ou 3V
La solution consistant à utiliser 2 batteries NIMH en série paraît optimale pour l'ESP8266 mais elle ne l'est pas pour les batteries :
La tension à pleine charge sera de 2.8V.
L'ESP8266 pourra fonctionner jusqu'à 2.5V
A 2.5V les batteries seront loin d'être vides. Il restera environ 30% de capacité, et il sera obligatoire de les décharger avant de les recharger afin d'éviter l'effet mémoire. Certains chargeurs font cela automatiquement.

Par contre la solution à 2 batteries NIMH est un peu plus intéressante pour l'ESP32 car sa tension minimale de fonctionnement de 2.3V se rapproche de la tension minimale des batteries : 2 x 1.1V.

1.2. Courant

Un ESP8266 consomme un courant important lors de la connexion WIFI :
https://www.ondrovo.com/a/20170207-esp-consumption/
Il est inutile de vouloir l'alimenter avec une source incapable de fournir ce courant (une batterie 9V par exemple).

1.3. Autonomie

La capacité de la batterie à utiliser dépendra de plusieurs facteurs :
  • consommation de la carte utilisée
  • consommation des capteurs
  • courant de repos du régulateur de tension
  • fréquence des réveils
  • etc.
Dans le présent article vous trouverez la description de quelques cartes ESP8266 et ESP32 avec leurs consommations respectives.

Dans cet autre article vous trouverez les caractéristiques de consommation de nombreux capteurs de température, humidité, pression et lumière :
https://riton-duino.blogspot.com/2018/12/les-capteurs-de-temperature-humidite.html

Lisez également celui-ci : https://riton-duino.blogspot.com/2019/02/alimenter-un-arduino-sur-pile-ou.html
Ce article vous fournira aussi d'autres renseignements :
  • utilisation éventuelle d'un régulateur
  • calcul de l'autonomie
  • vérification de la consommation
  • surveillance de la tension de la batterie
Si vous tenez absolument à alimenter l'ESP8266 ou l'ESP32 avec une batterie LITHIUM-ION ou LIPO, cet article vous aidera dans le choix de votre régulateur :
https://riton-duino.blogspot.com/2018/11/les-regulateurs-ldo.html
Le modèle choisi devra être capable de débiter 500mA.

2. L'ESP8266

2.1. Le firmware

L'ESP8266 peut être chargé avec différentes firmwares :
  • le firmware "AT commands"
  • le firmware NodeMCU
  • le firmware MicroPython
  • etc.
  • et enfin un firmware développé par vous-même avec l'IDE ARDUINO ou le SDK Espressif
Le firmware AT n'est utile que dans le cadre du pilotage d'un ESP8266 par un autre microcontrôleur ARDUINO ou autre, en passant par la ligne série. Cette solution était auparavant assez utilisée mais elle est en perte de vitesse. Il est difficile d'obtenir un résultat performant en utilisant ce moyen.
Et pourquoi s'encombrer d'un ARDUINO alors qu'un ESP8266 sait tout faire et bien mieux ?
Justifier ce choix par un nombre de GPIOs et d'entrées ADC plus important pour l'ARDUINO n'est valable que lorsque l'on a affaire à un ESP01, et il est possible d'étendre les GPIOs avec un expander I2C ou SPI. Et autant passer sur un ESP32 pour avoir plus d'entrées ADC, d'autant plus que la résolution est supérieure.

Le firmware NodeMCU et son langage LUA : apparemment le deep-sleep existe. Je ne l'ai pas essayé.

Le firmware MicroPython dispose aussi du deep-sleep.
Je n'ai pas encore essayé MicroPython sur ESP8266 mais j'avoue que je me laisserais facilement tenter.

Dans cet article nous nous intéresserons pour l'instant uniquement au langage C / C++ en utilisant l'IDE ARDUINO.

2.2. Le hardware

Dans une solution basse consommation à base d'ESP8266 il est intéressant d'utiliser le module nu et de l'implanter sur un PCB maison. D'une part cela permet d'être sûr qu'aucun composant superflu ne viendra augmenter la consommation du montage, d'autre part l'encombrement sera réduit.

Par contre pour des besoins de prototypage, il est tout de même plus intéressant de disposer d'une carte enfichable sur une breadboard.

Nous allons commencer par un petit schéma de base :
Ce schéma représente le minimum vital pour pouvoir travailler. L'ESP8266 est équipé de quelques composants et connexions :
  • RESET : un bouton-poussoir permettant le redémarrage
  • FLASH : un bouton-poussoir permettant le chargement
  • R1 : résistance de pull-up du de la broche RST
  • R2 : résistance de pull-up de la broche EN
  • R3 : résistance de pull-up du de la broche GPIO0
  • R4 : résistance de pull-up du de la broche GPIO2
  • FTDI : un connecteur de chargement
  • GPIO15 relié à GND
On peut facilement l'essayer sur une breadboard.

Le connecteur FTDI reçoit les signaux d'un convertisseur USB / série. RX et TX sont croisés bien entendu. On peut aussi alimenter le montage à l'aide du 3.3V du convertisseur.
Il est impératif de choisir un convertisseur 3.3V ou un modèle possédant un cavalier permettant de le basculer en 3.3V :
Il vaut mieux rapprocher les boutons RESET et FLASH pour pouvoir les manipuler avec un seul doigt.

Le chargement par l'IDE ARDUINO se passe de la façon suivante :
  • lancer le chargement
  • presser les boutons RESET et FLASH
  • relâcher le bouton RESET en maintenant le bouton FLASH enfoncé jusqu'au début du chargement (Téléversement ...)
Si le message "error: espcomm_upload_mem failed" s'affiche, revoyez votre câblage, y compris les pins RX TX qui doivent être croisées. Personne n'est à l'abri d'une erreur.

Les cartes du type WEMOS D1 MINI ou NodeMCU vous dispensent de ces manipulations de boutons. Il suffit de lancer le chargement

Chargement automatique
Il est également possible d'obtenir le chargement automatique d'un module ESP8266 nu, tout en conservant le chargement manuel, grâce à l'ajout de quelques composants :
Contrairement à ce qui se passe sur une carte NodeMCU qui a besoin des signaux DTR et RTS, j'ai voulu utiliser un seul fil : DTR ou RTS.
Le front descendant du signal DTR ou RTS est transformé en impulsion à travers un condensateur pour provoquer le reset (en bleu sur l'oscillogramme ci-dessous), tandis que le signal complet est appliqué sur GPIO0 (en jaune sur l'oscillogramme ci-dessous) pour démarrer l'ESP8266 en mode bootloader.

Pourquoi cette manière de procéder ? parce que la majeure partie des convertisseurs USB / série proposent un signal DTR ou RTS, rarement les deux.
 Le condensateur C2 permet d'envoyer juste une impulsion de reset à la pin RST de l'ESP8266.

La diode D1 permet d'éliminer la surtension sur la pin RST lors de la décharge du condensateur C2, surtension visible sur l'oscillogramme ci-dessous.

Le transistor Q1 transmet l'intégralité du signal DTR ou RTS à la pin GPIO0 :


En bleu : la pin RST
En jaune : la pin GPIO0

Ce montage est utilisable de ceux manières :
  • avec un convertisseur USB / série simple (3.3V + GND + RX + TX)
    • appuyer sur les boutons RESET et FLASH
    • lancer le chargement
    • relâcher le bouton RESET au début du chargement (Téléversement ...)
    • relâcher le bouton FLASH quand le chargement à commencé
  • avec un convertisseur USB / série complet (3.3V + GND + RX + TX + DTR ou RTS)
    • lancer le chargement
    • c'est tout

2.3. Les cartes de prototypage

Il existe différents types de cartes dites "breakout" permettant d'implanter un module ESP8266 sur une breadboard.

2.3.1. Adaptateurs simples

Ce sont des cartes simples ne possédant ni convertisseur USB / série ni régulateur de tension. On les trouve sous la dénomination ESP8266 WhiteBoard.
Elles peuvent être équipées d'un régulateur 3.3V et certaines connexions sont déjà réalisées :
  • résistance de 10KΩ entre CH_PD (ou EN) et +3.3V
  • résistance de 10KΩ entre GPIO2 et +3.3V
  • GPIO15 relié à GND
Si l'on veut utiliser une carte de ce type, il nous suffit donc d'ajouter :
  • le bouton RESET
  • le bouton FLASH
  • la résistance R1
  • la résistance R3
  • un FTDI
Ces cartes sont très encombrantes, en particulier en largeur, mais elles conviennent parfaitement au prototypage.

Alimentée en 3.3V, elle devrait avoir la même consommation que le module nu, c'est à dire entre 20µA et 30µA en sommeil profond.

Cet autre modèle existe, encore plus nu, plus étroit (merci à NB pour l'info) :

https://oshpark.com/shared_projects/BREwuIR9

Il nécessite des barettes mâles SMD au pas de 2.54 :
aliexpress.com




2.3.2. La carte WEMOS D1 MINI

Cette carte est un peu plus riche. Elles possède :
  • 11 GPIOs
  • un régulateur 3.3V
  • un convertisseur USB / série CH340
  • des résistances de pull-up sur les broches RST, EN, GPIO0 et GPIO2
  • une résistance de pull-down sur la broche GPIO15
  • quelques condensateurs de découplage
Cette carte occupe un volume raisonnable.
Alimentée en 3.3V, elle devrait consommer environ 100µA en sommeil profond.

2.3.3. La carte NodeMCU
Cette carte, plus ancienne, est plus encombrante. Elle offre à peu près les mêmes caractéristiques que la précédente, avec 17 GPIOs.

Cette carte occupe un volume important.
Alimentée en 3.3V, elle devrait consommer environ 100µA en sommeil profond.

2.3.4. La carte ESP8266-01

Cette carte est très peu encombrante. Elle possède seulement 2 GPIOs.

Un ESP01 sur lequel la LED rouge a été éliminée peut avoir une consommation très basse (20 à 30µA). Cela se fait très facilement en la faisant sauter avec l'ongle.

Par contre elle ne vous offrira pas la possibilité de se réveiller périodiquement, sauf si vous reliez la pin GPIO16 à la pin RESET à l'aide d'un petit fil soudé sur les pattes du processeur. Je vous conseille le fil à wrapper, un fer à souder avec pointe fine et une bonne loupe frontale.

Pour l'enficher sur une breadboard vous aurez besoin de ceci :

Pour charger l'ESP01 le câblage est celui-ci :
Ce schéma est inspiré de celui de l'ESP8266 plus haut (voir les explications ICI). Il permet d'obtenir un chargement automatique ou manuel.

2.4. Le sommeil profond

Nous allons nous intéresser à un seul mode de sommeil, le deep-sleep, seul capable d'assurer une consommation suffisamment faible pour pouvoir fonctionner sur batterie avec une autonomie suffisante.
Le sommeil profond est obtenu par un appel à une méthode de la librairie ESP :

ESP.deepSleep(µs);

L'ESP8266 sera réveillé soit quand le temps spécifié sera écoulé, soit sur un signal sur une de ses entrées.

En fait, contrairement à ce qui se passe sur un ARDUINO, le réveil par GPIO n'existe pas sur un ESP8266. Nous devons provoquer un reset et le logiciel devra aller consulter les informations de reset et lire l'état de la GPIO pour connaître la cause du réveil.

Vous allez certainement remarquer que cela implique un redémarrage complet, avec déroulement du startup, de l'initialisation de la librairie C / C++ et donc une énorme perte de temps.
Oui, mais il ne faut pas oublier qu'il faudra aussi reconnecter le modem au réseau WIFI, ce qui prend aussi beaucoup de temps.

L'ESP8266, tout comme l'ESP32 n'est pas conçu pour traiter rapidement des interruptions internes ou externes quand il est en sommeil profond, comme pourraient le faire un ATMEGA ou un STM32.

Nous allons partir d'un exemple concret, un montage destiné à de la surveillance :
  • un capteur de température (réveil cyclique)
  • deux capteurs de passage PIR (réveil par une GPIO)
Comme notre montage n'a pas la possibilité de se comporter comme un serveur WEB, nous pouvons envoyer des événements sous diverse formes :
  • envoyer une requête HTTP à un serveur
  • envoyer des données en JSON à un serveur DOMOTICZ ou JEEDOM
  • envoyer un mail
  • etc.
Pour cet exemple j'ai choisi d'envoyer un mail.

On trouve beaucoup de documentation sur le WEB :
https://projetsdiy.fr/esp8266-client-web-exemples-communication-tcp-ip-esp8266wifi-esp8266httpclient/
https://projetsdiy.fr/esp8266-client-web-envoyer-donnees-domoticz-tcpip-api-json/
https://projetsdiy.fr/envoyer-donnees-jeedom-api-json-http-esp8266/

Pour obtenir les deux modes de réveil il va nous falloir ajouter quelques petites choses à notre carte :
2.4.1. Réveil par un PIR
Pour réveiller l'ESP8266 en sommeil il nous faut générer une impulsion de courte durée sur la pin RST. Au repos cette PIN est à UN. Il va falloir générer un ZÉRO pendant un temps court : 1ms par exemple.

Or la sortie d'un PIR est à ZÉRO au repos et génère lors des détections de passage une impulsion positive très longue qui ne convient évidemment pas.

En regardant le schéma, à gauche, la sortie du PIR attaque un condensateur puis la base d'un transistor NPN. La constante de temps 1µF x 1KΩ est de 1ms.

Le front montant du signal du PIR va produire une impulsion positive sur la base du transistor qui va conduire et ramener le potentiel de la pin RST à ZÉRO durant environ 1ms.

La sortie du PIR1 est reliée également à GPIO4 et la sortie du PIR2 à GPIO12 afin que le logiciel puisse consulter l'état de ces entrées.

Les deux résistances R1, R2, R4 et R5 permettent de décharger le condensateur et de revenir à l'état de repos.

J'ai utilisé des boutons poussoirs pour simuler les PIRs. Si de vrais capteurs PIR sont utilisés les résistances R1 et R2 sont inutiles.
Elles doivent seulement être présentes si des contacts secs sont utilisés (interrupteur, relais, ILS, etc). Elles servent de résistances pull-down.


2.4.2. Possibilités
Si à l'entrée nous avions autre chose qu'un PIR, il faudrait adapter.

Dans le cas d'une source produisant une impulsion vers le bas, on pourrait remplacer le NPN par un PNP :
Comme nous avons deux entrées pour les PIRs, il nous faudrait implémenter deux de ces circuits.

Si la source produit une impulsion trop courte, l'ESP8266 va redémarrer mais le logiciel n'aura pas le temps de lire la GPIO. Il faudrait dans ce cas insérer un monostable :
Ce circuit produit une impulsion positive de 500ms sur GPIO4, largement suffisante pour que l'ESP8266 aie le temps de démarrer.

Ce monostable déclenche sur un front montant en entrée. Pour implémenter un monostable déclenchant sur front descendant, remplacer tout simplement la porte OR (CD4071) par un porte AND (CD4081).

Comme nous avons deux entrées à surveiller, il nous faudrait implémenter deux de ces circuits.

2.4.3. Réveil périodique
Le deuxième cas, le réveil périodique, est obtenu en reliant GPIO16 à la pin RST. GPIO16 est une pin utilisée par le circuit RTC de l'ESP8266 qui lorsque le timer arrivera à échéance, générera l'impulsion qui nous intéresse.

2.4.4. RemarquesL'électronique de déclenchement de réveil pour l'ESP8266 est assez conséquente, surtout si plusieurs entrées de réveil doivent être implémentées. Pour chaque entrée on a besoin de :
  • 1 condensateur
  • 3 résistances
  • 1 transistor
Si les impulsions sur les entrées sont courtes c'est encore pire. Pour chaque entrée on a besoin de :
  • 2 condensateurs
  • 4 résistances
  • 1 monostable
  • 1 transistor
Le circuit utilisé, le CD4071 possède 4 portes OR, donc il est possible d'implémenter 4 entrées avec un seul CD4071, mais c'est une piètre consolation.

Comparativement l'ESP32 n'a besoin d'aucun composant additionnel.
Si vous envisagez de réveiller un ESP8266 par une ou plusieurs entrées digitales, optez plutôt pour l'ESP32.
Voir paragraphe 3. L'ESP32.

Nous voici donc avec un schéma permettant de mettre en œuvre les deux cas de réveil qui nous intéressent.

2.5. Le sketch

Voici un exemple de sketch :

#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define SMTP_PORT     587
#define MOTION_PIN1   4
#define MOTION_PIN2   12
#define ONE_WIRE_PIN  5
#define SLEEP_TIME    (30*60)

enum rst_reason {
  REASON_DEFAULT_RST      = 0,         /* normal startup by power on */
  REASON_WDT_RST               = 1,         /* hardware watch dog reset */
  REASON_EXCEPTION_RST  = 2,        /* exception reset, GPIO status won’t change */
  REASON_SOFT_WDT_RST    = 3,        /* software watch dog reset, GPIO status won’t change */
  REASON_SOFT_RESTART     = 4,        /* software restart ,system_restart */
  REASON_DEEP_SLEEP_AWAKE = 5,   /* wake up from deep-sleep */
  REASON_EXT_SYS_RST      = 6            /* external system reset */
};

struct rst_info
{
  uint32 reason;
  uint32 exccause;
  uint32 epc1;
  uint32 epc2;
  uint32 epc3;
  uint32 excvaddr;
  uint32 depc;
};

const char* ssid = "Livebox-XXXX";
const char* password = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
char server[] = "smtp.xxxxxx.xx";
// Change to your base64, ASCII encoded user
const char userID[] = "XxXx
XxXxXxXx";
// change to your base64, ASCII encoded password
const char userPWD[] = "Yy
YyYyYyYyYyYy";
// sender
const char sender[] = "sender@xxxxxx.xx";
// recipent
const char recipient[] = "xxxxx.xxxxxxxx@gmail.com";
WiFiClient client;
OneWire oneWire(ONE_WIRE_PIN  );
DallasTemperature DS18B20(&oneWire);

void setup()
{
  int motionPin1;
  int motionPin2;
  rst_info *resetInfo;
  byte ret;

  Serial.begin(115200);
  resetInfo = ESP.getResetInfoPtr();
  Serial.print( "Wakeup reason: ");
  Serial.println((*resetInfo).reason);
  pinMode(MOTION_PIN1, INPUT_PULLUP);
  pinMode(MOTION_PIN2, INPUT_PULLUP);
  motionPin1 = digitalRead(MOTION_PIN1);
  motionPin2 = digitalRead(MOTION_PIN2);
  Serial.print("Motion1: ");
  Serial.println(motionPin1);
  Serial.print("Motion2: ");
  Serial.println(motionPin2);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)   {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.print("IPess: ");
  Serial.println(WiFi.localIP());
  switch (resetInfo->reason) {
    case REASON_DEFAULT_RST:
      ret = sendEmail("**** Just Started ****");
      break;
    case REASON_WDT_RST:
      ret = sendEmail("**** Watchdog Reset ****");
      break;
    case REASON_EXCEPTION_RST:
      ret = sendEmail("**** Exception Reset ****");
      break;
    case REASON_SOFT_WDT_RST:
      ret = sendEmail("**** Software Watchdog Reset ****");
      break;
    case REASON_SOFT_RESTART:
      ret = sendEmail("**** Software Reset ****");
      break;
    case REASON_DEEP_SLEEP_AWAKE:
      if (motionPin1) {
        ret = sendEmail("**** Motion1 Detected ****");
      }
      if (motionPin2) {
        ret = sendEmail("**** Motion2 Detected ****");
      }
      if (!motionPin1 && !motionPin2) {
        char temp[6];
        char s[32];
        dtostrf(getTemperature(), 5, 2, temp);
        sprintf(s, "**** temperture is %s ****", temp);
        ret = sendEmail(s);
      }
      break;
    case REASON_EXT_SYS_RST:
      ret = sendEmail("**** System Reset ****");
      break;
  }
  Serial.print("Going into deep sleep for ");
  Serial.print(SLEEP_TIME);
  Serial.println(" seconds");
  ESP.deepSleep(1000000L * SLEEP_TIME);
}

void loop()
{
}

byte sendEmail(const char *data)
{
  byte thisByte = 0;
  byte respCode;

  if (client.connect(server, SMTP_PORT) == 1) {
    Serial.println(F("connected"));
  } else {
    Serial.println(F("connection failed"));
    return 0;
  }
  if (!recv()) return 0;

  Serial.println(F("Sending HELLO"));
  client.println("EHLO www.example.com");
  if (!recv()) return 0;
  Serial.println(F("Sending auth login"));
  client.println("auth login");
  if (!recv()) return 0;
  Serial.println(F("Sending User"));
  client.println(userID);
  if (!recv()) return 0;
  Serial.println(F("Sending Password"));
  client.println(userPWD);
  if (!recv()) return 0;
  Serial.print(F("Sending From ")); Serial.println(sender);
  client.print(F("MAIL From: ")); client.println(sender);
  if (!recv()) return 0;
  Serial.print(F("Sending To ")); Serial.println(recipient);
  client.print(F("RCPT To: ")); client.println(recipient);
  if (!recv()) return 0;
  Serial.println(F("Sending DATA"));
  client.println(F("DATA"));
  if (!recv()) return 0;
  Serial.println(F("Sending email"));
  client.print(F("To: ")); client.println(recipient);
  client.print(F("From: ")); client.println(sender);
  client.println(F("Subject: My first Email from ESp8266\r\n"));
  client.print(F("From ESP8266 N° "));
  client.println(ESP.getChipId(), HEX);
  Serial.println(data);
  client.println(data);
  client.println(F("."));
  if (!recv()) return 0;
  Serial.println(F("Sending QUIT"));
  client.println(F("QUIT"));
  if (!recv()) return 0;
  client.stop();
  Serial.println(F("disconnected"));
  return 1;
}

byte recv()
{
  byte respCode;
  byte thisByte;
  int loopCount = 0;
  while (!client.available()) {
    delay(1);
    loopCount++;
    if (loopCount > 10000) {
      client.stop();
      Serial.println(F("\r\nTimeout"));
      return 0;
    }
  }
  respCode = client.peek();
  while (client.available()) {
    thisByte = client.read();
    Serial.write(thisByte);
  }
  if (respCode >= '4') {
    return 0;
  }
  return 1;
}

float getTemperature() {
  float tempC;
  do {
    DS18B20.requestTemperatures();
    tempC = DS18B20.getTempCByIndex(0);
    delay(100);
  } while (tempC == 85.0 || tempC == (-127.0));
  return tempC;
}

Comme on peut le constater ce code envoie un mail différent pour chaque cause de reset : reset système, réveil, exception, etc.
La lecture des pins GPIO4 et GPIO12 permet de déterminer la cause du réveil.
Comme il n'est pas possible de détecter l'impulsion sur GPIO16 dans le logiciel, on considère que le timer a déclenché le réveil si GPIO4 et GPIO12 sont à zéro.

Il vous faudra bien sûr remplacer certaines valeurs :

Le SSID de votre box

const char* ssid = "Livebox-XXXX";

Le mot de passe WIFI de votre box :

const char* password = "XXXXXXXXXXXXXXXXXXXXXXXXXX";

L'adresse de votre serveur de messagerie :

char server[] = "smtp.xxxxxx.xx";

Le port SMTP utilisé par votre serveur :

#define SMTP_PORT     587

Votre identifiant de messagerie codé en base64 :

const char userID[] = "XxXxXxXxXxXx";
Votre mot de passe de messagerie codé en base64 :

const char userPWD[] = "YyYyYyYyYyYyYy";

L'adresse mail de l'expéditeur du message :

const char sender[] = "sender@xxxxxx.xx";

L'adresse mail du destinataire du message :

const char recipient[] = "xxxxx.xxxxxxxx@gmail.com";

Pour encoder un identifiant ou un mot de passe en base64 :

Sous LINUX utiliser la commande base64.

Sinon :

https://www.base64encode.org/

2.6. L'IDE ARDUINO

Il vous faudra bien entendu installer le support ESP8266 :
https://github.com/esp8266/Arduino#installing-with-boards-manager

Il vous faut aussi installer deux librairies :
https://github.com/PaulStoffregen/OneWire.git
https://github.com/milesburton/Arduino-Temperature-Control-Library.git

De préférence installez la dernière version.

3. L'ESP32

3.1. Le firmware

Ici encore nous nous intéresserons pour l'instant uniquement au langage C / C++ en utilisant l'IDE ARDUINO.

3.2. Le hardware

Je n'ai pas testé de module ESP32 seul.

A première vue, le schéma minimal devrait être celui-ci :
Le connecteur marqué FTDI permet de raccorder un convertisseur USB / série.
Il faut bien sûr croiser TX et RX.
Rappel: il est impératif de choisir un convertisseur 3.3V ou un modèle possédant un cavalier permettant de le basculer en 3.3V :
Ce schéma devrait pouvoir permettre d'obtenir le chargement de l'ESP32 sans avoir à agir sur les boutons RESET (EN) et BOOT.
La pin GPIO0 possède déjà sa propre résistance interne de pull-up.

3.3. Les cartes de prototypage

3.3.1. Adaptateur simple

Ce sont des cartes simples ne possédant ni convertisseur USB / série ni régulateur de tension.

3.3.2. L'ESP-WROOM-32
Cette carte est la seule que j'aie testé.
Elle possède un port USB, un convertisseur USB / série CH340, un régulateur 3.3V et des boutons EN (RESET) et BOOT. Il faut appuyer sur BOOT avant le chargement par l'IDE ARDUINO.

Il est possible de se passer du port USB si l'on désire alimenter la carte directement en 3.3V, en éliminant du même coup la consommation du CH340.
Un FTDI sera câblé sur les broches de la carte :
  • GND du FTDI sur GND de la carte
  • RX du FTDI sur TX0 de la carte
  • TX du FTDI sur RX0 de la carte
  • DTR du FTDI sur EN de la carte
Le CTS du FTDI aurait pu être connecté sur la pin GPIO0 mais celle-ci n'est pas disponible sur les broches de la carte. Il faudra appuyer sur BOOT avant le chargement par l'IDE ARDUINO.

Cette carte consomme trop en sommeil profond : 3mA.
On est loin des 5µA attendus, mais elle nous permettra d'effectuer la mise en œuvre logicielle sans problème.


3.3.3. La FireBeatle
Cette carte semble être une des moins gourmande du marché, avec 10µA de consommation en sommeil profond.

Elle dispose d'un connecteur pour une batterie LITHIUM-ION ou LIPO. Elle est capable de recharger la batterie à partir du 5V ou de son connecteur USB.
Un TP4056 est implanté sur la carte.

3.3.4. La WEMOS LOLIN D32


Cette carte est censée consommer 150µA en sommeil profond.

Elle dispose également d'un connecteur pour une batterie LITHIUM-ION ou LIPO. Elle est capable de recharger la batterie à partir de son connecteur USB.

3.3.5. La WEMOS LOLIN32 (ancienne version de la D32)
Cette carte est censée consommer 170µA en sommeil profond.

Elle dispose également d'un connecteur pour une batterie LITHIUM-ION ou LIPO. Elle est capable de recharger la batterie à partir de son connecteur USB.


3.4. Le sommeil profond

Le sommeil profond a un fonctionnement différent de celui de l'ESP8266.

L'ESP32 est capable de faire la distinction entre plusieurs sources de réveil :
  • un réveil par une GPIO (ext0)
  • un réveil par plusieurs GPIOs (ext1)
  • un réveil par le touchpad
  • un réveil par RTC
Il est possible d'activer l'une ou l'autre ou plusieurs.

Réveil par une GPIO (0, 2, 4, 12 à 15, 25 à 27, 32 à 39) :

esp_sleep_enable_ext0_wakeup(gpio, state);

Dans ce mode, les GPIOs peuvent bénéficier de résistances internes de pull-up ou pull-down :

#include <driver/rtc_io.h>
rtc_gpio_pullup_en(gpio);

rtc_gpio_pulldown_en(gpio);

Réveil par plusieurs GPIOs (32 à 39) :

esp_sleep_enable_ext1_wakeup(gpios, state);

Dans ce mode, les GPIOs devront être équipées de pull-up ou pull-down matérielles externes.

Réveil par le touchpad :

touchAttachInterrupt(pad, callback, threshold);
esp_sleep_enable_touchpad_wakeup();


Réveil par la RTC :

esp_sleep_enable_timer_wakeup(µs);

Activation du mode deep-sleep :

esp_deep_sleep_start();

Lors du réveil la fonction esp_sleep_get_wakeup_cause() sera appelée pour connaître la cause du réveil :

switch (esp_sleep_get_wakeup_cause()) {
    case ESP_SLEEP_WAKEUP_EXT0:
      Serial.println("Wakeup by EXT0");
      break;
    case ESP_SLEEP_WAKEUP_EXT1:
      Serial.println("Wakeup by EXT1");
      break;
    case ESP_SLEEP_WAKEUP_TIMER:
      Serial.println("Wakeup by RTC");
      break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD:
      Serial.println("Wakeup by TouchPad");
      break;
}

Si le réveil par plusieurs GPIOs a été activé, il est possible de déterminer quelle GPIO a provoqué le réveil :

uint64_t wakeupBit = esp_sleep_get_ext1_wakeup_status();
if (wakeupBit & GPIO_SEL_33) {
  // GPIO 33 woke up
}
else if (wakeupBit & GPIO_SEL_34) {
  // GPIO 34
}


Et enfin, si le réveil par le touchpad a été activé, il est possible de déterminer quelle touche a provoqué le réveil :

touch_pad_t touchPin = esp_sleep_get_touchpad_wakeup_status();
switch(touchPin) {
  case 0  : Serial.println("Touch detected on GPIO 4"); break;
  case 1  : Serial.println("Touch detected on GPIO 0"); break;
  case 2  : Serial.println("Touch detected on GPIO 2"); break;
  case 3  : Serial.println("Touch detected on GPIO 15"); break;
  case 4  : Serial.println("Touch detected on GPIO 13"); break;
  case 5  : Serial.println("Touch detected on GPIO 12"); break;
  case 6  : Serial.println("Touch detected on GPIO 14"); break;
  case 7  : Serial.println("Touch detected on GPIO 27"); break;
  case 8  : Serial.println("Touch detected on GPIO 33"); break;
  case 9  : Serial.println("Touch detected on GPIO 32"); break;
  default : Serial.println("Wakeup not by touchpad"); break;
}


Nous allons partir du même exemple de client mail que pour l'ESP8266 :
  • un capteur de température (réveil cyclique)
  • un ou deux capteurs de passage PIR (réveil par GPIO)
Voici un petit schéma :

Comme vous pouvez le constater, par rapport au même schéma utilisant un ESP8266, celui-ci est beaucoup plus simple.

Les boutons poussoirs simulent les PIRs. Si de vrais capteurs PIR sont utilisés les résistances R2 et R3 sont inutiles.

Bien sûr, si l'on utilise une ESP-WROOM-32, seuls les boutons poussoirs doivent être câblés.

Si un seul bouton poussoir est utilisé sur GPIO33 :
Dans ce cas, connecter un bouton poussoir entre 3.3V et GPIO33, sans résistance de pull-down.

Si deux boutons poussoirs sont utilisés sur les GPIO32 et GPIO33 :
Dans ce cas, connecter deux boutons poussoirs entre 3.3V et GPIO32 et GPIO33, avec 2 résistances de pull-down.


3.4.1. Réveil par un ou deux PIR
Le problème est simplifié par rapport à l'ESP8266. Il est possible de spécifier sur quelle GPIO le processeur peut être réveillé. Dans l'exemple, GPIO_32 et GPIO_33 sont utilisées.

3.4.2. Possibilités
Contrairement à ce qui se passait sur l'ESP8266 le front montant ou descendant de la source de réveil peut être choisi.
Il n'y aura pas de modification hardware à apporter pour inverser le signal.

On pourra également activer des résistances internes de pull-up ou pull-down en cas de besoin.

Également il n'y aura pas besoin de maintenir le signal sur la ou les GPIOs si les impulsions de réveil sont courtes.

3.4.3. Réveil périodique
Ici également, il n'y a pas de modification hardware à réaliser pour prendre en compte le réveil par la RTC.

3.5. Le sketch

Le sketch suivant est prévu pour fonctionner dans deux modes :

Un seul bouton poussoir sur la GPIO33 :
Dans ce cas, connecter un bouton poussoir entre 3.3V et GPIO33, sans résistance de pull-down.
Commenter la ligne suivante :

//#define EXT1_WAKEUP

Deux boutons poussoirs sur les GPIO32 et GPIO33 :
Dans ce cas, connecter deux boutons poussoirs entre 3.3V et GPIO32 et GPIO33, avec 2 résistances de pull-down.
Décommenter la ligne suivante :

#define EXT1_WAKEUP

Le sketch :

#include <WiFi.h>
#include <rom/rtc.h>
#include <driver/rtc_io.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define SMTP_PORT     587
#define ONE_WIRE_PIN  5
#define SLEEP_TIME    (30*60)


#define EXT1_WAKEUP

#ifdef EXT1_WAKEUP
#define BUTTON_PIN_BITMASK 0x300000000
#endif

const char* ssid = "Livebox-XXXX";
const char* password = "XXXXXXXXXXXXXXXXXXXXXXXXXX";
char server[] = "smtp.xxxxxx.xx";
// Change to your base64, ASCII encoded user
const char userID[] = "XxXx
XxXxXxXx";
// change to your base64, ASCII encoded password
const char userPWD[] = "Yy
YyYyYyYyYyYy";
// sender
const char sender[] = "sender@xxxxxx.xx";
// recipent
const char recipient[] = "xxxxx.xxxxxxxx@gmail.com";
 


WiFiClient client;
OneWire oneWire(ONE_WIRE_PIN  );
DallasTemperature DS18B20(&oneWire);

void setup()
{
  byte ret;
  uint64_t wakeup_pin_mask;

  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)   {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.print("IPess: ");
  Serial.println(WiFi.localIP());
  switch (esp_sleep_get_wakeup_cause()) {
    case ESP_SLEEP_WAKEUP_EXT0:
      ret = sendEmail("**** Motion Detected ****");
      break;
    case ESP_SLEEP_WAKEUP_EXT1:
#ifdef EXT1_WAKEUP
      wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status();
      if (wakeup_pin_mask & GPIO_SEL_32) {
        ret = sendEmail("**** Motion1 Detected ****");
      }
      if (wakeup_pin_mask & GPIO_SEL_33) {
        ret = sendEmail("**** Motion2 Detected ****");
      }
      else {
      }
      break;
#endif
    case ESP_SLEEP_WAKEUP_TIMER:
      char temp[6];
      char s[32];
      dtostrf(getTemperature(), 5, 2, temp);
      sprintf(s, "**** temperture is %s ****", temp);
      ret = sendEmail(s);
      break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD:
      ret = sendEmail("**** TOUCH ****");
      break;
    case ESP_SLEEP_WAKEUP_ULP:
      ret = sendEmail("**** ULP ****");
      break;
    default:
      ret = sendEmail("**** Just Started ****");
      break;
  }
  Serial.print("Going into deep sleep for ");
  Serial.print(SLEEP_TIME);
  Serial.println(" seconds");
  delay(50);
  esp_sleep_enable_timer_wakeup(1000000L * SLEEP_TIME);
#ifdef EXT1_WAKEUP
  esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ANY_HIGH);
  // internal pull-ups not available !!!
#else
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1);
  rtc_gpio_pulldown_en(GPIO_NUM_33);
#endif
  esp_deep_sleep_start();
}

void loop()
{
}

byte sendEmail(const char *data)
{
  byte thisByte = 0;
  byte respCode;

  if (client.connect(server, SMTP_PORT) == 1) {
    Serial.println(F("connected"));
  } else {
    Serial.println(F("connection failed"));
    return 0;
  }
  if (!recv()) return 0;

  Serial.println(F("Sending HELLO"));
  client.println("EHLO www.example.com");
  if (!recv()) return 0;
  Serial.println(F("Sending auth login"));
  client.println("auth login");
  if (!recv()) return 0;
  Serial.println(F("Sending User"));
  client.println(userID);
  if (!recv()) return 0;
  Serial.println(F("Sending Password"));
  client.println(userPWD);
  if (!recv()) return 0;
  Serial.print(F("Sending From ")); Serial.println(sender);
  client.print(F("MAIL From: ")); client.println(sender);
  if (!recv()) return 0;
  Serial.print(F("Sending To ")); Serial.println(recipient);
  client.print(F("RCPT To: ")); client.println(recipient);
  if (!recv()) return 0;
  Serial.println(F("Sending DATA"));
  client.println(F("DATA"));
  if (!recv()) return 0;
  Serial.println(F("Sending email"));
  client.print(F("To: ")); client.println(recipient);
  client.print(F("From: ")); client.println(sender);
  client.println(F("Subject: My first Email from ESP32\r\n"));
  client.print(F("From ESP32 N° "));
  uint64_t chipID = ESP.getEfuseMac();
  client.println((uint16_t)(chipID >> 32), HEX);
  Serial.println(data);
  client.println(data);
  client.println(F("."));
  if (!recv()) return 0;
  Serial.println(F("Sending QUIT"));
  client.println(F("QUIT"));
  if (!recv()) return 0;
  client.stop();
  Serial.println(F("disconnected"));
  return 1;
}

byte recv()
{
  byte respCode;
  byte thisByte;
  int loopCount = 0;
  while (!client.available()) {
    delay(1);
    loopCount++;
    if (loopCount > 10000) {
      client.stop();
      Serial.println(F("\r\nTimeout"));
      return 0;
    }
  }
  respCode = client.peek();
  while (client.available()) {
    thisByte = client.read();
    Serial.write(thisByte);
  }

  if (respCode >= '4') {
    //  efail();
    return 0;
  }
  return 1;
}

float getTemperature() {
  float tempC;
  do {
    DS18B20.requestTemperatures();
    tempC = DS18B20.getTempCByIndex(0);
    delay(100);
  } while (tempC == 85.0 || tempC == (-127.0));
  return tempC;
}


Le code est simplifié par rapport à celui de l'ESP8266.

Il vous faudra bien sûr remplacer certaines valeurs (ssid, password, etc.) comme dans l'exemple de l'ESP8266.

La directive suivante permet d'attendre un réveil sur les deux GPIOs 32 et 33 :

#define EXT1_WAKEUP

Si la directive est commentée, seule la GPIO 33 est surveillée :

// #define EXT1_WAKEUP

3.6. L'IDE ARDUINO

Il vous faudra bien entendu installer le support ESP32 :
https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/boards_manager.md

Il vous faut aussi installer deux librairies :
https://github.com/PaulStoffregen/OneWire.git
https://github.com/milesburton/Arduino-Temperature-Control-Library.git

De préférence installez la dernière version.

4. Conclusion

J'ai réalisé le montage ESP8266 avec un ESP8266-12E soudé sur une carte adaptatrice simple. Il consomme 19µA au repos.

Une batterie de 200mAH suffirait pour l'alimenter pendant plus d'un an en sommeil profond, mais comme ce montage se réveille toutes les 30 minutes, pour avoir une bonne idée de la consommation globale il faudra tenir compte de la consommation pendant les périodes d'éveil (connexion WIFI plus ou moins longue, temps de transmission, etc.).

L'électronique de déclenchement de réveil pour l'ESP8266 est conséquente, surtout si plusieurs entrées de réveil doivent être implémentées, alors que l'ESP32 n'a besoin d'aucun composant additionnel.

Pour l'instant le montage à base d'ESP32-WROOM-32 consomme trop : 3mA en deep-sleep. 
La carte choisie n'est pas adaptée à ce que j'avais l'intention de faire.

J'espère que ce petit document vous aidera.

Cordialement
Henri


5. Lien utiles

Les capteurs de température, humidité, pression & luminosité 
Alimenter un ARDUINO sur Pile ou Batterie
Les régulateurs LDO
ESP32 Deep Sleep & Its Wake-up Sources


6. Mises à jour

25/02/2019 : ajout 3. L'ESP32
26/02/2019 : ajout 1. Alimentation sur batterie
                              3.3.3. La FireBeatle
                              3.3.4. La WEMOS LOLIN D32
                              3.3.5. La WEMOS TTGO
                              ESP8266 : utilisation de 2 capteurs PIR
                              2.4.4. Remarques
27/02/2019 : 2.3.4. La carte ESP8266-01 : ajout chargement automatique

43 commentaires:

  1. Salut,

    Concernant l'adaptateur pour esp8266-12, j'ai trouvé il y a deux ans, l'adaptateur suivant https://oshpark.com/shared_projects/BREwuIR9. Il est très étroit. Attention aux connecteurs, ce sont des modèles particuliers. Des SMT SMD https://fr.aliexpress.com/item/32767247777.html?spm=a2g0o.productlist.0.0.547f3120i0u9ua&algo_pvid=03f71d0d-821e-4c21-be55-3f00e55fca69&algo_expid=03f71d0d-821e-4c21-be55-3f00e55fca69-19&btsid=93c4a514-a48f-4529-a051-546634578bb3&ws_ab_test=searchweb0_0,searchweb201602_3,searchweb201603_52

    Il y a une petite vidéo très instructive: https://www.youtube.com/watch?v=_8egHjES1Tc

    Désolé, je n'ai pas trouvé comment mettre des liens plus sympa dans ce commentaire.

    RépondreSupprimer
    Réponses
    1. J'utilise un adaptateur uniquement dans le cas d'un prototypage sur breadboard.

      Pour ce qui est du PCB final j'implante l'ESP8266 directement sur la carte, sans adaptateur.

      Je vais quand même ajouter l'info.
      Merci.

      Supprimer
  2. Salut Henri,
    Je viens d'essayer l'ESP32 seul.
    Concernant le point 3.2 (L'ESP32 - Le hardware), c'est bon pour la partie reset, pas pour la partie GPIO0. Je suis obligé d'appuyer sur boot pour pouvoir flasher.
    Pour le bouton reset, ce n'est pas nécessaire.

    RépondreSupprimer
  3. J'ai regardé le schéma de la Wemos LOLIN32, car j'en ai une, et il y a un auto reset. Le schéma est là: https://wiki.wemos.cc/_media/products:lolin32:sch_lolin32_v1.0.0.pdf
    On y utilise un circuit (UMH3N) à base de deux transistors NPN, et une résistance à la base.
    J'essayerai à l'occasion, mais honnêtement ça ne me dérange pas d'appuyer sur les boutons. Pour le reste le schéma fonctionne très bien.
    En fait, je veux essayer le mode deep sleep sur l4SP32 nu pour continuer mes tests du banc de mesure, l'ESP8266 me posant trop de problèmes.

    RépondreSupprimer
    Réponses
    1. J'ai bien peur que l'ESP32 consomme autant au démarrage.

      Supprimer
  4. bonjour,
    j'ai réalisé un circuit avec une pile 3.7v, un esp8266 12, et un dht22 qui envoi sur une IP (stockée dans l'eeprom et modifiable par requète http) la température.
    il se met en deep sleep toutes les 10 minutes, tout va bien, je reçois sur le serveur les températures.

    le pb est que le dht 22 est branché sur le pin 5v, et qu'il reste allumé même en deep sleep.
    peut faire quelquechose pour qu'il ne soit pas alimenté pendant le deep sleep ?

    merci

    RépondreSupprimer
    Réponses
    1. Salut emanu,

      J'ai eu le même besoin. J'ai branché le + du DHT22 sur une pin de l'esp8266.
      Je mets cette broche à HIGH pour activer le composant, puis la remets à LOW.
      digitalWrite (DHT_POWER, HIGH); // On met sous tension le DHT22
      pinMode (DHT_POWER, OUTPUT); // Place la broche d'alimentation du DHT22 en mode OUTPUT
      delay(2000); // On attend un peu que le DHT22 soit sous tension
      // Attention, il faut au minimum 2 secondes
      // INDISPENSABLE sinon le premier résultat après power up sera faux

      ...
      pinMode (DHT_POWER, INPUT);
      digitalWrite (DHT_POWER, LOW); // On remet hors tension le DHT22

      Attention, l'attente est obligatoire après mise sous tension, sous peine d'avoir un résultat faux.

      Supprimer
    2. C'est exactement ce qu'il faut faire.

      Supprimer
  5. Merci, cet article est très intéressant, mais je suis toujours à la recherche d'une pile de 3,6V pouvant supporter le courant lors du réveil de l'ESP. La pile SAFT LS 14250 tombe rapidement en dessous de 3 V lors du démarrage.
    Connaissez-vous une autre référence de pile capable de supporter ce courant au démarrage.
    merci.

    RépondreSupprimer
    Réponses
    1. https://docs.rs-online.com/05ac/0900766b800cc0c7.pdf
      La datasheet de cette pile indique : 35mA maxi.
      Un ESP8266 consomme plus de 400mA pendant sa phase de connexion WIFI. Très mauvais choix.

      2 solutions :

      Batterie LIFEPO4 3.2V (tension maxi = 3.6V).
      Pas besoin de régulateur

      Batterie LITHIUM-ION 3.7V (tension maxi = 4.2V).
      Il faut un régulateur 3.3V (LDO 500mA), RT9013 par exemple
      Voir https://riton-duino.blogspot.com/2018/11/les-regulateurs-ldo.html

      Supprimer
  6. Merci pour cet article très complet et précis. J'utilise un ESP8266 (Wemos D1 Pro) avec ESPEasy et Jeedom. J'ai utilisé un nonostable CD4071 pour le réveil avec un PIR SR602, mais le temps est encore trop court (500 ms) pour Jeedom, comment passer à 1 seconde (je n'ai aucune formation en électronique).
    Merci

    RépondreSupprimer
    Réponses
    1. Avec un circuit RC le temps est proportionnel à la valeur de R et C. Donc doubler la valeur de la résistance ou du condensateur.

      Supprimer
  7. Bonjour Henri,
    Merci pour ce très intéressant tutoriel !
    Je souhaite développer un objet connecté très simple basé sur un ESP32 connecté à une LED et un bouton poussoir.
    Dans le but de commercialiser cet objet, je souhaite simplifier au maximum la façon de flasher l'ESP32.
    Le plus simple est de demander directement à l'assembleur du PCB de flasher l'ESP32... mais comme je veux pouvoir l'upgrader par la suite (et idéalement permettre à l'utilisateur de le faire lui même), quelle solution me conseillez-vous ... et selon quelle procédure ? Intégration d'un connecteur FTDI (comme sur votre schéma) ? Connexion par connecteur micro-USB (l'utilisateur n'aurait pas besoin d'un câble spécial ? Upload par WiFi (certainement la solution la plus simple pour l'utilisateur) ?
    Merci pour votre aide,
    Arnaud.

    RépondreSupprimer
    Réponses
    1. Connecteur FTDI : le plus simple à concevoir mais peu pratique.
      µUSB : impose la présence d'un FTDI sur la carte.
      WIFI : je n'ai jamais essayé l'OTA, mais c'est certainement la solution idéale.
      https://letmeknow.fr/blog/tag/ota/

      Supprimer
  8. Bonour, j'ai la carte NodeMCU ESP8266 en deepsleep alimenté en 3,3v elle consomme 8/9mA c'est énorme ! A priori le régulateur et l'uart sont toujours alimenté même en 3,3v. J'ai trouvé des infos ici https://tinker.yeoman.com.au/2016/05/29/running-nodemcu-on-a-battery-esp8266-low-power-consumption-revisited/ Mais il n'y a rien de facile sans faire de la soudure :/

    Je pensais partir sur une autre carte ep32 cette fois parmi celle que tu présente comme la wemos lolin d32, as tu des retours réel de consommation en mode deepsleep ?

    RépondreSupprimer
    Réponses
    1. J'ai mesuré 1.7mA en deepsleep sur une LOLIN32, l'ancienne version de la D32.
      Le meilleur moyen pour faire de la basse consommation reste tout de même le module ESP32 nu.

      Supprimer
    2. D'après mes essais ici :
      https://riton-duino.blogspot.com/2018/12/consommation-dune-carte-arduino.html

      En alimentant une NodeMCU en 3.3V, USB débranché, elle consomme 92µA.

      Supprimer
    3. Sur ce projet l'auteur utilise une Adafruit Feather :
      https://forum.arduino.cc/index.php?topic=682190.0
      Le montage complet consomme 1mA.

      Supprimer
  9. Un article complet. Excellent moyen de présentation. Les mots sont correctement pris en charge par des images et des extraits. Ici, par rapport à votre outil mentionné pour le codage base64, il existe un autre outil à cet effet, cet outil est
    url-decode.com/tool/base64-encode
    qui comprend également les outils liés aux utilitaires numériques, au convertisseur d'unité, aux développeurs, aux utilitaires de chaîne, au convertisseur et aux outils IP, ainsi que sous un seul lien. Vous le vérifiez également.

    RépondreSupprimer
  10. Bonjour Henri,

    Bravo pour cette présentation, cela est très clair et pédagogique (cela est d'ailleurs valable pour l'ensemble de votre blog) !!
    Je cherche à intégrer un ESP32 (probablement le nouveau ESP32-C3, pour le bluetooth 5.0) nu sur un pcb car le projet sera tourné basse consommation. Je m'interroge cependant sur l'antenne, savez-vous comment dessiner une antenne sur kicad (par exemple), quels sont les règles à respecter (largeur de piste, forme, isolement avec les autres signaux, ...) ?
    Sinon je sais qu'il existe des antennes céramique certainement plus simple à intégrer sur un pcb, mais je ne connais pas non plus les guidelines à suivre pour une implémentation correcte...
    Je suis preneur de toutes remarques pouvant m'éclairer sur ce sujet !
    Merci,

    Corentin.

    PS : je souhaite que le projet final soit le plus discret possible, j'espère donc pouvoir éviter la présence d'une antenne extérieur au boitier (très désagréable à l’œil).

    RépondreSupprimer
    Réponses
    1. Ce sujet a été abordé ici :
      https://forum.arduino.cc/?topic=670700

      Supprimer
    2. Merci pour ton lien, pas mal d'informations intéressantes y sont ! Je comprends surtout qu'il est bien plus préférable d'utiliser un module intégrant déjà l'antenne vu la complexité que requiert le routage avec des éléments HF.

      Supprimer
    3. C'est également mon avis, et l'encombrement sera le même.

      Supprimer
  11. Bonjour,
    Et merci pour l'article.
    Je débute dans l'utilisation des ESP.
    Je me suis amusé avec une carte de developpement ESP32 DEVKIT.
    Puis maintenant j'aimerai passer au module ESP32 seul pour une meilleure intégration et une consommatio reduite.
    J'essaie d'alimenter l'ESP32 de ma carte de developpement directement sur ces pin 3.3V et GND au préalable j'avais changé mon sketch (qui diffuse un reseau wifi), et rien ne se passe.
    Je pense bien etre à tort qu'il suffit d'alimenter ESP32 en 3.3V sans autre composant.
    Merci d'avance

    RépondreSupprimer
    Réponses
    1. Suivre simplement le schéma paragraphe 3.2.
      Sinon ce projet utilise un module nu :
      https://riton-duino.blogspot.com/2020/01/un-logger-analogique-et-digital-version.html
      Remarque : si le sketch a été chargé, c'est que l'ESP32 est correctement câblé. Voir aussi ce qui se passe sur le moniteur série.

      Supprimer
  12. Bonjour

    Merci pour votre article.

    J'ai une petite question supplémentaire car je suis assez novice.
    Je cherche à faire des interrupteurs wifi muraux (sur pile).
    Je suis équipé pour le moment avec des micromodules Chacon (RF433) mais je trouve que ce n'est pas très réactifs et je voudrais passer en wifi (pour gérer sous Jeedom) pour contrôle probablement des modules Shelly qui remplaceront mes relais Chacon (en attendant de faire mes propres relais).

    Mes 2 contraintes sont l'encombrement (boitier mural) et la consommation (pile ou batterie rechargeable).

    2 bonus seraient de
    - pouvoir recharger par µUSB
    - pouvoir gérer 2 inters (ou de pouvoir faire différentes actions selon le nombre d'appui sur le bouton poussoir (un peut comme les modules Shelly I3 qui sont vraiment bien mais qui nécessitent 220V)

    Du coup, quelle est la carte qui semblerait la plus intéressante à votre avis pour une utilisation simple?

    Niveau consommation, c'est la ESP8266-01 qui semble la plus économe. Dans ce cas, mon bouton poussoir servirait de reset?
    mais j'ai un peu peur du temps de latence entre le moment ou on appui sur le bouton et le moment ou mon ampoule s'allume... (et dans ce cas, je ne peux pas gérer 2 inters)

    Sinon plutôt la FireBeatle ou WEMOS LOLIN D32?

    Existe-t-il d'autre moyen pour réaliser un simple inter wifi ?

    merci d'avance de votre aide!




    RépondreSupprimer
    Réponses
    1. A mon avis un ESP32 (module nu) est plus économe en mode deep-sleep qu'un ESP01. Mais n'est-ce pas un canon pour tuer une mouche ?

      Mais pourquoi passer par le WIFI ?
      Avec un objet connecté MySensors à base d'ARDUINO PRO MINI 3.3V + NRF24L01 il serait possible de consommer moins de 2µA, avec un encombrement très réduit, quitte à utiliser un ATMEGA328P sous forme de chip nu, avec une réactivité supérieure au WIFI.
      https://www.mysensors.org/controller/jeedom
      Ce genre de montage requiert une passerelle, en général un ARDUINO NANO relié au serveur JEEDOM par USB.

      Supprimer
    2. Merci pour votre réponse.
      Effectivement c'est probablement surdimensionné.
      Je suis étonné que sur le marché, ces modules "simples" n'existent pas en wifi alors que l'on trouve des prises wifi à télécommande de partout!

      Je vais regarder les informations que vous m'avez donné.
      L'inconvénient est de repasser par une nouvelle passerelle et d'être lié a Jeedom. Lorsque j'ai commencé mon jeedom, j'ai voulu essayé plusieurs technologies, du coup j'ai plusieurs passerelles et/ou technologies (zigbee, rf433, wifi, BT, ...) cela fait beaucoup de chose et j'avais envie de plutôt recentrer petit à petit sur du wifi.
      La seconde raison est aussi de pouvoir le dissocié du jeedom car si un jour je décide de vendre la maison, c'est compliqué!

      Supprimer
    3. Un module ESP01 consomme une vingtaine de µA en veille, si l'on vire la LED. Cela peut être effectivement une solution intéressante et peu encombrante. Une batterie de 500mAh pourrait assurer une autonomie d'un an.
      Mais il nécessite une petite bidouille pour le tirer du mode deep-sleep par interruption :
      https://www.instructables.com/Enable-DeepSleep-on-an-ESP8266-01/
      Notez bien qu'avec un module ESP8266 (ESP12E par exemple) on pourra obtenir le même résultat, sans bricoler, dans un encombrement équivalent.
      Une carte du genre WEMOS D1 MINI consommera forcément plus (une centaine de µA), et sera plus encombrante.

      D'un module nu ESP8266 à un module nu ESP32 il n'y a qu'un pas. C'est un peu overkill mais il y a un avantage, une consommation inférieure à un ESP8266.

      Le problème est qu'utiliser un module nu impose la réalisation d'un PCB, mais que ce PCB pourra intégrer la batterie, et un chargeur USB (TP4056).

      Ensuite, d'un point de vue logiciel, l'interrupteur WIFI devra envoyer une requête à un module relais WIFI, qui lui sera forcément serveur, et alimenté sur secteur.
      Question latence, il suffit d'essayer pour voir si cela convient.

      Supprimer
    4. Mais le problème est que pour sortir du mode deep-sleep un ESP8266 ou un ESP32 redémarre et doit se reconnecter au réseau WIFI. La latence risque d'être juste énorme.

      Supprimer
  13. Merci pour les conseils.
    J'ai bien peur que la latence soit killer pour cette utilisation.
    Il faut que je trouve autre chose. Je vais peut etre passer sur du zigbee et si un jour je vend la maison, je remettrais les chacon RF ;op

    RépondreSupprimer
  14. Bonjour,
    Merci pour cet excellent article.
    Il me reste une question de novice concernant le passage d'un prototype à une "vraie réalisation" : je comprends qu'il faut utiliser un ESP8266 (ou autre) le plus 'nu' possible pour limiter la consommation des composants annexes. J'imagine qu'il en va de même pour les capteurs (température, humidité, etc.). Pour les capteurs que j'utilise (SHT35 et BMP388) je vois sur les modules du commerce qu'il y a systématiquement un régulateur de tension inclus dans ces modules alors qu'il n'est a priori pas nécessaire vu les plages de tensions en jeu avec une batterie adaptée. Est-il possible de s'en passer ? Vu la taille des capteurs, il me semble impossible (vu mes compétences et mon matériel) de les acheter à l'unité et les souder moi-même sur un circuit maison (qui permettrait d'éliminer ce régulateur). Quelles solutions du coup ? Est-ce envisageable d'un point de vue autonomie de garder les modules complets ? Merci !

    RépondreSupprimer
    Réponses
    1. Le module BMP388 apparemment est équipé de deux broches d'alimentation, 5V et 3.3V. Il suffit d'alimenter par la broche 3.3V, ce qui revient à appliquer du 3.3V sur la sortie du régulateur du module. Cela ne veut pas dire que le régulateur du module ne consommera pas de courant sur sa sortie, mais on peut très bien l'éliminer s'il en consomme trop.
      Les modules SHT31 SHT35 ne comportent pas de régulateur, tout du moins ceux que je connais.

      Supprimer
    2. Arf mince pas le mien, qui n'a qu'une entrée 5V. Ok pour le SHTxx, effectivement, j'avais regardé un peu vite. Merci pour votre réponse!

      Supprimer
  15. Avec un MOSFET ?
    https://riton-duino.blogspot.com/2018/08/alimenter-un-capteur-la-demande.html

    RépondreSupprimer
  16. Je pensais qu'il s'agissait un ESP32 nu.
    L'AMS1117 consomme 5mA.
    C'est assez difficile de jouer dans la basse consommation avec une carte complète. La meilleure : FireBeetle (10µA), équipée d'un RT9080.

    RépondreSupprimer
  17. Bonjour et merci de votre publication, je recherche une solution pour réaliser une montage en autonomie donc sur pile. sur 1 heure, je compte faire une mesure de 5 mn (sur les 5 mn, mon montage consomme environ 50 mA (capteur de CO2 avec préchauffage) " ce qui reste peu, je trouve ") le reste du temps en mode sleep ( je considère que je suis à 20 uA ) mais si je ne me trompe pas cela donne une consommation moyenne d'environ 4 mA h ! ! ! !
    maintenant, si j'utilise une pile "classique" => capacité 1250 mAh
    cela donne une autonomie de 13 / 15 jours maxi !
    donc impossible ! !
    je reste donc déçus, car vraiment peu de montages peuvent fonctionner en autonomie. ( même si esp est en mode sleep, votre montage doit "rien consommer" ou alors très peu de temps ! ! !
    si je raisonne à l'envers :
    esp en mode sleep => conso = 0 !
    pile 1250 mah
    on veut une autonomie de 1 an
    donc : 1250 / ( 365 * 24 ) = 0.14 mA h disponible en 1 heure ! ! !
    si on réveille un esp 1 fois par heure on dépasse déjà cette valeur ?
    je n'ai toujours pas de solution . . .

    RépondreSupprimer
    Réponses
    1. Avec un capteur nécessitant un préchauffage (plusieurs minutes probablement) il sera pratiquement impossible d'être autonome, à moins de disposer d'une recharge solaire.

      Supprimer
  18. Bonjour et merci pour ce blog ! Concernant l'utilisation d'un Panneau solaire associé à un TP4056 pour charger une batterie 18650 dans un montage esp8266, ne risque t'on pas de tromper le fonctionnement du TP4056 par la consommation de l'esp et du coup provoquer une surcharge de la batterie avec les risques connus ?

    RépondreSupprimer
    Réponses
    1. Cela dépend de pas mal de choses.

      Soit l'ESP8266 est serveur et il consomme 100mA à lui tout seul. Dans ce cas, le courant issu du TP4056 alimentera l'ESP8266. La batterie prendra ce qui lui est nécessaire. 100mA est un courant important pour un montage solaire + batterie, à moins de disposer d'un grand panneau, d'une batterie imposante et du chargeur adéquat.

      L'état de charge de la batterie est également à prendre en compte :
      Si la batterie est à moitié pleine, la phase de recharge dite "à courant constant" devrait être ralentie, puisque l'ESP8266 va en consommer une partie, mais ce n'est pas très gênant.

      Par contre si la batterie est presque pleine, le TP4056 aura du mal à gérer la phase de recharge dite "à courant décroissant".

      Donc en gros, en mode serveur, le TP4056 ne pourra probablement jamais assurer une charge complète.

      Soit l'ESP8266 est client, et utilise le mode veille la plupart du temps (20µA dans le meilleur des cas). Dans ce cas, le TP4056 pourra assurer pleinement son rôle. Au matin, si le soleil est au rendez-vous, l'énergie consommée durant la nuit sera vite récupérée.

      Par contre, à mon avis, dans les deux cas il n'y a aucun risque de surcharge de la batterie.

      Supprimer
    2. Salut Henri,
      J'ai trouvé un site génial pour les prototypes.
      https://lectronz.com/products/search?q=flexypin
      C'est valable pour plusieurs contrôleurs, ESP32 et raspberry compris.
      Ils ont les cartes, mais aussi cet ingénieux système qui permet d'enficher les procs. Ils deviennent réutilisables.
      Pas mal aussi pour les flasher séparément.
      J'ai pensé que ça valait la peine de les signaler.
      nb

      Supprimer
    3. Oui, et ce n'est pas excessivement cher.
      Merci.

      Supprimer