Mesure de la contenance et de la temperature d’une cuve de récupération d’eau de pluie

Mesure de la contenance et de la temperature d’une cuve de récupération d’eau de pluie

21 août 2022 3 Par Jérôme Ferrari

Bonjour à tous,

Aujourd’hui et pour se remettre en jambe après les vacances, je vous propose un petit tutoriel afin de fabriquer une solution permettant de suivre le niveau et la température d’une cuve de récupération d’eau de pluie et ainsi ouvrir la voie pour l’automatisation de l’arrosage d’un jardin.

Cette solution pourrait aussi servir dans des applications visant à la réutilisation des eaux grises pour optimiser la consommation de la maison.

Il y a 1 an, j’avais attaqué ce problème en utilisant un capteur à ultrasons HC-SR04 qui est le plus répandu dans le domaine des mesures low-cost mais celui-ci n’étant pas étanche, il avait fini par rendre l’âme au bout de quelques jours à cause du taux d’humidité dans la cuve malgré l’éloignement de celui-ci par rapport à la surface de l’eau…

Comme d’habitude les sources et les différents fichiers se trouverons à la fin de l’article.

Bref, nous pouvons débuter comme d’habitude avec la liste du matériel.

Partie 0: Liste du matériel

  • Un capteur à ultrasons étanche de chez DFRobot

https://wiki.dfrobot.com/_A02YYUW_Waterproof_Ultrasonic_Sensor_SKU_SEN0311

  • Une sonde de température DS18B20
  • Un wemos D1 mini
  • Un plaque à trou et divers connecteurs

Partie 1: Connexion des différents éléments

Attention, le capteur à ultrasons étanche de chez DFRobot contrairement au HC-SR04 utilise une liaison série pour communiquer.

Comme dans l’exemple donné sur le wiki de DFRobot, nous utiliserons une liaison série Software (basée sur les pins D1 et D2) afin de garder la liaison hardware pour le débogage.

En ce qui concerne le DS18D20, il n’y a pas de précaution particulière, si vous avez pris celui avec la platine d’adaptation sinon il faudra penser à mettre une résistance (vous trouverez tout ce qu’il faut sur google).

Ci-dessous un tableau récapitulatif des connections entre les éléments.

Wemos D1 miniCapteur à ultrasonsDS18D20
3.3V3.3V3.3V
GNDGNDGND
D1 (TX soft)RX
D2 (RX soft)TX
D6Signal

Voici un schéma de cablage pour aider à la compréhension

Pour ma part afin d’éviter des fils volants, j’ai figé le tout avec une plaque à trou

Ainsi quand on peut installer le Wemos sans problème

Partie 2: Programmation

En ce qui concerne la programmation, j’ai fait un mix entre le code de démonstration fourni par DFRobot et les autres codes que j’utilise pour envoyer les informations via MQTT.

Il n’y a que la librairie OneWire à avoir dans l’IDE Arduino afin de pouvoir lire le DS18D20

Vous pouvez copier/coller le code ci-dessous ou le télécharger dans la partie à la fin de l’article.

Pensez à renseigner le SSID ainsi que le mot de passe de votre Wifi et de mettre la bonne adresse IP de votre Broker MQTT.

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

#define wifi_ssid "YOURWIFISSID"
#define wifi_password "YOURWIFIPASSWORD"

#define mqtt_server "XXX.XXX.XXX.XXX"
#define mqtt_user "guest"  //s'il a été configuré sur Mosquitto
#define mqtt_password "guest" //idem

#define hauteureau_topic "cuve/hauteureau"  //Topic hauteur
#define temperatureeau_topic "cuve/temperatureeau"  //Topic temp

#define ONE_WIRE_PIN D6

OneWire oneWire(ONE_WIRE_PIN);
DallasTemperature sensors(&oneWire);

SoftwareSerial mySerial(D2,D1); // RX, TX
unsigned char data[4]={};
float distance;

//Buffer qui permet de décoder les messages MQTT reçus
char message_buff[100];

long lastMsg = 0;   //Horodatage du dernier message publié sur MQTT
long lastRecu = 0;
bool debug = false;  //Affiche sur la console si True

WiFiClient espClient;
PubSubClient client(espClient);

void setup()
{
 Serial.begin(57600);
 mySerial.begin(9600); 
 setup_wifi();           //On se connecte au réseau wifi
 client.setServer(mqtt_server, 1883);    //Configuration de la connexion au serveur MQTT
 delay(1000);
}

//Connexion au réseau WiFi
void setup_wifi() {
  delay(10);
//  Serial.println();
//  Serial.print("Connexion a ");
//  Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("Connexion WiFi etablie ");
  Serial.print("=> Addresse IP : ");
  Serial.print(WiFi.localIP());
}

