1010 - WiFiManager: https://github.com/tzapu/WiFiManager
1111 - ArduinoMqttClient (if MQTT is defined)
1212*/
13- #define VERSION " v5.9 "
13+ #define VERSION " v6.0 "
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
1717#define LIGHT_SLEEP_TIME 500
1818#define DEEP_SLEEP_TIME 29124 // 30 sec
19- #define LOW_ENERGY_DEEP_SLEEP_TIME 287924 // 5 min
2019#define DEEP_SLEEP_TIME_NO_DISPLAY_UPDATE DEEP_SLEEP_TIME + 965 // offset for no display update
2120static unsigned long lastMeasurementTimeMs = 0 ;
2221
@@ -77,19 +76,13 @@ CRGB leds[1];
7776#include < Wire.h>
7877SensirionI2cScd4x scd4x;
7978
80-
81- #ifndef ARDUINO_USB_MODE
82- #error This ESP32 SoC has no Native USB interface
83- #elif ARDUINO_USB_MODE == 1
84- #error This sketch should be used when USB is in OTG mode and MSC On Boot enabled
85- #endif
8679#include " USB.h"
87- #include < USBMSC.h >
88- USBMSC usbmsc ;
80+ #include " FirmwareMSC.h "
81+ FirmwareMSC MSC_Update ;
8982
9083RTC_DATA_ATTR bool USB_ACTIVE = false , initDone = false , BatteryMode = false , comingFromDeepSleep = false ;
91- RTC_DATA_ATTR bool LEDonBattery, LEDonUSB, useSmoothLEDcolor, invertDisplay, useFahrenheit, useWiFi, lowEnergyMode, english, limitMaxBattery;
92- RTC_DATA_ATTR uint8_t ledbrightness, HWSubRev, font;
84+ RTC_DATA_ATTR bool LEDonBattery, LEDonUSB, useSmoothLEDcolor, invertDisplay, useFahrenheit, useWiFi, english, limitMaxBattery;
85+ RTC_DATA_ATTR uint8_t ledbrightness, HWSubRev, font, skipMeasurement = 10 ;
9386RTC_DATA_ATTR float maxBatteryVoltage;
9487
9588/* TEST_MODE */
@@ -327,8 +320,7 @@ float getTempOffset() {
327320 if (useWiFi) return 12.2 ;
328321 return 4.4 ;
329322 } else {
330- if (lowEnergyMode) return 0.0 ;
331- return 0.8 ;
323+ return 0.0 ; // was with periodic measurment 0.8
332324 }
333325}
334326
@@ -348,7 +340,7 @@ void initOnce() {
348340 if (HWSubRev < 3 ) {
349341 Wire.begin (33 , 34 ); // green, yellow
350342 digitalWrite (LED_POWER, LOW); // LED on
351- FastLED.addLeds <APA102, 40 , 39 , RGB >(leds, 1 );
343+ FastLED.addLeds <APA102, 40 , 39 , BGR >(leds, 1 );
352344 } else {
353345 Wire.begin (3 , 2 );
354346 digitalWrite (LED_POWER, HIGH); // LED on
@@ -370,7 +362,6 @@ void initOnce() {
370362 preferences.begin (" co2-sensor" , true );
371363 maxBatteryVoltage = preferences.getFloat (" MBV" , 3.95 );
372364 useWiFi = preferences.getBool (" WiFi" , false );
373- lowEnergyMode = preferences.getBool (" lowEnergy" , false );
374365 LEDonBattery = preferences.getBool (" LEDonBattery" , false );
375366 LEDonUSB = preferences.getBool (" LEDonUSB" , true );
376367 ledbrightness = preferences.getInt (" ledbrightness" , 5 );
@@ -389,7 +380,7 @@ void initOnce() {
389380 scd4x.setSensorAltitude (HEIGHT_ABOVE_SEA_LEVEL);
390381 scd4x.setAutomaticSelfCalibrationEnabled (1 ); // Or use setAutomaticSelfCalibrationTarget if needed
391382 scd4x.setTemperatureOffset (getTempOffset ());
392- if (!( BatteryMode && lowEnergyMode) ) scd4x.startPeriodicMeasurement ();
383+ if (!BatteryMode) scd4x.startPeriodicMeasurement ();
393384
394385 displayInit ();
395386 delay (3000 ); // Wait for co2 measurement
@@ -497,7 +488,7 @@ void goto_deep_sleep(int ms) {
497488 esp_deep_sleep_start ();
498489}
499490
500- static void usbEventCallback (void * arg, esp_event_base_t event_base, int32_t event_id, void * event_data) {
491+ static void usbEventCallback (void * arg, esp_event_base_t event_base, int32_t event_id, void * event_data) {
501492 if (event_base == ARDUINO_USB_EVENTS) {
502493 switch (event_id) {
503494 case ARDUINO_USB_STARTED_EVENT:
@@ -521,7 +512,7 @@ static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t eve
521512
522513void goto_light_sleep (int ms) {
523514 comingFromDeepSleep = false ;
524-
515+
525516 if (useWiFi || TEST_MODE || USB_ACTIVE) {
526517 for (int i = 0 ; i < (ms / 100 ); i++) {
527518 if (digitalRead (BUTTON) == 0 ) {
@@ -534,7 +525,7 @@ void goto_light_sleep(int ms) {
534525 gpio_wakeup_enable (BUTTON, GPIO_INTR_LOW_LEVEL);
535526 esp_sleep_enable_gpio_wakeup ();
536527
537- esp_sleep_enable_timer_wakeup (ms * 1000 ); // periodic measurement every 5 sec -1.1 sec awake
528+ esp_sleep_enable_timer_wakeup (ms * 1000 ); // periodic measurement every 5 sec -1.1 sec awake
538529 esp_light_sleep_start ();
539530 }
540531}
@@ -594,6 +585,9 @@ void calibrate() {
594585 /* Only run this, if calibration is needed!
595586 let the Sensor run outside for 3+ minutes before.
596587 */
588+ scd4x.stopPeriodicMeasurement ();
589+ scd4x.wakeUp ();
590+ scd4x.startLowPowerPeriodicMeasurement ();
597591 displayCalibrationWarning ();
598592 delay (500 );
599593 for (int i = 0 ; i < 180 ; i++) {
@@ -789,15 +783,13 @@ void setup() {
789783 /* scd4x */
790784 if (HWSubRev < 3 ) {
791785 Wire.begin (33 , 34 ); // green, yellow
792- FastLED.addLeds <APA102, 40 , 39 , RGB >(leds, 1 );
786+ FastLED.addLeds <APA102, 40 , 39 , BGR >(leds, 1 );
793787 } else {
794788 Wire.begin (3 , 2 );
795789 FastLED.addLeds <WS2812, LED_PIN, GRB>(leds, 1 );
796790 }
797791 scd4x.begin (Wire, 0x62 ); // 0x62 is the default I2C address for SCD4x
798792
799- USB.onEvent (usbEventCallback);
800- usbmsc.isWritable (true );
801793 if (!initDone) initOnce ();
802794
803795#if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE
@@ -826,11 +818,17 @@ void setup() {
826818 }
827819
828820 if (useWiFi && !BatteryMode) startWiFi ();
821+
822+ if (!BatteryMode && !comingFromDeepSleep) {
823+ USB.onEvent (usbEventCallback);
824+ MSC_Update.begin ();
825+ USB.begin ();
826+ }
829827}
830828
831829
832830void loop () {
833- if ((!useWiFi || (lowEnergyMode && BatteryMode) ) && esp_sleep_get_wakeup_cause () == ESP_SLEEP_WAKEUP_GPIO) handleButtonPress ();
831+ if ((!useWiFi || BatteryMode) && esp_sleep_get_wakeup_cause () == ESP_SLEEP_WAKEUP_GPIO) handleButtonPress ();
834832 updateBatteryMode (); // check again in USB Power mode
835833 updateCharging ();
836834 measureESP32temperature ();
@@ -856,7 +854,7 @@ void loop() {
856854 goto_light_sleep (5000 - (millis () - lastMeasurementTimeMs));
857855 }
858856
859- if (!( BatteryMode && lowEnergyMode) && !TEST_MODE) {
857+ if (!BatteryMode && !TEST_MODE) {
860858 bool isDataReady = false ;
861859 uint16_t ready_error = scd4x.getDataReadyStatus (isDataReady);
862860 if (ready_error || !isDataReady) {
@@ -870,11 +868,27 @@ void loop() {
870868 uint16_t new_co2 = 420 ;
871869 float new_temperature = 0 .0f ;
872870 uint16_t error;
873- if (BatteryMode && lowEnergyMode ) {
874- scd4x.stopPeriodicMeasurement ();
871+ if (BatteryMode) {
872+ if (!comingFromDeepSleep) scd4x.stopPeriodicMeasurement ();
875873 scd4x.wakeUp ();
876874 scd4x.setTemperatureOffset (getTempOffset ());
877- // delay(10);
875+
876+ /* check if temp/humidity changed */
877+ scd4x.measureSingleShotRhtOnly ();
878+ uint16_t dummyCo2; // CO2 output is returned as 0 ppm
879+ float new_humidity = 0 .0f ;
880+ error = scd4x.readMeasurement (dummyCo2, new_temperature, new_humidity);
881+ if (!error
882+ && (skipMeasurement > 1 )
883+ && (fabs (new_temperature - temperature) < 0.5 )
884+ && (fabs (new_humidity - humidity) < 2.0 )) {
885+ scd4x.powerDown ();
886+ skipMeasurement--;
887+ saveMeasurement (co2, new_temperature, new_humidity);
888+ goto_deep_sleep (DEEP_SLEEP_TIME_NO_DISPLAY_UPDATE);
889+ }
890+ skipMeasurement = 10 ; // force update every 5 minutes
891+
878892 if (HWSubRev < 3 ) scd4x.measureSingleShot (); // Ignore first measurement after wake up.
879893 error = scd4x.measureAndReadSingleShot (new_co2, new_temperature, humidity);
880894 scd4x.powerDown ();
@@ -895,19 +909,12 @@ void loop() {
895909 extern uint16_t refreshes;
896910 if (BatteryMode || (refreshes % 6 == 1 )) {
897911 saveMeasurement (new_co2, new_temperature, humidity);
898-
899- if (BatteryMode && lowEnergyMode) { // fill measurements of past 5 min
900- for (int i=0 ; i<9 ; i++) {
901- saveMeasurement (new_co2, new_temperature, humidity);
902- }
903- }
904912 }
905913
906914 /* don't update in Battery mode, unless CO2 has changed by 4% or temperature by 0.5°C */
907915 if (!TEST_MODE && BatteryMode && comingFromDeepSleep) {
908916 if ((abs (new_co2 - co2) < (0.04 * co2)) && (fabs (new_temperature - temperature) < 0.5 )) {
909- if (lowEnergyMode) goto_deep_sleep (LOW_ENERGY_DEEP_SLEEP_TIME);
910- else goto_deep_sleep (DEEP_SLEEP_TIME_NO_DISPLAY_UPDATE);
917+ goto_deep_sleep (DEEP_SLEEP_TIME_NO_DISPLAY_UPDATE);
911918 }
912919 }
913920
@@ -957,11 +964,11 @@ void loop() {
957964 if (BatteryMode) {
958965 if (!comingFromDeepSleep) {
959966 scd4x.stopPeriodicMeasurement ();
960- scd4x.setTemperatureOffset (getTempOffset ());
961- if (!lowEnergyMode) scd4x.startLowPowerPeriodicMeasurement ();
967+ MSC_Update.end ();
968+ USB_ACTIVE = false ;
969+ delay (100 );
962970 }
963- if (lowEnergyMode) goto_deep_sleep (LOW_ENERGY_DEEP_SLEEP_TIME);
964- else goto_deep_sleep (DEEP_SLEEP_TIME);
971+ goto_deep_sleep (DEEP_SLEEP_TIME);
965972 }
966973
967974 goto_light_sleep (LIGHT_SLEEP_TIME);
0 commit comments