HA-Mesurer le Niveau d’Eau d’un Puit avec un ESP32

Intro

Dans mes projets domotiques, j’aime relever des défis pratiques. Aujourd’hui, je vous présente un système que j’ai conçu pour mesurer le niveau d’eau dans un puits situé trop loin de mon réseau Wi-Fi. Pour cela, j’utilise un ESP32 connecté en Ethernet (avec une option Wi-Fi possible), un capteur Modbus avec un afficheur 4-20 mA, et une sonde de niveau 4/20mA. La sonde de température DS18B20 est optionnelle.

Objectif du projet

L’objectif est de surveiller à distance le niveau d’eau d’un puit éloigné, en calculant le niveau, le volume et le pourcentage de remplissage. Ces données sont envoyées à Home Assistant via une connexion Ethernet stable, bien que le système puisse aussi fonctionner en Wi-Fi si nécessaire. Ce projet allie fiabilité et flexibilité pour une intégration domotique complète.

Le matériel utilisé

  • ESP32 avec module Ethernet WT32-ETH01 : Une carte combinant un ESP32 et une interface Ethernet LAN8720, idéale pour les zones hors portée Wi-Fi.
  • Convertisseur TTL/RS485 : J’utilise ce modèle pour interfacer le capteur Modbus avec l’ESP32.
  • Afficheur 4-20 mA avec RS485 : Cet afficheur universel (modèle HXDSBOXAI-485) mesure le niveau d’eau via une entréee analogique 4-20 mA et communique via Modbus-RTU. Il est configurable pour afficher des valeurs physiques (niveau, pourcentage, etc.) et supporte une alimentation DC 6-25V.
  • Capteur de niveau: Sonde 4/20 mA longueur de cable à adapter (6m dans mon cas).
  • Sonde DS18B20 : Connectée pour mesurer la température ambiante du chalet abritant le puits .
  • Câble Ethernet : Pour une connexion réseau fiable.

Pinout utilisé sur le WT32-ETH01 :

  • GPIO32 : Sonde DS18B20 (OneWire)
  • GPIO17 : TXD pour Modbus
  • GPIO5 : RXD pour Modbus
  • GPIO33 : Contrôle RS485 (485_EN)
  • GPIO23, GPIO18, GPIO16 : Pins Ethernet (MDC, MDIO, Power)

L’afficheur 4-20 mA

L’afficheur que j’ai choisi est un compteur d’entrée analogique universel avec interface RS485. Voici ses caractéristiques principales :

  1. Compatibilité : Il s’adapte à divers capteurs analogiques (température, pression, niveau, etc.) avec une entrée 4-20 mA ou 0-10V.
  2. Configuration : Par défaut, il gère 0-20 mA ou 0-10V, mais les paramètres de gain (F1-2) et de décalage (F1-3) permettent d’ajuster la plage. J’ai configuré F1-0 sur « 1 » pour une entrée 4-20 mA correspondant à 0-100 %.
  3. Affichage : Par défaut en pourcentage, mais j’ai défini une plage personnalisée (F0-3 à F0-4) pour afficher le niveau en mètres, à adapter à la sonde: 0-6 ml dans mon cas.
  4. Modbus-RTU : Avec une adresse par défaut de 1 (F7-0) et un baud rate de 9600 (F7-1), il communique facilement avec l’ESP32.
  5. Alimentation : 24V/40 mA, avec protection contre les surtensions.

Cet afficheur est compact (79 × 43 × 25 mm) et robuste, parfait pour un environnement extérieur comme un puits.

Mise en œuvre : câblage et connexions

Le schéma suivant, réalisé avec EasyEDA, illustre les connexions entre le WT32-ETH01, l’afficheur 4-20 mA, la sonde DS18B20 et l’alimentation :

