Composants · 14 min de lecture

Capteur de niveau d'eau Arduino : étalonnage, alarme et pompe

Capteur de niveau d'eau sur Arduino : étalonnage vide/moitié/plein, alimentation par broche contre la corrosion, alarme avec buzzer, pompe et code ESP32/Pico.

Un capteur de niveau d'eau est le moyen le plus simple et le moins cher de détecter avec Arduino jusqu'où monte l'eau dans un verre, un aquarium, une soucoupe de pot de fleurs ou un petit réservoir. À mesure que les pistes conductrices nues de la carte plongent dans l'eau, la tension de sa sortie analogique augmente ; Arduino lit cette tension avec analogRead() et décide si le récipient est « vide », « à moitié plein » ou « plein ». Il se branche avec trois fils, fonctionne avec quelques lignes de code et sert de base à de nombreux projets, de l'alarme de débordement à la commande automatique d'une pompe.

Dans ce guide, tu vas découvrir ce que contient le module, pourquoi la mesure n'atteint jamais 1023, comment réaliser l'étalonnage vide/moitié/plein et comment éviter la corrosion qui ronge le capteur en quelques semaines. Ensuite, tu construiras une alarme de débordement avec buzzer et une commande de pompe qui remplit un réservoir toute seule, tu compareras brièvement le capteur à un interrupteur à flotteur et au XKC-Y25 sans contact, puis tu verras comment faire la même chose avec l'ESP32 et le Raspberry Pi Pico.

Module capteur de niveau d'eau pour Arduino
Module capteur de niveau d'eau : les pistes conductrices entrelacées du bas plongent dans l'eau, les broches S, + et − du haut se branchent sur Arduino ; l'électronique doit toujours rester au sec.

Qu'est-ce qu'un capteur de niveau d'eau et comment fonctionne-t-il ?

La partie basse du module porte dix pistes conductrices qui ne se touchent pas et s'imbriquent comme les dents de deux peignes. Cinq sont des pistes d'alimentation reliées au +, les cinq autres sont des pistes de mesure qui vont à la base du transistor NPN S8050 placé en haut de la carte. Quand la carte est sèche, il n'y a que de l'air entre les pistes, le transistor est bloqué et la broche S reste proche de 0 V. Dès que la carte plonge dans l'eau, celle-ci relie les pistes d'alimentation et de mesure ; un petit courant entre dans la base, le transistor commence à conduire et la tension de la sortie S, prise sur l'émetteur, augmente. Plus l'eau monte, plus la longueur de piste mouillée est grande, plus la résistance entre les pistes diminue et plus la tension de sortie grimpe.

Ce fonctionnement a trois conséquences importantes. D'abord, le capteur ne mesure pas vraiment l'eau mais sa conductivité : les minéraux dissous dans l'eau du robinet font monter la valeur, alors que l'eau pure (distillée) ne donne presque rien. Ensuite, la sortie provient d'un transistor monté en émetteur suiveur, si bien que la tension n'atteint jamais celle de l'alimentation ; un capteur entièrement mouillé et alimenté en 5 V affiche en général entre 500 et 650 sur un Arduino Uno et n'approche jamais 1023. Enfin, la relation n'est pas linéaire : la valeur grimpe vite sur les premiers millimètres puis de plus en plus lentement. Ce capteur n'est donc pas une règle précise au millimètre, mais un indicateur pratique qui distingue de façon fiable quelques niveaux.

CaractéristiqueValeur
Tension de fonctionnement3,3–5 V continu
Courant de fonctionnementMoins de 20 mA (maximal quand il est entièrement mouillé)
SortieTension analogique (broche S), augmente avec le niveau d'eau
Zone de détectionEnviron 40 × 16 mm, soit au maximum environ 4 cm de hauteur d'eau
Taille de la carteEnviron 62 × 20 mm
Température de fonctionnement10–30 °C (donnée du fabricant)
BrochesS (signal), + (VCC), − (GND)

Branchement du capteur de niveau d'eau : Arduino Uno, ESP32 et Pico

