diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 702708c8..b9243d3d 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -428,16 +428,14 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const auto gpsFormat = radioConfig.preferences.gps_format; String displayLine = ""; - if (radioConfig.preferences.fixed_position) { - displayLine = "Fixed GPS"; - display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine); - } else if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) { + if (!gps->getIsConnected() && !radioConfig.preferences.fixed_position) { displayLine = "No GPS Module"; display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine); } else if (!gps->getHasLock() && !radioConfig.preferences.fixed_position) { displayLine = "No GPS Lock"; display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(displayLine))) / 2, y, displayLine); } else { + if (gpsFormat != GpsCoordinateFormat_GpsFormatDMS) { char coordinateLine[22]; geoCoord.updateCoords(int32_t(gps->getLatitude()), int32_t(gps->getLongitude()), int32_t(gps->getAltitude())); @@ -459,7 +457,17 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const geoCoord.getOSGREasting(), geoCoord.getOSGRNorthing()); } - display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine); + // If fixed position, display text "Fixed GPS" alternating with the coordinates. + if (radioConfig.preferences.fixed_position) { + if ((millis() / 10000) % 2) { + display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine); + } else { + display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth("Fixed GPS"))) / 2, y, "Fixed GPS"); + } + } else { + display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine); + } + } else { char latLine[22]; char lonLine[22]; @@ -1196,7 +1204,7 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) { display->drawString(x, y + FONT_HEIGHT_SMALL * 1, "IP: " + String(WiFi.softAPIP().toString().c_str())); - // Number of connections to the AP. Default mmax for the esp32 is 4 + // Number of connections to the AP. Default max for the esp32 is 4 display->drawString(x + SCREEN_WIDTH - display->getStringWidth("(" + String(WiFi.softAPgetStationNum()) + "/4)"), y + FONT_HEIGHT_SMALL * 1, "(" + String(WiFi.softAPgetStationNum()) + "/4)"); } else { diff --git a/src/main.cpp b/src/main.cpp index eafd1956..41d504e4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -282,6 +282,8 @@ class ButtonThread : public OSThread { #ifndef NO_ESP32 disablePin(); +#elif defined(HAS_EINK) + digitalWrite(PIN_EINK_EN,digitalRead(PIN_EINK_EN) == LOW); #endif } @@ -606,6 +608,7 @@ void setup() ) * 1000; DEBUG_MSG("myNodeInfo.bitrate = %f bytes / sec\n", myNodeInfo.bitrate); + // This must be _after_ service.init because we need our preferences loaded from flash to have proper timeout values PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS powerFSMthread = new PowerFSMThread(); diff --git a/src/mesh/generated/radioconfig.pb.h b/src/mesh/generated/radioconfig.pb.h index 8fb70d39..f1ce58de 100644 --- a/src/mesh/generated/radioconfig.pb.h +++ b/src/mesh/generated/radioconfig.pb.h @@ -153,6 +153,8 @@ typedef struct _RadioConfig_UserPreferences { uint32_t auto_screen_carousel_secs; uint32_t on_battery_shutdown_after_secs; uint32_t hop_limit; + char mqtt_username[32]; + char mqtt_password[32]; } RadioConfig_UserPreferences; typedef struct _RadioConfig { @@ -197,9 +199,9 @@ extern "C" { /* Initializer values for message structs */ #define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default} -#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0} +#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", ""} #define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero} -#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0} +#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, 0, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, "", 0, _GpsCoordinateFormat_MIN, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _RadioConfig_UserPreferences_EnvironmentalMeasurementSensorType_MIN, 0, 0, 0, 0, 0, 0, 0, 0, "", ""} /* Field tags (for use in manual encoding/decoding) */ #define RadioConfig_UserPreferences_position_broadcast_secs_tag 1 @@ -268,6 +270,8 @@ extern "C" { #define RadioConfig_UserPreferences_auto_screen_carousel_secs_tag 152 #define RadioConfig_UserPreferences_on_battery_shutdown_after_secs_tag 153 #define RadioConfig_UserPreferences_hop_limit_tag 154 +#define RadioConfig_UserPreferences_mqtt_username_tag 155 +#define RadioConfig_UserPreferences_mqtt_password_tag 156 #define RadioConfig_preferences_tag 1 /* Struct field encoding specification for nanopb */ @@ -343,7 +347,9 @@ X(a, STATIC, SINGULAR, UINT32, position_flags, 150) \ X(a, STATIC, SINGULAR, BOOL, is_always_powered, 151) \ X(a, STATIC, SINGULAR, UINT32, auto_screen_carousel_secs, 152) \ X(a, STATIC, SINGULAR, UINT32, on_battery_shutdown_after_secs, 153) \ -X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) +X(a, STATIC, SINGULAR, UINT32, hop_limit, 154) \ +X(a, STATIC, SINGULAR, STRING, mqtt_username, 155) \ +X(a, STATIC, SINGULAR, STRING, mqtt_password, 156) #define RadioConfig_UserPreferences_CALLBACK NULL #define RadioConfig_UserPreferences_DEFAULT NULL @@ -355,8 +361,8 @@ extern const pb_msgdesc_t RadioConfig_UserPreferences_msg; #define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg /* Maximum encoded size of messages (where known) */ -#define RadioConfig_size 458 -#define RadioConfig_UserPreferences_size 455 +#define RadioConfig_size 526 +#define RadioConfig_UserPreferences_size 523 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index 1004e755..5f9ef803 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -53,19 +53,6 @@ char contentTypes[][2][32] = {{".txt", "text/plain"}, {".html", "text/html"} // Our API to handle messages to and from the radio. HttpAPI webAPI; -uint32_t numberOfRequests = 0; -uint32_t timeSpeedUp = 0; - -uint32_t getTimeSpeedUp() -{ - return timeSpeedUp; -} - -void setTimeSpeedUp() -{ - timeSpeedUp = millis(); -} - void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) { @@ -105,8 +92,6 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) secureServer->registerNode(nodeJsonReport); secureServer->registerNode(nodeRoot); - secureServer->addMiddleware(&middlewareSpeedUp240); - // Insecure nodes insecureServer->registerNode(nodeAPIv1ToRadioOptions); insecureServer->registerNode(nodeAPIv1ToRadio); @@ -122,42 +107,6 @@ void registerHandlers(HTTPServer *insecureServer, HTTPSServer *secureServer) insecureServer->registerNode(nodeJsonReport); insecureServer->registerNode(nodeRoot); - insecureServer->addMiddleware(&middlewareSpeedUp160); -} - -void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function next) -{ - // We want to print the response status, so we need to call next() first. - next(); - - // Phone (or other device) has contacted us over WiFi. Keep the radio turned on. - // TODO: This should go into its own middleware layer separate from the speedup. - powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); - - setCpuFrequencyMhz(240); - setTimeSpeedUp(); - - numberOfRequests++; -} - -void middlewareSpeedUp160(HTTPRequest *req, HTTPResponse *res, std::function next) -{ - // We want to print the response status, so we need to call next() first. - next(); - - // Phone (or other device) has contacted us over WiFi. Keep the radio turned on. - // TODO: This should go into its own middleware layer separate from the speedup. - powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); - - // If the frequency is 240mhz, we have recently gotten a HTTPS request. - // In that case, leave the frequency where it is and just update the - // countdown timer (timeSpeedUp). - if (getCpuFrequencyMhz() != 240) { - setCpuFrequencyMhz(160); - } - setTimeSpeedUp(); - - numberOfRequests++; } void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res) @@ -403,10 +352,6 @@ void handleFormUpload(HTTPRequest *req, HTTPResponse *res) DEBUG_MSG("Form Upload - Disabling keep-alive\n"); res->setHeader("Connection", "close"); - DEBUG_MSG("Form Upload - Set frequency to 240mhz\n"); - // The upload process is very CPU intensive. Let's speed things up a bit. - setCpuFrequencyMhz(240); - // First, we need to check the encoding of the form that we have received. // The browser will set the Content-Type request header, so we can use it for that purpose. // Then we select the body parser based on the encoding. @@ -605,7 +550,6 @@ void handleReport(HTTPRequest *req, HTTPResponse *res) res->println("\"wifi\": {"); - res->printf("\"web_request_count\": %d,\n", numberOfRequests); res->println("\"rssi\": " + String(WiFi.RSSI()) + ","); if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) { @@ -736,15 +680,11 @@ void handleScanNetworks(HTTPRequest *req, HTTPResponse *res) for (int i = 0; i < n; ++i) { char ssidArray[50]; String ssidString = String(WiFi.SSID(i)); - // String ssidString = String(WiFi.SSID(i)).toCharArray(ssidArray, WiFi.SSID(i).length()); ssidString.replace("\"", "\\\""); ssidString.toCharArray(ssidArray, 50); if (WiFi.encryptionType(i) != WIFI_AUTH_OPEN) { - // res->println("{\"ssid\": \"%s\",\"rssi\": -75}, ", String(WiFi.SSID(i).c_str() ); - res->printf("{\"ssid\": \"%s\",\"rssi\": %d}", ssidArray, WiFi.RSSI(i)); - // WiFi.RSSI(i) if (i != n - 1) { res->printf(","); } diff --git a/src/mesh/http/ContentHandler.h b/src/mesh/http/ContentHandler.h index 779058d6..cc07cb83 100644 --- a/src/mesh/http/ContentHandler.h +++ b/src/mesh/http/ContentHandler.h @@ -18,10 +18,6 @@ void handleReport(HTTPRequest *req, HTTPResponse *res); void middlewareSpeedUp240(HTTPRequest *req, HTTPResponse *res, std::function next); void middlewareSpeedUp160(HTTPRequest *req, HTTPResponse *res, std::function next); -uint32_t getTimeSpeedUp(); -void setTimeSpeedUp(); - - // Interface to the PhoneAPI to access the protobufs with messages class HttpAPI : public PhoneAPI { diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp index d073c16a..500af510 100644 --- a/src/mesh/http/WebServer.cpp +++ b/src/mesh/http/WebServer.cpp @@ -63,16 +63,7 @@ static void handleWebResponse() if(secureServer) secureServer->loop(); insecureServer->loop(); - } - /* - Slow down the CPU if we have not received a request within the last few - seconds. - */ - - if (millis() - getTimeSpeedUp() >= (25 * 1000)) { - setCpuFrequencyMhz(80); - setTimeSpeedUp(); } } } @@ -112,8 +103,6 @@ static void taskCreateCert(void *parameter) } else { - setCPUFast(true); - DEBUG_MSG("Creating the certificate. This may take a while. Please wait...\n"); yield(); cert = new SSLCert(); @@ -145,9 +134,6 @@ static void taskCreateCert(void *parameter) prefs.putBytes("PK", (uint8_t *)cert->getPKData(), cert->getPKLength()); prefs.putBytes("cert", (uint8_t *)cert->getCertData(), cert->getCertLength()); } - - setCPUFast(false); - } isCertReady = true; diff --git a/src/mesh/http/WiFiAPClient.cpp b/src/mesh/http/WiFiAPClient.cpp index 9967c67b..91892b5d 100644 --- a/src/mesh/http/WiFiAPClient.cpp +++ b/src/mesh/http/WiFiAPClient.cpp @@ -103,6 +103,8 @@ void deinitWifi() saving on the 2.4g transceiver. */ + DEBUG_MSG("WiFi deinit\n"); + if (isWifiAvailable()) { WiFi.mode(WIFI_MODE_NULL); DEBUG_MSG("WiFi Turned Off\n"); @@ -140,6 +142,14 @@ static void onNetworkConnected() // Startup WiFi bool initWifi(bool forceSoftAP) { + if (forceSoftAP) { + DEBUG_MSG("WiFi ... Forced AP Mode\n"); + } else if (radioConfig.preferences.wifi_ap_mode) { + DEBUG_MSG("WiFi ... AP Mode\n"); + } else { + DEBUG_MSG("WiFi ... Client Mode\n"); + } + forcedSoftAP = forceSoftAP; if ((radioConfig.has_preferences && radioConfig.preferences.wifi_ssid[0]) || forceSoftAP) { @@ -152,30 +162,28 @@ bool initWifi(bool forceSoftAP) wifiPsw = NULL; if (*wifiName || forceSoftAP) { - if (forceSoftAP) { - - DEBUG_MSG("Forcing SoftAP\n"); - - const char *softAPssid = "meshtasticAdmin"; - const char *softAPpasswd = "12345678"; + if (radioConfig.preferences.wifi_ap_mode || forceSoftAP) { IPAddress apIP(192, 168, 42, 1); WiFi.onEvent(WiFiEvent); + WiFi.mode(WIFI_AP); + + if (forcedSoftAP) { + const char *softAPssid = "meshtasticAdmin"; + const char *softAPpasswd = "12345678"; + + DEBUG_MSG("Starting (Forced) WIFI AP: ssid=%s, ok=%d\n", softAPssid, WiFi.softAP(softAPssid, softAPpasswd)); + + } else { + DEBUG_MSG("Starting WIFI AP: ssid=%s, ok=%d\n", wifiName, WiFi.softAP(wifiName, wifiPsw)); + + } WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); - DEBUG_MSG("STARTING WIFI AP: ssid=%s, ok=%d\n", softAPssid, WiFi.softAP(softAPssid, softAPpasswd)); - DEBUG_MSG("MY IP ADDRESS: %s\n", WiFi.softAPIP().toString().c_str()); + DEBUG_MSG("MY IP AP ADDRESS: %s\n", WiFi.softAPIP().toString().c_str()); - dnsServer.start(53, "*", apIP); - - } else if (radioConfig.preferences.wifi_ap_mode) { - - IPAddress apIP(192, 168, 42, 1); - WiFi.onEvent(WiFiEvent); - - WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); - DEBUG_MSG("STARTING WIFI AP: ssid=%s, ok=%d\n", wifiName, WiFi.softAP(wifiName, wifiPsw)); - DEBUG_MSG("MY IP ADDRESS: %s\n", WiFi.softAPIP().toString().c_str()); + // This is needed to improve performance. + esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving dnsServer.start(53, "*", apIP); @@ -184,14 +192,13 @@ bool initWifi(bool forceSoftAP) getMacAddr(dmac); sprintf(ourHost, "Meshtastic-%02x%02x", dmac[4], dmac[5]); - Serial.println(ourHost); - WiFi.mode(WIFI_MODE_STA); WiFi.setHostname(ourHost); WiFi.onEvent(WiFiEvent); - // esp_wifi_set_ps(WIFI_PS_NONE); // Disable power saving - // WiFiEventId_t eventID = WiFi.onEvent( + // This is needed to improve performance. + esp_wifi_set_ps(WIFI_PS_NONE); // Disable radio power saving + WiFi.onEvent( [](WiFiEvent_t event, WiFiEventInfo_t info) { Serial.print("\nWiFi lost connection. Reason: "); @@ -250,7 +257,7 @@ static void WiFiEvent(WiFiEvent_t event) DEBUG_MSG("Authentication mode of access point has changed\n"); break; case SYSTEM_EVENT_STA_GOT_IP: - DEBUG_MSG("Obtained IP address: \n"); + DEBUG_MSG("Obtained IP address: "); Serial.println(WiFi.localIP()); onNetworkConnected(); break; @@ -271,7 +278,7 @@ static void WiFiEvent(WiFiEvent_t event) break; case SYSTEM_EVENT_AP_START: DEBUG_MSG("WiFi access point started\n"); - //Serial.println(WiFi.softAPIP()); + onNetworkConnected(); break; case SYSTEM_EVENT_AP_STOP: @@ -305,7 +312,7 @@ static void WiFiEvent(WiFiEvent_t event) DEBUG_MSG("Ethernet disconnected\n"); break; case SYSTEM_EVENT_ETH_GOT_IP: - DEBUG_MSG("Obtained IP address\n"); + DEBUG_MSG("Obtained IP address (SYSTEM_EVENT_ETH_GOT_IP)\n"); break; default: break; @@ -314,7 +321,7 @@ static void WiFiEvent(WiFiEvent_t event) void handleDNSResponse() { - if (radioConfig.preferences.wifi_ap_mode) { + if (radioConfig.preferences.wifi_ap_mode || isSoftAPForced()) { dnsServer.processNextRequest(); } } diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index c60ae50e..6235f37f 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -68,9 +68,22 @@ void MQTT::reconnect() if (wantsLink()) { const char *serverAddr = "mqtt.meshtastic.org"; // default hostname int serverPort = 1883; // default server port + const char *mqttUsername = "meshdev"; + const char *mqttPassword = "large4cats"; - if (*radioConfig.preferences.mqtt_server) + if (*radioConfig.preferences.mqtt_server) { serverAddr = radioConfig.preferences.mqtt_server; // Override the default + mqttUsername = radioConfig.preferences.mqtt_username; //do not use the hardcoded credentials for a custom mqtt server + mqttPassword = radioConfig.preferences.mqtt_password; + } else { + //we are using the default server. Use the hardcoded credentials by default, but allow overriding + if (*radioConfig.preferences.mqtt_username && radioConfig.preferences.mqtt_username[0] != '\0') { + mqttUsername = radioConfig.preferences.mqtt_username; + } + if (*radioConfig.preferences.mqtt_password && radioConfig.preferences.mqtt_password[0] != '\0') { + mqttPassword = radioConfig.preferences.mqtt_password; + } + } String server = String(serverAddr); int delimIndex = server.indexOf(':'); @@ -82,9 +95,9 @@ void MQTT::reconnect() } pubSub.setServer(serverAddr, serverPort); - DEBUG_MSG("Connecting to MQTT server %s, port: %d\n", serverAddr, serverPort); + DEBUG_MSG("Connecting to MQTT server %s, port: %d, username: %s, password %s\n", serverAddr, serverPort, mqttUsername, mqttPassword); auto myStatus = (statusTopic + owner.id); - bool connected = pubSub.connect(owner.id, "meshdev", "large4cats", myStatus.c_str(), 1, true, "offline"); + bool connected = pubSub.connect(owner.id, mqttUsername, mqttPassword, myStatus.c_str(), 1, true, "offline"); if (connected) { DEBUG_MSG("MQTT connected\n"); enabled = true; // Start running background process again diff --git a/src/nimble/BluetoothUtil.cpp b/src/nimble/BluetoothUtil.cpp index eae2a6db..42ff06b7 100644 --- a/src/nimble/BluetoothUtil.cpp +++ b/src/nimble/BluetoothUtil.cpp @@ -556,7 +556,7 @@ void setBluetoothEnable(bool on) bluetoothOn = on; if (on) { - if (!initWifi(isSoftAPForced())) // if we are using wifi, don't turn on bluetooth also + if (! isWifiAvailable() ) { Serial.printf("Pre BT: %u heap size\n", ESP.getFreeHeap()); // ESP_ERROR_CHECK( heap_trace_start(HEAP_TRACE_LEAKS) ); diff --git a/src/sleep.cpp b/src/sleep.cpp index 44720b4c..558dbf1d 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -14,6 +14,7 @@ #include "rom/rtc.h" #include #include +#include "mesh/http/WiFiAPClient.h" #include "nimble/BluetoothUtil.h" @@ -48,6 +49,22 @@ RTC_DATA_ATTR int bootCount = 0; void setCPUFast(bool on) { #ifndef NO_ESP32 + + if (isWifiAvailable()) { + /* + * + * There's a newly introduced bug in the espressif framework where WiFi is + * unstable when the frequency is less than 240mhz. + * + * This mostly impacts WiFi AP mode but we'll bump the frequency for + * all WiFi use cases. + * (Added: Dec 23, 2021 by Jm Casler) + */ + DEBUG_MSG("Setting CPU to 240mhz because WiFi is in use.\n"); + setCpuFrequencyMhz(240); + return; + } + setCpuFrequencyMhz(on ? 240 : 80); #endif }