diff --git a/README.md b/README.md
index 930a7f998..b8ffb4785 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,6 @@ Here are two (slightly outdated) examples utilizing various configuration option
- [Time Server Error](#time-server-error)
- [Licensing](#licensing)
-
## Required Components
Some links below are affiliate links. Using them helps support the project at no extra cost to you—thanks for your support!
@@ -61,6 +60,7 @@ Here are two (slightly outdated) examples utilizing various configuration option
| Enclosure | See [Enclosure Options](#enclosure-options). | See [Enclosure Options](#enclosure-options). | See [Enclosure Options](#enclosure-options). |
Other items needed:
+
- Wires ("Jumper Wires" if looking to minimize/avoid soldering).
- Solder Iron + Solder (unless following [Solder-Free Component Selection](#solder-free-component-selection-optional)).
- Linux, Windows, or MacOS computer (used to configure and install ESP32 firmware).
@@ -68,7 +68,7 @@ Other items needed:
### Panel Support
- Waveshare and Good Display make equivalent panels. Either variant will work.
+Waveshare and Good Display make equivalent panels. Either variant will work.
| Panel | Resolution | Colors | Notes |
|-----------------------------------------|------------|-----------------|-----------------------------------------------------------------------------------------------------------------------|
@@ -81,7 +81,7 @@ Other items needed:
| Waveshare 7.5in e-paper (v1) | 640x384px | Black/White | Limited support. Some information not displayed, see [image](showcase/demo-waveshare75-version1.jpg). |
| Good Display 7.5in e-paper (GDEW075T8) | 640x384px | Black/White | Limited support. Some information not displayed, see [image](showcase/demo-waveshare75-version1.jpg). |
- This software has limited support for accent colors. E-paper panels with additional colors tend to have longer refresh times, which will reduce battery life.
+This software has limited support for accent colors. E-paper panels with additional colors tend to have longer refresh times, which will reduce battery life.
### Enclosure Options
@@ -96,10 +96,11 @@ You'll want a nice way to show off your project. Here are a few popular choices.
screen angle = 80deg
screen is 15mm from the front
- 3D Printable
+
- Here is a list of community designs.
-
+
| Contributor | Link |
- |----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------|
+ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [Kingfisher](https://www.printables.com/@Kingfisher_32821) | [Printables](https://www.printables.com/model/1139047-weather-station-e-ink-frame) |
| [Francois Allard](https://www.printables.com/@FrAllard_1585397) | [Printables](https://www.printables.com/model/791477-weather-station-using-a-esp32) |
| [3D Nate](https://www.printables.com/@3DNate_451157) | [Printables](https://www.printables.com/model/661183-e-ink-weather-station-frame) |
@@ -111,25 +112,26 @@ You'll want a nice way to show off your project. Here are a few popular choices.
| [Plaste-Metz](https://www.printables.com/@PlasteMetz_576567) | [Printables](https://www.printables.com/model/1160924-weather-station-case) |
- If you want to share your own 3D printable designs, your contributions are highly encouraged and welcome!
+
- Picture Frame
### Solder-Free Component Selection (Optional)
This project can be completed without any soldering, if you choose your component selection carefully.
+
- Buy "Jumper Wires" to connect your components.
- Buy the [FireBeetle 2 ESP32-E w/ Headers](https://www.dfrobot.com/product-2231.html?tracking=PfSxQ8).
- Buy a BME280 with headers soldered from the factory.
- Buy a reset switch that is compatible with jumper wires.
-
## Setup Guide
### Wiring
The battery can be charged by plugging the FireBeetle ESP32 into the wall via the USB-C connector while the battery is plugged into the ESP32's JST connector.
- > **Warning**
- > The polarity of JST-PH2.0 connectors is not standardized! You may need to swap the order of the wires in the connector.
+> **Warning**
+> The polarity of JST-PH2.0 connectors is not standardized! You may need to swap the order of the wires in the connector.
NOTE: Waveshare now ships revision 2.3 of their e-paper HAT (no longer rev 2.2 ). Rev 2.3 has an additional `PWR` pin (not depicted in the wiring diagrams below); connect this pin to 3.3V.
@@ -151,7 +153,6 @@ Cut the low power pad for even longer battery life.

-
### Configuration, Compilation, and Upload
PlatformIO for VSCode is used for managing dependencies, code compilation, and uploading to ESP32.
@@ -170,12 +171,11 @@ PlatformIO for VSCode is used for managing dependencies, code compilation, and u
5. Configure Options.
- - Most configuration options are located in [config.cpp](platformio/src/config.cpp), with a few in [config.h](platformio/include/config.h).
+ - Most configuration options are located in [config.cpp](platformio/src/config.cpp), with a few in [config.h](platformio/include/config.h).
- 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.
@@ -196,13 +196,20 @@ PlatformIO for VSCode is used for managing dependencies, code compilation, and u
b. Click the upload arrow along the bottom of the VSCode window. (Should say "PlatformIO: Upload" if you hover over it.)
- - PlatformIO will automatically download the required third-party libraries, compile, and upload the code. :)
+ - PlatformIO will automatically download the required third-party libraries, compile, and upload the code. :)
- - You will only see this if you have the PlatformIO extension installed.
+ - You will only see this if you have the PlatformIO extension installed.
- - 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.
+ - 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.
- - 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.
+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.
### OpenWeatherMap API Key
@@ -213,25 +220,29 @@ This project will make calls to 2 different APIs ("One Call" and "Air Pollution"
- The One Call API 3.0 is only included in the "One Call by Call" subscription. This separate subscription includes 1,000 calls/day for free and allows you to pay only for the number of API calls made to this product.
Here's how to subscribe and avoid any credit card changes:
- - Go to
- - Follow the instructions to complete the subscription.
- - Go to and set the "Calls per day (no more than)" to 1,000. This ensures you will never overrun the free calls.
+
+- Go to
+- Follow the instructions to complete the subscription.
+- Go to and set the "Calls per day (no more than)" to 1,000. This ensures you will never overrun the free calls.
## Error Messages and Troubleshooting
### Low Battery
+
This error screen appears once the battery voltage has fallen below LOW_BATTERY_VOLTAGE (default = 3.20v). The display will not refresh again until it detects battery voltage above LOW_BATTERY_VOLTAGE. When battery voltage is between LOW_BATTERY_VOLTAGE and VERY_LOW_BATTERY_VOLTAGE (default = 3.10v) the esp32 will deep-sleep for periods of LOW_BATTERY_SLEEP_INTERVAL (default = 30min) before checking battery voltage again. If the battery voltage falls between LOW_BATTERY_SLEEP_INTERVAL and CRIT_LOW_BATTERY_VOLTAGE (default = 3.00v), then the display will deep-sleep for periods VERY_LOW_BATTERY_SLEEP_INTERVAL (default = 120min). If battery voltage falls below CRIT_LOW_BATTERY_VOLTAGE, then the esp32 will enter hibernate mode and will require a manual push of the reset (RST) button to begin updating again.
### WiFi Connection
+
This error screen appears when the ESP32 fails to connect to WiFi. If the message reads "WiFi Connection Failed" this might indicate an incorrect password. If the message reads "SSID Not Available" this might indicate that you mistyped the SSID or that the esp32 is out of the range of the access point. The esp32 will retry once every SLEEP_DURATION (default = 30min).
### API Error
+
This error screen appears if an error (client or server) occurs when making an API request to OpenWeatherMap. The second line will give the error code followed by a descriptor phrase. Positive error codes correspond to HTTP response status codes, while error codes <= 0 indicate a client(esp32) error. The esp32 will retry once every SLEEP_DURATION (default = 30min).
@@ -240,6 +251,7 @@ In the example shown to the left, "401: Unauthorized" may be the result of an in
### Time Server Error
+
This error screen appears when the esp32 fails to fetch the time from NTP_SERVER_1/NTP_SERVER_2. This error sometimes occurs immediately after uploading to the esp32; in this case, just hit the reset button or wait for SLEEP_DURATION (default = 30min) and the esp32 to automatically retry. If the error persists, try selecting closer/lower latency time servers or increasing NTP_TIMEOUT.
@@ -249,27 +261,26 @@ This error screen appears when the esp32 fails to fetch the time from NTP_SERVER
esp32-weather-epd is licensed under the [GNU General Public License v3.0](LICENSE) with tools, fonts, and icons whose licenses are as follows:
-| Name | License | Description |
-|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|
-| [Adafruit-GFX-Library: fontconvert](https://github.com/adafruit/Adafruit-GFX-Library/tree/master/fontconvert) | [BSD License](fonts/fontconvert/license.txt) | CLI tool for preprocessing fonts to be used with the Adafruit_GFX Arduino library. |
-| [pollutant-concentration-to-aqi](https://github.com/lmarzen/pollutant-concentration-to-aqi) | [GNU Lesser General Public License v2.1](platformio/lib/pollutant-concentration-to-aqi/LICENSE) | C library that converts pollutant concentrations to Air Quality Index(AQI). |
-| [GNU FreeFont](https://www.gnu.org/software/freefont/) | [GNU General Public License v3.0](https://www.gnu.org/software/freefont/license.html) | Font Family |
-| [Lato](https://fonts.google.com/specimen/Lato) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
-| [Montserrat](https://fonts.google.com/specimen/Montserrat) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
-| [Open Sans](https://fonts.google.com/specimen/Open+Sans) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
-| [Poppins](https://fonts.google.com/specimen/Poppins) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
-| [Quicksand](https://fonts.google.com/specimen/Quicksand) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
-| [Raleway](https://fonts.google.com/specimen/Raleway) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
-| [Roboto](https://fonts.google.com/specimen/Roboto) | [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) | Font Family |
-| [Roboto Mono](https://fonts.google.com/specimen/Roboto+Mono) | [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) | Font Family |
-| [Roboto Slab](https://fonts.google.com/specimen/Roboto+Slab) | [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) | Font Family |
-| [Ubuntu font](https://design.ubuntu.com/font) | [Ubuntu Font Licence v1.0](https://ubuntu.com/legal/font-licence) | Font Family |
-| [Weather Themed Icons](https://github.com/erikflowers/weather-icons) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | (wi-**.svg) Weather icon family by Lukas Bischoff/Erik Flowers. |
-| [Google Icons](https://fonts.google.com/icons) | [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) | (battery**.svg, visibility_icon.svg) Battery and visibility icons from Google Icons. |
-| [Biological Hazard Symbol](https://svgsilh.com/image/37775.html) | [CC0 v1.0](https://en.wikipedia.org/wiki/Public_domain) | (biological_hazard_symbol.svg) Biohazard icon. |
-| [House Icon](https://seekicon.com/free-icon/house_16) | [MIT License](http://opensource.org/licenses/mit-license.html) | (house.svg) House icon. |
-| [Indoor Temerature/Humidity Icons](icons/svg) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | (house_**.svg) Indoor temerature/humidity icons. |
-| [Ionizing Radiation Symbol](https://svgsilh.com/image/309911.html) | [CC0 v1.0](https://creativecommons.org/publicdomain/zero/1.0/) | (ionizing_radiation_symbol.svg) Ionizing radiation icons. |
-| [Phosphor Icons](https://github.com/phosphor-icons/homepage) | [MIT License](http://opensource.org/licenses/mit-license.html) | (wifi**.svg, warning_icon.svg, error_icon.svg) WiFi, Warning, and Error icons from Phosphor Icons. |
-| [Wind Direction Icon](https://www.onlinewebfonts.com/icon/251550) | [CC BY v3.0](http://creativecommons.org/licenses/by/3.0) | (meteorological_wind_direction_**deg.svg) Meteorological wind direction icon from Online Web Fonts. |
-
+| Name | License | Description |
+| ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
+| [Adafruit-GFX-Library: fontconvert](https://github.com/adafruit/Adafruit-GFX-Library/tree/master/fontconvert) | [BSD License](fonts/fontconvert/license.txt) | CLI tool for preprocessing fonts to be used with the Adafruit_GFX Arduino library. |
+| [pollutant-concentration-to-aqi](https://github.com/lmarzen/pollutant-concentration-to-aqi) | [GNU Lesser General Public License v2.1](platformio/lib/pollutant-concentration-to-aqi/LICENSE) | C library that converts pollutant concentrations to Air Quality Index(AQI). |
+| [GNU FreeFont](https://www.gnu.org/software/freefont/) | [GNU General Public License v3.0](https://www.gnu.org/software/freefont/license.html) | Font Family |
+| [Lato](https://fonts.google.com/specimen/Lato) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
+| [Montserrat](https://fonts.google.com/specimen/Montserrat) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
+| [Open Sans](https://fonts.google.com/specimen/Open+Sans) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
+| [Poppins](https://fonts.google.com/specimen/Poppins) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
+| [Quicksand](https://fonts.google.com/specimen/Quicksand) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
+| [Raleway](https://fonts.google.com/specimen/Raleway) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | Font Family |
+| [Roboto](https://fonts.google.com/specimen/Roboto) | [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) | Font Family |
+| [Roboto Mono](https://fonts.google.com/specimen/Roboto+Mono) | [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) | Font Family |
+| [Roboto Slab](https://fonts.google.com/specimen/Roboto+Slab) | [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) | Font Family |
+| [Ubuntu font](https://design.ubuntu.com/font) | [Ubuntu Font Licence v1.0](https://ubuntu.com/legal/font-licence) | Font Family |
+| [Weather Themed Icons](https://github.com/erikflowers/weather-icons) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | (wi-\*\*.svg) Weather icon family by Lukas Bischoff/Erik Flowers. |
+| [Google Icons](https://fonts.google.com/icons) | [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) | (battery\*\*.svg, visibility_icon.svg) Battery and visibility icons from Google Icons. |
+| [Biological Hazard Symbol](https://svgsilh.com/image/37775.html) | [CC0 v1.0](https://en.wikipedia.org/wiki/Public_domain) | (biological_hazard_symbol.svg) Biohazard icon. |
+| [House Icon](https://seekicon.com/free-icon/house_16) | [MIT License](http://opensource.org/licenses/mit-license.html) | (house.svg) House icon. |
+| [Indoor Temerature/Humidity Icons](icons/svg) | [SIL OFL v1.1](http://scripts.sil.org/OFL) | (house\_\*\*.svg) Indoor temerature/humidity icons. |
+| [Ionizing Radiation Symbol](https://svgsilh.com/image/309911.html) | [CC0 v1.0](https://creativecommons.org/publicdomain/zero/1.0/) | (ionizing_radiation_symbol.svg) Ionizing radiation icons. |
+| [Phosphor Icons](https://github.com/phosphor-icons/homepage) | [MIT License](http://opensource.org/licenses/mit-license.html) | (wifi\*\*.svg, warning_icon.svg, error_icon.svg) WiFi, Warning, and Error icons from Phosphor Icons. |
+| [Wind Direction Icon](https://www.onlinewebfonts.com/icon/251550) | [CC BY v3.0](http://creativecommons.org/licenses/by/3.0) | (meteorological*wind_direction*\*\*deg.svg) Meteorological wind direction icon from Online Web Fonts. |
diff --git a/platformio/include/client_utils.h b/platformio/include/client_utils.h
index 6b84689e8..1a04d0de1 100644
--- a/platformio/include/client_utils.h
+++ b/platformio/include/client_utils.h
@@ -28,6 +28,8 @@
#endif
wl_status_t startWiFi(int &wifiRSSI);
+wl_status_t startDefaultWiFi(int &wifiRSSI);
+wl_status_t configureWiFi(int &wifiRSSI);
void killWiFi();
bool waitForSNTPSync(tm *timeInfo);
bool printLocalTime(tm *timeInfo);
diff --git a/platformio/include/config.h b/platformio/include/config.h
index a8e46c9bb..7bb9cd121 100644
--- a/platformio/include/config.h
+++ b/platformio/include/config.h
@@ -284,8 +284,10 @@ extern const uint8_t PIN_BME_SDA;
extern const uint8_t PIN_BME_SCL;
extern const uint8_t PIN_BME_PWR;
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 unsigned long WIFI_TIMEOUT;
extern const unsigned HTTP_CLIENT_TCP_TIMEOUT;
extern const String OWM_APIKEY;
diff --git a/platformio/platformio.ini b/platformio/platformio.ini
index ddd4d64d6..77a602af9 100644
--- a/platformio/platformio.ini
+++ b/platformio/platformio.ini
@@ -27,7 +27,10 @@ lib_deps =
adafruit/Adafruit Unified Sensor @ 1.1.15
bblanchon/ArduinoJson @ 7.3.1
zinggjm/GxEPD2 @ 1.6.2
-
+ ; 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.17
[env:dfrobot_firebeetle2_esp32e]
board = dfrobot_firebeetle2_esp32e
diff --git a/platformio/src/client_utils.cpp b/platformio/src/client_utils.cpp
index 36b5a6cbf..2bfe3034a 100644
--- a/platformio/src/client_utils.cpp
+++ b/platformio/src/client_utils.cpp
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
// additional libraries
#include
@@ -49,7 +50,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"
*
@@ -58,33 +59,94 @@
wl_status_t startWiFi(int &wifiRSSI)
{
WiFi.mode(WIFI_STA);
- Serial.printf("%s '%s'", TXT_CONNECTING_TO, WIFI_SSID);
- WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
- // timeout if WiFi does not connect in WIFI_TIMEOUT ms from now
- unsigned long timeout = millis() + WIFI_TIMEOUT;
- 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
+
+/* 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() + WIFI_TIMEOUT;
+ 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)
+ 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.
+ */
+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"
+ *
+ * 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);
+
+ // 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("%s '%s'\n", TXT_COULD_NOT_CONNECT_TO, 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 ded8ba79f..9b99a70f4 100644
--- a/platformio/src/config.cpp
+++ b/platformio/src/config.cpp
@@ -15,41 +15,46 @@
* along with this program. If not, see .
*/
-#include
#include "config.h"
+#include
// PINS
-// The configuration below is intended for use with the project's official
+// The configuration below is intended for use with the project's official
// wiring diagrams using the FireBeetle 2 ESP32-E microcontroller board.
//
// Note: LED_BUILTIN pin will be disabled to reduce power draw. Refer to your
-// board's pinout to ensure you avoid using a pin with this shared
+// board's pinout to ensure you avoid using a pin with this shared
// functionality.
//
// ADC pin used to measure battery voltage
-const uint8_t PIN_BAT_ADC = A2; // A0 for micro-usb firebeetle
+const uint8_t PIN_BAT_ADC = A2; // A0 for micro-usb firebeetle
// Pins for E-Paper Driver Board
const uint8_t PIN_EPD_BUSY = 14; // 5 for micro-usb firebeetle
-const uint8_t PIN_EPD_CS = 13;
-const uint8_t PIN_EPD_RST = 21;
-const uint8_t PIN_EPD_DC = 22;
-const uint8_t PIN_EPD_SCK = 18;
-const uint8_t PIN_EPD_MISO = 19; // 19 Master-In Slave-Out not used, as no data from display
+const uint8_t PIN_EPD_CS = 13;
+const uint8_t PIN_EPD_RST = 21;
+const uint8_t PIN_EPD_DC = 22;
+const uint8_t PIN_EPD_SCK = 18;
+const uint8_t PIN_EPD_MISO =
+ 19; // 19 Master-In Slave-Out not used, as no data from display
const uint8_t PIN_EPD_MOSI = 23;
-const uint8_t PIN_EPD_PWR = 26; // Irrelevant if directly connected to 3.3V
+const uint8_t PIN_EPD_PWR = 26; // Irrelevant if directly connected to 3.3V
// I2C Pins used for BME280
const uint8_t PIN_BME_SDA = 17;
const uint8_t PIN_BME_SCL = 16;
-const uint8_t PIN_BME_PWR = 4; // Irrelevant if directly connected to 3.3V
+const uint8_t PIN_BME_PWR = 4; // Irrelevant if directly connected to 3.3V
const uint8_t BME_ADDRESS = 0x76; // 0x76 if SDO -> GND; 0x77 if SDO -> VCC
// WIFI
-const char *WIFI_SSID = "ssid";
+const char *WIFI_SSID = "ssid";
const char *WIFI_PASSWORD = "password";
const unsigned long WIFI_TIMEOUT = 10000; // ms, WiFi connection timeout.
+// 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";
// HTTP
-// The following errors are likely the result of insuffient http client tcp
+// The following errors are likely the result of insuffient http client tcp
// timeout:
// -1 Connection Refused
// -11 Read Timeout
@@ -58,7 +63,7 @@ const unsigned HTTP_CLIENT_TCP_TIMEOUT = 10000; // ms
// OPENWEATHERMAP API
// OpenWeatherMap API key, https://openweathermap.org/
-const String OWM_APIKEY = "abcdefghijklmnopqrstuvwxyz012345";
+const String OWM_APIKEY = "abcdefghijklmnopqrstuvwxyz012345";
const String OWM_ENDPOINT = "api.openweathermap.org";
// OpenWeatherMap One Call 2.5 API is deprecated for all new free users
// (accounts created after Summer 2022).
@@ -69,7 +74,8 @@ const String OWM_ENDPOINT = "api.openweathermap.org";
// product.
//
// Here’s how to subscribe and avoid any credit card changes:
-// - Go to https://home.openweathermap.org/subscriptions/billing_info/onecall_30/base?key=base&service=onecall_30
+// - Go to
+// https://home.openweathermap.org/subscriptions/billing_info/onecall_30/base?key=base&service=onecall_30
// - Follow the instructions to complete the subscription.
// - Go to https://home.openweathermap.org/subscriptions and set the "Calls per
// day (no more than)" to 1,000. This ensures you will never overrun the free
@@ -92,12 +98,12 @@ const char *TIMEZONE = "EST5EDT,M3.2.0,M11.1.0";
// For more information about formatting see
// https://man7.org/linux/man-pages/man3/strftime.3.html
// const char *TIME_FORMAT = "%l:%M%P"; // 12-hour ex: 1:23am 11:00pm
-const char *TIME_FORMAT = "%H:%M"; // 24-hour ex: 01:23 23:00
+const char *TIME_FORMAT = "%H:%M"; // 24-hour ex: 01:23 23:00
// Time format used when displaying axis labels. (Max 11 characters)
// For more information about formatting see
// https://man7.org/linux/man-pages/man3/strftime.3.html
// const char *HOUR_FORMAT = "%l%P"; // 12-hour ex: 1am 11pm
-const char *HOUR_FORMAT = "%H"; // 24-hour ex: 01 23
+const char *HOUR_FORMAT = "%H"; // 24-hour ex: 01 23
// Date format used when displaying date in top-right corner.
// For more information about formatting see
// https://man7.org/linux/man-pages/man3/strftime.3.html
@@ -124,7 +130,7 @@ const int SLEEP_DURATION = 30; // minutes
// Bed Time Power Savings.
// If BED_TIME == WAKE_TIME, then this battery saving feature will be disabled.
// (range: [0-23])
-const int BED_TIME = 00; // Last update at 00:00 (midnight) until WAKE_TIME.
+const int BED_TIME = 00; // Last update at 00:00 (midnight) until WAKE_TIME.
const int WAKE_TIME = 06; // Hour of first update after BED_TIME, 06:00.
// Note that the minute alignment of SLEEP_DURATION begins at WAKE_TIME even if
// Bed Time Power Savings is disabled.
@@ -145,11 +151,11 @@ const int HOURLY_GRAPH_MAX = 24;
// minutes). Once the battery voltage has fallen to CRIT_LOW_BATTERY_VOLTAGE,
// the esp32 will hibernate and a manual press of the reset (RST) button to
// begin operating again.
-const uint32_t WARN_BATTERY_VOLTAGE = 3535; // (millivolts) ~20%
-const uint32_t LOW_BATTERY_VOLTAGE = 3462; // (millivolts) ~10%
-const uint32_t VERY_LOW_BATTERY_VOLTAGE = 3442; // (millivolts) ~8%
-const uint32_t CRIT_LOW_BATTERY_VOLTAGE = 3404; // (millivolts) ~5%
-const unsigned long LOW_BATTERY_SLEEP_INTERVAL = 30; // (minutes)
+const uint32_t WARN_BATTERY_VOLTAGE = 3535; // (millivolts) ~20%
+const uint32_t LOW_BATTERY_VOLTAGE = 3462; // (millivolts) ~10%
+const uint32_t VERY_LOW_BATTERY_VOLTAGE = 3442; // (millivolts) ~8%
+const uint32_t CRIT_LOW_BATTERY_VOLTAGE = 3404; // (millivolts) ~5%
+const unsigned long LOW_BATTERY_SLEEP_INTERVAL = 30; // (minutes)
const unsigned long VERY_LOW_BATTERY_SLEEP_INTERVAL = 120; // (minutes)
// Battery voltage calculations are based on a typical 3.7v LiPo.
const uint32_t MAX_BATTERY_VOLTAGE = 4200; // (millivolts)
@@ -163,4 +169,3 @@ const uint32_t MIN_BATTERY_VOLTAGE = 3000; // (millivolts)
// FONTS
// ALERTS
// BATTERY MONITORING
-
diff --git a/platformio/src/main.cpp b/platformio/src/main.cpp
index ec74ebc80..2d7a7ef4e 100644
--- a/platformio/src/main.cpp
+++ b/platformio/src/main.cpp
@@ -199,16 +199,48 @@ void setup()
uint32_t batteryVoltage = UINT32_MAX;
#endif
- // All data should have been loaded from NVS. Close filesystem.
- prefs.end();
-
String statusStr = {};
String tmpStr = {};
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)
+ {
+ prefs.putBool("prev_configured", false);
+ Serial.println("WIFI config pin detected");
+ initDisplay();
+ 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);
+ }
+ }
+ else
+ {
+ if (prefs.getBool("prev_configured", false))
+ {
+ wifiStatus = startWiFi(wifiRSSI);
+ }
+ else
+ {
+ wifiStatus = startDefaultWiFi(wifiRSSI);
+ }
+ }
+
+
+ // All data should have been loaded from NVS. Close filesystem.
+ prefs.end();
+
if (wifiStatus != WL_CONNECTED)
{ // WiFi Connection Failed
killWiFi();
@@ -231,7 +263,7 @@ void setup()
}
powerOffDisplay();
beginDeepSleep(startTime, &timeInfo);
- }
+ }
// TIME SYNCHRONIZATION
configTzTime(TIMEZONE, NTP_SERVER_1, NTP_SERVER_2);