Analyse du schéma :

  1. Alimentation :
    • Un module MP1584EN convertit une entrée 220V AC (via un transformateur 220V AC/15V DC) en 5V DC pour alimenter le WT32-ETH01 et l’afficheur.
    • Les pins 5V et GND du WT32-ETH01 (broches 9 et 8) sont utilisées pour alimenter la carte.
    • L’afficheur 4-20 mA est alimenté via ses bornes PWR et GND (DC 6-25V), ici connectées à la sortie 5V du MP1584EN.
  2. Connexion Ethernet :
    • Le port Ethernet (netPort0) du WT32-ETH01 est connecté à un câble RJ45 pour rejoindre mon réseau local.
    • Les pins GPIO23 (MDC), GPIO18 (MDIO), et GPIO16 (Power) gèrent la communication Ethernet, comme configuré dans le code ESPHome.
  3. Connexion Modbus (Afficheur 4-20 mA) :
    • Le convertisseur TTL/RS485 (MAX485-TTL) est utilisé pour interfacer l’ESP32 avec l’afficheur.
    • Côté ESP32 : TX (GPIO17), RX (GPIO5), et Flow Control (GPIO33) sont connectés au MAX485.
    • Côté afficheur : Les bornes 485+ et 485- de l’afficheur (HXDSBOXAI-485) sont connectées aux bornes A et B du MAX485.
    • La sonde de niveau (non détaillée dans le schéma) est connectée aux bornes A+ et MA de l’afficheur pour fournir le signal 4-20 mA.
  4. Sonde DS18B20 :
    • Connectée à GPIO32 (OneWire) via un connecteur JST-XH-03.
    • Une résistance de pull-up de 4.7 kΩ (R1) est placée entre les lignes de données et VCC (5V) pour assurer une communication stable.
    • Les bornes VCC, GND et DATA de la sonde sont connectées respectivement à 5V, GND et GPIO32.
  5. Connecteurs supplémentaires :
    • Un connecteur JST-XH-03 (Afficheur) est prévu pour les signaux de la sonde de niveau (A+, A-, GND).
    • Un connecteur SX1509 (non utilisé ici) est présent pour d’éventuelles extensions.

Étapes de mise en œuvre :

  1. Alimentation : Connectez le module MP1584EN à une source 220V AC via un transformateur 15V DC. Branchez la sortie 5V aux pins 5V et GND du WT32-ETH01 et de l’afficheur.
  2. Ethernet : Reliez le port Ethernet du WT32-ETH01 à votre réseau via un câble RJ45.
  3. Modbus :
    • Connectez le convertisseur TTL/RS485 à l’ESP32 : TX (GPIO17), RX (GPIO5), Flow Control (GPIO33).
    • Reliez les bornes A et B du convertisseur aux bornes 485+ et 485- de l’afficheur.
    • Branchez la sonde de niveau aux bornes A+ et MA de l’afficheur.
  4. DS18B20 : Connectez la sonde à GPIO32 avec une résistance de 4.7 kΩ entre VCC et DATA.
  5. Flasher l’ESP32 : Utilisez ESPHome Dashboard pour uploader le firmware via USB.
  6. Vérification : Une fois alimenté, l’ESP32 se connecte au réseau (LED LINK sur le WT32-ETH01 s’allume), et les données apparaissent dans Home Assistant.

La configuration avec ESPHome

J’utilise ESPHome pour programmer l’ESP32 et intégrer les données dans Home Assistant. Voici le code YAML :

#Pin Name Description
#1 EN1 Enable signal, active high
#2 CFG IO32, CFG                       ---<
#3 485_EN Enable pin of IO33, RS485    ---<
#4 RXD IO5, RXD2                       ---<
#5 TXD IO17, TXD2                      ---<
#6 GND GND
#7 3V3 3V3 power supply
#8 GND GND
#9 5V 5V power supply
#10 LINK Network connection indicator pin
#11 GND GND
#12 IO39 IO39, only supports input
#13 IO36 IO36, only supports input
#14 IO15 IO15
#15 I014 IO14
#16 IO12 IO12
#17 IO35 IO35, only supports input
#18 IO4 IO4
#19 IO2 IO2
#20 GND GND


substitutions:
  device_name: esp174-esp32-eth0-chalet2
  adress_ip: "192.168.0.174"
  friendly_name: esp174
  time_timezone: "Europe/Paris"
  
esphome:
  name: ${device_name}
  
esp32:
  board: wt32-eth01 #esp-wrover-kit

# Enable logging
logger:
  level: info

# Enable Home Assistant API
api:
ota:
  platform: esphome
web_server:
  port: 80

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO0_IN
  phy_addr: 1
  power_pin: GPIO16

  manual_ip:
    static_ip: ${adress_ip}
    gateway: 192.168.0.254
    subnet: 255.255.255.0
    dns1: 192.168.0.254
    
# Connection sonde(s) de température DS18b20
one_wire:
  - platform: gpio    
    pin: 32

  
uart:
  id: mod_bus
  tx_pin: 17
  rx_pin: 5
  baud_rate: 9600
  stop_bits: 1
  debug:
    direction: BOTH
    dummy_receiver: false
    after:
      timeout: 150ms
    sequence:
      - lambda: |-
          UARTDebug::log_string(direction, bytes);

modbus:
  #send_wait_time: 200ms
  id: modbus1
  flow_control_pin: 33

modbus_controller:
  - id: afficheur
    ## the Modbus device addr
    address: 0x1
    modbus_id: modbus1
    update_interval: 10s
    command_throttle: 50ms
    # setup_priority: -10
