Niveau d'eau cuve de récupération 10m3

Bonjour,
Comme beaucoup de sujets que j'ai trouvé ici cette problématique n'est pas la première. Ce qui m'embête le plus c'est le côté "physique" et j'aimerai avoir un retour d'expérience.

Contexte (schéma en PJ) :
• Cuve à eau 10m3 (2,5m x 2,5m) récupérant 300m2 de toiture dans le nord (pas souvent vide vous vous en doutez …). Récupération de l'eau pour WC/Linge + jardin
• Arduino à 10m de la cuve dans le garage, câble 2,5mm² dispo sous fourreau pour la liaison (si nécessaire)
• Souhait de lecture du niveau de la cuve

Aujourd'hui trois choix de capteurs pour répondre à la problématique :
• le premier HCSR04 bien connu (non étanche) pas pour mon utilisation
• le second A02YYUW qui lui est étanche lien ici
• le dernier un capteur de pression lien ici

Le plus simple pour moi serait d'utiliser la seconde solution qui est plutôt simple. Tension de fonctionnement 5V et courant 0,008A qui s'adapte bien à l'arduino. En imaginant rallonger le câble avec un câble de faible section même 0,5mm² AWG20 pour 10m j'ai 0,15% de chute = négligeable.

Première question comment feriez-vous pour rallonger le câble ? Quand j'ai fait la cuve j'ai passé un 2,5mm² mais ça va être compliqué d'adapter là-dessus. Deux solutions :
• Fabriquer moi-même une rallonge avec du câble 9/10 et connecteurs PH2.0 4P. A mon avis il faut du matériels adaptés (sertissage), ça ne me dérange pas d'acheter mais il faut quelque chose de bonne qualité.
• Trouver une rallonge toute faite mais je n'arrive pas à mettre la main dessus, j'ai surement pas le bon vocabulaire.

Ce qui me fait peur de cette solution c'est l'angle des 60° j'ai peur que ça rebondisse sur plein de choses avant que ça arrive sur l'eau (parois béton, tuyau PVC …). Je pourrai éventuellement descendre le capteur mais j'aurai toujours des obstacles quand le niveau d'eau baissera. D'où la deuxième solution avec le capteur pression que je pourrais "colsonner" sur mon tuyau PVC de descente (aspiration pompe).
Par contre ce qui me dérange c'est la partie câblage, car ce capteur nécessite du 24V et donc une autre source d'alimentation. Comment je peux la gérer ? Pour le capteur si jamais je le prendrai en voltage output 0-5V pour calquer au PWM arduino.

Tout ça pour vous dire que je suis un peu perdu sur la solution à mettre en œuvre et ne connaissant pas tout … j'ai de bonnes bases en élec et en programmation mais pas trop en électronique (d'où mon souhait à me lancer là-dedans pour apprendre). J'ai le starter pack d'ELEGOO avec lequel je me suis fait la main.

Grosso modo que me conseillez-vous ?
Désolé pour la redondance des sujets, mais comme tout le monde on pense que son cas est isolé même si les sujets se recoupent !

Bien cordialement,
Michael PRUVOST

Le capteur est livré avec un câble de raccordement.

Il suffit de raccorder tes 10m de câble à ce petit câble de raccordement en utilisant des connecteurs Wago par exemple. Il faudrait peut-être mettre cette partie dans un petit boitier étanche.

La portion de l'onde qui n'aura pas rebondie reviendra plus vite et moins atténuée que les rebonds et ces échos parasites devraient sans doute être ignorés.
Au pire tu peux toujours placer un tube (diamètre et longueur à déterminer empiriquement) autour de l’émetteur pour réduire la largeur du cône.

J'ai fait cela pour une cuve de 7500l

j'avais eu quelques soucis sur la transmission, j'avais posé la question sur des idées Looking for new ideas on what to explore to debug a distance sensor et au final avec avec le bon fil ça a fonctionné (et ça fonctionnait même sur 20m)

J'ai mis un capteur DYP-A02YY et un petit M5Stack, j'ai un petit système qui est fonctionnel depuis Novembre 2023