Broche du capteurArduino UnoESP32Raspberry Pi Pico
S (signal)A0GPIO 34 (ADC1)GP26 (ADC0)
+ (VCC)D7 (l'alimente seulement pendant la mesure)GPIO 25GP15
− (GND)GNDGNDGND
Ne branche pas la broche + du capteur en permanence sur le 5V. Quand un courant continu traverse sans arrêt les pistes mouillées, l'électrolyse démarre : le revêtement des pistes reliées au + se dissout, les pistes noircissent et en quelques semaines les mesures commencent à dériver. De plus, seule la partie basse de la carte, avec les pistes conductrices, doit aller dans l'eau ; si la partie haute avec le transistor, la LED et les broches est mouillée, c'est le court-circuit.

Le moyen le plus simple d'éviter la corrosion est d'alimenter le capteur par une broche numérique, comme dans le tableau : le code met la broche à HIGH juste avant la mesure, attend 10 ms, lit la valeur et remet la broche à LOW. Dans un système qui mesure une fois par seconde, les pistes ne sont sous tension que 1 % du temps, ce qui ralentit l'usure d'environ cent fois. Entièrement mouillé, le module consomme au plus une vingtaine de mA. La limite recommandée pour une broche de l'Arduino Uno est de 20 mA et le maximum absolu de 40 mA, et la broche n'est active que quelques millisecondes : ce branchement est donc sûr, et les broches de l'ESP32 fournissent aussi ce courant sans peine. Les broches du Pico, elles, fonctionnent par défaut avec une intensité de sortie plus faible ; quand le capteur est entièrement mouillé, la tension de la broche baisse un peu et les valeurs lues diminuent. Tant que tu étalonnes avec le même câblage, ce n'est pas un problème ; si tu veux des valeurs plus stables, tu peux commuter le + du capteur avec un petit transistor PNP comme le BC557 : l'émetteur va sur la broche 3V3 de la carte, le collecteur sur le + du capteur et la base sur la broche GPIO à travers une résistance de 1 kΩ ; le capteur s'allume alors quand la broche est à LOW. Pour choisir un transistor adapté, jette un œil à l'outil transistors.

Pas à pas : la première mesure avec Arduino

  1. Relie la broche S du capteur à A0, la broche + à D7 et la broche − à GND. Tiens la carte verticale, pistes vers le bas.
  2. Ouvre le code ci-dessous dans l'Arduino IDE, choisis Arduino Uno comme carte et le bon port, puis téléverse-le.
  3. Ouvre le moniteur série et règle-le sur 9600 bauds. Vérifie que la valeur est proche de 0 quand le capteur est sec.
  4. Plonge lentement le capteur dans un verre d'eau : d'abord la pointe seule, puis jusqu'à la moitié, puis jusqu'à la ligne où s'arrêtent les pistes. À chaque étape, attends quelques secondes et note la valeur.
C++ (Arduino IDE)
1const int SENSOR_PIN = A0;   // S → A0
2const int POWER_PIN = 7;     // + → D7 (yalnızca ölçerken besle / power only while measuring)
3
4int readSensor() {
5  digitalWrite(POWER_PIN, HIGH);        // sensörü aç / power the sensor
6  delay(10);                            // değerin oturmasını bekle / let the reading settle
7  long sum = 0;
8  for (int i = 0; i < 8; i++) {         // 8 ölçümün ortalaması / average of 8 readings
9    sum += analogRead(SENSOR_PIN);
10  }
11  digitalWrite(POWER_PIN, LOW);         // sensörü kapat / power off
12  return sum / 8;
13}
14
15void setup() {
16  pinMode(POWER_PIN, OUTPUT);
17  digitalWrite(POWER_PIN, LOW);         // kapalı başla / start powered off
18  Serial.begin(9600);
19}
20
21void loop() {
22  int raw = readSensor();
23  Serial.print("Ham deger / Raw value: ");
24  Serial.println(raw);
25  delay(1000);                          // saniyede bir ölç / measure once a second
26}

La fonction readSensor() n'allume le capteur qu'environ 11 ms par mesure. L'attente de 10 ms laisse le transistor et l'eau entre les pistes se stabiliser ; ensuite, la moyenne de 8 lectures lisse les petites fluctuations de chaque échantillon. Sur l'Uno, chaque analogRead() prend environ 0,1 ms, donc 8 lectures durent moins de 1 ms. Si tu remues l'eau ou bouges le verre, tu verras les valeurs sauter dans le moniteur série ; c'est normal, car la surface en mouvement modifie sans cesse la longueur mouillée des pistes.

Vide, moitié, plein : comment étalonner le capteur

N'utilise pas tels quels les seuils des codes trouvés sur internet : chaque capteur, chaque eau et chaque tension d'alimentation donnent des valeurs différentes. Étalonne dans le récipient où le capteur servira vraiment et avec la même eau : l'eau de l'aquarium pour un aquarium, de l'eau avec engrais pour une cuve d'arrosage fertilisée. Trace au feutre des lignes à 0, 10, 20, 30 et 40 mm sur le capteur, plonge la carte jusqu'à chaque ligne, attends 3 à 4 secondes que la valeur se stabilise et note le nombre affiché dans le moniteur série. Le tableau donne des plages typiques pour l'eau du robinet et une alimentation de 5 V ; inscris tes propres valeurs à côté.

NiveauProfondeur immergéeValeur typique sur Uno (5 V, eau du robinet)
Vide0 mm (sec)0–20
BasEnviron 5–10 mm250–400
MoitiéEnviron 20 mm400–480
PleinEnviron 40 mm (ligne où s'arrêtent les pistes)480–650

Ce qui frappe dans le tableau, c'est la vitesse à laquelle les valeurs montent dans le premier centimètre, puis leur tassement : entre 0 et 10 mm, l'écart peut atteindre plusieurs centaines d'unités, mais entre 20 et 40 mm il ne reste que quelques dizaines. C'est pourquoi, au lieu de tracer une seule droite avec map(), l'interpolation linéaire par morceaux, qui applique un rapport différent entre chaque paire de points mesurés, donne un résultat bien plus précis. Le code suivant garde les cinq points que tu as mesurés dans deux tableaux, convertit la valeur brute en millimètres et affiche le niveau par son nom. Il te suffit d'écrire tes propres mesures dans le tableau RAW, dans l'ordre croissant.

C++ (Arduino IDE)
1const int SENSOR_PIN = A0;
2const int POWER_PIN = 7;
3
4// Kendi kalibrasyon ölçümlerin / your own calibration readings
5const int N = 5;
6const int RAW[N] = {0, 330, 440, 490, 520};   // ham değer, küçükten büyüğe / raw value, ascending
7const int MM[N]  = {0, 10, 20, 30, 40};       // batma derinliği (mm) / immersion depth (mm)
8
9int readSensor() {
10  digitalWrite(POWER_PIN, HIGH);
11  delay(10);
12  long sum = 0;
13  for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
14  digitalWrite(POWER_PIN, LOW);
15  return sum / 8;
16}
17
18int rawToMm(int raw) {
19  if (raw <= RAW[0]) return MM[0];
20  for (int i = 1; i < N; i++) {
21    if (raw <= RAW[i]) {                      // iki nokta arasında oran kur / interpolate between two points
22      return map(raw, RAW[i - 1], RAW[i], MM[i - 1], MM[i]);
23    }
24  }
25  return MM[N - 1];                           // en üst noktanın üstü / above the top point
26}
27
28const char* levelName(int mm) {
29  if (mm < 3)  return "Bos / Empty";
30  if (mm < 15) return "Az / Low";
31  if (mm < 30) return "Yarim / Half";
32  return "Dolu / Full";
33}
34
35void setup() {
36  pinMode(POWER_PIN, OUTPUT);
37  digitalWrite(POWER_PIN, LOW);
38  Serial.begin(9600);
39}
40
41void loop() {
42  int raw = readSensor();
43  int mm = rawToMm(raw);
44  Serial.print(raw);
45  Serial.print(" -> ");
46  Serial.print(mm);
47  Serial.print(" mm, ");
48  Serial.println(levelName(mm));
49  delay(1000);
50}
Quand tu sors le capteur de l'eau, la valeur ne retombe pas tout de suite à 0 : le fin film d'eau et les gouttes restés entre les pistes maintiennent la mesure nettement au-dessus de zéro pendant un moment. Place donc le seuil « vide » un peu au-dessus de 0 et, pour les décisions marche/arrêt comme une alarme, utilise deux seuils distincts : un pour activer, un pour désactiver. Cette méthode s'appelle l'hystérésis ; elle empêche un relais ou un buzzer de s'allumer et de s'éteindre chaque seconde pendant que le niveau oscille juste autour du seuil.

Alarme de débordement avec buzzer

L'une des tâches les plus utiles d'un capteur de niveau d'eau est de signaler un débordement : placé sous la machine à laver ou la chaudière, dans une soucoupe, dans le bac à condensats d'un climatiseur ou au bord d'un seau qui se remplit, le capteur déclenche l'alarme dès que l'eau touche sa pointe. Le niveau « bas » du tableau d'étalonnage suffit déjà pour cela. Le code ci-dessous utilise un buzzer actif et la LED intégrée de l'Uno ; quand la valeur dépasse ALARM_ON, le buzzer sonne tous les quarts de seconde, et quand elle repasse sous ALARM_OFF, il se tait. Comme la temporisation utilise millis() au lieu de delay(), la mesure et le buzzer ne se bloquent pas mutuellement. Pour les types de buzzer, consulte Qu'est-ce qu'un buzzer ?, et pour le principe de millis(), millis() et delay().

C++ (Arduino IDE)
1const int SENSOR_PIN = A0;   // S → A0
2const int POWER_PIN = 7;     // + → D7
3const int BUZZER_PIN = 8;    // aktif buzzer + ucu / active buzzer +
4const int LED_PIN = 13;      // Uno'nun dahili LED'i / Uno's built-in LED
5
6const int ALARM_ON = 200;    // bu değer ve üstü taşma / at or above: overflow (kendin ölç / measure yours)
7const int ALARM_OFF = 100;   // bunun altına inince alarm biter / alarm clears below this
8
9bool alarmActive = false;
10bool buzzerOn = false;
11unsigned long lastRead = 0;
12unsigned long lastBeep = 0;
13
14int readSensor() {
15  digitalWrite(POWER_PIN, HIGH);
16  delay(10);
17  long sum = 0;
18  for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
19  digitalWrite(POWER_PIN, LOW);
20  return sum / 8;
21}
22
23void setup() {
24  pinMode(POWER_PIN, OUTPUT);
25  pinMode(BUZZER_PIN, OUTPUT);
26  pinMode(LED_PIN, OUTPUT);
27  digitalWrite(POWER_PIN, LOW);
28  Serial.begin(9600);
29}
30
31void loop() {
32  unsigned long now = millis();
33
34  if (now - lastRead >= 1000) {                       // saniyede bir ölç / measure once a second
35    lastRead = now;
36    int level = readSensor();
37    if (!alarmActive && level >= ALARM_ON) alarmActive = true;    // taşma başladı / overflow started
38    if (alarmActive && level < ALARM_OFF) alarmActive = false;    // su çekildi / water receded
39    Serial.print("Seviye / Level: ");
40    Serial.println(level);
41  }
42
43  if (alarmActive) {
44    if (now - lastBeep >= 250) {                      // 250 ms öt, 250 ms sus / 250 ms on, 250 ms off
45      lastBeep = now;
46      buzzerOn = !buzzerOn;
47      digitalWrite(BUZZER_PIN, buzzerOn ? HIGH : LOW);
48    }
49  } else if (buzzerOn) {
50    buzzerOn = false;
51    digitalWrite(BUZZER_PIN, LOW);
52  }
53  digitalWrite(LED_PIN, alarmActive ? HIGH : LOW);
54}

Commande de pompe : remplir un réservoir automatiquement

La deuxième application classique est le remplissage automatique qui maintient le niveau dans une plage donnée. Tu veux peut-être compléter l'eau qui s'évapore d'un aquarium à partir d'un seau de réserve, garder plein l'abreuvoir de ton animal ou alimenter la cuve d'une serre. La logique est simple : quand le niveau descend sous START_BELOW, la pompe démarre, et quand il atteint STOP_ABOVE, elle s'arrête. L'écart entre ces deux seuils est l'hystérésis qui évite que la pompe ne s'allume et s'éteigne sans arrêt. N'oublie pas que le capteur n'a qu'une zone de détection d'environ 4 cm ; fixe la carte à une hauteur telle que la plage d'eau que tu veux maintenir tombe dans ces 4 cm.

Mini pompe à eau immergée 6 V
Mini pompe immergée 3–6 V : elle fonctionne sous l'eau et consomme environ 100 à 250 mA, elle se commande donc via un relais ou un MOSFET, et non directement par une broche d'Arduino.

La pompe consomme bien plus de courant qu'une broche d'Arduino ne peut en fournir : commande-la avec un module relais ou un MOSFET à niveau logique accompagné d'une diode de roue libre, alimente la pompe par une source séparée et relie les GND des deux sources. Tu trouveras les détails dans Qu'est-ce qu'un module relais ?, utiliser un MOSFET et la mini pompe à eau. La partie la plus importante du code est une sécurité : si la pompe tourne pendant toute la durée MAX_RUN_MS sans que le niveau atteigne la cible, le système verrouille la pompe et te prévient par de courts bips. Le tuyau est peut-être sorti, le seau de réserve vide ou le capteur a bougé ; sans ce verrouillage, la pompe pourrait tourner à sec pendant des heures ou tout inonder.

C++ (Arduino IDE)
1const int SENSOR_PIN = A0;
2const int POWER_PIN = 7;
3const int PUMP_PIN = 8;                 // röle IN / relay IN
4const int BUZZER_PIN = 9;               // aktif buzzer / active buzzer
5const bool RELAY_ACTIVE_LOW = true;     // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
6
7const int START_BELOW = 300;            // bunun altında doldur / start filling below this (kendin ölç / measure yours)
8const int STOP_ABOVE = 480;             // bu değerde dur / stop at this value
9const unsigned long MAX_RUN_MS = 30000; // en uzun çalışma 30 sn / max run time 30 s
10
11bool pumpOn = false;
12bool fault = false;
13unsigned long pumpStart = 0;
14
15int readSensor() {
16  digitalWrite(POWER_PIN, HIGH);
17  delay(10);
18  long sum = 0;
19  for (int i = 0; i < 8; i++) sum += analogRead(SENSOR_PIN);
20  digitalWrite(POWER_PIN, LOW);
21  return sum / 8;
22}
23
24void setPump(bool on) {
25  pumpOn = on;
26  bool pinHigh = RELAY_ACTIVE_LOW ? !on : on;
27  digitalWrite(PUMP_PIN, pinHigh ? HIGH : LOW);
28}
29
30void setup() {
31  setPump(false);              // pin çıkış olmadan önce kapalı konuma al / set off before the pin becomes an output
32  pinMode(PUMP_PIN, OUTPUT);
33  pinMode(POWER_PIN, OUTPUT);
34  pinMode(BUZZER_PIN, OUTPUT);
35  digitalWrite(POWER_PIN, LOW);
36  Serial.begin(9600);
37}
38
39void loop() {
40  if (fault) {                 // arıza: pompa kilitli, kesik kesik öt / fault: pump locked out, beep
41    digitalWrite(BUZZER_PIN, HIGH);
42    delay(200);
43    digitalWrite(BUZZER_PIN, LOW);
44    delay(1800);
45    return;                    // yeniden başlatmak için reset / press reset to restart
46  }
47
48  int level = readSensor();
49
50  if (!pumpOn && level < START_BELOW) {
51    setPump(true);             // seviye düştü, doldur / level low, start filling
52    pumpStart = millis();
53  } else if (pumpOn && level >= STOP_ABOVE) {
54    setPump(false);            // istenen seviyeye ulaşıldı / target level reached
55  } else if (pumpOn && millis() - pumpStart > MAX_RUN_MS) {
56    setPump(false);            // süre doldu, seviye yükselmedi / timed out, level did not rise
57    fault = true;
58  }
59
60  Serial.print("Seviye / Level: ");
61  Serial.print(level);
62  Serial.println(pumpOn ? "  pompa / pump ON" : "  pompa / pump OFF");
63  delay(500);
64}
Eau et électricité dans le même projet : place l'Arduino, le relais et l'alimentation au-dessus et à l'écart des récipients d'eau, et isole les raccords avec de la gaine thermorétractable ou de la colle chaude. Si tu utilises une pompe ou une électrovanne en 230 V, fais réaliser le raccordement au secteur par une personne qualifiée et travaille sur un circuit protégé par un interrupteur différentiel. Les petites pompes immergées chauffent et tombent vite en panne si elles tournent à sec ; ajouter un interrupteur à flotteur dans le seau de réserve constitue une bonne deuxième sécurité.

Capteur de niveau d'eau, interrupteur à flotteur et XKC-Y25 : comparatif

CaractéristiqueCapteur de niveau d'eau (pistes conductrices)Interrupteur à flotteurXKC-Y25 (sans contact)
Principe de détectionConductivité de l'eauAimant flottant et contact reedVariation de capacité derrière la paroi du récipient
SortieAnalogique (quelques niveaux)Contact ouvert ou ferméNumérique (liquide présent ou non)
Plage de mesureEnviron 0–4 cmUn point (hauteur de montage)Un point (hauteur de montage)
Contact avec l'eauOui, pistes dans l'eauOui, corps dans l'eauNon, se colle à l'extérieur du récipient
CorrosionOui ; alimentation par broche indispensableQuasi nulleAucune
Alimentation3,3–5 VInutile (contact passif)5–24 V, environ 5 mA
Idéal pourExpériences, alarme de débordement, petits récipientsRéservoirs fixes, protection de pompeRéservoirs fermés en plastique ou en verre, liquides corrosifs
PrixLe moins cherBon marchéPlus cher que les autres

Un interrupteur à flotteur se compose d'une tige contenant un contact reed et d'un flotteur aimanté qui coulisse le long de celle-ci. Quand l'eau monte, le flotteur s'élève, l'aimant arrive au niveau du contact reed et le contact se ferme ou s'ouvre. En retournant le flotteur sur la tige, tu passes d'un fonctionnement normalement ouvert (NO) à normalement fermé (NC). Pour le brancher sur Arduino, relie un fil à une broche numérique et l'autre à GND, puis configure la broche en INPUT_PULLUP ; comme il ne subit pas l'usure par électrolyse, il dure bien plus longtemps dans une installation fixe. Les contacts des petits modèles sont généralement limités à environ 0,5 A et 10 W : commande donc la pompe via un relais et non directement. Pour comprendre le fonctionnement d'un contact reed, lis l'article Interrupteur reed.

Interrupteur à flotteur comme capteur de niveau d'eau
Interrupteur à flotteur : le flotteur aimanté monte avec l'eau et ouvre ou ferme le contact reed de la tige.
C++ (Arduino IDE)
1const int FLOAT_PIN = 2;    // bir kablo D2'ye, diğeri GND'ye / one wire to D2, the other to GND
2
3void setup() {
4  pinMode(FLOAT_PIN, INPUT_PULLUP);   // dahili pull-up direnci / internal pull-up resistor
5  Serial.begin(9600);
6}
7
8void loop() {
9  // Kontak kapalıyken pin LOW okunur / the pin reads LOW when the contact is closed
10  if (digitalRead(FLOAT_PIN) == LOW) {
11    Serial.println("Kontak kapali / Contact closed");
12  } else {
13    Serial.println("Kontak acik / Contact open");
14  }
15  delay(500);
16}

Le XKC-Y25, lui, est un capteur capacitif qui ne touche jamais l'eau : on le colle à l'extérieur d'un réservoir en plastique ou en verre et il détecte la présence de liquide derrière la paroi. D'après le fabricant, il fonctionne entre 5 et 24 V, consomme environ 5 mA, détecte à travers des parois non métalliques jusqu'à 13 mm d'épaisseur et réagit en environ 500 ms. Le niveau haut de sa sortie est égal à la tension d'alimentation : si tu branches sur un ESP32 ou un Pico un XKC-Y25 alimenté en 5 V, il te faut un pont diviseur de tension (l'outil pont diviseur calcule les bonnes résistances). Nous détaillons le réglage de sensibilité et les modèles à sorties différentes dans l'article capteur de niveau sans contact XKC-Y25.

Capteur de niveau de liquide sans contact XKC-Y25
XKC-Y25 : capteur capacitif collé à l'extérieur du réservoir ; comme il ne touche jamais l'eau, il ne se corrode pas.

Surveiller le niveau d'eau depuis ton téléphone avec l'ESP32

Avec l'ESP32, tu peux envoyer la mesure sur ton téléphone par Wi-Fi. Relie toujours la broche S du capteur à une broche de l'ADC1 (GPIO 32–39) ; les broches de l'ADC2 ne sont pas lisibles quand le Wi-Fi est actif. L'ADC de l'ESP32 est sur 12 bits, les valeurs vont donc de 0 à 4095, et comme le capteur est alimenté en 3,3 V, les nombres ne sont pas comparables à ceux de l'Uno : il faut refaire l'étalonnage. L'ADC de l'ESP32 n'est pas parfaitement linéaire près de 0 V et près du haut de sa plage, mais comme seule compte ici la différence entre les niveaux, et non la tension absolue, cela ne pose pas de problème. Le code suivant mesure toutes les deux secondes et sert une petite page web qui se rafraîchit toute seule toutes les cinq secondes et que tu peux ouvrir depuis ton téléphone sur le même réseau.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <WebServer.h>
3
4const char* WIFI_SSID = "WIFI_ADIN";      // ağ adın / your network name
5const char* WIFI_PASS = "WIFI_SIFREN";    // ağ şifren / your network password
6
7const int SENSOR_PIN = 34;   // S → GPIO 34 (ADC1, Wi-Fi ile çalışır / works with Wi-Fi)
8const int POWER_PIN = 25;    // + → GPIO 25
9const int HALF = 1500;       // yarım eşiği / half threshold (kendin ölç / measure yours)
10const int FULL = 2000;       // dolu eşiği / full threshold (kendin ölç / measure yours)
11
12WebServer server(80);
13int lastRaw = 0;
14unsigned long lastRead = 0;
15
16int readSensor() {
17  digitalWrite(POWER_PIN, HIGH);
18  delay(10);
19  long sum = 0;
20  for (int i = 0; i < 16; i++) sum += analogRead(SENSOR_PIN);   // 0–4095
21  digitalWrite(POWER_PIN, LOW);
22  return sum / 16;
23}
24
25const char* levelName(int raw) {
26  if (raw < 100) return "Bos / Empty";
27  if (raw < HALF) return "Az / Low";
28  if (raw < FULL) return "Yarim / Half";
29  return "Dolu / Full";
30}
31
32void handleRoot() {
33  String html = "<!DOCTYPE html><html><head><meta charset='utf-8'>"
34                "<meta name='viewport' content='width=device-width'>"
35                "<meta http-equiv='refresh' content='5'></head><body>"
36                "<h1>Su seviyesi / Water level</h1><h2>";
37  html += levelName(lastRaw);
38  html += "</h2><p>Ham deger / Raw: ";
39  html += lastRaw;
40  html += "</p></body></html>";
41  server.send(200, "text/html", html);
42}
43
44void setup() {
45  Serial.begin(115200);
46  pinMode(POWER_PIN, OUTPUT);
47  digitalWrite(POWER_PIN, LOW);
48  WiFi.begin(WIFI_SSID, WIFI_PASS);
49  while (WiFi.status() != WL_CONNECTED) {   // bağlanana kadar bekle / wait until connected
50    delay(500);
51    Serial.print(".");
52  }
53  Serial.println();
54  Serial.print("Adres / Address: http://");
55  Serial.println(WiFi.localIP());
56  server.on("/", handleRoot);
57  server.begin();
58}
59
60void loop() {
61  server.handleClient();
62  if (millis() - lastRead >= 2000) {        // 2 sn'de bir ölç / measure every 2 s
63    lastRead = millis();
64    lastRaw = readSensor();
65  }
66}

Avant de téléverser, remplace WIFI_SSID et WIFI_PASS par les informations de ton réseau ; l'ESP32 ne se connecte qu'aux réseaux 2,4 GHz. En ouvrant le moniteur série à 115200 bauds, il suffit de taper l'adresse affichée dans le navigateur de ton téléphone. Si tu veux recevoir une notification quand le niveau est « plein », tu peux transformer la même mesure en message avec la méthode de l'article bot Telegram avec ESP32.

Alarme de débordement avec Raspberry Pi Pico et MicroPython

Sur le Raspberry Pi Pico, ce sont les broches GP26, GP27 et GP28 qui servent aux mesures analogiques. La fonction read_u16() de MicroPython ramène la mesure 12 bits du Pico sur la plage 0–65535, tes seuils seront donc des nombres bien plus grands que sur l'Uno. Le code ci-dessous alimente le capteur par GP15, lit la sortie S sur GP26 et signale un débordement par trois bips courts d'un buzzer actif relié à GP14. Comme pour le premier programme, fixe les seuils à partir de tes propres mesures.

MicroPython
1from machine import ADC, Pin
2import time
3
4sensor = ADC(26)                    # GP26 (ADC0) → S
5power = Pin(15, Pin.OUT, value=0)   # GP15 → sensör + / sensor +
6buzzer = Pin(14, Pin.OUT, value=0)  # GP14 → aktif buzzer / active buzzer
7
8ALARM_ON = 20000    # bu değer ve üstü taşma / at or above: overflow (kendin ölç / measure yours)
9ALARM_OFF = 10000   # bunun altında alarm biter / alarm clears below this
10
11def read_level(samples=8):
12    power.value(1)
13    time.sleep_ms(10)               # değerin oturmasını bekle / let the reading settle
14    total = 0
15    for _ in range(samples):
16        total += sensor.read_u16()  # 0–65535
17    power.value(0)
18    return total // samples
19
20alarm = False
21while True:
22    level = read_level()
23    if not alarm and level >= ALARM_ON:
24        alarm = True
25    elif alarm and level < ALARM_OFF:
26        alarm = False
27    print("Seviye / Level:", level, "ALARM" if alarm else "")
28    if alarm:
29        for _ in range(3):          # üç kısa bip / three short beeps
30            buzzer.value(1)
31            time.sleep_ms(150)
32            buzzer.value(0)
33            time.sleep_ms(150)
34    else:
35        time.sleep(1)

Idées de projets avec un capteur de niveau d'eau

  • Alerte de débordement de soucoupe : Un buzzer qui sonne quand l'eau s'accumule dans la soucoupe après l'arrosage ; associé à un capteur d'humidité du sol, il forme un système d'arrosage complet.
  • Remise à niveau automatique d'aquarium : Un remplissage limité dans le temps qui remplace l'eau évaporée à partir d'un seau de réserve grâce à une mini pompe.
  • Gamelle d'eau pour animal : Un avertisseur qui allume une LED ou envoie une notification sur le téléphone via l'ESP32 quand la gamelle se vide.
  • Détecteur d'inondation : Une alarme de fuite avec le capteur posé à plat au sol sous la machine à laver, près de la chaudière ou à la cave.
  • Cuve de serre intelligente : Une protection qui surveille le niveau de la cuve d'arrosage et verrouille la pompe quand elle est vide ; elle s'intègre facilement au projet de serre connectée.
  • Jauge de récupérateur d'eau de pluie : Un panneau qui affiche le niveau vide, moitié ou plein sur un écran LCD I2C ; tu peux aussi ajouter un capteur de pluie pour savoir quand la pluie commence.

Erreurs fréquentes et solutions

SymptômeCause probableSolution
La valeur reste à 0, même dans l'eauLa broche + n'est pas alimentée (POWER_PIN ne passe jamais à HIGH) ou S est sur la mauvaise brocheVérifie les lignes pinMode et digitalWrite et que S est bien sur une broche analogique
La valeur saute au hasard même à secLa broche S est en l'air ou la masse n'est pas reliéeVérifie les trois fils ; la masse doit être commune
Elle n'atteint jamais 1023, même totalement immergéC'est normal ; la sortie vient d'un émetteur suiveurFixe les seuils d'après la valeur la plus haute que tu as mesurée
Aucune valeur dans l'eau pureL'eau distillée ou purifiée conduit très peuPour ce type d'eau, utilise un XKC-Y25 ou un interrupteur à flotteur
Les valeurs baissent ou dérivent en quelques semainesÉlectrolyse et dépôts sur les pistesAlimente le capteur par une broche, nettoie les pistes avec une brosse douce et remplace le capteur si besoin
La pompe ou le buzzer bascule sans arrêt au seuilUn seul seuil est utilisé ; la surface agitée fait varier la valeurUtilise deux seuils distincts pour marche et arrêt (hystérésis) et fais une moyenne
Sur l'ESP32, la valeur n'est plus lisible une fois le Wi-Fi connectéLe capteur est sur une broche de l'ADC2Déplace S sur une broche de l'ADC1, entre GPIO 32 et 39
Pour prolonger la vie du capteur, place-le verticalement dans l'eau, n'immerge que la partie des pistes et recouvre l'électronique du haut de colle chaude ou de vernis transparent ; ne recouvre surtout pas les pistes elles-mêmes, sinon elles ne pourront plus mesurer la conductivité. Pour une installation fixe qui restera des mois dans l'eau, la solution la plus robuste consiste à utiliser ce capteur pour le prototype, puis à passer à un interrupteur à flotteur ou à un capteur sans contact dans le système final.

Le capteur de niveau d'eau enseigne les mesures analogiques, l'étalonnage, l'hystérésis et des problèmes bien réels comme la corrosion avec un seul module bon marché. Si tu dois mesurer au centimètre près le niveau d'un grand réservoir, tu peux passer à une solution à ultrasons comme le capteur de distance HC-SR04. Dans l'application BlueGrays, tu trouveras la station d'arrosage intelligente et des projets d'alarme avec buzzer, avec schémas et code pas à pas, et tu pourras facilement y ajouter le capteur de niveau d'eau.

Questions fréquentes

Comment fonctionne un capteur de niveau d'eau ?

Quand les pistes conductrices entrelacées de la carte plongent dans l'eau, celle-ci les relie et un courant circule vers la base du transistor S8050 du module. Plus le transistor conduit, plus la tension de la broche S augmente ; Arduino lit cette tension avec analogRead() pour savoir jusqu'où monte l'eau.

Pourquoi mon capteur de niveau d'eau se corrode-t-il ?

Quand un courant continu traverse sans arrêt les pistes mouillées, l'électrolyse démarre et le revêtement des pistes reliées au + se dissout. Si tu alimentes le capteur par une broche numérique au lieu du 5V et ne l'allumes que quelques millisecondes par mesure, l'usure ralentit fortement et le capteur tient des mois.

Un capteur de niveau d'eau fonctionne-t-il dans l'eau distillée ?

Pas vraiment. Comme le capteur mesure la conductivité de l'eau, l'eau distillée ou purifiée, sans minéraux dissous, donne des valeurs très faibles. Pour ce type d'eau, mieux vaut choisir des capteurs qui ne dépendent pas de la conductivité, comme le XKC-Y25 sans contact ou un interrupteur à flotteur.

Pourquoi la valeur du capteur de niveau d'eau n'atteint-elle pas 1023 ?

La sortie S est prise sur l'émetteur du transistor, donc la tension reste inférieure à l'alimentation, et le courant de base est limité par la résistance de l'eau. Sur un Arduino Uno en 5 V, un capteur entièrement mouillé affiche en général entre 500 et 650 ; fixe tes seuils à partir de ce maximum.

Peut-on immerger complètement un capteur de niveau d'eau ?

Non. Seule la partie basse avec les pistes conductrices doit aller dans l'eau ; si la partie haute avec le transistor, la LED et les broches est mouillée, il y a court-circuit et le capteur mesure mal ou tombe en panne. Protéger l'électronique avec de la colle chaude ou du vernis prolonge sa durée de vie.

Comment mesurer le niveau d'une grande cuve d'eau ?

Ce capteur ne couvre qu'environ 4 cm, il ne convient donc pas aux grandes cuves. Pour une mesure continue, on utilise des capteurs à ultrasons étanches comme le JSN-SR04T fixés dans le couvercle ; pour surveiller seulement quelques points critiques, on place des interrupteurs à flotteur à différentes hauteurs.

Voir tous les projets
Utilisation du buzzer
#13Débutant

Utilisation du buzzer

Tu t'es déjà demandé comment une sonnette ou une alarme produit son son ? L'Arduino fait biper un petit buzzer à intervalles courts : bip, silence, bip, silence. Tu vois comment l'électricité devient

4.7(89)
161
Mesurer l'intensité lumineuse avec une LDR
#11Débutant

Mesurer l'intensité lumineuse avec une LDR

Envie de voir en chiffres à quel point ta chambre est lumineuse ? Le LDR, une petite pièce sensible à la lumière, mesure la lumière ambiante, et l'Arduino écrit la valeur sur l'écran de ton ordinateur

4.6(81)
139
Mesure de l'intensité lumineuse avec le module LDR ESP32
#113Débutant

Mesure de l'intensité lumineuse avec le module LDR ESP32

Suivi en temps réel sur le moniteur série de la valeur brute de l'ADC du module LDR et du pourcentage relatif de luminosité calculé à partir de références dans l'obscurité et à la lumière. Ce pourcentage n'est pas une mesure en lux. Permet de comprendre le principe de calibrage du module. Il est préférable de réaliser cet exercice avant le projet 10, car il sert à déterminer la valeur seuil.

4.6(36)
55
Station d'irrigation intelligente
#83Avancé
Premium

Station d'irrigation intelligente

Un jardinier qui arrose tes plantes tout seul pour qu'elles ne sèchent pas pendant tes vacances. Un capteur d'humidité mesure à quel point la terre est mouillée ; quand elle devient sèche, l'Arduino f

5.0(42)
57
Lecture d'un interrupteur reed
#37Débutant

Lecture d'un interrupteur reed

Tu t'es déjà demandé comment marche l'interrupteur magnétique des alarmes de portes et de fenêtres ? Quand un aimant approche du module à relais reed, le minuscule interrupteur à l'intérieur se ferme

4.4(21)
27
Serveur Web asynchrone ESP32 (avec affichage de l'adresse IP sur l'écran LCD)
#129Avancé

Serveur Web asynchrone ESP32 (avec affichage de l'adresse IP sur l'écran LCD)

Dans ce projet, nous transformons l'ESP32 en un serveur web asynchrone que vous pouvez contrôler depuis votre téléphone ou votre ordinateur connecté au même réseau Wi-Fi. Grâce à la bibliothèque ESPAsyncWebServer, le serveur peut traiter plusieurs requêtes simultanément (contrairement au classique WebServer.h qui se bloque sur une seule requête). Depuis votre navigateur, vous pourrez vous connecter à l'adresse IP de l'ESP32, puis allumer et éteindre la LED co

4.8(16)
26
Système d'Alarme de Mouvement ESP32 (PIR + Buzzer + LED + Telegram)
#145Avancé
Premium

Système d'Alarme de Mouvement ESP32 (PIR + Buzzer + LED + Telegram)

Un système d'alarme de sécurité intelligent qui active le buzzer et la LED lorsque le capteur PIR détecte un mouvement, tout en envoyant une notification instantanée au propriétaire via Telegram. Il intègre un délai d'attente de 30 secondes pour limiter la fréquence des alarmes répétées ; ce mécanisme ne vérifie pas la validité des détections du capteur PIR et n'élimine pas les faux déclenchements. Idéal pour la sécurité domestique, la surveillance de garage, d'entrepôts ou de bureaux. Avec l'ES

0.0(0)
9