From 90d4bf40d91c442798d84cd77feedc3295a34ed8 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 8 Jul 2023 03:44:48 -0700 Subject: [PATCH 01/12] add WiFiManager library ref --- platformio/platformio.ini | 4 ++++ platformio/src/client_utils.cpp | 1 + 2 files changed, 5 insertions(+) diff --git a/platformio/platformio.ini b/platformio/platformio.ini index 9f8c2c67c..440d47f26 100644 --- a/platformio/platformio.ini +++ b/platformio/platformio.ini @@ -25,6 +25,10 @@ lib_deps = adafruit/Adafruit Unified Sensor @ ^1.1.5 bblanchon/ArduinoJson @ ^6.19.3 zinggjm/GxEPD2 @ ^1.4.5 + ; WiFiManager seems to have some platformio build integration issues + ; possibly related to release tag conventions. + ; https://github.com/tzapu/WiFiManager/issues/1453 + https://github.com/tzapu/WiFiManager.git@2.0.16-rc.2+sha.3a303ee [env:dfrobot_firebeetle2_esp32e] diff --git a/platformio/src/client_utils.cpp b/platformio/src/client_utils.cpp index dc69b3abe..5f747bff3 100644 --- a/platformio/src/client_utils.cpp +++ b/platformio/src/client_utils.cpp @@ -25,6 +25,7 @@ #include #include #include +#include // additional libraries #include From b964dc643131f3aacca9891c96e79b1bf5291ad9 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 8 Jul 2023 03:45:38 -0700 Subject: [PATCH 02/12] integrate WiFiManager --- platformio/include/client_utils.h | 1 + platformio/include/config.h | 4 +-- platformio/src/client_utils.cpp | 58 ++++++++++++++++++++++--------- platformio/src/config.cpp | 7 ++-- platformio/src/main.cpp | 20 ++++++++++- 5 files changed, 67 insertions(+), 23 deletions(-) diff --git a/platformio/include/client_utils.h b/platformio/include/client_utils.h index 4abae4a5b..7d988cb81 100644 --- a/platformio/include/client_utils.h +++ b/platformio/include/client_utils.h @@ -28,6 +28,7 @@ #endif wl_status_t startWiFi(int &wifiRSSI); +wl_status_t configureWiFi(int &wifiRSSI); void killWiFi(); bool setupTime(tm *timeInfo); bool printLocalTime(tm *timeInfo); diff --git a/platformio/include/config.h b/platformio/include/config.h index 5accaac0b..9e6b82b3f 100644 --- a/platformio/include/config.h +++ b/platformio/include/config.h @@ -195,8 +195,8 @@ extern const uint8_t PIN_EPD_MOSI; extern const uint8_t PIN_BME_SDA; extern const uint8_t PIN_BME_SCL; extern const uint8_t BME_ADDRESS; -extern const char *WIFI_SSID; -extern const char *WIFI_PASSWORD; +extern const uint8_t PIN_CONFIGURE_WIFI; +extern const char *WIFI_AP_SSID; extern const String OWM_APIKEY; extern const String OWM_ENDPOINT; extern const String OWM_ONECALL_VERSION; diff --git a/platformio/src/client_utils.cpp b/platformio/src/client_utils.cpp index 5f747bff3..d6ed7f103 100644 --- a/platformio/src/client_utils.cpp +++ b/platformio/src/client_utils.cpp @@ -58,33 +58,57 @@ wl_status_t startWiFi(int &wifiRSSI) { WiFi.mode(WIFI_STA); - Serial.printf("Connecting to '%s'", WIFI_SSID); - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - // timeout if WiFi does not connect in 10s from now - unsigned long timeout = millis() + 10000; - wl_status_t connection_status = WiFi.status(); + WiFiManager wifi_manager; + wifi_manager.setConnectTimeout(10); - while ((connection_status != WL_CONNECTED) && (millis() < timeout)) + // Turn off config AP fallback to save on battery on random errors + wifi_manager.setEnableConfigPortal(false); + if (wifi_manager.autoConnect(WIFI_AP_SSID)) { - Serial.print("."); - delay(50); - connection_status = WiFi.status(); + wifiRSSI = WiFi.RSSI(); // get WiFi signal strength now, because the WiFi + // will be turned off to save power! + Serial.println("IP: " + WiFi.localIP().toString()); } - Serial.println(); + return WiFi.status(); +} // startWiFi + +/* Callback called when WIFI config AP is enabled. + * Takes in the WiFiManager instance. + * + * Returns WiFi status. + */ +void configModeCallback(WiFiManager *myWiFiManager) +{ + Serial.println("Entered Configuration Mode"); + Serial.println("Config SSID: " + myWiFiManager->getConfigPortalSSID()); + Serial.println("Config IP Address: " + WiFi.softAPIP()); +} + +/* Power-on and start WiFi config AP. + * Takes int parameter to store WiFi RSSI, or “Received Signal Strength + * Indicator" + * + * Returns WiFi status. + */ +wl_status_t configureWiFi(int &wifiRSSI) +{ + WiFi.mode(WIFI_STA); + + WiFiManager wifi_manager; + wifi_manager.setConnectTimeout(10); + wifi_manager.setConfigPortalTimeout(60 * 5); + wifi_manager.setAPCallback(configModeCallback); - if (connection_status == WL_CONNECTED) + // Start the configuration AP portal with 10 minute timeout + if (wifi_manager.startConfigPortal(WIFI_AP_SSID)) { wifiRSSI = WiFi.RSSI(); // get WiFi signal strength now, because the WiFi // will be turned off to save power! Serial.println("IP: " + WiFi.localIP().toString()); } - else - { - Serial.printf("Could not connect to '%s'\n", WIFI_SSID); - } - return connection_status; -} // startWiFi + return WiFi.status(); +} // configureWiFi /* Disconnect and power-off WiFi. */ diff --git a/platformio/src/config.cpp b/platformio/src/config.cpp index 308995829..49e460ea1 100644 --- a/platformio/src/config.cpp +++ b/platformio/src/config.cpp @@ -34,9 +34,10 @@ const uint8_t PIN_BME_SDA = 17; const uint8_t PIN_BME_SCL = 16; const uint8_t BME_ADDRESS = 0x76; // if sensor does not work, try 0x77 -// WIFI CREDENTIALS -const char *WIFI_SSID = "ssid"; -const char *WIFI_PASSWORD = "password"; +// Pin used for WiFi config AP +const uint8_t PIN_CONFIGURE_WIFI = 27; // 27 is a HW button on the Firebeetle +// WIFI +const char *WIFI_AP_SSID = "Weather_Station"; // OPENWEATHERMAP API // OpenWeatherMap API key, https://openweathermap.org/ diff --git a/platformio/src/main.cpp b/platformio/src/main.cpp index fdd748736..cf51b7809 100644 --- a/platformio/src/main.cpp +++ b/platformio/src/main.cpp @@ -186,8 +186,26 @@ void setup() tm timeInfo = {}; // START WIFI + wl_status_t wifiStatus; int wifiRSSI = 0; // “Received Signal Strength Indicator" - wl_status_t wifiStatus = startWiFi(wifiRSSI); + + pinMode(PIN_CONFIGURE_WIFI, INPUT_PULLUP); + if (digitalRead(PIN_CONFIGURE_WIFI) == LOW) + { + Serial.println("WIFI config pin detected"); + do + { + drawError(wifi_x_196x196, "Weather Station is in WIFI configuration mode", ""); + } while (display.nextPage()); + // Configure WIFI + Serial.println("Entering config mode"); + wifiStatus = configureWiFi(wifiRSSI); + } + else + { + wifiStatus = startWiFi(wifiRSSI); + } + if (wifiStatus != WL_CONNECTED) { // WiFi Connection Failed killWiFi(); From 7022049fce1ff9aedd963954b939cd12259e1995 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 8 Jul 2023 05:10:00 -0700 Subject: [PATCH 03/12] remove callback causing bootloop --- platformio/src/client_utils.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/platformio/src/client_utils.cpp b/platformio/src/client_utils.cpp index d6ed7f103..00f0799ca 100644 --- a/platformio/src/client_utils.cpp +++ b/platformio/src/client_utils.cpp @@ -73,18 +73,6 @@ wl_status_t startWiFi(int &wifiRSSI) return WiFi.status(); } // startWiFi -/* Callback called when WIFI config AP is enabled. - * Takes in the WiFiManager instance. - * - * Returns WiFi status. - */ -void configModeCallback(WiFiManager *myWiFiManager) -{ - Serial.println("Entered Configuration Mode"); - Serial.println("Config SSID: " + myWiFiManager->getConfigPortalSSID()); - Serial.println("Config IP Address: " + WiFi.softAPIP()); -} - /* Power-on and start WiFi config AP. * Takes int parameter to store WiFi RSSI, or “Received Signal Strength * Indicator" @@ -98,7 +86,6 @@ wl_status_t configureWiFi(int &wifiRSSI) WiFiManager wifi_manager; wifi_manager.setConnectTimeout(10); wifi_manager.setConfigPortalTimeout(60 * 5); - wifi_manager.setAPCallback(configModeCallback); // Start the configuration AP portal with 10 minute timeout if (wifi_manager.startConfigPortal(WIFI_AP_SSID)) From 5c4db7594f164eba3c4f7ee4ffb8e8a338f3ac92 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 8 Jul 2023 05:10:58 -0700 Subject: [PATCH 04/12] init display and fix display message --- platformio/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platformio/src/main.cpp b/platformio/src/main.cpp index cf51b7809..c77b2ebf0 100644 --- a/platformio/src/main.cpp +++ b/platformio/src/main.cpp @@ -193,9 +193,10 @@ void setup() if (digitalRead(PIN_CONFIGURE_WIFI) == LOW) { Serial.println("WIFI config pin detected"); + initDisplay(); do { - drawError(wifi_x_196x196, "Weather Station is in WIFI configuration mode", ""); + drawError(wifi_x_196x196, "Weather Station is in", "WIFI configuration mode"); } while (display.nextPage()); // Configure WIFI Serial.println("Entering config mode"); From b1f256c676952e87a92d723649226405b3f40440 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 8 Jul 2023 06:31:07 -0700 Subject: [PATCH 05/12] restore and fix configModeCallback --- platformio/src/client_utils.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/platformio/src/client_utils.cpp b/platformio/src/client_utils.cpp index 00f0799ca..c1fda4dd7 100644 --- a/platformio/src/client_utils.cpp +++ b/platformio/src/client_utils.cpp @@ -73,6 +73,18 @@ wl_status_t startWiFi(int &wifiRSSI) return WiFi.status(); } // startWiFi +/* Callback when WiFi config AP is started + * Takes in a WiFiManager instance. + */ +void configModeCallback(WiFiManager *myWiFiManager) +{ + Serial.println("Entered Configuration Mode"); + Serial.print("Config SSID: "); + Serial.println(myWiFiManager->getConfigPortalSSID()); + Serial.print("Config IP Address: "); + Serial.println(WiFi.softAPIP()); +} + /* Power-on and start WiFi config AP. * Takes int parameter to store WiFi RSSI, or “Received Signal Strength * Indicator" @@ -86,7 +98,8 @@ wl_status_t configureWiFi(int &wifiRSSI) WiFiManager wifi_manager; wifi_manager.setConnectTimeout(10); wifi_manager.setConfigPortalTimeout(60 * 5); - + wifi_manager.setAPCallback(configModeCallback); + // Start the configuration AP portal with 10 minute timeout if (wifi_manager.startConfigPortal(WIFI_AP_SSID)) { From 3e204ce11a1d34ca381c6c232c691b8dd656b1a3 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 29 Jul 2023 19:29:07 -0700 Subject: [PATCH 06/12] re-add default wifi --- platformio/include/client_utils.h | 1 + platformio/include/config.h | 2 ++ platformio/src/client_utils.cpp | 39 ++++++++++++++++++++++++++++++- platformio/src/config.cpp | 4 ++++ platformio/src/main.cpp | 20 ++++++++++++---- 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/platformio/include/client_utils.h b/platformio/include/client_utils.h index 7d988cb81..392b14ee5 100644 --- a/platformio/include/client_utils.h +++ b/platformio/include/client_utils.h @@ -28,6 +28,7 @@ #endif wl_status_t startWiFi(int &wifiRSSI); +wl_status_t startDefaultWiFi(int &wifiRSSI); wl_status_t configureWiFi(int &wifiRSSI); void killWiFi(); bool setupTime(tm *timeInfo); diff --git a/platformio/include/config.h b/platformio/include/config.h index 9e6b82b3f..dba05aba4 100644 --- a/platformio/include/config.h +++ b/platformio/include/config.h @@ -196,6 +196,8 @@ extern const uint8_t PIN_BME_SDA; extern const uint8_t PIN_BME_SCL; extern const uint8_t BME_ADDRESS; extern const uint8_t PIN_CONFIGURE_WIFI; +extern const char *WIFI_SSID; +extern const char *WIFI_PASSWORD; extern const char *WIFI_AP_SSID; extern const String OWM_APIKEY; extern const String OWM_ENDPOINT; diff --git a/platformio/src/client_utils.cpp b/platformio/src/client_utils.cpp index c1fda4dd7..a7e8c080d 100644 --- a/platformio/src/client_utils.cpp +++ b/platformio/src/client_utils.cpp @@ -49,7 +49,7 @@ static const uint16_t OWM_PORT = 443; #endif -/* Power-on and connect WiFi. +/* Power-on and connect WiFi using WiFi Manager. * Takes int parameter to store WiFi RSSI, or “Received Signal Strength * Indicator" * @@ -73,6 +73,43 @@ wl_status_t startWiFi(int &wifiRSSI) return WiFi.status(); } // startWiFi +/* Power-on and connect WiFi. + * Takes int parameter to store WiFi RSSI, or “Received Signal Strength + * Indicator" + * + * Returns WiFi status. + */ +wl_status_t startDefaultWiFi(int &wifiRSSI) +{ + WiFi.mode(WIFI_STA); + Serial.printf("Connecting to '%s'", WIFI_SSID); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + + // timeout if WiFi does not connect in 10s from now + unsigned long timeout = millis() + 10000; + wl_status_t connection_status = WiFi.status(); + + while ((connection_status != WL_CONNECTED) && (millis() < timeout)) + { + Serial.print("."); + delay(50); + connection_status = WiFi.status(); + } + Serial.println(); + + if (connection_status == WL_CONNECTED) + { + wifiRSSI = WiFi.RSSI(); // get WiFi signal strength now, because the WiFi + // will be turned off to save power! + Serial.println("IP: " + WiFi.localIP().toString()); + } + else + { + Serial.printf("Could not connect to '%s'\n", WIFI_SSID); + } + return connection_status; +} // startDefaultWiFi + /* Callback when WiFi config AP is started * Takes in a WiFiManager instance. */ diff --git a/platformio/src/config.cpp b/platformio/src/config.cpp index 49e460ea1..dca430174 100644 --- a/platformio/src/config.cpp +++ b/platformio/src/config.cpp @@ -34,6 +34,10 @@ const uint8_t PIN_BME_SDA = 17; const uint8_t PIN_BME_SCL = 16; const uint8_t BME_ADDRESS = 0x76; // if sensor does not work, try 0x77 +// WIFI CREDENTIALS +const char *WIFI_SSID = "ssid"; +const char *WIFI_PASSWORD = "password"; + // Pin used for WiFi config AP const uint8_t PIN_CONFIGURE_WIFI = 27; // 27 is a HW button on the Firebeetle // WIFI diff --git a/platformio/src/main.cpp b/platformio/src/main.cpp index c77b2ebf0..de23f8ebb 100644 --- a/platformio/src/main.cpp +++ b/platformio/src/main.cpp @@ -133,7 +133,7 @@ void setup() // refresh is when voltage is no longer low. To keep track of that we will // make use of non-volatile storage. // Open namespace for read/write to non-volatile storage - prefs.begin("lowBat", false); + prefs.begin("app_persistence", false); bool lowBat = prefs.getBool("lowBat", false); // low battery, deep-sleep now @@ -188,10 +188,11 @@ void setup() // START WIFI wl_status_t wifiStatus; int wifiRSSI = 0; // “Received Signal Strength Indicator" - + pinMode(PIN_CONFIGURE_WIFI, INPUT_PULLUP); if (digitalRead(PIN_CONFIGURE_WIFI) == LOW) { + prefs.putBool("prev_configured", false); Serial.println("WIFI config pin detected"); initDisplay(); do @@ -201,10 +202,21 @@ void setup() // Configure WIFI Serial.println("Entering config mode"); wifiStatus = configureWiFi(wifiRSSI); + if (wifiStatus == WL_CONNECTED) + { + prefs.putBool("prev_configured", true); + } } else { - wifiStatus = startWiFi(wifiRSSI); + if (prefs.getBool("prev_configured", false)) + { + wifiStatus = startWiFi(wifiRSSI); + } + else + { + wifiStatus = startDefaultWiFi(wifiRSSI); + } } if (wifiStatus != WL_CONNECTED) @@ -229,7 +241,7 @@ void setup() } display.powerOff(); beginDeepSleep(startTime, &timeInfo); - } + } // FETCH TIME bool timeConfigured = false; From b4e2d14a9476db3c4de90a3321caeca786395229 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 29 Jul 2023 20:08:10 -0700 Subject: [PATCH 07/12] document wifi manager --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a959bae2c..b6273f005 100644 --- a/README.md +++ b/README.md @@ -135,8 +135,8 @@ PlatformIO for VSCode is used for managing dependencies, code compilation, and u - Important settings to configure in config.cpp: - - WiFi credentials (ssid, password). - + - WiFi credentials (ssid, password, ap ssid). + - Open Weather Map API key (it's free, see next section for important notes about obtaining an API key). - Latitude and longitude. @@ -165,6 +165,12 @@ PlatformIO for VSCode is used for managing dependencies, code compilation, and u - If you are getting errors during the upload process, you may need to install drivers to allow you to upload code to the ESP32. +7. Boot options. + + - To configure WiFi without requiring a change in cofigs and re-upload, a [WiFi Manager](https://github.com/tzapu/WiFiManager) has been integrated. To use it hold HW button 27 (or PIN_CONFIGURE_WIFI config value) down and press and release the reset button. This will cause the weather station to create an ad-hoc wifi network named "Weather_Station" (or the value of WIFI_AP_SSID). Connect to this network (ideally using a mobile device) to configure the WiFi network. Visit the WiFi Manger site for further details. + > **Note** + > Once you reset with the button held down any previously configured WiFi network will be lost however. This does not impact the compiled defaults and resetting without the button held down after previously configured WiFi networks have been cleared will cause the weather station to connect to the compiled config vaules. + ### OpenWeatherMap API Key Sign up here to get an API key; it's free. https://openweathermap.org/api From 58381ebcb9ce7881b38b00e8e0a6ee15b6da4584 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 29 Jul 2023 20:20:15 -0700 Subject: [PATCH 08/12] clean up instructions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6273f005..d4873d85f 100644 --- a/README.md +++ b/README.md @@ -167,9 +167,9 @@ PlatformIO for VSCode is used for managing dependencies, code compilation, and u 7. Boot options. - - To configure WiFi without requiring a change in cofigs and re-upload, a [WiFi Manager](https://github.com/tzapu/WiFiManager) has been integrated. To use it hold HW button 27 (or PIN_CONFIGURE_WIFI config value) down and press and release the reset button. This will cause the weather station to create an ad-hoc wifi network named "Weather_Station" (or the value of WIFI_AP_SSID). Connect to this network (ideally using a mobile device) to configure the WiFi network. Visit the WiFi Manger site for further details. + - To support a change in WiFi networks without requiring a change in code and re-upload, [WiFi Manager](https://github.com/tzapu/WiFiManager) has been integrated. To use this feature, pull HW pin 27 `PIN_CONFIGURE_WIFI` down and press and release the reset button. This will cause the weather station to create an ad-hoc wifi network named "Weather_Station" `WIFI_AP_SSID`. Connect to this network to configure the WiFi network. Visit the WiFi Manger site for further details. > **Note** - > Once you reset with the button held down any previously configured WiFi network will be lost however. This does not impact the compiled defaults and resetting without the button held down after previously configured WiFi networks have been cleared will cause the weather station to connect to the compiled config vaules. + > Each time you reset using this method the previously configured WiFi network will be lost. After you perform this reset the compiled defaults can still be used by performing a normal reset without connecting to the ad-hoc network and configuring the WiFi. ### OpenWeatherMap API Key From 39e339d7d606fc5138364fc5a51421d68441c780 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Wed, 25 Oct 2023 23:06:05 -0700 Subject: [PATCH 09/12] fix formatting --- platformio/src/client_utils.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platformio/src/client_utils.cpp b/platformio/src/client_utils.cpp index f1734aa64..a299628a6 100644 --- a/platformio/src/client_utils.cpp +++ b/platformio/src/client_utils.cpp @@ -92,21 +92,21 @@ wl_status_t startDefaultWiFi(int &wifiRSSI) while ((connection_status != WL_CONNECTED) && (millis() < timeout)) { - Serial.print("."); - delay(50); - connection_status = WiFi.status(); + Serial.print("."); + delay(50); + connection_status = WiFi.status(); } Serial.println(); if (connection_status == WL_CONNECTED) { - wifiRSSI = WiFi.RSSI(); // get WiFi signal strength now, because the WiFi - // will be turned off to save power! - Serial.println("IP: " + WiFi.localIP().toString()); + wifiRSSI = WiFi.RSSI(); // get WiFi signal strength now, because the WiFi + // will be turned off to save power! + Serial.println("IP: " + WiFi.localIP().toString()); } else { - Serial.printf("Could not connect to '%s'\n", WIFI_SSID); + Serial.printf("Could not connect to '%s'\n", WIFI_SSID); } return connection_status; } // startDefaultWiFi From 70004be3f7aff362b0a854e842f104c6dd067a09 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Mon, 20 Nov 2023 23:07:45 -0800 Subject: [PATCH 10/12] fix auto formating --- platformio/src/main.cpp | 205 +++++++++++++++++++++++++--------------- 1 file changed, 128 insertions(+), 77 deletions(-) diff --git a/platformio/src/main.cpp b/platformio/src/main.cpp index 91b5b6ec4..c065ac87c 100644 --- a/platformio/src/main.cpp +++ b/platformio/src/main.cpp @@ -15,13 +15,13 @@ * along with this program. If not, see . */ +#include #include #include -#include #include +#include #include #include -#include #include "api_response.h" #include "client_utils.h" @@ -30,14 +30,14 @@ #include "icons/icons_196x196.h" #include "renderer.h" #ifndef USE_HTTP -#include + #include #endif #ifdef USE_HTTPS_WITH_CERT_VERIF -#include "cert.h" + #include "cert.h" #endif // too large to allocate locally on stack -static owm_resp_onecall_t owm_onecall; +static owm_resp_onecall_t owm_onecall; static owm_resp_air_pollution_t owm_air_pollution; Preferences prefs; @@ -45,9 +45,11 @@ Preferences prefs; /* Put esp32 into ultra low-power deep-sleep (<11μA). * Aligns wake time to the minute. Sleep times defined in config.cpp. */ -void beginDeepSleep(unsigned long &startTime, tm *timeInfo) { - if (!getLocalTime(timeInfo)) { - Serial.println("Failed to obtain time before deep-sleep, referencing " +void beginDeepSleep(unsigned long &startTime, tm *timeInfo) +{ + if (!getLocalTime(timeInfo)) + { + Serial.println("Failed to obtain time before deep-sleep, referencing " \ "older time."); } @@ -55,40 +57,48 @@ void beginDeepSleep(unsigned long &startTime, tm *timeInfo) { int extraHoursUntilWake = 0; int curHour = timeInfo->tm_hour; - if (timeInfo->tm_min >= 58) { // if we are within 2 minutes of the next hour, - // then round up for the + if (timeInfo->tm_min >= 58) + { // if we are within 2 minutes of the next hour, then round up for the // purposes of bed time curHour = (curHour + 1) % 24; extraHoursUntilWake += 1; } - if (BED_TIME < WAKE_TIME && curHour >= BED_TIME && - curHour < WAKE_TIME) { // 0 B v W 24 + if (BED_TIME < WAKE_TIME && curHour >= BED_TIME && curHour < WAKE_TIME) + { // 0 B v W 24 // |--------------zzzzZzz---| extraHoursUntilWake += WAKE_TIME - curHour; - } else if (BED_TIME > WAKE_TIME && curHour < WAKE_TIME) { // 0 v W B 24 + } + else if (BED_TIME > WAKE_TIME && curHour < WAKE_TIME) + { // 0 v W B 24 // |zZz----------------zzzzz| extraHoursUntilWake += WAKE_TIME - curHour; - } else if (BED_TIME > WAKE_TIME && curHour >= BED_TIME) { // 0 W B v 24 + } + else if (BED_TIME > WAKE_TIME && curHour >= BED_TIME) + { // 0 W B v 24 // |zzz----------------zzzZz| extraHoursUntilWake += WAKE_TIME - (curHour - 24); - } else // This feature is disabled (BED_TIME == WAKE_TIME) - { // OR it is not past BED_TIME + } + else // This feature is disabled (BED_TIME == WAKE_TIME) + { // OR it is not past BED_TIME extraHoursUntilWake = 0; } - if (extraHoursUntilWake == - 0) { // align wake time to nearest multiple of SLEEP_DURATION - sleepDuration = - SLEEP_DURATION * 60ULL - - ((timeInfo->tm_min % SLEEP_DURATION) * 60ULL + timeInfo->tm_sec); - } else { // align wake time to the hour - sleepDuration = extraHoursUntilWake * 3600ULL - - (timeInfo->tm_min * 60ULL + timeInfo->tm_sec); + if (extraHoursUntilWake == 0) + { // align wake time to nearest multiple of SLEEP_DURATION + sleepDuration = SLEEP_DURATION * 60ULL + - ((timeInfo->tm_min % SLEEP_DURATION) * 60ULL + + timeInfo->tm_sec); + } + else + { // align wake time to the hour + sleepDuration = extraHoursUntilWake * 3600ULL + - (timeInfo->tm_min * 60ULL + timeInfo->tm_sec); } // if we are within 2 minutes of the next alignment. - if (sleepDuration <= 120ULL) { + if (sleepDuration <= 120ULL) + { sleepDuration += SLEEP_DURATION * 60ULL; } @@ -100,15 +110,16 @@ void beginDeepSleep(unsigned long &startTime, tm *timeInfo) { #endif esp_sleep_enable_timer_wakeup(sleepDuration * 1000000ULL); - Serial.println("Awake for " + String((millis() - startTime) / 1000.0, 3) + - "s"); + Serial.println("Awake for " + + String((millis() - startTime) / 1000.0, 3) + "s"); Serial.println("Deep-sleep for " + String(sleepDuration) + "s"); esp_deep_sleep_start(); } // end beginDeepSleep /* Program entry point. */ -void setup() { +void setup() +{ unsigned long startTime = millis(); Serial.begin(115200); @@ -124,9 +135,9 @@ void setup() { // DFRobot FireBeetle Esp32-E V1.0 has voltage divider (1M+1M), so readings // are multiplied by 2. Readings are divided by 1000 to convert mV to V. double batteryVoltage = - static_cast(analogRead(PIN_BAT_ADC)) / 1000.0 * (3.5 / 2.0); - // use / 1000.0 * (3.3 / 2.0) multiplier above for firebeetle esp32 - // use / 1000.0 * (3.5 / 2.0) for firebeetle esp32-E + static_cast(analogRead(PIN_BAT_ADC)) / 1000.0 * (3.5 / 2.0); + // use / 1000.0 * (3.3 / 2.0) multiplier above for firebeetle esp32 + // use / 1000.0 * (3.5 / 2.0) for firebeetle esp32-E Serial.println("Battery voltage: " + String(batteryVoltage, 2)); // When the battery is low, the display should be updated to reflect that, but @@ -136,39 +147,48 @@ void setup() { bool lowBat = prefs.getBool("lowBat", false); // low battery, deep-sleep now - if (batteryVoltage <= LOW_BATTERY_VOLTAGE) { - if (lowBat == false) { // battery is now low for the first time + if (batteryVoltage <= LOW_BATTERY_VOLTAGE) + { + if (lowBat == false) + { // battery is now low for the first time prefs.putBool("lowBat", true); prefs.end(); initDisplay(); - do { + do + { drawError(battery_alert_0deg_196x196, "Low Battery", ""); } while (display.nextPage()); display.powerOff(); } - if (batteryVoltage <= CRIT_LOW_BATTERY_VOLTAGE) { // critically low battery + if (batteryVoltage <= CRIT_LOW_BATTERY_VOLTAGE) + { // critically low battery // don't set esp_sleep_enable_timer_wakeup(); // We won't wake up again until someone manually presses the RST button. Serial.println("Critically low battery voltage!"); Serial.println("Hibernating without wake time!"); - } else if (batteryVoltage <= VERY_LOW_BATTERY_VOLTAGE) { // very low battery - esp_sleep_enable_timer_wakeup(VERY_LOW_BATTERY_SLEEP_INTERVAL * 60ULL * - 1000000ULL); + } + else if (batteryVoltage <= VERY_LOW_BATTERY_VOLTAGE) + { // very low battery + esp_sleep_enable_timer_wakeup(VERY_LOW_BATTERY_SLEEP_INTERVAL + * 60ULL * 1000000ULL); Serial.println("Very low battery voltage!"); - Serial.println("Deep-sleep for " + - String(VERY_LOW_BATTERY_SLEEP_INTERVAL) + "min"); - } else { // low battery - esp_sleep_enable_timer_wakeup(LOW_BATTERY_SLEEP_INTERVAL * 60ULL * - 1000000ULL); + Serial.println("Deep-sleep for " + + String(VERY_LOW_BATTERY_SLEEP_INTERVAL) + "min"); + } + else + { // low battery + esp_sleep_enable_timer_wakeup(LOW_BATTERY_SLEEP_INTERVAL + * 60ULL * 1000000ULL); Serial.println("Low battery voltage!"); - Serial.println("Deep-sleep for " + String(LOW_BATTERY_SLEEP_INTERVAL) + - "min"); + Serial.println("Deep-sleep for " + + String(LOW_BATTERY_SLEEP_INTERVAL) + "min"); } esp_deep_sleep_start(); } // battery is no longer low, reset variable in non-volatile storage - if (lowBat == true) { + if (lowBat == true) + { prefs.putBool("lowBat", false); } #else @@ -184,57 +204,73 @@ void setup() { int wifiRSSI = 0; // “Received Signal Strength Indicator" pinMode(PIN_CONFIGURE_WIFI, INPUT_PULLUP); - if (digitalRead(PIN_CONFIGURE_WIFI) == LOW) { + if (digitalRead(PIN_CONFIGURE_WIFI) == LOW) + { prefs.putBool("prev_configured", false); Serial.println("WIFI config pin detected"); initDisplay(); - do { - drawError(wifi_x_196x196, "Weather Station is in", - "WIFI configuration mode"); + do + { + drawError(wifi_x_196x196, "Weather Station is in", "WIFI configuration mode"); } while (display.nextPage()); // Configure WIFI Serial.println("Entering config mode"); wifiStatus = configureWiFi(wifiRSSI); - if (wifiStatus == WL_CONNECTED) { - prefs.putBool("prev_configured", true); + if (wifiStatus == WL_CONNECTED) + { + prefs.putBool("prev_configured", true); } - } else { - if (prefs.getBool("prev_configured", false)) { + } + else + { + if (prefs.getBool("prev_configured", false)) + { wifiStatus = startWiFi(wifiRSSI); - } else { + } + else + { wifiStatus = startDefaultWiFi(wifiRSSI); } } - + + // All data should have been loaded from NVS. Close filesystem. prefs.end(); - if (wifiStatus != WL_CONNECTED) { // WiFi Connection Failed + if (wifiStatus != WL_CONNECTED) + { // WiFi Connection Failed killWiFi(); initDisplay(); - if (wifiStatus == WL_NO_SSID_AVAIL) { + if (wifiStatus == WL_NO_SSID_AVAIL) + { Serial.println("Network Not Available"); - do { + do + { drawError(wifi_x_196x196, "Network Not", "Available"); } while (display.nextPage()); - } else { + } + else + { Serial.println("WiFi Connection Failed"); - do { + do + { drawError(wifi_x_196x196, "WiFi Connection", "Failed"); } while (display.nextPage()); } display.powerOff(); beginDeepSleep(startTime, &timeInfo); - } + } // TIME SYNCHRONIZATION configTzTime(TIMEZONE, NTP_SERVER_1, NTP_SERVER_2); bool timeConfigured = waitForSNTPSync(&timeInfo); - if (!timeConfigured) { // Failed To Fetch The Time + if (!timeConfigured) + { // Failed To Fetch The Time Serial.println("Time Synchronization Failed"); killWiFi(); initDisplay(); - do { + do + { drawError(wi_time_4_196x196, "Time Synchronization", "Failed"); } while (display.nextPage()); display.powerOff(); @@ -252,24 +288,28 @@ void setup() { client.setCACert(cert_Sectigo_RSA_Domain_Validation_Secure_Server_CA); #endif int rxStatus = getOWMonecall(client, owm_onecall); - if (rxStatus != HTTP_CODE_OK) { + if (rxStatus != HTTP_CODE_OK) + { killWiFi(); statusStr = "One Call " + OWM_ONECALL_VERSION + " API"; tmpStr = String(rxStatus, DEC) + ": " + getHttpResponsePhrase(rxStatus); initDisplay(); - do { + do + { drawError(wi_cloud_down_196x196, statusStr, tmpStr); } while (display.nextPage()); display.powerOff(); beginDeepSleep(startTime, &timeInfo); } rxStatus = getOWMairpollution(client, owm_air_pollution); - if (rxStatus != HTTP_CODE_OK) { + if (rxStatus != HTTP_CODE_OK) + { killWiFi(); statusStr = "Air Pollution API"; tmpStr = String(rxStatus, DEC) + ": " + getHttpResponsePhrase(rxStatus); initDisplay(); - do { + do + { drawError(wi_cloud_down_196x196, statusStr, tmpStr); } while (display.nextPage()); display.powerOff(); @@ -278,28 +318,35 @@ void setup() { killWiFi(); // WiFi no longer needed // GET INDOOR TEMPERATURE AND HUMIDITY, start BME280... - float inTemp = NAN; + float inTemp = NAN; float inHumidity = NAN; Serial.print("Reading from BME280... "); TwoWire I2C_bme = TwoWire(0); Adafruit_BME280 bme; I2C_bme.begin(PIN_BME_SDA, PIN_BME_SCL, 100000); // 100kHz - if (bme.begin(BME_ADDRESS, &I2C_bme)) { - inTemp = bme.readTemperature(); // Celsius - inHumidity = bme.readHumidity(); // % + if(bme.begin(BME_ADDRESS, &I2C_bme)) + { + inTemp = bme.readTemperature(); // Celsius + inHumidity = bme.readHumidity(); // % // check if BME readings are valid // note: readings are checked again before drawing to screen. If a reading // is not a number (NAN) then an error occurred, a dash '-' will be // displayed. - if (std::isnan(inTemp) || std::isnan(inHumidity)) { + if (std::isnan(inTemp) || std::isnan(inHumidity)) + { statusStr = "BME read failed"; Serial.println(statusStr); - } else { + } + else + { + inTemp = inTemp - 7.25; Serial.println("Success"); } - } else { + } + else + { statusStr = "BME not found"; // check wiring Serial.println(statusStr); } @@ -311,7 +358,8 @@ void setup() { // RENDER FULL REFRESH initDisplay(); - do { + do + { drawCurrentConditions(owm_onecall.current, owm_onecall.daily[0], owm_air_pollution, inTemp, inHumidity); drawForecast(owm_onecall.daily, timeInfo); @@ -330,4 +378,7 @@ void setup() { /* This will never run */ -void loop() {} // end loop +void loop() +{ +} // end loop + From 87fab081a337505208e73c5da48c0416ff705157 Mon Sep 17 00:00:00 2001 From: jfujitani Date: Sat, 13 Apr 2024 16:11:43 -0700 Subject: [PATCH 11/12] remove inTemp offset --- platformio/src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/platformio/src/main.cpp b/platformio/src/main.cpp index 26f9cc665..5031efd34 100644 --- a/platformio/src/main.cpp +++ b/platformio/src/main.cpp @@ -341,7 +341,6 @@ void setup() } else { - inTemp = inTemp - 7.25; Serial.println(TXT_SUCCESS); } } From de76df3371abc2de60101a299616cda4d0aaef99 Mon Sep 17 00:00:00 2001 From: John Fujitani Date: Sat, 8 Mar 2025 13:01:22 -0800 Subject: [PATCH 12/12] fix README --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index d318e3211..bef9f204b 100644 --- a/README.md +++ b/README.md @@ -238,16 +238,13 @@ PlatformIO for VSCode is used for managing dependencies, code compilation, and u - If using a FireBeetle 2 ESP32-E and you receive the error `Wrong boot mode detected (0x13)! The chip needs to be in download mode.` unplug the power from the board, connect GPIO0 ([labeled 0/D5](https://wiki.dfrobot.com/FireBeetle_Board_ESP32_E_SKU_DFR0654#target_5)) to GND, and power it back up to put the board in download mode. -<<<<<<< HEAD 7. Boot options. - To support a change in WiFi networks without requiring a change in code and re-upload, [WiFi Manager](https://github.com/tzapu/WiFiManager) has been integrated. To use this feature, pull HW pin 27 `PIN_CONFIGURE_WIFI` down and press and release the reset button. This will cause the weather station to create an ad-hoc wifi network named "Weather_Station" `WIFI_AP_SSID`. Connect to this network to configure the WiFi network. Visit the WiFi Manger site for further details. > **Note** > Each time you reset using this method the previously configured WiFi network will be lost. After you perform this reset the compiled defaults can still be used by performing a normal reset without connecting to the ad-hoc network and configuring the WiFi. -======= - - If you are getting other errors during the upload process, you may need to install drivers to allow you to upload code to the ESP32. ->>>>>>> main + - If you are getting other errors during the upload process, you may need to install drivers to allow you to upload code to the ESP32. ### OpenWeatherMap API Key Sign up here to get an API key; it's free.