Allez, on passe la seconde. On va directement passer sur un ESP8266 avec ESPHome pour une intégration directe dans Home Assistant !

J’avais déjà fabriqué, il y a quelques années un capteur pour mesurer le niveau de mon puits. C’était une première version, basée sur un arduino, un module NRF24 et programmé avec la librairie MySensors. Pour ceux qui n’ont pas encore lu le premier article, c’est ici : Mesure de niveau pour puits. Depuis, je suis passé à Home Assistant, et avec lui ESPHome. J’ai donc basculé des Arduino aux ESP8266 et au no-code …

Expression de besoin

Ici rien ne change. On veux mesurer le niveau d’un puit. On en profite pour relever la température et l’humidité de la pièce au passage (qui peut le plus peut le moins :)).
Par contre les nouveaux besoins sont :

  • Pas de programmation à faire. Le C++ c’est vraiment pas mon fort. Je devais avoir des fuites mémoires car j’avais des plantages réguliers
  • Intégration directe dans Home Assistant

Solution technique

Sur la partie capteur aucun changement :

  • Mesure du niveau à l’aide d’un capteur de pression : MPX5700AP
  • Température et humidité avec un AM2302 (ça tombe bien, j’en ai en stock)

Pour la partie compute, on passe d’un arduino à un Wemos D1. Il s’agit d’un ESP8266 courant, peu cher et facile à intégrer sur le circuit. En fait n’importe quel appareil supporté par ESPHome fera l’affaire. L’important étant de disposer d’une entrée analogique pour le capteur de pression.

Et pour la partie affichage, j’ai abandonné l’écran LCD 2 ligne. Je ne le consultait jamais et il faisait un peu vieillot. Je vais le remplacer par des LED :

  • Led bleue pour le statut de connexion à Home Assistant
  • Led verte qui clignotera si le niveau est OK
  • Led rouge qui clignotera si le niveau est trop bas

Schéma électronique

J’ai fait minimaliste :

  • Un étage d’alimentation pour avoir du 5V (pour le circuit) et du 3.3V (pour le capteur de pression)
  • Un circuit simple avec des connecteurs pour l’alim et le capteur de pression.

Les seules choses à retenir sont :

  • le filtre RC appliqué sur le capteur de pression conformément à sa documentation
  • la résistance de pull-up sur l’AM2302

PCB

Pour la création du PCB, rien de bien extraordinaire. J’ai juste adapté la taille des pads et des pistes pour la fabrication par une CNC3018 (voir les paramètres que j’utilise).

J’ai intégré les contraintes suivantes:

  • les leds et leurs résistances en CMS pour simplifier la mise dans un boitier
  • une encoche pour le capteur de température afin qu’il soit à l’extérieur du boitier pour limiter le biais

Circuit Assemblé

Ce n’est pas du grand art, mais ça fait déjà plus pro que les plaques d’essai où tu soudes fils à travers tout 🙂

Boitier

Pour le boitier, j’ai utilisé Fusion 360. J’ai longtemps utilisé Tinkercad, mais je préfère le rendu de Fusion:

  • TinkerCad permet de démarrer très vite et de faire des choses simple très rapidement, mais on se retrouve vite à galérer avec les placement et les mesures lorsqu’on intègre des couvercles et des encoches.
  • Fusion 360 demande un gros effort pour comprendre la logique de l’outil et la manière de s’en servir, mais passé ce cap : les choses qui semblaient insurmontables avec TinkerCad deviennent facile.

Après, chacun sa préférence, je ne juge pas 😉

Note : Fusion 360 pour un usage perso est gratuit. Il a bien des limitation, mais que je n’ai jamais atteintes avec mon utilisation.

ESPHome

On arrive aux choses intéressantes. On a un circuit, il faut quand même que ça fonctionne.

Dans Home Assistant, on peut aller dans la section ESPHome et créer un nouvel appareil. Une fois fait, on peut connecter le nodeMCU en USB et uploader la première fois le firmware. Les fois suivantes, on pourra pousser les mises à jour par le Wifi (OTA). Ah, c’est beau la technologie …

