├── requirements.txt ├── LICENSE ├── WaterLevelSensorMQTT.ino └── Readme.md /requirements.txt: -------------------------------------------------------------------------------- 1 | # Requirements 2 | ESP8266 Board 3 | JSN-SR04T Waterproof ultrasonic sensor 4 | Arduino IDE 5 | Arduino Board Library: Generic ESP8266 Module 6 | Arduino Library: EspMQTTClient 7 | RaspberryPi 8 | Node-Red 9 | MQTT Mosquito Broker 10 | Grafana 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Portfedh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /WaterLevelSensorMQTT.ino: -------------------------------------------------------------------------------- 1 | // Code to measure water level in a water tank 2 | // Board: ESP8266 NodeMCU 3 | // 15 May 2021 4 | // Pablo Cruz Lemini 5 | // portfedh@gmail.com 6 | 7 | // Mills Function 8 | const unsigned long event_interval = 300000; // 5 minute interval, 300 second 9 | //const unsigned long event_interval = 2000; // 2 second interval. For testing 10 | unsigned long previous_time = 0; 11 | 12 | // MQTT Library 13 | #include "EspMQTTClient.h" 14 | 15 | #define WIFI_SSID "" // WiFi Username 16 | #define WIFI_PASS "" // Wifi Password 17 | 18 | #define BROKER_IP "" // IP adress of MQTT broker 19 | #define BROKER_USERNAME "" // Broker username 20 | #define BROKER_PASSWORD "" // Broker password 21 | #define CLIENT_NAME "" // MQTT client name to identify the device 22 | #define BROKER_PORT // MQTT Port. No "" needed 23 | #define lastwill_topic "" // MQTT topic to report lastwill and testament. 24 | #define lastwill_text "" // MQTT memssage to report lastwill and testament. 25 | 26 | String client_name = CLIENT_NAME; // MQTT Topic to report initial value 27 | String startup_topic = ""; // MQTT Topic to report startup 28 | String water_level_topic = ""; // MQTT topic to report values 29 | 30 | // Function to connect to MQTT 31 | EspMQTTClient client( 32 | WIFI_SSID, 33 | WIFI_PASS, 34 | BROKER_IP, 35 | BROKER_USERNAME, 36 | BROKER_PASSWORD, 37 | CLIENT_NAME, 38 | BROKER_PORT 39 | ); 40 | 41 | // Water Sensor pins 42 | #define TRIG 14 //GPIO Number 14, D5 43 | #define ECHO 12 //GPIO Number 12, D6 44 | 45 | void setup() { 46 | 47 | Serial.begin(115200); // Serial monitoring 48 | 49 | // Enable debugging messages sent to serial output 50 | client.enableDebuggingMessages(); 51 | 52 | // Enable the web updater. 53 | client.enableHTTPWebUpdater(); 54 | 55 | // MQTT Last Will & Testament 56 | client.enableLastWillMessage( lastwill_topic , lastwill_text); 57 | 58 | // Water level sensor Pin Setup 59 | pinMode(TRIG, OUTPUT); // Initializing Trigger Output 60 | pinMode(ECHO, INPUT_PULLUP); // Initializing Echo Input 61 | } 62 | 63 | // MQTT Innitial Connection 64 | void onConnectionEstablished() { 65 | client.publish(startup_topic, String(client_name + " is now online.")); 66 | } 67 | 68 | void loop() { 69 | 70 | // MQTT Loop: Must be called once per loop. 71 | client.loop(); 72 | 73 | // Mills Loop 74 | unsigned long current_time = millis(); 75 | 76 | // Mills if Statement 77 | if(current_time - previous_time >= event_interval) { 78 | // Set the trigger pin to low for 2uS 79 | digitalWrite(TRIG, LOW); 80 | delayMicroseconds(2); 81 | 82 | // Send a 20uS high to trigger ranging 83 | digitalWrite(TRIG, HIGH); 84 | delayMicroseconds(20); 85 | 86 | // Send pin low again 87 | digitalWrite(TRIG, LOW); 88 | 89 | // Read pulse times 90 | int distance = pulseIn(ECHO, HIGH,26000); 91 | 92 | //Convert the pulse duration to distance 93 | distance= distance/58; 94 | 95 | //Print Result in serial monitor 96 | Serial.print("Distance "); 97 | Serial.print(distance); 98 | Serial.println("cm"); 99 | 100 | // MQTT Client Publisher 101 | client.publish(water_level_topic, String(distance)); 102 | 103 | // Mills Update timing for next time 104 | previous_time = current_time; 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # MQTT Water Level Sensor 2 | 3 | ![Water Level Sensor](https://pablocruz.io/wp-content/uploads/2022/11/water_level_featured-2048x970.png) 4 | 5 | I recently made a blog post describing this project in detail. 6 | 7 | You find the post [here.](https://pablocruz.io/water-level-monitor/) 8 | 9 | The idea of this sensor is to monitor the water level of a water tank and report its values every 5 minutes. 10 | 11 | This way the water level can be checked remotely, and an alarm set to go off if the value falls below a certain range. 12 | 13 | The same sensor and code may be used to monitor the level of other liquids in a container with a height up to 4 meters. 14 | 15 | ## What it does 16 | 17 | The Arduino code uses a JSN-SR04T ultrasonic sensor, connected to an ESP8266 and an electrical outlet to read and send the data through Wi-Fi and MQTT. 18 | 19 | The microcontroller will take measurements every 5 minutes and transform the ultrasonic value time into the distance from the sensor in cm. 20 | 21 | Measurements will be sent through WIFI to an MQTT broker. Although the code for the MQTT in not provided, here is a brief description of what can be achieved: 22 | 23 | With an MQTT broker, Node-Red and Grafana, you can receive the values, store them in a database and then display them in a graphical manner. 24 | 25 | Both Grafana and Node-Red can be integrated with Telegram. This allows message alarms to be sent in case water level falls below a threshold value. 26 | 27 | The code in WaterLevelSensorMQTT.ino will output the distance to the water level in cm, and the calculation to determine the existing volume of water (in Liters) is made in Node-Red. 28 | 29 | An alternative would be calculating the water volume directly in the ESP8266 and report as its output to MQTT. 30 | 31 | I chose the former method in case the formula needed any changes. You can update Node-Red remotely, but you must be physically close to flash the ESP8266. 32 | 33 | The formula to determine the water volume will vary depending on the container shape, but the height of the shape will be calculated using: 34 | ***height = total_height - sensor_distance*** 35 | 36 | ## How to Install 37 | 38 | To use this script, you must have the following: 39 | 40 | Hardware: 41 | 42 | - ESP8266 43 | - JSN-SR04T ultrasonic sensor 44 | - An Electrical connection to power microcontroller and sensor 45 | - A watertight electrical box 46 | - Optional: Electrical PVC conduit 47 | - Optional: [3D Printed Sensor Fitting](https://www.prusaprinters.org/prints/67422-jsn-sr04t-water-level-sensor-case) 48 | 49 | Software: 50 | 51 | - ESP8266 Boards installed from the Boards Manager 52 | - Arduino Library: [EspMQTTClient.h](https://www.arduino.cc/reference/en/libraries/espmqttclient/) 53 | 54 | The sensor requires 3V input to work and so can be powered directly from the microcontroller. 55 | 56 | Connection Diagram: 57 | -- Connection Diagram --- 58 | 59 | Some Photos of the setup: 60 | 61 | ![Water Tank 1](https://bite-size.mx/WaterTank1.png) 62 | ![Water Tank 3](https://bite-size.mx/WaterTank2.png) 63 | ![Water Tank 3](https://bite-size.mx/WaterTank3.png) 64 | 65 | ## How to Use 66 | 67 | 1. Open the WaterLevelSensorMQTT.ino file: 68 | - Add your Wi-Fi username & password 69 | - Define your MQTT port (1883 is conventionally used) 70 | - Add your MQTT broker Username & Password 71 | - Define a name to identify your sensor 72 | - Define the MQTT topic the sensor will publish the data into 73 | 74 | 2. Verify and upload your code 75 | 76 | 3. Check with the serial monitor that the values are being reported 77 | 78 | 4. Check with your MQTT broker that values are being reported correctly through Wi-Fi. 79 | 80 | Output should be something similar to the following: 81 | 82 | ---(Serial Monitor GIF here)--- 83 | 84 | ----(Over MQTT Broker GIF here)-- 85 | 86 | Here is an image of how the information looks when written into influxdb and then displayed in Grafana. The graph shows a 15 day period. 87 | 88 | ![Grafana Output](http://bite-size.mx/GrafanaWaterLevelSensor.png) 89 | 90 | ## Use cases 91 | 92 | I designed this to monitor the water level in my main water tank, located in my roof. I plan on installing a second one in a water cistern. 93 | 94 | Other uses could be: 95 | 96 | - Monitor the level of liquid in any industrial container. 97 | - Monitor the water level of a municipal water reservoir. 98 | - Monitor the amount of product or Inventory in a specific rack through its heigh. 99 | - Monitor the presence of a car in a parking space 100 | 101 | ## Contributing 102 | 103 | The explanation of how to use this sensor could be broadened by: 104 | 105 | - Explaining how to configure the MQTT Broker 106 | - Explaining how to configure Node-Red 107 | - Explaining how to configure a database (I use Influx DB) 108 | - Explaining how to set up Grafana to visualize the information 109 | - Explaining how to set up alarms with Telegram 110 | 111 | It could go even further by: 112 | 113 | - Explaining how to set up the database and Grafana on AWS/Azure or a server you can access from anywhere. 114 | - How to create an API so anyone can download the information. 115 | --------------------------------------------------------------------------------