1010 - WiFiManager: https://github.com/tzapu/WiFiManager
1111 - ArduinoMqttClient (if MQTT is defined)
1212*/
13- #define VERSION " v5.1 "
13+ #define VERSION " v5.2 "
1414
1515#define HEIGHT_ABOVE_SEA_LEVEL 50 // Berlin
1616#define TZ_DATA " CET-1CEST,M3.5.0,M10.5.0/3" // Europe/Berlin time zone from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
@@ -94,10 +94,11 @@ RTC_DATA_ATTR uint16_t sensorStatus, serial0, serial1, serial2;
9494RTC_DATA_ATTR uint16_t co2 = 400 ;
9595RTC_DATA_ATTR float temperature = 0 .0f , humidity = 0 .0f ;
9696
97- RTC_DATA_ATTR uint8_t hour = 0 ;
98- RTC_DATA_ATTR uint8_t halfminute = 0 ;
99- RTC_DATA_ATTR uint16_t co2measurements[24 ][120 ]; // every 30 sec
100- RTC_DATA_ATTR tempHumData tempHumMeasurements[24 ][40 ]; // every 1.5 minutes
97+ RTC_DATA_ATTR uint16_t currentIndex = 0 ;
98+ RTC_DATA_ATTR bool overflow = false ;
99+ #define NUM_MEASUREMENTS (24 *120 )
100+ RTC_DATA_ATTR uint16_t co2measurements[NUM_MEASUREMENTS]; // every 30 sec
101+ RTC_DATA_ATTR tempHumData tempHumMeasurements[NUM_MEASUREMENTS / 3 ]; // every 1.5 minutes
101102
102103/* WIFI */
103104bool shouldSaveConfig = false ;
@@ -195,12 +196,15 @@ void HandleRootClient() {
195196 strftime (time, 20 , " %Y-%m-%dT%H:%M:%S" , &timeinfo);
196197 message += " const endTime = new Date('" + String (time) + " ').getTime();\n " ;
197198
199+ uint16_t index;
200+ if (overflow) index = NUM_MEASUREMENTS;
201+ else index = currentIndex;
198202 time_t now = mktime (&timeinfo);
199- time_t timestamp = now - hour* 60 * 60 - halfminute* 30 ;
203+ time_t timestamp = now - index * 30 ;
200204 struct tm * timeinfo2 = localtime (×tamp);
201205 strftime (time, 20 , " %Y-%m-%dT%H:%M:%S" , timeinfo2);
202206 message += " const startTime = new Date('" + String (time) + " ').getTime();\n " ;
203- message += " const numPoints = " + String (hour* 120 + halfminute ) + " ;\n " ;
207+ message += " const numPoints = " + String (index ) + " ;\n " ;
204208
205209 message += " function generateValues(start, end, numPoints) { let values = []; let step = (end - start) / (numPoints - 1); for (let i = 0; i < numPoints; i++) { values.push(start + (step * i));} return values;}\n " ;
206210 message += " let times = generateValues(startTime, endTime, numPoints).map(time => new Date(time));\n " ;
@@ -210,18 +214,13 @@ void HandleRootClient() {
210214 const size_t bufferSize = 2048 ;
211215 String Buffer, Element;
212216 Buffer.reserve (bufferSize);
213- int i, j, numEnties;
214- for (i = 0 ; i <= hour; i++) {
215- if (i != hour) numEnties = 120 ;
216- else numEnties = halfminute;
217- for (j = 0 ; j < numEnties; j++) {
218- Element = String (co2measurements[i][j]) + " ," ;
219- if (Buffer.length () + Element.length () > bufferSize) {
220- server.sendContent (Buffer);
221- Buffer = " " ;
222- }
223- Buffer += Element;
224- }
217+ for (int i = 0 ; i < index; i++) {
218+ Element = String (getCO2Measurement (i)) + " ," ;
219+ if (Buffer.length () + Element.length () > bufferSize) {
220+ server.sendContent (Buffer);
221+ Buffer = " " ;
222+ }
223+ Buffer += Element;
225224 }
226225 server.sendContent (Buffer);
227226
@@ -232,39 +231,31 @@ void HandleRootClient() {
232231 server.sendContent (message);
233232
234233 Buffer = " const y1Values = [" ;
235- for (i = 0 ; i <= hour; i++) {
236- if (i != hour) numEnties = 40 ;
237- else numEnties = ceil (halfminute / 3.0 );
238- for (j = 0 ; j < numEnties; j++) {
239- float temp = tempHumMeasurements[i][j].temperature / 10.0 ;
240- if (useFahrenheit) sprintf (tempString, " %.1f" ,(temp * 1 .8f ) + 32 .0f ); // convert to °F
241- else sprintf (tempString, " %.1f" , temp);
242- Element = String (tempString) + " ," ;
243- if (Buffer.length () + Element.length () > bufferSize) {
244- server.sendContent (Buffer);
245- Buffer = " " ;
246- }
247- Buffer += Element;
234+ index = index / 3.0 ;
235+ for (int i = 0 ; i < index; i++) {
236+ if (useFahrenheit) sprintf (tempString, " %.1f" ,(getTempMeasurement (i)/10.0 * 1 .8f ) + 32 .0f ); // convert to °F
237+ else sprintf (tempString, " %.1f" , getTempMeasurement (i)/10.0 );
238+ Element = String (tempString) + " ," ;
239+ if (Buffer.length () + Element.length () > bufferSize) {
240+ server.sendContent (Buffer);
241+ Buffer = " " ;
248242 }
243+ Buffer += Element;
249244 }
250245 server.sendContent (Buffer);
251246
252247 Buffer = " ];\n const y2Values = [" ;
253- for (i = 0 ; i <= hour; i++) {
254- if (i != hour) numEnties = 40 ;
255- else numEnties = ceil (halfminute / 3.0 );
256- for (j = 0 ; j < numEnties; j++) {
257- Element = String (tempHumMeasurements[i][j].humidity ) + " ," ;
258- if (Buffer.length () + Element.length () > bufferSize) {
259- server.sendContent (Buffer);
260- Buffer = " " ;
261- }
262- Buffer += Element;
248+ for (int i = 0 ; i < index; i++) {
249+ Element = String (getHumMeasurement (i)) + " ," ;
250+ if (Buffer.length () + Element.length () > bufferSize) {
251+ server.sendContent (Buffer);
252+ Buffer = " " ;
263253 }
254+ Buffer += Element;
264255 }
265256 server.sendContent (Buffer);
266257
267- message = " ];\n const numPoints2 = " + String (int (hour* 40 + ceil (halfminute/ 3.0 )) ) + " ;\n " ;
258+ message = " ];\n const numPoints2 = " + String (index ) + " ;\n " ;
268259 message += " let times2 = generateValues(startTime, endTime, numPoints2).map(time => new Date(time));\n " ;
269260 message += " const data2 = [{x: times2, y: y1Values, name: 'Temperature', mode:'lines'}, " ;
270261 message += " {x: times2, y: y2Values, name: 'Humidity', yaxis: 'y2', mode:'lines'}];\n " ;
@@ -634,22 +625,30 @@ void rainbowMode() {
634625}
635626
636627void saveMeasurement (uint16_t co2, float temperature, float humidity) {
637- if (halfminute == 120 ) {
638- halfminute = 0 ;
639- hour++;
640- }
641- if (hour == 24 ) {
642- for (int i = 0 ; i < 23 ; ++i) memcpy (co2measurements[i], co2measurements[i + 1 ], sizeof (uint16_t ) * 120 ); // destination, source
643- for (int i = 0 ; i < 23 ; ++i) memcpy (tempHumMeasurements[i], tempHumMeasurements[i + 1 ], sizeof (tempHumData) * 40 );
644- hour = 23 ;
628+ co2measurements[currentIndex] = co2;
629+ if (!(currentIndex % 3 )) { // every 1.5 minutes
630+ tempHumMeasurements[currentIndex / 3 ].temperature = (uint16_t )(temperature * 10 );
631+ tempHumMeasurements[currentIndex / 3 ].humidity = (uint8_t ) humidity;
645632 }
646633
647- co2measurements[hour][halfminute] = co2 ;
648- if (!(halfminute % 3 )) { // every 1.5 minutes
649- tempHumMeasurements[hour][halfminute / 3 ]. temperature = ( uint16_t )(temperature * 10 ) ;
650- tempHumMeasurements[hour][halfminute / 3 ]. humidity = ( uint8_t )humidity ;
634+ currentIndex++ ;
635+ if (currentIndex >= NUM_MEASUREMENTS) {
636+ currentIndex = 0 ;
637+ overflow = true ;
651638 }
652- halfminute++;
639+ }
640+
641+ uint16_t getCO2Measurement (uint16_t index) {
642+ if (!overflow) return co2measurements[index];
643+ else return co2measurements[(currentIndex + index) % NUM_MEASUREMENTS];
644+ }
645+ uint16_t getTempMeasurement (uint16_t index) {
646+ if (!overflow) return tempHumMeasurements[index].temperature ;
647+ else return tempHumMeasurements[(int )(ceil (currentIndex/3.0 ) + index) % (NUM_MEASUREMENTS/3 )].temperature ;
648+ }
649+ uint8_t getHumMeasurement (uint16_t index) {
650+ if (!overflow) return tempHumMeasurements[index].humidity ;
651+ else return tempHumMeasurements[(int )(ceil (currentIndex/3.0 ) + index) % (NUM_MEASUREMENTS/3 )].humidity ;
653652}
654653
655654void handleWiFiChange () {
@@ -718,6 +717,7 @@ void startWiFi() {
718717 WiFi.setHostname (Hostname); // hostname when connected to home network
719718
720719 wifiManager.setConfigPortalBlocking (false );
720+ wifiManager.setWiFiAutoReconnect (true );
721721 wifiManager.autoConnect (" OpenCO2 Sensor" ); // name of broadcasted SSID
722722
723723#ifdef MQTT
@@ -803,7 +803,10 @@ void loop() {
803803 measureESP32temperature ();
804804
805805 if (useWiFi && !BatteryMode) {
806- if (WiFi.status () != WL_CONNECTED) wifiManager.process ();
806+ if (WiFi.status () != WL_CONNECTED) {
807+ wifiManager.autoConnect (" OpenCO2 Sensor" ); // Attempt to reconnect
808+ wifiManager.process ();
809+ }
807810#ifdef airgradient
808811 if (WiFi.status () == WL_CONNECTED) server.handleClient ();
809812#endif /* airgradient */
0 commit comments