├── README.md ├── waterLevel.html └── waterLevel.ino /README.md: -------------------------------------------------------------------------------- 1 | # esp8266-waterLevel 2 | water level control system using ESP8266 and HC-SR04 3 | complete demonstration and setup details in this YouTube video: watch->like->subscribe-> https://youtu.be/KK4ebz8kvqs 4 | 5 | Instructions: 6 | 7 | Step 1: 8 | 9 | you need a cylindrical tank and measure its capacity in liters, may use this tool for that 10 | http://aqua.ucdavis.edu/Calculations/Volume_of_a_Cylindrical_Tank.htm 11 | if don't have cylidrical tank, then need to modify code accordingly. 12 | 13 | relay connected to water pump, nodemcu pin D4 14 | 15 | hc sr04 TRIG connected to D1 and Echo connected to D2 through a voltage divider, (1k,2k) 16 | 17 | Step 2: 18 | 19 | modify these two lines as per capacity in FusionCharts.ready() function 20 | "lowerLimit": "0", 21 | "upperLimit": "15", 22 | 23 | modify slider paramters as per capacity and default settings 24 | max: 16, 25 | min: 0, 26 | range: true, 27 | values: [3, 12], 28 | 29 | you can locate these settings inside $("#flat-slider-vertical-1").slider( 30 | 31 | html file is already included in Arduino sketch, you can modify these paramters inside arduino sketch. 32 | 33 | Step3: 34 | 35 | create new adafruit IO feed and name it as 'waterLevel' 36 | 37 | uncomment these two lines in sketch and write your wifi ssid/password 38 | 39 | /*const char* ssid = "ssid"; 40 | 41 | const char* password = "password";*/ 42 | 43 | also uncomment and write here your own adafruit IO username and key. 44 | 45 | //#define AIO_USERNAME "programmer5"//replace it with your username 46 | 47 | //#define AIO_KEY "6e5fd35c936743808ceae4e101f6cbd1"//replace it with your key 48 | 49 | uncomment these lines as well, write radius of tank and total height in units of inches, 50 | 51 | //#define RADIUS 5.5 52 | 53 | //#define MAX_HEIGHT 10 54 | 55 | modify this line if you have to connect relay to some pin other than D4 56 | 57 | #define MOTOR_CONTROL_PIN D4 58 | 59 | Connect trig of ultrasonic sensor at D1 and echo at D2, modify this line otherwise 60 | 61 | UltraSonicDistanceSensor distanceSensor(D1,D2); //D1 trig, D2=echo 62 | 63 | these are default water level limits, these values will be applied on reset until user sends new limits from webpage. 64 | 65 | int waterLevelLowerThreshold=3; 66 | 67 | int waterLevelUpperThreshold=12; 68 | 69 | Need to install this HCSR04 library: https://github.com/Martinsos/arduino-lib-hc-sr04 70 | -------------------------------------------------------------------------------- /waterLevel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | My first chart using FusionCharts Suite XT 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 50 | 65 | 66 | 110 | 111 | 112 |
113 | 114 |
115 | 116 |
117 |
118 |
119 | 120 |
121 |
FusionCharts XT will load here!
122 |
Motor OFF
128 |
129 | 130 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /waterLevel.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "Adafruit_MQTT.h" 5 | #include "Adafruit_MQTT_Client.h" 6 | 7 | const char index_html[] PROGMEM={"\n" 8 | "\n" 9 | "\n" 10 | "My first chart using FusionCharts Suite XT\n" 11 | "\n" 12 | "\n" 13 | "\n" 14 | "\n" 15 | "\n" 16 | "\n" 17 | "\n" 18 | "\n" 19 | "\n" 56 | "\n" 71 | "\t\n" 72 | "\n" 116 | "\n" 117 | "\n" 118 | "
\n" 119 | "\n" 120 | "
\n" 121 | " \n" 122 | "
\n" 123 | "
\n" 124 | "
\n" 125 | " \n" 126 | "
\n" 127 | "
FusionCharts XT will load here!
\n" 128 | "\t
Motor OFF
\n" 134 | "
\n" 135 | "\n" 136 | "\n" 165 | "\n" 166 | "\t\n" 167 | "" 168 | }; 169 | //create new adafruit IO feed and name it as 'waterLevel' 170 | //uncomment these two lines and write your wifi ssid/password 171 | /*const char* ssid = "ssid"; 172 | const char* password = "password";*/ 173 | //also uncomment and write here your own adafruit IO username and key. 174 | //#define AIO_USERNAME "programmer5"//replace it with your username 175 | //#define AIO_KEY "6e5fd35c936743808ceae4e101f6cbd5"//replace it with your key 176 | //uncomment these lines as well, write radius of tank and total height in units of inches, 177 | //#define RADIUS 5.5 178 | //#define MAX_HEIGHT 10 179 | //modify this line if you have to connect relay to some pin other than D4 180 | #define MOTOR_CONTROL_PIN D4 181 | //Connect trig of ultrasonic sensor at D1 and echo at D2, modify this line otherwise 182 | UltraSonicDistanceSensor distanceSensor(D1,D2); //D1 trig, D2=echo 183 | //these are default water level limits, these values will be applied until on reset until user sends new limits from webpage. 184 | int waterLevelLowerThreshold=3; 185 | int waterLevelUpperThreshold=12; 186 | 187 | 188 | #define AIO_SERVER "io.adafruit.com" 189 | #define AIO_SERVERPORT 1883 // use 8883 for SSL 190 | float volume; 191 | float liters; 192 | // Create an ESP8266 WiFiClient class to connect to the MQTT server. 193 | WiFiClient client; 194 | // or... use WiFiFlientSecure for SSL 195 | //WiFiClientSecure client; 196 | 197 | // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. 198 | Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY); 199 | Adafruit_MQTT_Publish waterLevel = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/waterLevel"); 200 | 201 | /*************************** Sketch Code ************************************/ 202 | 203 | // Bug workaround for Arduino 1.6.6, it seems to need a function declaration 204 | // for some reason (only affects ESP8266, likely an arduino-builder bug). 205 | void MQTT_connect(); 206 | 207 | 208 | String inputString = ""; // a string to hold incoming data 209 | String dataToSend=""; 210 | int waterLevelDownCount=0,waterLevelUpCount=0; 211 | 212 | ESP8266WebServer server(80); 213 | void handleRoot() { 214 | server.send_P(200, "text/html;charset=UTF-8", index_html); 215 | } 216 | 217 | void handleLevelRequest(){ 218 | server.send(200,"text",String(liters)); 219 | } 220 | 221 | void handleNotFound(){ 222 | String message = "File Not Found\n\n"; 223 | server.send(404, "text/plain", message); 224 | } 225 | void handleStatus() 226 | { 227 | if(digitalRead(MOTOR_CONTROL_PIN)==0)//MOTOR ON 228 | server.send(200, "text/plain","on"); 229 | else server.send(200, "text/plain","off"); 230 | } 231 | void handleRangeSetting(){ 232 | waterLevelLowerThreshold=(server.arg(0)).toInt(); 233 | waterLevelUpperThreshold=(server.arg(1)).toInt(); 234 | Serial.print(waterLevelLowerThreshold); 235 | Serial.print(":"); 236 | Serial.println(waterLevelUpperThreshold); 237 | 238 | server.send(200, "text/plain", ""); 239 | } 240 | 241 | void measure_Volume() 242 | { 243 | float heightInch=0.393701*distanceSensor.measureDistanceCm(); 244 | Serial.println(heightInch); 245 | if(heightInch>MAX_HEIGHT) 246 | heightInch=MAX_HEIGHT; 247 | if(heightInch<0) 248 | heightInch=0; 249 | volume=3.14*RADIUS*RADIUS*(MAX_HEIGHT-heightInch);//MAX_HEIGHT-distance will give actual height, 250 | liters=volume*0.0164 ; 251 | Serial.println(liters); 252 | 253 | if(liters<=waterLevelLowerThreshold) 254 | waterLevelDownCount++; 255 | else waterLevelDownCount=0; 256 | 257 | if(liters>=waterLevelUpperThreshold) 258 | waterLevelUpCount++; 259 | else waterLevelUpCount=0; 260 | 261 | waterLevel.publish(liters); 262 | 263 | 264 | if(waterLevelDownCount==3) 265 | {//TURN ON RELAY 266 | Serial.println("motor turned on"); 267 | digitalWrite(MOTOR_CONTROL_PIN,LOW);//Relay is active LOW 268 | } 269 | if(waterLevelUpCount==3) 270 | {//TURN OFF RELAY 271 | Serial.println("motor turned off"); 272 | digitalWrite(MOTOR_CONTROL_PIN,HIGH);//Relay is active LOW 273 | } 274 | } 275 | void runPeriodicFunc() 276 | { 277 | static const unsigned long REFRESH_INTERVAL1 = 2100; // 2.1sec 278 | static unsigned long lastRefreshTime1 = 0; 279 | 280 | if(millis() - lastRefreshTime1 >= REFRESH_INTERVAL1) 281 | { 282 | measure_Volume(); 283 | lastRefreshTime1 = millis(); 284 | } 285 | } 286 | 287 | void MQTT_connect() { 288 | int8_t ret; 289 | 290 | // Stop if already connected. 291 | if (mqtt.connected()) { 292 | return; 293 | } 294 | 295 | Serial.print("Connecting to MQTT... "); 296 | 297 | while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected 298 | Serial.println(mqtt.connectErrorString(ret)); 299 | Serial.println("Retrying MQTT connection in 5 seconds..."); 300 | mqtt.disconnect(); 301 | delay(5000); // wait 5 seconds 302 | } 303 | Serial.println("MQTT Connected!"); 304 | } 305 | 306 | 307 | void setup(void){ 308 | Serial.begin(115200); 309 | delay(100); 310 | pinMode(MOTOR_CONTROL_PIN, OUTPUT); 311 | WiFi.begin(ssid, password); 312 | Serial.println(""); 313 | 314 | while (WiFi.status() != WL_CONNECTED) { 315 | delay(500); 316 | Serial.print("."); 317 | } 318 | Serial.print("IP address:"); 319 | Serial.println(WiFi.localIP()); 320 | 321 | server.on("/", handleRoot); 322 | server.on("/level",handleLevelRequest); 323 | server.on("/configRange",handleRangeSetting); 324 | server.on("/motor_status",handleStatus); 325 | 326 | server.onNotFound(handleNotFound); 327 | 328 | server.begin(); 329 | Serial.println("HTTP server started"); 330 | } 331 | 332 | void loop(void){ 333 | runPeriodicFunc(); 334 | 335 | MQTT_connect(); 336 | server.handleClient(); 337 | } 338 | --------------------------------------------------------------------------------