-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEsp8266Starter.ino
253 lines (213 loc) · 8.54 KB
/
Esp8266Starter.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
//
// Esp8266 Starter System - A Self-contained starter system for development of ESP8266 based projects
//
// This system includes the following base capabilities
// - WiFi support, including using WiFiManager to save credentials
// - A simple LittleFS based preferences system with web edit/save of configuration file (for non-wifi settings)
// - A fully functioning system control website with
// 1) a system status view
// 2) a view/edit settings capability
// 3) an event history (logging) capability
// 4) some basic system controls (reset, clear WiFi settings, send email msg, etc)
// - Code to send email using smt2go.com smtp services as well as integration of email settings into prferences system
// - A simple event history system that records event messages strings along with a timestamp of when event happened
// - Misc date and time utilities to help with displaying current date and time and elapsedmillis timestamps
//
// Dependencies - ESP8266WiFi, DNSServer, ESP8266WebServer, WiFiManager,
// NTPClient, WiFiClient, LittleFS, time.h, TZ.h
// ElapsedMillis
// All of these are probably available through the Arduino IDE Library Manager, but some may need to be installed by
// .zip files downloaded from github. I seem to have downloaded .zips for wifimanager, ntpclient, and elapsedmillis
// but I think they're all available through library manager now.
//
// This project was developed on a NodeMCU 1.0 ESP-12E module using the Arduino IDE 1.8.15
// with this additional board manager: http://arduino.esp8266.com/stable/package_esp8266com_index.json
//
#include <elapsedMillis.h>
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#include <time.h>
#include <sys/time.h>
#include <TZ.h>
#define MYTZ TZ_America_New_York
#define BUILTIN_LED_ON LOW // Note: Write 0 to turn ON built-in LED on NodeMCU
#define BUILTIN_LED_OFF HIGH
// Define some timing values (all in milliseconds)
#define WEB_SESSION_TIMEOUT (unsigned long) 300*1000 // New session if > 5 mins since activity (also blink if active)
#define EMAIL_ERROR_BLINK_TIME (unsigned long) 60*1000 // blink for 1 min after email error
#define ACTIVITY_LED_ON_TIME 50 // ms
#define ACTIVITY_LED_OFF_TIME 100 // ms
#define SLOW_BLINK_ON_TIME 1000 // times in ms
#define SLOW_BLINK_RATE 2000 //
#define FAST_BLINK_ON_TIME 150 //
#define FAST_BLINK_RATE 300 //
#define MILLIS_IN_A_DAY 86400000
#define MILLIS_IN_A_WEEK 604800000
elapsedMillis timeSinceSystemStarted = 0;
elapsedMillis timeSinceSoftReset = 0;
elapsedMillis timeSinceWebSessionStarted = MILLIS_IN_A_DAY;
elapsedMillis timeSinceLastWebActivity = MILLIS_IN_A_DAY;
elapsedMillis timeSinceLastEmailAttempt = MILLIS_IN_A_DAY;
elapsedMillis timeSinceLastEmailSendError = MILLIS_IN_A_DAY;
elapsedMillis timeSinceLastEmailSentOk = MILLIS_IN_A_DAY;
elapsedMillis timeSinceStatusBlinkStarted = MILLIS_IN_A_DAY;
// Additions here my need to be re initialized in clearStats()
unsigned long int softResetCount=0;
unsigned long int email1SentCount=0;
unsigned long int email2SentCount=0;
unsigned long int emailSupressedCount=0;
unsigned long int emailErrorCount=0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
delay(300);
digitalWrite(LED_BUILTIN, BUILTIN_LED_OFF);
initializeEventHistoryStorage();
initializePreferencesManager();
// Use WiFiManager to handle persistence of ssid and password.
// If ssid and password is saved, wifi manager will autoconnecct
// On first time or if password changed, wifi mgr starts in AP mode
// which allows connection from any device to configure ssid and password.
// Access point server IP defaults to 192.168.4.1
WiFiManager wifiManager;
wifiManager.setDebugOutput(false);
wifiManager.autoConnect(); // auto generated name ESP + ChipID
// if you get here you have connected to the WiFi
String ipString = WiFi.localIP().toString();
Serial.println("WiFi Connected, IP Address is " + ipString);
setupWebserver();
Serial.println("HTTP server started");
// Set time zone for localtime() calls
configTime(MYTZ, "pool.ntp.org");
Serial.println("Initialization Complete");
}
void loop() {
updateStatusLED();
handleWebseverProcessing();
if ((timeSinceLastWebActivity < WEB_SESSION_TIMEOUT) && (timeSinceWebSessionStarted > MILLIS_IN_A_DAY))
timeSinceWebSessionStarted = 0;
else if (timeSinceLastWebActivity > WEB_SESSION_TIMEOUT)
timeSinceWebSessionStarted = MILLIS_IN_A_DAY;
// Prevent timers from wrapping
if (timeSinceWebSessionStarted > MILLIS_IN_A_WEEK)
timeSinceWebSessionStarted = MILLIS_IN_A_DAY;
if (timeSinceLastWebActivity > MILLIS_IN_A_WEEK)
timeSinceLastWebActivity = MILLIS_IN_A_DAY;
if (timeSinceLastEmailAttempt > MILLIS_IN_A_WEEK)
timeSinceLastEmailAttempt = MILLIS_IN_A_DAY;
if (timeSinceLastEmailSendError > MILLIS_IN_A_WEEK)
timeSinceLastEmailSendError = MILLIS_IN_A_DAY;
if (timeSinceLastEmailSentOk > MILLIS_IN_A_WEEK)
timeSinceLastEmailSentOk = MILLIS_IN_A_DAY;
if (timeSinceStatusBlinkStarted > MILLIS_IN_A_WEEK)
timeSinceStatusBlinkStarted = MILLIS_IN_A_DAY;
}
void updateStatusLED() {
uint8_t LED_State = BUILTIN_LED_ON;
if (timeSinceLastEmailSendError < EMAIL_ERROR_BLINK_TIME) {
// Blink LED fast for a while after email send error
if (timeSinceStatusBlinkStarted > FAST_BLINK_ON_TIME) {
LED_State = BUILTIN_LED_OFF;
if (timeSinceStatusBlinkStarted > FAST_BLINK_RATE)
timeSinceStatusBlinkStarted = 0;
}
} else if (timeSinceLastWebActivity < WEB_SESSION_TIMEOUT) {
// Blink LED slowly if a web session is active
if (timeSinceStatusBlinkStarted > SLOW_BLINK_ON_TIME) {
LED_State = BUILTIN_LED_OFF;
if (timeSinceStatusBlinkStarted > SLOW_BLINK_RATE)
timeSinceStatusBlinkStarted = 0;
}
} else {
// No recent emails sent keep LED off
LED_State = BUILTIN_LED_OFF;
}
digitalWrite(LED_BUILTIN, LED_State);
}
void sendMailMessageType1() {
timeSinceLastEmailAttempt = 0;
if (getPreferencesBoolean("sendMailEnabled") == false) {
emailSupressedCount++;
addEventHistoryEntry("Email not sent. SendMail is disabled in settings");
return;
}
byte ok = sendEmail(1);
if (!ok) {
emailErrorCount++;
timeSinceLastEmailSendError=0;
} else {
flashBuiltinLED(ACTIVITY_LED_ON_TIME, ACTIVITY_LED_OFF_TIME);
email1SentCount++;
timeSinceLastEmailSentOk=0;
addEventHistoryEntry("Email 1 message was sent successfully");
}
}
void sendMailMessageType2() {
timeSinceLastEmailAttempt = 0;
if (getPreferencesBoolean("sendMailEnabled") == false) {
emailSupressedCount++;
addEventHistoryEntry("Email not sent. SendMail is disabled in settings");
return;
}
byte ok = sendEmail(2);
if (!ok) {
emailErrorCount++;
timeSinceLastEmailSendError=0;
} else {
flashBuiltinLED(ACTIVITY_LED_ON_TIME, ACTIVITY_LED_OFF_TIME);
email2SentCount++;
timeSinceLastEmailSentOk=0;
addEventHistoryEntry("Email 2 message was sent successfully");
}
}
void doSoftReset() {
timeSinceWebSessionStarted = MILLIS_IN_A_DAY;
timeSinceLastWebActivity = MILLIS_IN_A_DAY;
timeSinceLastEmailAttempt = MILLIS_IN_A_DAY;
timeSinceLastEmailSendError = MILLIS_IN_A_DAY;
timeSinceLastEmailSentOk = MILLIS_IN_A_DAY;
email1SentCount=0;
email2SentCount=0;
emailSupressedCount=0;
emailErrorCount=0;
initializeEventHistoryStorage();
softResetCount++;
timeSinceSoftReset = 0;
addEventHistoryEntry("Soft restart completed");
}
void flashBuiltinLED(int onTimeDelay, int offTimeDelay) {
digitalWrite(LED_BUILTIN, BUILTIN_LED_ON);
delay(onTimeDelay);
digitalWrite(LED_BUILTIN, BUILTIN_LED_OFF);
delay(offTimeDelay);
}
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
#endif // __arm__
unsigned long freeMemory() {
#if defined(ARDUINO_ARCH_AVR)
char top;
return &top - (__brkval ? __brkval : __malloc_heap_start);
#elif defined(ARDUINO_ARCH_SAMD)
char top;
return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(TEENSYDUINO)
char top;
return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(ESP8266)
return system_get_free_heap_size();
#elif defined(ESP32)
return ESP.getFreeHeap();
#elif defined(EPOXY_DUINO)
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
#else
#error Unsupported platform
#endif
}