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.

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éristique | Valeur |
|---|---|
| Tension de fonctionnement | 3,3–5 V continu |
| Courant de fonctionnement | Moins de 20 mA (maximal quand il est entièrement mouillé) |
| Sortie | Tension analogique (broche S), augmente avec le niveau d'eau |
| Zone de détection | Environ 40 × 16 mm, soit au maximum environ 4 cm de hauteur d'eau |
| Taille de la carte | Environ 62 × 20 mm |
| Température de fonctionnement | 10–30 °C (donnée du fabricant) |
| Broches | S (signal), + (VCC), − (GND) |
Branchement du capteur de niveau d'eau : Arduino Uno, ESP32 et Pico
| Broche du capteur | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| S (signal) | A0 | GPIO 34 (ADC1) | GP26 (ADC0) |
| + (VCC) | D7 (l'alimente seulement pendant la mesure) | GPIO 25 | GP15 |
| − (GND) | GND | GND | GND |
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
- Relie la broche S du capteur à A0, la broche + à D7 et la broche − à GND. Tiens la carte verticale, pistes vers le bas.
- Ouvre le code ci-dessous dans l'Arduino IDE, choisis Arduino Uno comme carte et le bon port, puis téléverse-le.
- 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.
- 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.
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é.
| Niveau | Profondeur immergée | Valeur typique sur Uno (5 V, eau du robinet) |
|---|---|---|
| Vide | 0 mm (sec) | 0–20 |
| Bas | Environ 5–10 mm | 250–400 |
| Moitié | Environ 20 mm | 400–480 |
| Plein | Environ 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.
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}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().
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.

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.
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}Capteur de niveau d'eau, interrupteur à flotteur et XKC-Y25 : comparatif
| Caractéristique | Capteur de niveau d'eau (pistes conductrices) | Interrupteur à flotteur | XKC-Y25 (sans contact) |
|---|---|---|---|
| Principe de détection | Conductivité de l'eau | Aimant flottant et contact reed | Variation de capacité derrière la paroi du récipient |
| Sortie | Analogique (quelques niveaux) | Contact ouvert ou fermé | Numérique (liquide présent ou non) |
| Plage de mesure | Environ 0–4 cm | Un point (hauteur de montage) | Un point (hauteur de montage) |
| Contact avec l'eau | Oui, pistes dans l'eau | Oui, corps dans l'eau | Non, se colle à l'extérieur du récipient |
| Corrosion | Oui ; alimentation par broche indispensable | Quasi nulle | Aucune |
| Alimentation | 3,3–5 V | Inutile (contact passif) | 5–24 V, environ 5 mA |
| Idéal pour | Expériences, alarme de débordement, petits récipients | Réservoirs fixes, protection de pompe | Réservoirs fermés en plastique ou en verre, liquides corrosifs |
| Prix | Le moins cher | Bon 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.

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.

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.
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.
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ôme | Cause probable | Solution |
|---|---|---|
| La valeur reste à 0, même dans l'eau | La broche + n'est pas alimentée (POWER_PIN ne passe jamais à HIGH) ou S est sur la mauvaise broche | Vérifie les lignes pinMode et digitalWrite et que S est bien sur une broche analogique |
| La valeur saute au hasard même à sec | La broche S est en l'air ou la masse n'est pas reliée | Vé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 suiveur | Fixe les seuils d'après la valeur la plus haute que tu as mesurée |
| Aucune valeur dans l'eau pure | L'eau distillée ou purifiée conduit très peu | Pour 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 pistes | Alimente 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 seuil | Un seul seuil est utilisé ; la surface agitée fait varier la valeur | Utilise 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'ADC2 | Déplace S sur une broche de l'ADC1, entre GPIO 32 et 39 |
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.
Projets à réaliser après cet article
Voir tous les projets
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

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

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.

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

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

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

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
Autres articles
Application BlueGrays
Réalise ce montage pas à pas sur ton téléphone
Schéma, code et liste des composants sur un seul écran. Plus de 200 projets Arduino, ESP32 et Pico à réaliser.
Scanne avec ton téléphone
Pointe l’appareil photo vers le code : la boutique d’applications de ton téléphone s’ouvre.
ou ouvre la boutique