Le fichier de configuration est plutôt parlant, mais les points à noter sont:

  1. J’ai un capteur qui lit l’entrée analogique et calcule la hauteur d’eau du puit en se basant sur la formule fournie dans la documentation du MPX. J’ai juste ajouté la variable “offset” pour calibrer le niveau zéro (avant de plonger le capteur)
  2. J’ai capteur fictif (template) qui calcule taux de remplissage du puit en pourcentage (par rapport à mon installation) et qui définit le statut (composant “select”) : OK, Low, Out of range
  3. J’utilise le composant “interval” pour faire clignoter les Led selon la valeur du statut.

Et voici le fichier YAML de mon module

 esphome:
  name: buanderie
  platform: ESP8266
  board: d1_mini_pro
  on_boot: 
    then:
      - switch.turn_off: led_critical
      - switch.turn_off: led_heartbeat

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "***********************************"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Buanderie Fallback Hotspot"
    password: "*********************"

captive_portal:

status_led:
  pin: D5

sensor:
  - platform: dht
    pin: D3
    model: AM2302
    temperature:
      name: "Temperature Buanderie"
      id: temp
    humidity:
      name: "Humidité Buanderie"
      id: hum
    update_interval: 30s
  - platform: adc
    pin: A0
    name: "Niveau puit"
    update_interval: 5s
    id: puits_level
    filters:
      - sliding_window_moving_average:
          window_size: 6
          send_every: 6
      - lambda: |-
          auto offset=0.33;
          id(puits_level).state = ((((x - 0.04) / 0.0012858)- 100)/10) - offset;
          id(puit_perc).update();
          return ((((x - 0.04) / 0.0012858)- 100)/10) - offset;
    unit_of_measurement: "M"
    state_class: "measurement"
    accuracy_decimals: 2
  - platform: template
    name: "Remplissage puit"
    id: puit_perc
    unit_of_measurement: "%"
    state_class: "measurement"
    accuracy_decimals: 0
    update_interval: 5s
    lambda: |-
      auto limitMax=2.9;
      auto limitLow=0.3;
      auto call = id(level_status).make_call();
      if ((id(puits_level).state < limitLow) && (id(puits_level).state >0)) { 
        call.set_option("Low");
      } else if ((id(puits_level).state >= limitLow) && (id(puits_level).state <limitMax)) { 
        call.set_option("OK");
      } else { 
        call.set_option("Out of Range");
      }
      call.perform();
      return id(puits_level).state * 100 / limitMax;

binary_sensor:
  - platform: template
    id: led_alert
    name: Alerte niveau bas

select:
  - platform: template
    id: level_status
    name: level_status
    options: 
      - "OK"
      - "Low"
      - "Out of Range"
    initial_option: "Out of Range"
    optimistic: true


switch:
  - id: led_critical
    platform: gpio
    pin: D7
    internal: True
  - id: led_heartbeat
    platform: gpio
    pin: D6
    internal: True

interval:
  - interval: 1s
    then:
      - lambda: |-
          if (id(level_status).state == "OK") {
            if (id(led_heartbeat).state) { id(led_heartbeat).turn_off(); } else { id(led_heartbeat).turn_on(); }
            id(led_critical).turn_off();
          } else if (id(level_status).state == "Low") {
            if (id(led_critical).state) { id(led_critical).turn_off(); } else { id(led_critical).turn_on(); }
            id(led_heartbeat).turn_off();
          } else {
            if (id(led_heartbeat).state) { 
              id(led_heartbeat).turn_off(); 
              id(led_critical).turn_on(); 
            } else { 
              id(led_heartbeat).turn_on(); 
              id(led_critical).turn_off(); 
            }
          }

Conclusion

J’espère que cet article vous aura plu … et surtout inspiré pour de nouvelles réalisations !

By Kevin

Leave a Reply

Your email address will not be published. Required fields are marked *