-
Notifications
You must be signed in to change notification settings - Fork 1
/
ESP8266WaterDetector.ino
278 lines (231 loc) · 7.02 KB
/
ESP8266WaterDetector.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/*
WaterDetectorWiFi
ESP8266 NodeMCU Based IoT Water Detector with Temperature Probe
Poll water sensors and one-wire tempature sensor and send results to web or mqtt server
Author: Jason A. Cox - @jasonacox - https://github.com/jasonacox/WaterDetectorWiFi
Date: 17 Feb 2020
*/
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <OneWire.h>
#include <DallasTemperature.h> /* For one-wire temp probe */
// TO DO - Add MQTT
#ifndef WIFISSID
#define WIFISSID "Your Network SSID"
#define WIFIPASS "Your Password"
#endif
#define SENSORID 100 // Serial Number - Unqiue for IoT Device
/* Pins */
#define LED 14 // LED on GPIO14 = D5
#define WATER_1 13 // Water Sensor NPN Transitor on GPIO13 = D7
#define WATER_2 12 // Water Sensor NPN Transitor on GPIO12 = D6
#define ONEWIRE 4 // OneWire Buss on GPIO4 = D2
/* States */
#define DRY 0
#define WET 1
#define FLOOD 2
#define NIL -1
/* Debug Mode? Verbose Output */
#define DEBUG 1
/* Wifi Settings */
const char* ssid = WIFISSID;
const char* password = WIFIPASS;
/* Server location to send alerts and status */
const char* host = "10.10.10.10"; // HTTP Server
const uint16_t port = 80;
#define URIPREFIX "/sensor.php" // URI to send updates
const char* mqtt = "10.10.10.10"; // MQTT Server
const uint16_t mqttport = 1883;
/* globals */
int state;
int count;
ESP8266WiFiMulti WiFiMulti;
OneWire oneWire(ONEWIRE); // DS18B20 One-Wire Temp Probe
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature.
DeviceAddress Thermometer; // variable to hold device addresses
int deviceCount = 0;
// uint8_t sensor1[8] = { 0x28, 0xFF, 0xAB, 0x06, 0x81, 0x14, 0x02, 0xA0 };
/*
* SETUP - Runs on Startup ONLY
*/
void setup() {
Serial.begin(115200);
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(WATER_1, INPUT_PULLUP);
pinMode(WATER_2, INPUT_PULLUP);
digitalWrite(LED_BUILTIN, LOW); // turn the LED on (HIGH is the voltage level)
digitalWrite(LED, HIGH);
// We start by connecting to a WiFi network
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(ssid, password);
Serial.println();
Serial.println();
Serial.print("Wait for WiFi... ");
while (WiFiMulti.run() != WL_CONNECTED) {
digitalWrite(LED, LOW);
delay(10);
digitalWrite(LED, HIGH);
delay(10);
digitalWrite(LED, LOW);
delay(10);
digitalWrite(LED, HIGH);
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);
digitalWrite(LED_BUILTIN, HIGH); // turn the LED off by making the voltage LOW
digitalWrite(LED, LOW);
delay(500);
state = NIL;
count = 0;
/* fire up one-wire temp probe and get list of devices available */
// Start up the library for DS18B20 One-Wire Temp Probe
sensors.begin();
// locate devices on the bus
Serial.println("Locating devices...");
Serial.print("Found ");
deviceCount = sensors.getDeviceCount();
Serial.print(deviceCount, DEC);
Serial.println(" devices.");
Serial.println("");
Serial.println("Printing addresses...");
for (int i = 0; i < deviceCount; i++)
{
Serial.print("Sensor ");
Serial.print(i+1);
Serial.print(" : ");
sensors.getAddress(Thermometer, i);
printAddress(Thermometer);
}
}
/*
* MAIN LOOP
*/
void loop() {
int sensor1 = 0;
int sensor2 = 0;
/* Force heartbeat every 300 cycles ~= 5m */
count++;
if(count > 300) {
count = 0;
state = NIL;
}
// Heartbeat - flash onboard LED
digitalWrite(LED_BUILTIN, LOW);
delay(10);
digitalWrite(LED_BUILTIN, HIGH);
// Capture current temp
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
if(DEBUG) {
Serial.print(" : Temp = ");
Serial.print(temperatureC);
Serial.print("ºC / ");
float temperatureF = sensors.getTempFByIndex(0);
Serial.print(temperatureF);
Serial.println("ºF");
}
// Poll water sensors
sensor1 = digitalRead(WATER_1); // waterlevel alert 1
sensor2 = digitalRead(WATER_2); // waterlevel alert 2
if(DEBUG) {
Serial.print("STATE: ");
Serial.print(state, DEC);
Serial.print(" - Water Sensors: Location 1 = ");
Serial.print(sensor1, DEC);
Serial.print(" - Location 2 = ");
Serial.println(sensor2, DEC);
}
// Detected water at sensor1 = low water warning
if(sensor1 == 0 and state < WET) {
digitalWrite(LED, HIGH);
Serial.println("** Water Detected - Low Water Warning **");
state = WET;
// Push update to server
sendStatus(1, SENSORID, temperatureC);
}
// Detected water at sensor2 = highwater warning
if(sensor2 == 0 and state != FLOOD) {
digitalWrite(LED, HIGH);
Serial.println("** Flood Detected - High Water Warning **");
state = FLOOD;
// Push update to server
sendStatus(2, SENSORID, temperatureC);
}
// Sensor2 clears but sensor1 still alerting = downgrade to low water warning
if(sensor1 == 0 and sensor2 == 1 and state == FLOOD) {
digitalWrite(LED, HIGH);
Serial.println("** Downgrade to Low Water Warning **");
state = WET;
// Push update to server
sendStatus(1, SENSORID, temperatureC);
}
// Sensor1 and Sensor2 clear
if(sensor1 == 1 and sensor2 == 1 and state != DRY) {
digitalWrite(LED, LOW);
Serial.println("** Sensor Dry - All Clear **");
state = DRY;
// Push update to server
sendStatus(0, SENSORID, temperatureC);
}
// Wait about a second
delay(990);
}
/*
* Prints OneWire Bus Device Address
*/
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
Serial.print("0x");
if (deviceAddress[i] < 0x10) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
if (i < 7) Serial.print(", ");
}
Serial.println("");
}
/*
* Send Status to Web Server - water level and temperature
* waterlevel: 1=wet, 0=dry
* temp: floating point degrees celcius
*/
void sendStatus(int waterlevel, int id, float temp)
{
// Use WiFiClient class to create TCP connections
WiFiClient client;
// Send via HTTP GET
if (!client.connect(host, port)) {
Serial.println("connection failed");
Serial.println("wait 5 sec...");
delay(5000);
return;
}
client.print("GET ");
client.print(URIPREFIX);
client.print("?waterlevel=");
client.print(waterlevel);
client.print("&id=");
client.print(id);
client.print("&temp=");
client.print(temp);
client.println(" HTTP/1.0");
client.println();
//read back one line from server
Serial.println("receiving from remote server");
String line = client.readStringUntil('\r');
Serial.println(line);
Serial.println("closing connection");
client.stop();
// Send via MQTT
// TBD
}