sensor:  

# Lecture Registre F0-1 -> Valeur affichée
  - platform: modbus_controller
    modbus_controller_id: afficheur
    id: _niv_eau
    name: "${friendly_name}_Niveau_Puit"
    address: 0x0001
    unit_of_measurement: "mL"
    register_type: holding
    value_type: U_WORD
    accuracy_decimals: 2
    #register_count: 1
    #response_size: 2
    device_class: volume
    state_class: measurement
    filters:
      - multiply: 0.01
#      - sliding_window_moving_average:
#          window_size: 10 # moyenne sur x lectures
#          send_every: 5 # envoi toutes les x lectures
#          send_first_at: 1 # envoi à la premiere lecture


  - platform: dallas_temp
    address: 0xab0321117f919d28
    name: "${friendly_name}_temperature_air"
    update_interval: 60s    
    id: temp_air
    filters:
      - filter_out: 0.0

############### TEMPLATE  ######################"
# Calcul volume eau
  - platform: template
    name: "${friendly_name}_volume_puit"
    id: volume
    icon: mdi:flash
    unit_of_measurement: "m³"
    device_class: volume
    state_class: measurement    
    accuracy_decimals: 2
    lambda: |-
      return (id(_niv_eau).state*0.6*0.6*3.14159);
      
  - platform: template
    name: "${friendly_name}_niveau_remplissage_puit"
    id: niveau
    icon: mdi:flash
    unit_of_measurement: "%"
    state_class: measurement    
    accuracy_decimals: 2
    lambda: |-
      return (id(_niv_eau).state/5.8*100);

  - platform: template
    name: "${friendly_name}_niveau_reserve_puit"
    id: niveau_reserve
    icon: mdi:flash
    unit_of_measurement: "m"
    device_class: distance
    state_class: measurement    
    accuracy_decimals: 2
    lambda: |-
      return (5.8-id(_niv_eau).state);

#Etat de la connection
binary_sensor:
  - platform: status
    name: "${friendly_name} Status"

Explications :

  1. Ethernet : Configuré avec une IP statique (192.168.0.174) pour une connexion fiable. Les pins GPIO23, GPIO18 et GPIO16 gèrent le module LAN8720.
  2. Modbus : L’afficheur est interrogé toutes les 10 secondes via UART (9600 bauds). Le registre 0x0001 donne le niveau brut, converti en mètres (x0.01).
  3. DS18B20 : Mesure la température toutes les 60 secondes.
  4. Capteurs calculés :
    • Volume : niveau * π * (0.6 m)² (puits cylindrique de 60 cm de diamètre).
    • Pourcentage : niveau / 5.8 * 100 (profondeur max de 5.8 m).
    • Réserve : 5.8 – niveau.
  5. Wi-Fi possible : En remplaçant la section ethernet par une configuration wifi si le signal est correct.

Installation et mise en route

  1. Câblage :
    • Convertisseur TTL/RS485 : TX (GPIO17), RX (GPIO5), contrôle (GPIO33).
    • Afficheur 4-20 mA : Connecté au convertisseur via RS485 (A+, B-).
    • DS18B20 : Sur GPIO32.
    • Ethernet : Câble RJ45 au réseau.
  2. Configuration de l’afficheur : Réglé sur 4-20 mA (F1-0=1), plage d’affichage personnalisée via F0-3/F0-4, adresse Modbus 1.
  3. Flasher l’ESP32 : Via ESPHome Dashboard avec un câble USB.
  4. Home Assistant : L’API détecte automatiquement les entités comme sensor.esp174_Niveau_Puit.

Utilisation dans Home Assistant

Les données (niveau, volume, pourcentage, température) alimentent mes automatisations.

Exemple d’automatisme

Surveillance du niveau du puit avec notification si niveau inférieur à 0.8ml pendant 5mn.

alias: Notification niveau bas puits
description: ""
mode: single
triggers:
  - entity_id:
      - sensor.esp174_niveau_remplissage_puit
    for:
      hours: 0
      minutes: 5
      seconds: 0
    below: 0.8
    trigger: numeric_state
conditions: []
actions:
  - data:
      message: >-
        {{states("sensor.date_time") }}{{-"\n"-}} Niveau Puit
        {{states('sensor.esp174_niveau_puit')}} ml
      title: Niveau eau puit inferieur à 0.8 ml depuis 10mn
    action: notify.telegram

Surveillance de la température et notification via le Blueprint Notification « Nagging Alerting Notification Automation »

Avec le « binary_sensor.alarme_temp_chalet_bass » calculé dans « /config/helpers/ »

