Skip to content

Commit b348dd0

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 b348dd0

File tree

3 files changed

+116
-5
lines changed

3 files changed

+116
-5
lines changed

OpenCO2_Sensor.ino

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,11 @@ Adafruit_DotStar strip(1, 40, 39, DOTSTAR_BRG); // numLEDs, DATAPIN, CLOCKPIN
6565
SensirionI2CScd4x scd4x;
6666

6767
RTC_DATA_ATTR bool initDone = false;
68-
RTC_DATA_ATTR extern bool BatteryMode = false;
69-
RTC_DATA_ATTR extern bool comingFromDeepSleep = false;
68+
RTC_DATA_ATTR bool BatteryMode = false;
69+
RTC_DATA_ATTR bool comingFromDeepSleep = false;
7070
RTC_DATA_ATTR int ledbrightness = 5;
7171
RTC_DATA_ATTR bool LEDalwaysOn = false;
72-
RTC_DATA_ATTR extern int HWSubRev = 1; //default only
72+
RTC_DATA_ATTR int HWSubRev = 1; //default only
7373
RTC_DATA_ATTR float maxBatteryVoltage;
7474

7575
/* TEST_MODE */
@@ -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: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
RTC_DATA_ATTR int refreshes = 1;
2121
RTC_DATA_ATTR UBYTE *BlackImage;
22+
extern bool BatteryMode;
23+
extern bool comingFromDeepSleep;
24+
extern int HWSubRev;
2225

2326
sFONT big=bahn_big; //gotham_big nothing_big bahn_big
2427
sFONT mid=bahn_mid; //gotham_mid nothing_mid bahn_mid
@@ -196,6 +199,63 @@ void displayWriteMeasuerments(uint16_t co2, float temperature, float humidity) {
196199
#endif
197200
}
198201

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

0 commit comments

Comments
 (0)