Skip to content

Commit

Permalink
QR code display the CO2 values over last 24h
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
davidkreidler committed Jul 29, 2023
1 parent 765f969 commit b348dd0
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 5 deletions.
60 changes: 55 additions & 5 deletions OpenCO2_Sensor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ Adafruit_DotStar strip(1, 40, 39, DOTSTAR_BRG); // numLEDs, DATAPIN, CLOCKPIN
SensirionI2CScd4x scd4x;

RTC_DATA_ATTR bool initDone = false;
RTC_DATA_ATTR extern bool BatteryMode = false;
RTC_DATA_ATTR extern bool comingFromDeepSleep = false;
RTC_DATA_ATTR bool BatteryMode = false;
RTC_DATA_ATTR bool comingFromDeepSleep = false;
RTC_DATA_ATTR int ledbrightness = 5;
RTC_DATA_ATTR bool LEDalwaysOn = false;
RTC_DATA_ATTR extern int HWSubRev = 1; //default only
RTC_DATA_ATTR int HWSubRev = 1; //default only
RTC_DATA_ATTR float maxBatteryVoltage;

/* TEST_MODE */
Expand Down Expand Up @@ -374,6 +374,52 @@ void rainbowMode() {
}
}

RTC_DATA_ATTR uint8_t hour = 0;
RTC_DATA_ATTR uint8_t halfminute = 0;
RTC_DATA_ATTR uint16_t measurements[24][120];
void saveMeasurement(uint16_t co2){
if (halfminute == 120) {
halfminute=0;
hour++;
}
if (hour == 24) {
for (int i=0; i<23; ++i) memcpy(measurements[i], measurements[i + 1], sizeof(uint16_t) * 120);
hour = 23;
}

measurements[hour][halfminute] = co2;
halfminute++;
}

int qrcodeNumber = 0;
void fiveSecPressed() {
//rainbowMode();

//DEMO DATA:
/*hour = 2;
for (int i=0; i<120; i++) {
measurements[0][i] = 400+i;
measurements[1][i] = 520+i;
measurements[2][i] = 1000+i;
}
halfminute = 120;*/

qrcodeNumber = hour; // start at current hour
extern int refreshes;
refreshes = 1; // force full update
for (int i=0; i<200; i++) {
if (digitalRead(GPIO_NUM_0) == 0) { //goto next qr code
displayQRcode(measurements);
goto_light_sleep(500);
if (qrcodeNumber == hour) qrcodeNumber = 0;
else qrcodeNumber++;
i = 0; //display qrcode again for 20 sec
}
delay(100);
}
refreshes = 1; // force full update
}

void setup() {
pinMode(DISPLAY_POWER, OUTPUT);
pinMode(LED_POWER, OUTPUT);
Expand Down Expand Up @@ -402,7 +448,10 @@ void setup() {
pinMode(GPIO_NUM_0, INPUT_PULLUP);
int secPressed = 0;
while (digitalRead(GPIO_NUM_0) == 0) {
if (secPressed == 4) rainbowMode();
if (secPressed == 4) {
fiveSecPressed();
return;
}
secPressed++;
delay(1000);
}
Expand Down Expand Up @@ -489,6 +538,7 @@ void loop() {
errorToString(error, errorMessage, 256);
displayWriteError(errorMessage);
} else {
if (BatteryMode) saveMeasurement(new_co2);
/* dont update in Battery mode, unless CO2 has changed by 3% or temperature by 0.5°C */
if (!TEST_MODE && BatteryMode && comingFromDeepSleep) {
if ((abs(new_co2 - co2) < (0.03*co2)) && (fabs(new_temperature - temperature) < 0.5)) {
Expand Down Expand Up @@ -572,7 +622,7 @@ void loop() {
scd4x.setTemperatureOffset(0.8);
scd4x.startLowPowerPeriodicMeasurement();
}
goto_deep_sleep(29000);
goto_deep_sleep(29500);
}

goto_light_sleep(4000);
Expand Down
1 change: 1 addition & 0 deletions epd_abstraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ void displayWriteTestResults(float voltage, uint16_t sensorStatus, uint16_t seri
void displayBattery(uint8_t percentage);
void updateDisplay();
void displayRainbow();
void displayQRcode(uint16_t measurements[24][120]);

#endif /* EPD_ABSTRACTION_H */
60 changes: 60 additions & 0 deletions epd_abstraction.ino
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

RTC_DATA_ATTR int refreshes = 1;
RTC_DATA_ATTR UBYTE *BlackImage;
extern bool BatteryMode;
extern bool comingFromDeepSleep;
extern int HWSubRev;

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

#include "qrcode.h"
#define ESP_QRCODE_CONFIG() (esp_qrcode_config_t) { \
.display_func = draw_qr_code, \
.max_qrcode_version = 26, \
.qrcode_ecc_level = ESP_QRCODE_ECC_LOW, \
}

void draw_qr_code(const uint8_t * qrcode) {
int qrcodeSize = esp_qrcode_get_size(qrcode);
int scaleFactor = 1;

if (qrcodeSize < 24) scaleFactor = 7;
else if (qrcodeSize < 28) scaleFactor = 6;
else if (qrcodeSize < 34) scaleFactor = 5;
else if (qrcodeSize < 42) scaleFactor = 4;
else if (qrcodeSize < 56) scaleFactor = 3;
else if (qrcodeSize < 84) scaleFactor = 2;

int Start = (200 - (qrcodeSize *scaleFactor)) / 2;
Paint_Clear(WHITE);
for (int y=0; y < qrcodeSize; y++) {
for (int x=0; x < qrcodeSize; x++) {
if (esp_qrcode_get_module(qrcode, x, y)) {
if (scaleFactor > 1) Paint_DrawRectangle(Start + x * scaleFactor,
Start + y * scaleFactor,
Start + x * scaleFactor + scaleFactor,
Start + y * scaleFactor + scaleFactor,
BLACK, DOT_PIXEL_1X1, DRAW_FILL_FULL);
else Paint_SetPixel(x + (200-qrcodeSize)/2, y + (200-qrcodeSize)/2, BLACK);
}
}
}

if (qrcodeNumber+1 >= 10) Paint_DrawNum(200-5*11, 200-16, qrcodeNumber+1, &Font16, BLACK, WHITE);
else Paint_DrawNum(200-4*11, 200-16, qrcodeNumber+1, &Font16, BLACK, WHITE);
Paint_DrawString_EN(200-3*11, 200-16, "/", &Font16, WHITE, BLACK);
Paint_DrawNum(200-2*11, 200-16, hour+1, &Font16, BLACK, WHITE);
updateDisplay();
}

void displayQRcode(uint16_t measurements[24][120]) {
char buffer[5*120+1];
int numEnties = halfminute;
if (hour > qrcodeNumber) numEnties = 120; // display all values included in previous hours

for (int i=0; i<numEnties; i++) {
char tempStr[6];
snprintf(tempStr, sizeof(tempStr), "%d", measurements[qrcodeNumber][i]);

if (i == 0) snprintf(buffer, sizeof(buffer), "%s", tempStr);
else snprintf(buffer + strlen(buffer), sizeof(buffer) - strlen(buffer), " %s", tempStr);
}

esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG();
esp_qrcode_generate(&cfg, buffer);
}

void displayWriteError(char errorMessage[256]){
Paint_DrawString_EN(5, 40, errorMessage, &Font20, WHITE, BLACK);
}
Expand Down

0 comments on commit b348dd0

Please sign in to comment.