Or any MQTT based system
This article accompanies the "DIY Water Leakage Sensor" YouTube series.
It contains the code, libraries, diagrams, 3D print files and more information that I promised in the videos:
You can always go ahead and buy a ready-to-use a solution like this CONNECTIFY Smart Water Leakage Sensor but these devices usually would only work with their respective apps, and some of them would require you to pay extra in order to receive push notifications. Now, this article and its video provide a step-by-step guide and links to everything you need to build the same device for 3x cheaper than the cheapest option available.
In addition to detecting water leakage and sending notifications. This device:
In my case, I will be sending the notifications to my Home Assistant setup in order to trigger a pre-defined automation that:
The beauty of this is I can decide to trigger any type of notifications in the future such as playing an alarm sound or sending SMS notifications...
So without further ado, let's start with a list of all hardware components, Apps and Libraries I've used in this project:
This Water Level Sensor Module has a series of ten exposed copper traces, five of which are power traces and five are sense traces. These traces are interlaced so that there is one sense trace between every two power traces. Usually these traces are not connected but are bridged by water when submerged
The working of the water level sensor is pretty straightforward: The series of exposed parallel conductors, together acts as a variable resistor (just like a potentiometer) whose resistance varies according to the water level. The change in resistance corresponds to the distance from the top of the sensor to the surface of the water.
The resistance is inversely proportional to the height of the water:
The sensor produces an output voltage according to the resistance, which by measuring we can determine the water level.
I've decided to use the WEMOS R1 D2 microchip for this project because it has a small size that saves space and can easily fit in a printable 3D case, but also because of a few reasons:
The wiring is pretty straightforward. Please follow the diagram bellow. Also, here are some notes that might help you figure it out:
Wiring source files are included under wiring folder
No one likes wires hanging around, and so I included the source and STL files for the 3D case I prepared for this project. All of it is under 3d folder folder and you can do whatever the heck you want with it.
The code within main.cpp
file is well documented, but I'll try to explain the concepts and ideas behind the code in this section. But first of all, copy the file secrets_copy.h
to secrets.h
and edit its content with your details: WiFi credentials, Home Assistant details...
The sketch begins with the creation of a few objects we'll need along the way: Ticker
that calls repeating actions and which we will use to put the board to sleep and then wake up. WiFiClient
that we use to connect to Wifi and PubSubClient
that we use to send data through MQTT
Ticker ticker;
WiFiClient espClient;
PubSubClient client(espClient);
Then we declare a few variables like the Arduino pins for the sensor reading and power, as long as the sleep duration and number of tries we aim to do while connecting to WiFi because we want to avoid draining the battery trying to connect to WiFi indefinitely.
#define sensorPower D7 // Power pin
#define sensorPin A0 // Analog Sensor pins
#define durationSleep 30 // seconds
#define NB_TRYWIFI 20 // WiFi connection retries
As you might have noticed, there is no loop()
function in this sketch, only a setup()
function, and that's because instead of executing some commands in a loop fashion like most Arduino projects, this board is programmed to go to sleep until its wake up moment arrives, in which case, it will executing everything until setup()
function before going back to sleep again. Here is how it's programmed:
void setup()
{
// only print debug messages to serial if we're in debug mode
if (DEBUG == true) {
Serial.print("Waking up ");
}
// Step 1: Set D7 pin as an output pin ready to receive power
pinMode(sensorPower, OUTPUT); // Set D7 as an OUTPUT
digitalWrite(sensorPower, LOW);
...
// Step 2: Wake the sensor up & get a reading
int waterLevel = readSensor();
...
// Step 3: If water is detected then
if (waterLevel > 1) {
connectToWiFi(); // 1- connect to WiFi
connectToHass(); // 2- connect to Home Assistant MQTT broker
publishAlarmToHass(waterLevel); // 3- publish the water level on the MQTT topic
}
// Step 4: Go back to sleep for the next 30 sec
ESP.deepSleep(durationSleep * 1000000);
}
The function that reads the water level is straightforward and well documented as well:
int readSensor()
{
// Step 1 : Turn the sensor ON by providing power to D7 pin
digitalWrite(sensorPower, HIGH);
// Step 2 : Wait for a just little bit
delay(10);
// Step 3 : Perform the reading
sensorData = analogRead(sensorPin);
// Step 4 : Turn the sensor OFF
digitalWrite(sensorPower, LOW);
return sensorData;
}
All contribution to this project is appreciated