//Reconnexion
void reconnect() {
  //Boucle jusqu'à obtenur une reconnexion
  while (!client.connected()) {
    Serial.print("Connexion au serveur MQTT...");
    if (client.connect("BBXCuve", mqtt_user, mqtt_password)) {
      Serial.println("OK");
    } else {
      Serial.print("KO, erreur : ");
      Serial.print(client.state());
      Serial.println(" On attend 5 secondes avant de recommencer");
      delay(5000);
    }
  }
}

void loop()
{
if (!client.connected()) {
    reconnect();
  }
  client.loop();
  long now = millis();
    do{
     for(int i=0;i<4;i++)
     {
       data[i]=mySerial.read();
     }
  }while(mySerial.read()==0xff);

  mySerial.flush();

  if(data[0]==0xff)
    {
      int sum;
      sum=(data[0]+data[1]+data[2])&0x00FF;
      if(sum==data[3])
      {
        distance=(data[1]<<8)+data[2];
        if(distance>30)
          {
           Serial.print("distance=");
           Serial.print(distance/10);
           Serial.println("cm");
           if (now - lastMsg > 1000 * 60) {
           Serial.println("toto");
           lastMsg = now;
         //  int distancetemp = distance;
           client.publish(hauteureau_topic, String(distance/10).c_str(), true);
           sensors.requestTemperatures();
           float temperature = sensors.getTempCByIndex(0);
           Serial.println(temperature);
           Serial.println("°C");
           client.publish(temperatureeau_topic, String(temperature).c_str(), true);
           }
           
          }else 
             {
               Serial.println("Below the lower limit");
             }
      }else Serial.println("ERROR");
     }
     delay(100);
}

Maintenant que tout est ok et téléversé, nous pouvons passer à l’installation du dispositif.

Partie 3: Installation sur la cuve

Il faudra penser à protéger l’électronique dans un boitier étanche et à l’alimenter avec du 5V.

En ce qui concerne le DS18D20, il n’y a pas de précaution particulière à prendre, car le capteur sera directement plongé dans l’eau

Pour le capteur à ultrasons, celui a besoin d’être parallèle à la surface de l’eau et éloigné de la surface donc j’ai prévu un petit bonus ^^.

Ce bonus et la conception d’un support pouvant être imprimé en 3D.

Vous pouvez retrouver le fichier sur le site thingiverse

https://www.thingiverse.com/thing:5473373

Au final, une fois le support imprimé, le montage donne cela:

Nous pouvons maintenant installer le tout sur la cuve.

Maintenant que le capteur est installé, afin de calculer le volume d’eau restant, il faut penser à prendre les mesures suivantes:

  • Distance entre le fond du bassin et le capteur en centimètres (pour ici 79cm)
  • La superficie du bassin (en m²)

Si tout est ok, nous pouvons passer sur Jeedom pour intégrer ce nouveau capteur

Partie 4: Intégration dans Jeedom

En ce qui concerne l’intégration dans Jeedom, cette fois, j’utilise le plugin MQTT (et non JMQTT mais c’est la même chose) et le plugin Virtuel.

la première étape est d’aller dans le plugin MQTT

Puis de rechercher le topic qui est apparu (ici Cuve)

Activez et affectez le sur un objet parent (ici Extérieur)

Puis allez dans l’onglet commandes et cochez Historiser et Afficher

Normalement, vous devriez vous retrouver avec le visuel suivant dans l’objet Extérieur

Comme vous pouvez le voir, le dispositif nous renvoi bien la température aussi la distance entre le capteur et la surface.

Si tout est ok et afin de pouvoir avoir le volume d’eau, maintenant, vous pouvez aller dans le plugin Virtuel

Cliquez sur Ajouter et donnez un nom à votre capteur virtuel (ici appelé Volume eau)

Cliquez maintenant sur Commandes et ensuite sur Ajouter une info virtuelle

Renseignez le nom (ici volume eau reservoir)

Choisissez le type Numérique

Dans valeur, mettez la formule suivante:

(1000*((“hauteurentrecapteuretfond”-#[Extérieur][cuve][hauteureau]#)/100)*”Surfacedeau”)

pour mon exemple, cela donne la formule ci-dessous car j’ai 3 cuves reliées ensembles

Faites bien attention, les virgules des décimales doivent être des points ( je sais pas si je me suis bien fait comprendre ^^)

Voilà, vous avez plus qu’à sauvegarder et retourner sur l’objet extérieur pour vérifier si tout est ok

Maintenant, vous avez un capteur opérationnel.

Après quelques temps, vous pourrez voir l’historique de l’utilisation et du remplissage de la cuve

Si vous en êtes là et que tout est opérationnel, féliciations!

Partie 5: Codes et fichiers

Code

Voilà c’est tout pour aujourd’hui, je ferais sûrement un autre article sur l’implémentation d’un arrosage automatique à partir de ces données.

Bonne rentrée à tous,

Jérôme