-
Notifications
You must be signed in to change notification settings - Fork 1
/
setup.h
311 lines (268 loc) · 13.9 KB
/
setup.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
#ifndef setup_ino
#define setup_ino Jan 1, 2021
#include "utilities.h"
#define PORTAL_TIMEOUT 5 // Portal Timeout in minutes (how long to wait as configuration access point)
void setupConnection(void){
WiFi.mode(WIFI_STA);
int Portal_timeOut = (PORTAL_TIMEOUT * 60); // (minutes * seconds);
#if AUTOCONNECT // AutoConnect obtain credentials from web page
if(WiFi.status() != WL_CONNECTED) {
WiFiManager wm;
wm.setConfigPortalTimeout(Portal_timeOut); // autoConnect function will return, no matter the outcome in xxx seconds
if(wm.getWiFiIsSaved()){
// Serial.println(F("============== WiFi Saved =================="));
wm.autoConnect(MYHOSTNAME"_AP");
} else {
// Serial.println(F("=============== WiFi *NOT* Saved ==================="));
WiFi.begin(ssid, password);
}
}
#else
WiFi.begin(ssid, password);
#endif
int connect_attempts = 120; // around 60 seconds
while (WiFi.status() != WL_CONNECTED && connect_attempts >= 0) {
Serial.print('.');
connect_attempts--;
delay(500); yield();
}
Serial.println("");
if(WiFi.status() != WL_CONNECTED) m_reset(); // Give up, force reboot
// Free Heap = 31600 HeapFragmentation = 6 MaxFreeBlockSize = 29792 OK
// Free Heap = 30224 HeapFragmentation = 26 MaxFreeBlockSize = 22040 !OK
showFree(true);
if(ESP.getHeapFragmentation() > 12){
Serial.println(F("Heap too fragmented reboot forced")); // Configure AP Access point fragments memory;
m_reset(); // free some memory
}
Serial.println("");
Serial.print(F("Connected to "));
Serial.println(WiFi.SSID());
Serial.print(F("IP address: "));
Serial.println(WiFi.localIP());
}
void setupmDNS(void){
if (MDNS.begin(hostname)) {
Serial.print(F("MDNS responder started http://"));
Serial.print(hostname); Serial.println(F(".local"));
}
}
void setupBuiltInLED(void){
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
digitalWrite(LED_BUILTIN, HIGH); // Off
}
void setupSerial(void){
delay(100);
Serial.begin(74880); //115200);
Serial.print(F(copyright)); Serial.print(F(" ")); Serial.println(F(compiledate));
}
void setupServer(void){
server.onNotFound(handleNotFound);
server.on(F("/") , rootPage);
server.on(F("/test") , testPage);
server.on(F("/stationsL"), stationPage8x8); // large screen
server.on(F("/stationsW"), stationPage4x16); // small screen ipad or phone rotated 90 deg
server.on(F("/stationsN"), stationPage2x32); // small screen phone
server.on(F("/reboot") , rebootPage);
server.on(F("/sliderpage"), slider_page);
server.on(F("/wxID"), iDLED); // For html get function that calls flash LEDs
server.begin();
Serial.println(F("HTTP server started"));
}
//void setupClient(){
//
//}
/*
setupAirportString()
to prevent memory fragmentation create the airport string only once
thoughts:
- Break up the new airport string (without NULL stations) to download a few smaller segments that should use less memory.
- Either use a structure for the substrings or an index array to store the last index of the last station in the airport array
this should limit the time used for String search which I think is causing corrupted data.
globals needed
- Total number of substrings (integer for cycle) might be possible to use a flag or null pointer in the substrings array
- Number of substrings array for the substring pointers into the airports string (without NULLS)
- Number of substrings array with index into the airport array for each sub string remember airport array contains NULLs
*/
/*
* setupBigBlock()
* Idea here is to block out a large chunk of memory to use instead of dynamic Strings that may cause memory
* fragmentation resulting traps when the SSL connection does not having enough continuous free space to build
* it's buffers
*
* The airport substrings and the WX data structures also use in this space the WX Raw Text field will use up
* the remaining block up to the end of the block after which point to the static Out Of Memory message
*
*/
// Has to be at least 5 chars * the number of Stations
// in good weather add 72 chars for each WX text field (good weather)
// 100 active stations needs = 500 + 7200 total of 7,200 Bytes
// WX download connect needs 30000 continuous bytes
// #define bigBlockSize (1024 * 7) // 7 K
// #define bigBlockSize (512 * 15) // 7.5 k Some out of memory 4 today
// #define bigBlockSize (256 * 31) // 7.75 k
// #define bigBlockSize (128 * 63) // 7.875 k
#define bigBlockSize (1024 * 8) // 8K works in good weather with 100 active stations OK with 64 active
// #define bigBlockSize (512 * 17) // 8.5K somewhat OK frequent download fragmentation & errors occasional reboots
// #define bigBlockSize (256 * 35) // 8.75K Max with 104 stations
// #define bigBlockSize (128 * 71) // 8.875K Max with 96 stations
// #define bigBlockSize (1024 * 10)
static char bigBlock[((sizeof(char) * bigBlockSize) +2)]; // add additional byte for terminator if the last block of data just happens to == bigBlockSize
static int firstAvailable = 0; // Tracks the next unused location in the bigBlockSize array
void setupBigBlock(){
// bigBlock = new char[((sizeof(char) * bigBlockSize) +1)]; // better to allocate memory outside of function that way the block is defined first
for(int i = 0; i < bigBlockSize; i++){
bigBlock[i] = '\0';
}
firstAvailable = 0;
}
//String airportString = "";
char* airportString = NULL; // working c-string airports array without the NULL's
// Thoughts as this string does not change unless airports are modified requiring program re-upload
// so after being created might use a check for first run after upload only then create and store this string and pointers into ee-ROM
// delete this now temporary working string and work only from ee-ROM memory this saves #airports * 5 of valuable ram space (500 bytes for 100 stations)
// + a few bytes for the pointers
/*
*
* setupAirportString()
*
*
* const static int numOfAirportsGet = 25; // NUM_AIRPORTS; // Number of airports to download per loop MOVED to .h
* int actualNumAirports = NUM_AIRPORTS; // Total without NULL locations
* int airportStringsSize = 0; // total number of char's needed
* int noOfAirportStrings = 1; // if dividing up for download how many substrings needed / used
* char** airportStrings; // pointers to substrings
* int* airportIndex; // Last location in airports[] for each airport substring limit station's
*
*/
void setupAirportString() {
if (airportString != NULL) {
// Serial.println(F("airportString Already setup skipping recreation to prevent memory fragmentation"));
return;
}
// First find the number of stations and compute amount of memory needed to be allocated
actualNumAirports = 0; // Actual number of active WX stations without the NULL's
for (int i = 0; i < NUM_AIRPORTS; i++) {
if (strncmp_P("NULL", airports[i], 4) != 0)
actualNumAirports++;
mtrsf[i].mtrlighting = false; // reset lightning
mtrsf[i].mtrstat = NOTUSED;
mtrsf[i].mtrspeed = 0; // wind in knots
mtrsf[i].mtrgusts = 0; // reset wind gusts
// mtrsf[i].mtrtime[0] = '\0'; // Observation Time Note: Replaced with rawText
mtrsf[i].rawText = ooMem; // Default pointer to static "Out Of Memory"
}
// These are created once for life never deleted
airportStringsSize = ((sizeof(char) * (actualNumAirports) ) * 5); // integer use to create, sanity checks and prevent overflows length includes ',' or the null ie "KJXN,"
airportString = &bigBlock[firstAvailable++]; // This is the string of WX stations to be sent to WX_Weather.com for the get (downloads)
firstAvailable += airportStringsSize;
airportString[0] = '\0'; //
// Using pointers create several null terminated sub-strings from airportString
noOfAirportStrings = (int) ( ( (double) actualNumAirports / (double) numOfAirportsGet) + 0.9); // number of sub strings needed round up for the last possibly partial line
airportStrings = new char*[sizeof(char*) * noOfAirportStrings]; // For the pointers into the airportString replace the last ',' with a null creating shorter c_strings
airportIndex = new int[noOfAirportStrings+1]; // index into the main airports string to limit number of string compares when processing data downloaded using the sub
airportIndex[0] = 0; // stings. Make +1 because we are starting with 0 and the last location = the end
int sindex[actualNumAirports]; // temp to track and convert string index to substring index
int sidxi = 0; // iterator for sindex
Serial.println(F("Creating a new airportString"));
for (int i = 0; i < NUM_AIRPORTS; i++) {
if (strncmp_P("NULL", airports[i], 4) != 0 ) {
strcat_P(airportString, airports[i]);
strcat(airportString, ","); // Separate stations
sindex[sidxi++] = i; // sequential index to LEDS without NULL stations
mtrsf[i].mtrstat = UNKWN;
} else { // Added to report null stations V.W>
mtrsf[i].mtrstat = NOTUSED; // Default meteorology status 99 is for NULL locations a tag to skip progressing in stations html page
}
}
Serial.print(F("AirportString = \n{")); Serial.print(airportString); Serial.println("}");
// Finished creating working c-string.
// now break into several null terminated sub c-strings
// link the index between the end of substring and airports limiting string compares to this subset when finding LED ID from the downloaded data
airportStrings[0] = airportString; // noOfAirportStrings = 0 Always need the first c-string / substring
// remove the last ','
if( airportString[strlen(airportString) -1] == ','){
airportString[strlen(airportString) -1] = '\0'; // terminate end even if partial
} // else Serial.println("Something is verry wrong airportString not ',' terminated");
for (int i = 1; i < noOfAirportStrings; i++) { // the end of first is the start of next sub-string
airportStrings[i] = airportString + ((numOfAirportsGet * 5) * i); // remember first string / substring started at 0
if (airportString[(numOfAirportsGet * 5 * i) - 1] == ',') { // Should be the last char in substring
airportString[(numOfAirportsGet * 5 * i) - 1] = '\0'; // replace with the null terminate making it a substring
airportIndex[i] = sindex[i * numOfAirportsGet];
Serial.print(F("Last in substring = ")); Serial.println((airportStrings[i]-5));
} // else { OhNo somthing is very wrong }
} // Last one may be shorter then the rest
airportIndex[noOfAirportStrings] = sindex[actualNumAirports-1];
Serial.print(F(" Last index number = ")); Serial.println(airportIndex[noOfAirportStrings]);
/*
* NUM_AIRPORTS 15
* airports[][5]
* 0 "KBEH", // 1
* 1 "KLWA", // 2
* 2 "NULL", // 3
* 3 "KAZO", // 4
* 4 "KBTL", // 5
* 5 "KRMY", // 6
* 6 "NULL", // 7
* 7 "KHAI", // 8
* 8 "KIRS", // 9
* 9 "KOEB", // 10
* 0 "KJYM", // 11
* 11 "NULL", // 12
* 12 "KADG", // 13
* 13 "KUSE", // 14
* 14 "KTOL", // 15
*
*
* airportString "KBEH,KLWA,KAZO,KBTL,KRMY,KHAI,KIRS,KOEB,KJYM,KADG,KUSE,KTOL"
* * * *
* ->0 ->26 ->51
*
* actualNumAirports = 12
*
* airportStringsSize = 60
*
* numOfAirportsGet = 5
*
* noOfAirportStrings = 3
*
* airportStrings[]
* 0 ->0
* 1 ->26
* 2 ->51
*
* sindex[]
* 0 0 // KBEH
* 1 1 // KLWA
* 2 3 // KAZO
* 3 4 // KBTL
* 4 5 // KRMY
* 5 7 // KHAI
* 6 8 // KIRS
* 7 9 // KOEB
* 8 10 // KJYM
* 9 12 // KADG
* 10 13 // KUSE
* 11 14 // KTOL
*
*
* airportIndex[]
* 0 5
* 1 12
* 2 14
*
*/
Serial.print(F("Creating a new airportString ")); Serial.print(strlen( airportString));
Serial.print(F(" size ")); Serial.print(airportStringsSize);
Serial.print(F(" noOf ")); Serial.print(noOfAirportStrings);
Serial.print(F(" sizeof ")); Serial.println(sizeof(airportStrings));
for (int i = 0; i < noOfAirportStrings; i++) {
Serial.print(i);
Serial.print(F(">>"));
Serial.print(airportStrings[i]);
Serial.print(F("<< "));
Serial.println(airportIndex[i+1]); // started with 0 with one additional location
}
return;
}
#endif