(le M5Stack est maintenant dans l'abri de jardin pas dans la cuve bien sûr :slight_smile: )

merci pour vos réponses. Je vais garder la première solution, je vais commander la pièce et je verrai comment je vais rallonger ca car il faut 4 fils.

J-M-L peux-tu m'en dire plus sur ta solution ? Je vois rapidement que tu as été embêté avec le RJ45, qui en effet devait être un peu court. Tu es parti sur un 24 AWG. Peux-tu faire un schéma de raccordement avec les différentes pièces ? J'ai un peu de mal à comprendre. Merci à toi (vous). Michael

Bonjour me revoilà,
j'ai tout ce qu'il faut pour que ça marche mais ça ne fonctionne pas.

Ca fonctionne avec un capteur ultrasons HCSR04 mais pas avec le étanche A02YYUW, il reste bloqué à 15cm, je ne sais pas trop pourquoi ...
Est-ce le capteur en défaut ?

Voici le code :

#include <Wire.h>              // Bibliothèque pour la communication I2C
#include <LiquidCrystal_I2C.h>  // Bibliothèque pour l'écran LCD 16x2

// Définition des broches pour le capteur ultrason
const int trigPin = 9;
const int echoPin = 10;

// Initialisation de l'écran LCD (adresse I2C, 16 colonnes, 2 lignes)
LiquidCrystal_I2C lcd(0x27, 16, 2);  // Remplacez 0x27 par l'adresse correcte si nécessaire

void setup() {
  // Initialisation de la communication série pour débogage
  Serial.begin(9600);

  // Configuration des pins du capteur ultrason
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // Initialisation de l'écran LCD
  lcd.begin(16, 2);  // Initialisation avec 16 colonnes et 2 lignes
  lcd.backlight();  // Allume le rétroéclairage
  lcd.setCursor(0, 0);  // Positionne le curseur en haut à gauche
  lcd.print("Distance: ");
}

void loop() {
  // Envoie un signal de 10µs pour déclencher le capteur ultrason
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Lit la durée de l'écho du capteur ultrason
  long duration = pulseIn(echoPin, HIGH);

  // Vérification que la durée n'est pas trop courte (pas d'écho valide)
  if (duration <= 0) {
    Serial.println("Erreur de mesure");
    lcd.setCursor(0, 1);
    lcd.print("Erreur        ");
    delay(500);
    return;
  }

  // Calcule la distance en centimètres
  long distance = duration * 0.0344 / 2;

  // Vérification de la plage de la distance
  if (distance < 2 || distance > 400) {
    Serial.println("Distance invalide");
    lcd.setCursor(0, 1);
    lcd.print("Distance inv.  ");
    delay(500);
    return;
  }

  // Affiche la distance sur le moniteur série pour débogage
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // Affiche la distance sur l'écran LCD
  lcd.setCursor(0, 1);  // Positionne le curseur sur la deuxième ligne
  lcd.print("                ");  // Efface la ligne
  lcd.setCursor(0, 1);  // Retourne à la première colonne de la deuxième ligne
  lcd.print(distance);   // Affiche la distance
  lcd.print(" cm");      // Affiche l'unité "cm"

  delay(500);  // Attente de 500ms avant la prochaine lecture
}

et le retour :
19:25:49.194 -> Distance: 16 cm
19:25:49.773 -> Distance: 15 cm
19:25:50.336 -> Distance: 15 cm
19:25:50.907 -> Distance: 15 cm
19:25:51.483 -> Distance: 15 cm
19:25:52.062 -> Distance: 15 cm

d'avance merci
cordialement,

Si vous utilisez ce code aussi pour le A02YYUW, c'est normal que ça ne fonctionne pas.

c'est un capteur qui fonctionne en mode série (UART).

cf A02YYUW Waterproof Ultrasonic Sensor Wiki - DFRobot


J'ai juste un câble avec 4 fils ( le port série Tx/Rx est 3.3V et GND) qui rejoint mon capteur

Description du montage ?

Les ondes Ultra-son rebondissent au niveau d'une interface au changement de milieu.

On définit un coefficient de réflexion au niveau de l'interface comme en électronique → c'est le côté universel de la physique.

Une interface air/eau donne un coefficient de réflexion proche 1, c'est-à-dire une réflexion totale.

Étanche veut-il dire que le capteur peut être plongé dans l'eau ou seulement qu'il résiste à la pluie ?
Il y a déjà une première interface capteur/boitier, supporte t-il une seconde interface ?

As-tu envisagé les capteurs optiques comme le VL53L1X qui peuvent s'utiliser comme un capteur à US non étanche ?
Le VL53L1X peut mesurer jusqu'à 4 m.
Son cône d'émission est réduit.
STMicroelectronic propose une gamme complète pour différentes distances.

Il fonctionne aussi selon le principe de réflexion totale, mais là, c'est un rayon Laser de classe1, c'est-à-dire non dangereux.

Bonjour Merci pour vos réponses,

En effet JML je n'avais pas fait attention à cette subtilité, le code est modifié ainsi. Voici le dernier :

#include <LiquidCrystal_I2C.h>
#include <AltSoftSerial.h>

// Configuration du capteur A02YYUW
AltSoftSerial mySerial; // Utilisation de AltSoftSerial

// Configuration de l'écran LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adresse I2C de l'écran LCD (vérifiez avec le scanner I2C)

// Configuration de la LED RGB
const int redPin = 9;
const int greenPin = 8;
const int bluePin = 7;

// Dimensions de la cuve
const float hauteurCuve = 207.0; // Hauteur en cm
const float diametreCuve = 234.0; // Diamètre en cm

// Variables pour millis()
unsigned long previousMillis = 0;
const long interval = 10000; // Délai de 1 seconde

void setup() {
  // Initialisation de la communication série
  mySerial.begin(9600);
  Serial.begin(9600);

  // Initialisation de l'écran LCD
  lcd.init();
  lcd.backlight();
  lcd.clear();

  // Configuration des broches de la LED RGB
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);

  delay(5000); // Délai de stabilisation du capteur au démarrage
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    // Lecture de la distance depuis le capteur
    mySerial.write(0x55); // Envoi de la commande de mesure
    delay(200); // Délai de stabilisation après la commande

    if (mySerial.available() >= 4) {
      byte header = mySerial.read();
      byte distanceHigh = mySerial.read();
      byte distanceLow = mySerial.read();
      byte checksum = mySerial.read();

      if (header == 0xFF) {
        int distance = (distanceHigh << 8) | distanceLow; // Distance en mm
        float distanceCm = distance / 10.0; // Distance en cm

        // Calcul du niveau d'eau en cm
        float niveauEauCm = hauteurCuve - distanceCm;

        // Calcul du volume d'eau en litres
        float rayonCuve = diametreCuve / 2.0;
        float volumeEauLitres = (PI * rayonCuve * rayonCuve * niveauEauCm) / 1000.0;

        // Affichage sur l'écran LCD
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Eau: ");
        lcd.print(volumeEauLitres);
        lcd.print(" L");
        lcd.setCursor(0, 1);
        lcd.print("Niveau: ");
        lcd.print(niveauEauCm);
        lcd.print(" cm");

        // Contrôle de la LED RGB
        controlRGB(niveauEauCm);

        // Affichage sur le moniteur série
        Serial.print("Distance: ");
        Serial.print(distanceCm);
        Serial.print(" cm, Niveau: ");
        Serial.print(niveauEauCm);
        Serial.print(" cm, Volume: ");
        Serial.print(volumeEauLitres);
        Serial.println(" L");
      }
    }
  }
}

