Système Intelligent de Détection de Fuite d'Eau et de Contrôle de Vanne
Composants et Fournitures
| Composant | Quantité |
|---|---|
| Boîtier en aluminium | 1 |
| Arduino UNO | 1 |
| Shield Ethernet Arduino 2 | 1 |
| Alimentation électrique | 1 |
| Boîtier AC | 1 |
| Kit de LEDs avec résistances | 1 |
| Relais (1 double 5V et 1 double 12V) | 1 |
| Vanne motorisée | 1 |
| Connecteurs JST | 1 |
| Capteur d'eau | 1 |
À propos du projet
Vue d'ensemble
Lors d'une discussion avec un ami, j'ai réalisé que les fuites d'eau constituent un problème majeur. Mon ami a dû remplacer tous les meubles de son sous-sol simplement parce qu'un tuyau avait cassé pendant son absence au travail.
Ce projet est similaire à celui que j'ai publié pour le concours Microsoft IoT, mais celui-ci est basé sur Arduino, et non sur Raspberry Pi. Mon approche consiste à déléguer des responsabilités simples à des dispositifs simples (comme Arduino) plutôt que de centraliser de nombreuses tâches sur une plateforme puissante (Raspberry Pi, DragonBoard ou PC). Ces dispositifs effectuent leur tâche de base et, en option, se connectent au réseau pour offrir des services avancés. En cas de panne réseau, ils continuent de fonctionner localement.
Le système surveille les fuites d'eau et déclenche des actions comme la fermeture de l'arrivée d'eau principale selon le défaut détecté. Il publie également des messages sur un broker MQTT, s'intégrant ainsi dans un système domotique plus large.
Installation physique

L'arrivée d'eau principale se trouve en bas. Le premier dispositif est installé par les services de distribution d'eau pour contrôler la pression. J'ai installé la partie supérieure sur la photo. La vanne motorisée (en bleu) est montée en parallèle avec une vanne manuelle. Sur ce schéma, la vanne manuelle est ouverte et la vanne motorisée est donc court-circuitée, ce qui est utile en cas de coupure de courant. En mode normal, la vanne manuelle doit être fermée.
La vanne contient un moteur DC 12V qui tourne dans un sens ou l'autre selon la polarité. Une boucle de retour indique si la vanne est ouverte ou fermée. Pour l'ouvrir, il suffit d'appliquer une tension positive sur la connexion en haut à gauche.
Le contrôleur

De gauche à droite : prise secteur, bouton de réinitialisation, LEDs d'état, connecteurs (capteurs, moteur), interfaces Ethernet et USB.
- LED1 (Rouge) : Fixe = fuite locale détectée, Clignotante = fuite distante détectée, Éteinte = aucune fuite
- LED2 (Jaune) : Fixe = impossible de contrôler la vanne, Clignotante = broker MQTT inaccessible, Éteinte = tout va bien
- LED3 (Bleue) : Fixe = tout fonctionne, Clignotante = vanne fermée, Éteinte = système hors tension

Capteur placé aux endroits à risque de fuite.

