Skip to content

Commit 04b3913

Browse files
committed
QR code display the CO2 values over last 24h
Press the button for 5+ seconds to show a QR code containing each the co2 values of 1h. Up to 24 QR codes will be stored. Measurements are only stored and displayed in battery mode.
1 parent 765f969 commit 04b3913

File tree

3 files changed

+110
-2
lines changed

3 files changed

+110
-2
lines changed

OpenCO2_Sensor.ino

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,52 @@ void rainbowMode() {
374374
}
375375
}
376376

377+
RTC_DATA_ATTR uint8_t hour = 0;
378+
RTC_DATA_ATTR uint8_t halfminute = 0;
379+
RTC_DATA_ATTR uint16_t measurements[24][120];
380+
void saveMeasurement(uint16_t co2){
381+
if (halfminute == 120) {
382+
halfminute=0;
383+
hour++;
384+
}
385+
if (hour == 24) {
386+
for (int i=0; i<23; ++i) memcpy(measurements[i], measurements[i + 1], sizeof(uint16_t) * 120);
387+
hour = 23;
388+
}
389+
390+
measurements[hour][halfminute] = co2;
391+
halfminute++;
392+
}
393+
394+
int qrcodeNumber = 0;
395+
void fiveSecPressed() {
396+
//rainbowMode();
397+
398+
//DEMO DATA:
399+
/*hour = 2;
400+
for (int i=0; i<120; i++) {
401+
measurements[0][i] = 400+i;
402+
measurements[1][i] = 520+i;
403+
measurements[2][i] = 1000+i;
404+
}
405+
halfminute = 120;*/
406+
407+
qrcodeNumber = hour; // start at current hour
408+
extern int refreshes;
409+
refreshes = 1; // force full update
410+
for (int i=0; i<200; i++) {
411+
if (digitalRead(GPIO_NUM_0) == 0) { //goto next qr code
412+
displayQRcode(measurements);
413+
goto_light_sleep(500);
414+
if (qrcodeNumber == hour) qrcodeNumber = 0;
415+
else qrcodeNumber++;
416+
i = 0; //display qrcode again for 20 sec
417+
}
418+
delay(100);
419+
}
420+
refreshes = 1; // force full update
421+
}
422+
377423
void setup() {
378424
pinMode(DISPLAY_POWER, OUTPUT);
379425
pinMode(LED_POWER, OUTPUT);
@@ -402,7 +448,10 @@ void setup() {
402448
pinMode(GPIO_NUM_0, INPUT_PULLUP);
403449
int secPressed = 0;
404450
while (digitalRead(GPIO_NUM_0) == 0) {
405-
if (secPressed == 4) rainbowMode();
451+
if (secPressed == 4) {
452+
fiveSecPressed();
453+
return;
454+
}
406455
secPressed++;
407456
delay(1000);
408457
}
@@ -489,6 +538,7 @@ void loop() {
489538
errorToString(error, errorMessage, 256);
490539
displayWriteError(errorMessage);
491540
} else {
541+
if (BatteryMode) saveMeasurement(new_co2);
492542
/* dont update in Battery mode, unless CO2 has changed by 3% or temperature by 0.5°C */
493543
if (!TEST_MODE && BatteryMode && comingFromDeepSleep) {
494544
if ((abs(new_co2 - co2) < (0.03*co2)) && (fabs(new_temperature - temperature) < 0.5)) {
@@ -572,7 +622,7 @@ void loop() {
572622
scd4x.setTemperatureOffset(0.8);
573623
scd4x.startLowPowerPeriodicMeasurement();
574624
}
575-
goto_deep_sleep(29000);
625+
goto_deep_sleep(29500);
576626
}
577627

578628
goto_light_sleep(4000);

epd_abstraction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ void displayWriteTestResults(float voltage, uint16_t sensorStatus, uint16_t seri
1414
void displayBattery(uint8_t percentage);
1515
void updateDisplay();
1616
void displayRainbow();
17+
void displayQRcode(uint16_t measurements[24][120]);
1718

1819
#endif /* EPD_ABSTRACTION_H */

epd_abstraction.ino

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,63 @@ void displayWriteMeasuerments(uint16_t co2, float temperature, float humidity) {
196196
#endif
197197
}
198198

199+
#include "qrcode.h"
200+
#define ESP_QRCODE_CONFIG() (esp_qrcode_config_t) { \
201+
.display_func = draw_qr_code, \
202+
.max_qrcode_version = 26, \
203+
.qrcode_ecc_level = ESP_QRCODE_ECC_LOW, \
204+
}
205+
206+
void draw_qr_code(const uint8_t * qrcode) {
207+
int qrcodeSize = esp_qrcode_get_size(qrcode);
208+
int scaleFactor = 1;
209+
210+
if (qrcodeSize < 24) scaleFactor = 7;
211+
else if (qrcodeSize < 28) scaleFactor = 6;
212+
else if (qrcodeSize < 34) scaleFactor = 5;
213+
else if (qrcodeSize < 42) scaleFactor = 4;
214+
else if (qrcodeSize < 56) scaleFactor = 3;
215+
else if (qrcodeSize < 84) scaleFactor = 2;
216+
217+
int Start = (200 - (qrcodeSize *scaleFactor)) / 2;
218+
Paint_Clear(WHITE);
219+
for (int y=0; y < qrcodeSize; y++) {
220+
for (int x=0; x < qrcodeSize; x++) {
221+
if (esp_qrcode_get_module(qrcode, x, y)) {
222+
if (scaleFactor > 1) Paint_DrawRectangle(Start + x * scaleFactor,
223+
Start + y * scaleFactor,
224+
Start + x * scaleFactor + scaleFactor,
225+
Start + y * scaleFactor + scaleFactor,
226+
BLACK, DOT_PIXEL_1X1, DRAW_FILL_FULL);
227+
else Paint_SetPixel(x + (200-qrcodeSize)/2, y + (200-qrcodeSize)/2, BLACK);
228+
}
229+
}
230+
}
231+
232+
if (qrcodeNumber+1 >= 10) Paint_DrawNum(200-5*11, 200-16, qrcodeNumber+1, &Font16, BLACK, WHITE);
233+
else Paint_DrawNum(200-4*11, 200-16, qrcodeNumber+1, &Font16, BLACK, WHITE);
234+
Paint_DrawString_EN(200-3*11, 200-16, "/", &Font16, WHITE, BLACK);
235+
Paint_DrawNum(200-2*11, 200-16, hour+1, &Font16, BLACK, WHITE);
236+
updateDisplay();
237+
}
238+
239+
void displayQRcode(uint16_t measurements[24][120]) {
240+
char buffer[5*120+1];
241+
int numEnties = halfminute;
242+
if (hour > qrcodeNumber) numEnties = 120; // display all values included in previous hours
243+
244+
for (int i=0; i<numEnties; i++) {
245+
char tempStr[5];
246+
snprintf(tempStr, sizeof(tempStr), "%d", measurements[qrcodeNumber][i]);
247+
248+
if (i == 0) snprintf(buffer, sizeof(buffer), "%s", tempStr);
249+
else snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), " %s", tempStr);
250+
}
251+
252+
esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG();
253+
esp_qrcode_generate(&cfg, buffer);
254+
}
255+
199256
void displayWriteError(char errorMessage[256]){
200257
Paint_DrawString_EN(5, 40, errorMessage, &Font20, WHITE, BLACK);
201258
}

0 commit comments

Comments
 (0)