void controlRGB(float niveauEauCm) {
  if (niveauEauCm < hauteurCuve * 0.25) {
    // Niveau bas : LED rouge
    setColor(255, 0, 0);
  } else if (niveauEauCm < hauteurCuve * 0.5) {
    // Niveau moyen-bas : LED jaune
    setColor(255, 255, 0);
  } else if (niveauEauCm < hauteurCuve * 0.75) {
    // Niveau moyen-haut : LED cyan
    setColor(0, 255, 255);
  } else {
    // Niveau haut : LED verte
    setColor(0, 255, 0);
  }
}

void setColor(int red, int green, int blue) {
  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
}

Par contre j'ai un problème pour réinitialiser la mesure je dois "téléverser" c'est un peu chiant du coup ... je ne sais pas pourquoi. J'ai mis des petites data entre deux pour éloigner la prise de mesure est ainsi de suite mais rien y fait. Avez vous une idée ?

Pour 68tjs, le montage c'est une cuve à eau de 10m3 béton. Arduino à 10m. Pour le moment tout est sur mon bureau :slight_smile: (photo en PJ)

Le capteur sera placé au dessus de la ligne d'eau sur un support spécifique en inox.

dans l'attente de vous lire
merci

que voulez vous dire par là ?

dans mon code je lis les octets en attendant le marqueur de début 0xFF avant de lire les octets suivants

Quand je "relance" le téléversement depuis le logiciel Arduino la distance se met à jour mais après même en bougeant le capteur la distance ne se modifie pas.
Savez-vous me mettre en visu votre code ? A voir vous n'avez pas utilisé un ARDUINO. Je suis un peu perdu et tourne en rond depuis 2 jours. Mon câblage sur la photo est juste ?

