Whole Home Wireless Water Leak Detector and Emergency Water Shut Off System
by marciot in Workshop > Home Improvement
4098 Views, 22 Favorites, 0 Comments
Whole Home Wireless Water Leak Detector and Emergency Water Shut Off System
I live in a second story condominium and I've always had a concern about a major water leak in my unit causing damage to my own home as well as my downstairs neighbor.
For years, I have placed a 9V water alarm in my water heater's pan, but such an alarm only does any good if I am home at the time.
In this Instructable, I will describe a wireless whole-home wireless water leak detector and shut off system.
The problem can roughly be divided into two parts:
- Electronically shutting of the water to your home
- Detecting the leaks and controlling the valve
For the first part, there major determining factor is whether you want to have a plumber install a motorized valve in your plumbing or whether you want a retrofit that requires no modifications to the home's existing plumbing.
The second part, the determining factor is whether you want a single unit which detects the leaks and shuts off the water at one location, or whether you want a whole home system that consists of a central control unit as well as one or more wireless sensor modules you can put throughout the house.
We will look at some of these options in turn. I will also share some of my failures and a few turn-key commercial solutions you may consider.
Supplies
Option 1: User-Installable DIY Retro-fit Motorized Winch
- 12V 6 RPM Worm Gear Motor
- 12V DC Power Supply
- Fishing Line
- PVC Pipe
- 3D Printed Parts
Option 2 (Recommended): Plumber-Installed Motorized Ball-Valve:
- Taco Two-Way, Normally Open, 24VAC Motorized Zone Valve
- 24V AC Power Supply
Required: Water Leak Detector and Valve Shut-off Unit
- Adafruit HUZZAH32
- Adafruit Latching Mini Relay FeatherWing
- USB 5V Charger and USB cable (to power the ESP32)
Optional: Remote Water Leak Sensor Modules
- Adafruit HUZZAH32
-
Lithium Ion Polymer Battery Ideal for Feathers
First Option: Motorized Water Shut-Off Winch
Your home's plumbing likely already has a manual main water shutoff valve. One way to accomplish our goals is to use a motor to mechanically actuate the valve.
In an earlier Instructable, I had added a PVC extension lever to my water valve. This lever was meant to make it easier for me to reach the valve, but later I realized that the additional leverage would allow me to use a simple motorized winch and some fishing line to pull the valve closed. I made an end-cap for the lever with a small hole for a cotter pin. I mounted everything such that when the valve was completely closed, the cotter pin would be pulled out by the tension on the line, allowing the motor to free-spin.
I searched for a "12V worm gear motor" on eBay and was able to purchase an inexpensive high-torque motor. I designed a pulley for the motor in OpenSCAD and a custom bracket that would allow me to clamp it to some pipes that ran parallel to the valve I wanted to shut off.
I then ran some fishing line from the pulley to the cotter pin. By connecting the motor to 12V, the pully will wind up the fishing line and pull the valve closed.
I chose to mount my winch to some parallel pipes, but it could be mounted any place that is appropriate for your situation.
Once installed, this valve can easily be controlled by a microcontroller such as the ESP32 with a relay board and a small plug-in 12V DC transformer.
Resources:
A Failed Experiment: 3D Printed Clamp on Actuator
The goal for this step was to design a 3D printed part that can mount the motor directly to the to the pipe and close the tap manually. This would make it a relatively easy retrofit for existing plumbing and was meant to be a more elegant solution than my winch.
The challenge here is making the part strong enough to push the handle. I've build several prototypes and have made corrections to make the plastic parts as strong as they can be. While I resolved various failure modes, at last the hole for the D-shaped motor axle in the "pusher" part striped out and failed to transmit enough torque to turn the handle.
Even printing this part at 100% infill did not help. It would seem as the weak link is the part that connects the motor axle to the tap; that part would have to be machined out of metal to deliver sufficient turning force.
Even though 3D printing a clamp-on motorized actuator seemed workable in theory, it does not work unless you have the ability to machine parts. At this point, it seems my original winch idea, no matter how clumsy, had the advantage of offering sufficient leverage to accomplish the task.
In the next step we will look at what I consider to be the "ideal" solution.
Additional resources:
Suggested Option: Plumber-Installed Motorized Ball Valve
This month, I got a quote to replace an aging water heater and HVAC system and took the opportunity to ask my contractor to install an electro-mechanical ball-valve into my plumbing for me. This is by far the best solution for this project and is what I would recommend.
I chose Taco valves which can found on Grainger by searching for "Taco Motorized Zone Valve." My contractor told me they used that brand in-house and that it was a good choice. Later this month, they will install a 12M810 into my plumbing right after the water main.
Here are the specifications you want to look for:
- Two way: Meaning it is a straight-through, rather than T valve.
- Normally open: You want the valve to remain open when not energized.
- 4.9Cv, 8.9Cv and 10.3Cv: I originally naively assumed this meant "control voltage," but later found out this referred to flow rate. My contractor went with the 10.3 Cv.
- 24VAC: This refers to the power supply voltage, which is also the control voltage.
- Closed system: This is the type my contractor suggested I use for my municipal water system; there are also Taco valves for "geothermal systems," but I do not know the difference.
- Sweat vs NPT: This refers to the connection type.
- 1/2 vs. 3/4: This refers to the pipe diameter.
How the Taco Valve Works:
At first, I was very confused as to how the valve could open and close without having a digital control signal, but this YouTube video clarified things for me. In short, this is what I learned:
- The normally open valve closes when 24V AC is applied to it.
- It also has an internal capacitor that charges up and allows the valve to re-open when the 24VAC power is removed.
- It has two additional terminals for an internal end-stop switch. This can be used to detect when the valve is fully closed, but will not be used in our build.
- BONUS TRIVIA: "Taco" is not pronounced like the crunchy Mexican delicacy, but rather like Waco, Texas.
Once installed, this valve can easily be controlled by a microcontroller such as the ESP32 with a relay board and a small plug-in 24V AC transformer.
DIY Control Electronics Using the ESP32
There are several ways to build the electronics, but I found that the ESP32 had two key advantages:
- It has wireless capabilities, allowing for several water sensors throughout the house communicating with a central ESP32 that controls the shut off valve.
- It has pins with capacitive touch, which can be used to sense water with no additional electronics.
A good choice for this build is the Adafruit ESP32 Feather boards. These boards can be mated with a relay module and also have the ability to use battery power, which is a capability I plan to use for the remote sensors:
Detecting Water Using the ESP32
Detecting water with the ESP32 is very simple. Only two wires are needed, one going to GND and another going to one of the TOUCH pins. I chose to use GPIO #4/TOUCH0.
For my initial testing, I uploaded the following sketch to the board using the Arduino IDE:
void setup() {<br> Serial.begin(115200); delay(1000); // give me time to bring up serial monitor Serial.println("ESP32 Water Detection Test"); } void loop() { Serial.println(touchRead(4)); // get value of Touch 0 pin = GPIO 4 delay(1000); }
If you are new to using this board and are not familiar with the Arduino IDE, I will refer you to the Adafruit Feather guide.
This sketch takes measurements every second and prints them to the serial console. I will use this to test the ability of the ESP32 to detect water.
After I uploaded my sketch, I opened up the serial console and observed the output as I dipped the wires in the water. I observed that when the two wires were out of water, I was getting values around 70, while when submerged, the values dropped to zero. This should make it very easy to write some code to detect a leak and respond to it.
Controlling the Water Shutoff Valve
The second half of this project is to control the valve. Regardless of whether you are using the DIY motorized winch, or the plumber-installed Taco valve, the trick is to use a relay board, such as the Adafruit Latching Mini Relay FeatherWing. We can use either the latching version or the non-latching version, but I chose the latching version to conserve power.
I will refer to the Adafruit guide for the physical soldering; you want to stack the board on your Feather and wire up the "SET" pin to one of the GPIO (General Purpose I/O) pins and the "UNSET" to another. For the purposes of this example, let's use GPIO #16 and GPIO #17 for this.
Here is the code:
#define SENSOR_PIN 4 // Touch 0 pin = GPIO 4 #define SET_PIN 16 // Relay SET Pin = GPIO 16 #define UNSET_PIN 17 // Relay UNSET Pin = GPIO 17 #define LOW_SENSE_THRESHOLD 10 // Threshold for detecting water #define HIGH_SENSE_THRESHOLD 50 // Threshold for detecting no water bool isOpen; void closeRelay() { Serial.println("Closing relay"); digitalWrite(SET_PIN, HIGH); delay(20); digitalWrite(SET_PIN, LOW); isOpen = false; } void openRelay() { Serial.println("Opening relay"); digitalWrite(UNSET_PIN, HIGH); delay(20); digitalWrite(UNSET_PIN, LOW); isOpen = true; } void setup() { Serial.begin(115200); delay(1000); // give me time to bring up serial monitor Serial.println("ESP32 Water Shut-Off Controller"); pinMode(SET_PIN, OUTPUT); pinMode(UNSET_PIN, OUTPUT); openRelay(); } void loop() { const int value = touchRead(SENSOR_PIN); if(value < LOW_SENSE_THRESHOLD && isOpen == true) { closeRelay(); } if(value > HIGH_SENSE_THRESHOLD && isOpen == false) { openRelay(); } delay(1000); // Wait one second }
There are a couple things going on here. There are two functions called "openRelay()" and "closeRelay()" which set or unset the relay. Because we are using the latching relay, we simply need to pulse the output for 10 milliseconds. I chose to do it for a total 20 milliseconds to give us a wide margin.
There is also a variable called "isOpen" which keeps track of whether the relay is open or closed. We keep track of this so we won't repeatedly pulse the control lines, which would waste power.
Each second, we read the sensor and then compare it against two threshold values, LOW_SENSE_THRESHOLD and HIGH_SENSE_THRESHOLD. This tells us whether to close or open the relay. After the "&&" which is a logical AND, there is a second check against the "isOpen" variable. We only open the relay if the variable indicates it is closed and only close it if the variable indicates that it is open.
Resources:
Adding Remote Wireless Capabilities
The sketch we created in the previous step allows us to place a single ESP32 near our water shut-off valve and run a pair of wires to someplace nearby where we want to monitor for leaks, such as the pan under our water heater.
This itself is a pretty good outcome, but to make things a bit more interesting we will add wireless capabilities to our project so that you can place multiple sensors throughout the house, such as underneath cabinets or near a toilet, to automatically shut off the main water valve if there is a leak there as well.
To accomplish this, we will modify our existing sketch so it connects to our WiFi network and sets up a small web server on our network to allow the valve to be triggered by another sensor else where in the house.
#define WIFI_SSID "enter-your-ssid-here" #define WIFI_PSK "enter-your-password-here" #define SENSOR_PIN 4 // Touch 0 pin = GPIO 4 #define SET_PIN 16 // Relay SET Pin = GPIO 16 #define UNSET_PIN 17 // Relay UNSET Pin = GPIO 17 #define LOW_SENSE_THRESHOLD 10 // Threshold for detecting water #define HIGH_SENSE_THRESHOLD 50 // Threshold for detecting no water #include <WiFi.h> #include <HTTPSServer.hpp> #include <SSLCert.hpp> #include <HTTPRequest.hpp> #include <HTTPResponse.hpp> using namespace httpsserver; HTTPServer server = HTTPServer(); void handleRoot(HTTPRequest * req, HTTPResponse * res); void handleCloseRelay(HTTPRequest * req, HTTPResponse * res); void handleOpenRelay(HTTPRequest * req, HTTPResponse * res); void handle404(HTTPRequest * req, HTTPResponse * res); bool isOpen; void closeRelay() { Serial.println("Closing relay"); digitalWrite(SET_PIN, HIGH); delay(20); digitalWrite(SET_PIN, LOW); isOpen = false; } void openRelay() { Serial.println("Opening relay"); digitalWrite(UNSET_PIN, HIGH); delay(20); digitalWrite(UNSET_PIN, LOW); isOpen = true; } void setup() { Serial.begin(115200); delay(1000); // give me time to bring up serial monitor Serial.println("ESP32 Water Shut-Off Controller"); pinMode(SET_PIN, OUTPUT); pinMode(UNSET_PIN, OUTPUT); openRelay(); // Connect to Wi-Fi network with SSID and password Serial.println("Setting up WiFi"); WiFi.begin(WIFI_SSID, WIFI_PSK); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.print("Connected. IP="); Serial.println(WiFi.localIP()); ResourceNode * nodeRoot = new ResourceNode("/", "GET", &handleRoot); ResourceNode * nodeOpen = new ResourceNode("/open", "GET", &handleOpenRelay); ResourceNode * nodeClose = new ResourceNode("/close", "GET", &handleCloseRelay); ResourceNode * node404 = new ResourceNode("", "GET", &handle404); server.registerNode(nodeRoot); server.registerNode(nodeOpen); server.registerNode(nodeClose); server.setDefaultNode(node404); Serial.println("Starting server..."); server.start(); if (server.isRunning()) { Serial.println("Server ready."); } } void loop() { const int value = touchRead(SENSOR_PIN); if(value < LOW_SENSE_THRESHOLD && isOpen == true) { closeRelay(); } if(value > HIGH_SENSE_THRESHOLD && isOpen == false) { openRelay(); } server.loop(); } void handleOpenRelay(HTTPRequest * req, HTTPResponse * res) { openRelay(); handleRoot(req, res); } void handleCloseRelay(HTTPRequest * req, HTTPResponse * res) { closeRelay(); handleRoot(req, res); } void handleRoot(HTTPRequest * req, HTTPResponse * res) { res->setHeader("Content-Type", "text/html"); res->println("<!DOCTYPE html>"); res->println("<html>"); res->println("<head><title>ESP32 Water Shut-Off Controller</title></head>"); res->println("<body>"); if(isOpen) { res->println("<h1>The relay is open</h1>"); } else { res->println("<h1>The relay is closed</h1>"); } res->print("<p>Your server is running for "); res->print((int)(millis()/1000), DEC); res->println(" seconds.</p>"); res->println("</body>"); res->println("</html>"); } void handle404(HTTPRequest * req, HTTPResponse * res) { req->discardRequestBody(); res->setStatusCode(404); res->setStatusText("Not Found"); res->setHeader("Content-Type", "text/html"); res->println("<!DOCTYPE html>"); res->println("<html>"); res->println("<head><title>Not Found</title></head>"); res->println("<body><h1>404 Not Found</h1><p>The requested resource was not found on this server.</p></body>"); res->println("</html>"); }
There is a couple things you need to do to get this sketch ready. The first is you want to install the ESP32 HTTPS Server to your Arduino IDE. I chose to use this library because it has the capability of serving HTTPS, although for now I am using a simple HTTP connection. You then want to modify the first two lines with the network SSID and password.
Resources:
Testing the Remote Valve Control
Now, once you have uploaded the sketch to the ESP32, open the serial console, reset your board and note down the IP address that is printed at startup. For this example, we will assume it is 192.168.1.92.
Now, using a web browser on your PC, connect to "http://192.168.1.92". You should get a web page indicating that the relay is open.
Now, change the URL to "http://192.168.1.92/close" and you should get a web page saying the valve is closed. If you have the motorized winch or Taco valve wired into the ESP32, the motor will run or the valve will close.
Now, change the URL to "http://192.168.1.92/open" and you should get a web page saying the valve is open. If you have the motorized winch or Taco valve wired into the ESP32, the motor will stop running or the valve will re-open.
Congratulations! We have the first half of our wireless whole-house water leak detector and shut-off system complete! In the next step, we will make the remote sensors. These will consist of an ESP32 and a LiPo battery. As before, it will sense water using two wires, but instead of having a relay, it will simply use the web server we just created to trigger the remote valve!
Making the Remote Sensors
For the remote sensor boards, we want to use the same basic water sensing code, but instead of triggering a local relay, we simply make an HTTP request to the web server running on the hub device:
This is how we do it:
#define WIFI_SSID "enter-your-ssid-here"<br>#define WIFI_PSK "enter-your-password-here" #define CONTROLLER_IP "192.168.1.92" #define SENSOR_PIN 4 // Touch 0 pin = GPIO 4 #define SET_PIN 16 // Relay SET Pin = GPIO 16 #define UNSET_PIN 17 // Relay UNSET Pin = GPIO 17 #define LOW_SENSE_THRESHOLD 10 // Threshold for detecting water #define HIGH_SENSE_THRESHOLD 50 // Threshold for detecting no water #include <WiFi.h> #include <HTTPClient.h> bool isOpen; void sendRequest(char* url) { HTTPClient http; http.begin(url); int httpCode = http.GET(); if (httpCode > 0) { Serial.print("GET"); Serial.print(url); Serial.print(" Status: "); Serial.println(httpCode); } else { Serial.println("Error on HTTP request"); } http.end(); isOpen = false; } void closeRelay() { sendRequest("http://" CONTROLLER_IP "/close"); isOpen = true; } void openRelay() { sendRequest("http://" CONTROLLER_IP "/open"); isOpen = true; } void setup() { Serial.begin(115200); delay(1000); // give me time to bring up serial monitor Serial.println("ESP32 Water Shut-Off Controller"); pinMode(SET_PIN, OUTPUT); pinMode(UNSET_PIN, OUTPUT); openRelay(); // Connect to Wi-Fi network with SSID and password Serial.println("Setting up WiFi"); WiFi.begin(WIFI_SSID, WIFI_PSK); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.print("Connected. IP="); Serial.println(WiFi.localIP()); } void loop() { const int value = touchRead(SENSOR_PIN); if(value < LOW_SENSE_THRESHOLD && isOpen == true) { closeRelay(); } if(value > HIGH_SENSE_THRESHOLD && isOpen == false) { openRelay(); } }
You will need to modify the first three lines with the network SSID and password for your wireless network and the IP address of the central device.
To test things out, dip water sensor wires in water and see if it closes the relay on the central module!
References:
Appendix: Exploring Some Commercial Solutions
During the research phase for this project, I came across a few commercial solutions to this problem. For completeness, I am including these here so you can get an idea of what is out there.
The Taco LeakBreaker System
For those who want a turn-key system, I also found out Taco sold the exact same valve as part of their Taco LeakBreaker system.
This system is meant for installation at the water heater. I wanted to have a wireless system with multiple sensor throughout the house and it does not appear that this system supports that. However, the fact that it used the exact same valve I had selected made me confident in my choice.
It also appears that this complete system, depending on where you get it, may be less expensive than the standalone Taco valve itself. So perhaps you could get this even if you intended to make an ESP32 based controller. I did not try this, so I cannot say for certain that it is the exact same valve, but it might be worth investigating.
The Snap by LeakSmart
A few hours after making a post on Facebook about my motorized water shut-off valve, I started to see ads for water leak shut-off systems. The Snap by LeakSmart caught my eye, because like my motorized winch it can be attached to a home's existing plumbing without modifications.
The design here is interesting in that it can drive the shut-off valve directly. Although this system is very complete and capable, it also is somewhat expensive.
Nonetheless, I like how they turn the valve and how this system can clamp on to the existing plumbing. Earlier on this Instructable I show my failed attempt to replicate this with 3D printed parts. It's pretty clear that this device has to be pretty robust to deliver the necessary torque.