alias: BluePrint Notification Temp basse Chalet
description: "# Surveillance de la temperature du chalet"
use_blueprint:
  path: pavax/nagging_alert_notification.yaml
  input:
    condition_entity_state: "on"
    sensor_entity: binary_sensor.alarme_temp_chalet_basse
    alert_state: "on"
    alert_action:
      - data:
          message: >-
            {{states("sensor.date_time") }} {{-"\n"-}}T° Basse Chalet
            ={{states("sensor.esp174_temperature_air") }}°C
          title: Alarme Temperature Basse Chalet!!!
        action: notify.telegram
    resolved_action:
      - data:
          message: >-
            {{states("sensor.date_time") }} {{-"\n"-}}T° Basse Chalet
            ={{states("sensor.esp174_temperature_air") }}°C
          title: Fin Alarme Temperature Basse chalet !!!
        action: notify.telegram
    notify_message: " "
    notify_device: 367dba31447009458e03b70e3a29b6b2
    repeat_delay: 1800
    resolved_message: " "
    initial_delay: 300
    max_alerts: 5

Exemple carte

type: grid
cards:
  - type: heading
    heading_style: title
    heading: NIVEAU PUIT
  - type: custom:mushroom-entity-card
    entity: sensor.esp174_niveau_puit
    name: Niveau Puit
  - type: tile
    entity: sensor.esp174_volume_puit
    name: Volume
  - type: tile
    entity: sensor.esp174_niveau_reserve_puit
    name: Reserve
    icon: mdi:arrow-expand-vertical
  - type: tile
    entity: sensor.esp174_niveau_remplissage_puit
    name: Remplissage
    icon: mdi:water-well-outline
  - chart_type: line
    period: day
    type: statistics-graph
    entities:
      - sensor.esp174_niveau_puit
    days_to_show: 3
    hide_legend: true
    stat_types:
      - state
      - min
      - max
      - mean
    logarithmic_scale: false
  - type: grid
    cards:
      - type: statistic
        entity: sensor.esp174_niveau_puit
        period:
          calendar:
            period: week
        stat_type: min
        name: Min
      - type: statistic
        entity: sensor.esp174_niveau_puit
        period:
          calendar:
            period: week
        stat_type: mean
        name: Moyenne
      - type: statistic
        entity: sensor.esp174_niveau_puit
        period:
          calendar:
            period: week
        stat_type: max
        name: Max
type: grid
cards:
  - type: heading
    heading: TEMPERATURE AMBIANTE
    heading_style: title
    badges: []
  - type: custom:mushroom-entity-card
    entity: sensor.esp174_temperature_air
    name: Temp Ambiante
    fill_container: false
  - chart_type: line
    period: day
    type: statistics-graph
    entities:
      - sensor.esp174_temperature_air
    stat_types:
      - min
      - mean
      - max
    hide_legend: true
    days_to_show: 3
  - type: grid
    cards:
      - type: statistic
        entity: sensor.esp174_temperature_air
        period:
          calendar:
            period: week
        stat_type: min
        name: Min
      - type: statistic
        entity: sensor.esp174_temperature_air
        period:
          calendar:
            period: week
        stat_type: mean
        name: Moyenne
      - type: statistic
        entity: sensor.esp174_temperature_air
        period:
          calendar:
            period: week
        stat_type: max
        name: Max
  - type: heading
    heading_style: title
    badges: []
    heading: ESP CHALET et PZEM
  - type: vertical-stack
    cards:
      - square: false
        columns: 2
        type: grid
        cards:
          - type: custom:mushroom-entity-card
            entity: binary_sensor.esp174_status
            icon: mdi:account
            name: Status ESP174
          - type: custom:mushroom-entity-card
            entity: binary_sensor.esp131_pzem_chalet_status
            icon: mdi:account
            name: Status ESP131 (PZEM)

Pourquoi ce système ?

  • Fiabilité : L’Ethernet assure une connexion stable là où le Wi-Fi ne passe pas.
  • Flexibilité : L’afficheur Modbus et le code ESPHome s’adaptent à d’autres capteurs ou configurations (Wi-Fi si besoin).
  • Économique : Avec un WT32-ETH01 (~15 €), un convertisseur (~2 €) et un afficheur (~10 €), c’est abordable mais le plus onéreux étant la sonde 4/20 ma (~50€).

Conclusion

Cet ESP32 avec Ethernet et Modbus me permet de surveiller le niveau d’eau de mon puits avec précision, même loin de mon Wi-Fi. Intégré à Home Assistant, il enrichit mes automatisations tout en restant flexible. Si vous avez un puits ou un projet à distance, ce système pourrait vous inspirer. Des idées pour l’améliorer ? Laissez un commentaire sur domo.rem81.com !

Laisser un commentaire

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