Je voyais aussi sur d'autre site que le capteur attendait peut-être du 3,3V mais ça n'y fait rien.
Je dois avoir un problème de code au niveau des octets d'envoi mais je ne comprends pas tout encore.

D'avance merci

voici mon code de lecture

// ----------------------------------------------------------------
// GESTION DE LA LECTURE DU CAPTEUR DE DISTANCE
// ----------------------------------------------------------------

void triParInsertion(uint16_t arr[], int size) {
  for (int i = 1; i < size; ++i) {
    uint16_t key = arr[i];
    int j = i - 1;

    while (j >= 0 && arr[j] > key) {
      arr[j + 1] = arr[j];
      --j;
    }
    arr[j + 1] = key;
  }
}

bool lireUneFois(uint16_t & distance) {
  const uint8_t marqueurDebut = 0xFF;
  static bool attenteMarqueur = true;
  static uint8_t data[3];
  static uint8_t dataIndex = 0;

  if (Serial2.available() != 0) {
    uint8_t r = Serial2.read();

    if (attenteMarqueur) {
      if (r == marqueurDebut) {
        dataIndex = 0;
        attenteMarqueur = false;
      }
    } else {
      data[dataIndex++] = r;
      if (dataIndex >= sizeof data) {
        attenteMarqueur = true;
        distance = (((uint16_t)data[0]) << 8) + data[1];
        uint8_t ck = (((uint16_t)data[0]) + ((uint16_t)data[1]) - 1u) & 0x00FFu;
        return (data[2] == ck);
      }
    }
  }
  return false;
}


bool lireDistance(uint16_t & distance) {
  static uint16_t distances[5];
  static   const uint8_t nbEchantillons = sizeof distances / sizeof * distances;
  static uint8_t currentIndex = 0;

  if (lireUneFois(distances[currentIndex])) {
    if (++currentIndex >= nbEchantillons) {
      currentIndex = 0;
      triParInsertion(distances, nbEchantillons); // avec peu d'échantillons un tri par insertion est assez rapide
      distance = distances[nbEchantillons / 2];
      if (! premiereAcquisitionTerminee) debutChronoOff = millis();
      premiereAcquisitionTerminee = true;
      return true;
    }
  }
  return false;
}

Je lis depuis Serial2 car mon M5Stick a deux ports séries, pour vous il faudrait prendre votre port Série virtuel.

j'ai une fonction que j'appelle depuis la loop

void updateData(bool forcerAffichage = false) {

  if (lireDistance(distance) || forcerAffichage) { // distance contient la distance en mm, pas modifiée si lecture non prête
    drawFillStatus(distance, forcerAffichage);
  }
}

La fonction lireDistance() fait en fait 5 mesures en appelant la fonction lireUneFois() et classe les distance avec la fonction triParInsertion() et je prends comme distance l'échantillon médian ➜ ça permet de gérer le cas où une lecture ne serait pas cohérente.

il y a une petite machine à état qui fait qu'on attend de recevoir le marqueur de début de trame 0xFF avant d'essayer de lire les 3 octets qui représentent le vrai payload.

la fonction drawFillStatus() est spécifique à mon environnement, elle fait le petit dessin sur l'écran du M5Stack qui montre la barre de remplissage et affiche le volume d'eau dans la cuve et le pourcentage.

elle prend en paramètre un booléen qui dit de forcer l'affichage ou pas. Si on ne force pas l'affilage, la fonction va regarder si les anciennes valeurs affichées sont les mêmes que celles que l'on vient de calculer et ne faire l'affichage que si elles sont différentes.

C'est le booléen passé en paramètre à drawFillStatus() qui dit si on veut forcer l'affichage donc j'appelle dans le setup()

  updateData(true); // true pour forcer un affichage

et ensuite dans la loop on peut se contenter de

  updateData(); 

(sauf si l'utilisateur change les paramètres de distance qui me servent à calculer le %age et volume - dans ce cas il faut forcer un affichage )

bonjour,

un peu plus simple dans le fonctionnement (puisque c'est juste un interrupteur ouvert ou fermé)
mais peut-être plus dur à installer dans la cuve

tu as de simple détecteur de niveau (https://www.gotronic.fr/art-detecteur-de-niveau-no-flsw1-11543.htm)

tu en mets 3 ou 4 et tu auras une info basique type 25/50/75/100 %

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.