-
Notifications
You must be signed in to change notification settings - Fork 1
/
watering.h
345 lines (256 loc) · 7.99 KB
/
watering.h
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
#ifndef __WATERING_H__
#define __WATERING_H__
// Choose IDE, because we need different hacks depending IDE
#define IDE_ARDUINO 1
#define IDE_ECLIPSE 2
#define IDE_USED IDE_ECLIPSE
//#define IDE_USED IDE_ARDUINO
// Log and web server filesystem definitions; don't hange
#define FS_NONE 0
#define FS_SD_CARD 1
#define FS_SPIFFS 2
#define FS_TYPE FS_SPIFFS
// Comment to disable Serial debug prints
#define WATERING_DEBUG
// Comment to disable MQTT support
//#define WATERING_MQTT
// Comment to disable OTA support
#define OTA_ENABLED
// Comment to disable web browser update support
#define WEB_UPDATE_ENABLED
// If uncommented, enables low power mode: gets MCU to sleep when detects a long period of waiting time.
// Not compatible with FS_SD_CARD
#define WATERING_LOW_POWER_MODE
// For different sensors, positive or neative ones
// Out Of Water sensor
// - Negative sensor:
#define OOW_READ_EXTRA_FUN(x) not(x)
// - Positive sensor:
//#define OOW_READ_EXTRA_FUN(x) x
// If uncommented, enables DHT functionality for that specific sensor. Uncomment only one.
// Not compatible with FS_SD_CARD.
// Remember DHT11 is 5V
//#define WATERING_DHTTYPE DHT11
//#define WATERING_DHTTYPE DHT21
#define WATERING_DHTTYPE DHT22
#ifdef WATERING_DHTTYPE
// DHT data pin
#define WATERING_DHT_PIN D6
// DHT activation
#define WATERING_DHT_ACTIVATE_PIN D7
// status variables
int dht_h = 0;
int dht_t = 0;
#endif
#define SOIL_SENSOR_READ_PIN A0
#define PUMP_ACTIVATE_PIN D1
#define WATER_LEVEL_PIN D2
#if FS_TYPE == FS_SPIFFS
#define SOIL_SENSOR_ACTIVATE_PIN D5
#else
#define SOIL_SENSOR_ACTIVATE_PIN D0
#endif
/**
* Initial config, overwritten if CONFIG.TXT is found on FileSystem
*/
char wifi_mode = 'A'; // A-AP, S-Station (usual)
// Behaviour configuration. Remember, sensor value is higher when dryer is soil.
int soilSensorMinLevel = 700; // Below this level pump starts. Remember, 10-bit on ESP8266
int soilSensorMaxLevel = 550; // Avobe this level pump stops. Remember, 10-bit on ESP8266
// Timers adjustments
#ifdef WATERING_DEBUG
unsigned long int timeWarmingMilis = 15000; // ms warming sensor before read. TESTING, 15s
unsigned long int timeReadMilisStandBy = 45000; // ms between sensor reads - Stand by. TESTING, 45s
unsigned long int timeReadMilisWatering = 5000; //ms between sensor reads - watering, 5s
#else
unsigned long int timeWarmingMilis = 35000; // ms warming sensor before read. 35sec
unsigned long int timeReadMilisStandBy = 600000; //ms between sensor reads - Stand by. 600s; 10 min
unsigned long int timeReadMilisWatering = 5000; //ms between sensor reads - watering, 5s
#endif
// Needed libraries
#include <Arduino.h>
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#if FS_TYPE == FS_SD_CARD
#include <SD.h>
#elif FS_TYPE == FS_SPIFFS
#if IDE_USED == IDE_ECLIPSE
#define FS_NO_GLOBALS // Avoid File compile error on Eclipse
#include "FS.h"
extern fs::FS SPIFFS;
#else
#include "FS.h"
#endif
#endif
#ifdef WATERING_DEBUG
#include <GDBStub.h>
#endif
#ifdef OTA_ENABLED
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#endif
#ifdef WEB_UPDATE_ENABLED
#include <ESP8266HTTPUpdateServer.h>
#endif
#include <Wire.h>
#include <SPI.h>
#include <uRTCLib.h>
#ifdef WATERING_DHTTYPE
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#endif
#ifdef WATERING_MQTT
#include <PubSubClient.h>
#endif
// Globals
char *reportingApiKey = NULL;
char* ssid = NULL;
char* password = NULL;
char* mdnshostname = NULL;
// Fixed IPs to speed-up connections
IPAddress* mqttIp = NULL;
IPAddress* apiIp = NULL;
IPAddress* wifiIp = NULL;
IPAddress* wifiNet = NULL;
IPAddress* wifiGW = NULL;
IPAddress* wifiDNS1 = NULL;
IPAddress* wifiDNS2 = NULL;
/** END Initial config **/
#define SOIL_SENSOR_STATUS_OFF false
#define SOIL_SENSOR_STATUS_ON true
#define PUMP_STATUS_OFF false
#define PUMP_STATUS_ON true
#define OOW_SENSOR_STATUS_OFF false
#define OOW_SENSOR_STATUS_ON true
/********************************
* Function declarations
******************************* */
void parseConfigIpValue(IPAddress**, char *);
void parseConfigString(char **, String *);
void parseConfigLine(String);
bool doReport();
bool doReportConfig();
void report();
void returnFail(String);
void handleStatus();
void handleGetConfig();
void soilSensorProcessValue();
void soilSensorActuations();
void soilSensorChecks();
void soilSensorLoop();
void setupHW(void);
void setupSD(void);
void handleSetRTC();
void setRTC();
void loadConfig();
void handleFiles();
void handleResetSD();
void parseIPVaraible();
void setupWiFi(void);
void setupMandatoryInitialValues();
void setup(void);
void loop(void);
bool saveConfig(void);
void handleSaveConfig(void);
#ifdef WATERING_DEBUG
void debugStatus();
#endif
#ifdef WATERING_LOW_POWER_MODE
void goToDeepSleep(long int);
#endif
#ifdef OTA_ENABLED
void setupOTA(void);
#endif
void AttachWifiEvents(void);
void onStationModeConnected(const WiFiEventStationModeConnected &);
void onStationModeDisconnected(const WiFiEventStationModeDisconnected &);
//void onStationModeDHCPTimeout(void);
#ifdef WATERING_MQTT
void mqttCallback(char*, byte*, unsigned int);
#endif
/** Status global variables **/
char lastReport[1024]; // Take care, very long string
unsigned long int lastReportTime = 0;
unsigned long int lastSoilSensorActivationTime = 0;
unsigned long int lastSoilSensorReadTime = 0;
int lastSoilSensorRead = -1;
bool pumpRunning = PUMP_STATUS_OFF;
bool outOfWater = OOW_SENSOR_STATUS_ON;
bool soilSensorStatus = SOIL_SENSOR_STATUS_ON;
bool hasSD = false;
unsigned long actMilis = 0;
bool doingReport = false;
#ifdef WATERING_LOW_POWER_MODE
bool DeepSleep = false;
#endif
#ifdef WATERING_DEBUG
#define W_DEBUG(a) Serial.print(a)
#define W_DEBUGLN(a) Serial.println(a)
#define W_DEBUG2(a, b) Serial.print(a, b)
#define W_DEBUGLN2(a, b) Serial.println(a, b)
#else
#define W_DEBUG(a)
#define W_DEBUGLN(a)
#define W_DEBUG2(a, b)
#define W_DEBUGLN2(a, b)
#endif
// For different sensors, positive or neative ones
// Out Of Water sensor
// - Negative sensor:
#define OOW_READ_EXTRA_FUN(x) not(x)
// - Positive sensor:
//#define OOW_READ_EXTRA_FUN(x) x
// ChipSelect form SD reader connected to SPI
//#define WATERING_SD_CS 4
//Usually not needed to change (RTC and EEPROM):
//#define URTCLIB_ADDRESS 0x68
//#define URTCLIB_EE_ADDRESS 0x57
#if defined(WATERING_LOW_POWER_MODE) && FS_TYPE == FS_SD_CARD
#error "Low power mode cannot be active at the same time as FS_SD_CARD"
#endif
#if defined(WATERING_DHTTYPE) && FS_TYPE == FS_SD_CARD
#error "DHT functionality cannot be active at the same time as FS_SD_CARD"
#endif
#ifdef WATERING_DEBUG
#define W_DEBUG(a) Serial.print(a)
#define W_DEBUGLN(a) Serial.println(a)
#define W_DEBUG2(a, b) Serial.print(a, b)
#define W_DEBUGLN2(a, b) Serial.println(a, b)
#else
#define W_DEBUG(a)
#define W_DEBUGLN(a)
#define W_DEBUG2(a, b)
#define W_DEBUGLN2(a, b)
#endif
#define DATA_VERSION 2
#define DATA_TYPE_LOG 1
#define DATA_TYPE_CONFIG 2
// ChipSelect form SD reader connected to SPI
//#define WATERING_SD_CS 4
//Usually not needed to change (RTC and EEPROM):
//#define URTCLIB_ADDRESS 0x68
//#define URTCLIB_EE_ADDRESS 0x57
//Wifi Connection Status, to handle actul wifi reconnection problems:
#define WIFI_STATUS_DISCONNECTED 0
#define WIFI_STATUS_CONNECTED 1
char wifiConnectionStatus = WIFI_STATUS_DISCONNECTED;
// min ms of waiting time to trigger deep sleep. Default: 60000 (= 1min)
#define LOW_POWER_DIFF 60000
// ms of waiting time to shut off sensor between reads. Default: 2000 (= 2sec)
#define REGULAR_SENSOR_DIFF 2000
#ifdef ESP8266
#define EXTRA_YIELD() yield()
#else
#define EXTRA_YIELD()
#endif
#if defined(WATERING_LOW_POWER_MODE) && FS_TYPE == FS_SD_CARD
#error "Low power mode cannot be active at the same time as FS_SD_CARD"
#endif
#if defined(WATERING_DHTTYPE) && FS_TYPE == FS_SD_CARD
#error "DHT functionality cannot be active at the same time as FS_SD_CARD"
#endif
#endif