⚠️ AVERTISSEMENT IMPORTANT
L'alimentation AC/DC utilisée possède deux sorties : 12V DC pour la vanne motorisée (contrôlée par deux relais) et exactement 5V DC pour l'Arduino. C'est pourquoi j'alimente directement le circuit 5V, pas le Vin qui nécessite au moins 6V. Une fois l'alimentation AC/DC connectée, ne branchez JAMAIS ni la prise jack Arduino ni le câble USB. Pour déboguer via USB, fabriquez un câble sans les lignes d'alimentation, conservez seulement les lignes de données. La liaison entre le boîtier AC et l'alimentation est en 110V : ne touchez jamais !
Code
Détection de fuite et contrôle vanne motorisée (Arduino)
#include <PubSubClient.h>
#include <Network.h>
#include <Timer.h>
#include <SPI.h>
#include <Ethernet.h>
#include <Dns.h>
#include <avr/wdt.h>
/* Fonctionnement matériel :
- Boîtier principal : Arduino Uno + Shield Ethernet
- LED rouge : fixe (fuite locale), clignotante (fuite distante), éteinte (OK)
- LED jaune : fixe (vanne HS), clignotante (MQTT inaccessible), éteinte (OK)
- LED bleue : fixe (vanne ouverte + surveillance), clignotante (vanne fermée), éteinte (système down)
- Bouton poussoir : déclenche un auto-test
- Double relais pour contrôler la vanne motorisée distante
- Double relais pour lire les fins de course de la vanne
- Détecteurs d'eau (tous en parallèle sur 3 connecteurs façade)
Vanne motorisée :
- Jaune/Bleu : alimentation moteur DC
- Noir : entrée fins de course (mis à GND dans notre circuit)
- Rouge : passe à GND en position fermée
- Vert : passe à GND en position ouverte
(Note : pas de garantie de continuité après mise hors tension)
*/
// Configuration réseau
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xCF, 0xFC, 0xEE };
IPAddress ip(192, 168, 12, 215);
IPAddress server(192, 168, 12, 130);
EthernetClient ethClient;
PubSubClient client(ethClient);
#define mqttClientPrefix "GLX"
#define mqttClientLocation "BASEMENT"
#define mqttClientUID "001"
#define mqttClientStatusTopic "Status"
#define mqttClientFaultTopic "Fault"
const int mqttInterval = 20;
int mqttIntervalCnt = 0;
int isConnectedToBroker = -1;
// Broches
const int SystemLedPin = A0;
const int FaultLedPin = A1;
const int AlarmLedPin = A2;
const int WaterDetectorPin = 2;
const int ToggleButtonPin = 3;
const int SdCardPin = 4;
const int ValveClosedPin = 5;
const int ValveOpenedPin = 6;
const int ValveControl1 = 8;
const int ValveControl2 = 7;
// États
int isWaterDetected = 0;
int isWaterDetectedRemotely = 0;
int isValveClosed = -1;
const int valveTimeOut = 15;
int isConnectedToValve = -1;
volatile boolean isResetRequested = 0;
const int mainLoopDelay = 500;
void(* resetFunc) (void) = 0;
void setup() {
wdt_disable();
Serial.begin(9600);
Serial.println(F("Début setup"));
pinMode(SystemLedPin, OUTPUT);
pinMode(FaultLedPin, OUTPUT);
pinMode(AlarmLedPin, OUTPUT);
pinMode(WaterDetectorPin, INPUT);
pinMode(ToggleButtonPin, INPUT);
pinMode(ValveOpenedPin, INPUT);
pinMode(ValveClosedPin, INPUT);
pinMode(ValveControl1, OUTPUT); digitalWrite(ValveControl1, HIGH);
pinMode(ValveControl2, OUTPUT); digitalWrite(ValveControl2, HIGH);
pinMode(SdCardPin, OUTPUT); digitalWrite(SdCardPin, HIGH);
testLeds();
client.setServer(server, 1883);
client.setCallback(MQTTBrokerCallback);
Ethernet.begin(mac, ip);
Serial.print(F("IP actuelle : ")); Serial.print(Ethernet.localIP());
Serial.print(F(" - IP broker MQTT : ")); Serial.println(server);
if (openValve() == 0) {
Serial.println(F("Vanne ouverte, surveillance active"));
subscribeToRemoteWaterSensors();
} else {
Serial.println(F("Impossible d'ouvrir la vanne. Utilisez le bypass plomberie"));
}
enableInterruptOnResetButton();
delay(1500);
Serial.println(F("Fin setup"));
}
void loop() {
configureLedsWithInitialStates();
if (isResetRequested == 1) {
Serial.println(F("Réinitialisation demandée via bouton"));
publishStatus();
wdt_enable(WDTO_1S);
delay(5000);
Serial.println(F("Ce message ne devrait jamais apparaître"));
}
readLocalWaterSensor();
if (isWaterDetected == 1 || isWaterDetectedRemotely == 1) {
if (isValveClosed == 0) closeValve();
}
if (mqttIntervalCnt == 0) {
if (isWaterDetected == 1) publishFault();
publishStatus();
mqttIntervalCnt = mqttInterval;
} else {
if (isConnectedToValve == 0) {
Serial.println(F("Système HS - impossible de contrôler la vanne"));
} else {
Serial.print(F("."));
}
mqttIntervalCnt--;
}
delay(mainLoopDelay / 2);
client.loop();
configureLedsWithFinalStates();
delay(mainLoopDelay / 2);
}
// ... (fonctions de gestion capteur, bouton, vanne, LEDs, MQTT - voir code complet)
Bibliothèque MQTT
Disponible en téléchargement uniquement.
Schémas

Processus de fabrication
- Vannes à pincement et pompes péristaltiques : la référence pour les systèmes de boues de chaux abrasives
- Maîtriser le contrôle des capteurs et actionneurs sur Raspberry Pi : Accéléromètre, Servo et Streaming de données
- Système automatisé de remplissage et de surveillance de piscine
- Débogage du système bi-cœur Arduino Portenta H7 avec Segger J-Link
- Construire une télécommande Android universelle avec Arduino, 1Sheeld et contrôle IR
- Créer des animations et jeux sur LCD avec Arduino UNO
- Construire une Tirelire Intelligente : Contrôler un Accepteur de Pièces avec Arduino Nano
- Centre de contrôle d'alimentation Arduino : N-FET, P-FET, Relais et RTC
- Détecteur de fréquence audio Arduino — Mesurer le pic sonore avec module haute sensibilité