Surveiller sa consommation d’eau avec Domoticz et un ESP8266

Voici un montage électronique simple qui permet de surveiller sa consommation domestique d’eau facilement.  Il suffit de quelques composants, un module microcontrôleur basé sur la puce ESP8266 compatible Arduino, et une solution serveur afin de produire de beaux graphiques de consommation.

Dans mon installation d’eau de ville actuelle, la compagnie de distribution d’eau a installé un compteur de type Kent V100 (PSM) de la marque Elster. Ce compteur dispose d’une discrète encoche pour placer un détecteur d’impulsion magnétique. La documentation du fournisseur indique qu’une impulsion est générée pour chaque demi-litre d’eau qui traverse le compteur.

Le principe de la solution est donc simple: à l’aide d’un petit module connecté au Wifi domestique, détecter chaque impulsion et l’envoyer directement au système de comptage et d’agrégation Domoticz.

J’ai choisi d’envoyer en temps réel toute impulsion détectée, et donc ne pas faire d’agrégation au niveau du module proche du compteur pour plusieurs raisons:

  1. cela simplifie le code: chaque impulsion génère l’envoi d’un message à Domoticz
  2. la fiabilité: en cas de coupure de courant, je ne perds pas d’information
  3. la disponibilité de la mesure: je peux regarder en temps réel ma consommation sous Domoticz – je ne dois pas attendre plusieurs minutes pour voir ce que je viens de consommer.

Matériel

Le matériel à mettre en œuvre est assez simple et ne nécessite que des composants disponibles facilement:

schéma

 

La patte D1 est utilisée en entrée, et la patte D2 en sortie pour allumer une LED lorsqu’une impulsion est détectée.

Grâce à la résistance R2, la patte D1 est maintenue à la masse en temps normal.  Quand une impulsion est détectée, l’interrupteur se ferme et force une tension VCC sur la patte D1.

 

 

Voici ce que cela donne sur une plaque à essai.

 

 

Code source

Pour ce microprogramme, j’ai choisi d’utiliser des interruptions.  Cela permet à priori de ne rater aucune impulsion, tout en me permettant de découvrir comment utiliser des interruptions avec un ESP8266.  L’intérêt est relativement limité pour un projet à un seul capteur, mais cela prend tout son sens si un même microcontrôleur reçoit des stimuli de plusieurs capteurs en parallèle.

Le code du programme est décomposé en deux parties, comme c’est très souvent le cas avec des microcontrôleurs compatibles Arduino.

L’initialisation est dans la fonction void setup(). On y définit les entrées et sorties, on active le Wifi, et on configure les interruptions.  Je définis deux interruptions:

  • Une interruption quand un front montant est détecté sur l’entrée D1:
    attachInterrupt(digitalPinToInterrupt(reedPin), debounceInterrupt, RISING);
  • Une interruption basée sur un timer interne configuré toutes les secondes:
    // Internal timer values, used for interrupts.
    unsigned long delay_timer0 = 80000000L; // 80 MHz == 1 sec
    
    
    timer0_isr_init();
    timer0_attachInterrupt(timer0_ISR);
    timer0_write(ESP.getCycleCount() + delay_timer0);
    

La boucle principale du programme est du coup toute simple, puisqu’une bonne partie de la logique est réalisée dans les fonctions liées aux interruptions.

void loop() {
  // Turn on LED when actual pulse is detected.
  // The ledState is controlled in interrupt functions.
  if (ledState == HIGH) {
    int value = pulses;
    pulses = 0;
#ifdef DOMOTICZ
    sendPulseToDomoticz(value);
#endif
    digitalWrite(reedLedPin,HIGH);
    delay(2000);
    digitalWrite(reedLedPin,LOW);
    ledState = LOW;
  }
}

Ce code se contente d’allumer la LED si une impulsion a été reçue et d’envoyer le nombre d’impulsions reçues vers Domoticz.

Quand une interruption est générée à cause d’une impulsion, la fonction void debounceInerrupt() est exécutée, elle se charge de supprimer une fausse impulsion due au rebond et de met la variable ledState à HIGH.  Cette variable est utilisée dans la boucle principale.  Il faut noter qu’à priori, il n’y a pas de rebond ou fausse impulsion sur un capteur reed car ce n’est pas un simple interrupteur mécanique, mais bon, autant être prudent!

Il y a une chose importante à retenir à propos des interruptions: lors de l’exécution de la fonction liée à une interruption, toutes les interruptions sont désactivées! Il faut donc que cette fonction soit la plus courte et la plus simple possible pour éviter un temps d’exécution trop long dans cette fonction.  Une solution est de seulement mettre à jour certaines variables qui ne seront traitées que dans la boucle principale.

Résultats

Voici le rapport mensuel disponible dans Domoticz: pour chaque jour, la consommation est indiquée.

Voici le montage sur plaque à essai.  Je l’ai monté sur la plaque de mon oscilloscope Nscope: cela m’a permis de vérifier l’absence de rebond sur le capteur 🙂

Améliorations futures

Plusieurs petites améliorations ou évolutions peuvent être apportées au montage actuel.

Tout d’abord la robustesse de la connexion Wifi.  Pour l’instant, la connexion est initialisée au démarrage et c’est tout.  Si le point d’accès est temporairement indisponible, l’ESP8266 ne se reconnecte pas et donc n’envoie plus ses données.  Dans la boucle principale du programme, il faudrait donc rajouter des étapes de vérification de l’état du Wifi et de reconnexion éventuelle.

Ensuite, dans le principe de fonctionnement actuel, au plus je consomme d’eau, au plus il y a de requêtes le serveur d’agrégation.  Si on prend un cas limite avec énormément de capteurs connectés, cela peut inutilement charger le réseau Wifi, et surtout charger l’ESP8266.  Une meilleure solution serait par exemple de n’envoyer les données du capteurs que toutes les minutes ou toutes les cinq minutes – donc de pré-agréger les impulsions dans le microcontrôleur.  Il faut alors utiliser la mémoire non volatile EEPROM disponible sur la puce, pour éviter toute perte de données, par exemple en cas de perte de courant.  C’est d’autant plus pertinent que l’intervalle d’envoi des données est long.

Enfin, la dernière amélioration n’est pas sur le montage lui-même, mais plutôt sur la solution côté serveur. Par facilité, j’ai choisi Domoticz qui est une solution existante, mais elle manque de flexibilité et de granularité.  En effet, Domoticz agrège automatiquement les données et ne conserve pas toutes les données en base de données, mais uniquement les valeurs agrégées.  Cela implique qu’il est par exemple impossible de savoir précisément combien de litres ont été utilisés vendredi passé pour l’arrosage de la nouvelle pelouse; ou d’afficher en détails la consommation du matin à l’heure des douches. La solution est de créer son propre serveur de stockage et d’affichage, par exemple avec une base de données spécialisée dans les séries temporelles (time series database) comme InfluxDB, couplée à une application de création de graphique et dashboards comme Grafana.

 

PS: tout le code et le schéma sont disponibles sur Gihub: https://github.com/xluthi/pulse_counter_esp8266

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *