From 868a09fde2da3ca06d690bd9b46c827ab3bfb37c Mon Sep 17 00:00:00 2001 From: kscholty Date: Sun, 27 Aug 2023 16:21:14 +0200 Subject: [PATCH] Refactored the tickWifi loop in AhoyWifi. Especially to evoid threading issues. Does also work wioth ESP32-S2 now. Has been tested with ESP32-S2 end ESP32 WROOM --- src/app.cpp | 4 +- src/config/config.h | 12 ++++ src/platformio.ini | 31 ++++++++- src/wifi/ahoywifi.cpp | 153 ++++++++++++++++++++++++++++++++++++++++-- src/wifi/ahoywifi.h | 12 +++- 5 files changed, 199 insertions(+), 13 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 179e3ba3..d5b9a0ff 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -225,9 +225,9 @@ void app::onNetwork(bool gotIp) { #if !defined(ETHERNET) if (WIFI_AP == WiFi.getMode()) { mMqttEnabled = false; - everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL"); } - #endif /* !defined(ETHERNET) */ + everySec(std::bind(&ahoywifi::tickWifiLoop, &mWifi), "wifiL"); +#endif /* !defined(ETHERNET) */ mInnerLoopCb = [this]() { this->loopStandard(); }; } else { #if defined(ETHERNET) diff --git a/src/config/config.h b/src/config/config.h index c4947ec8..73b996ad 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -56,6 +56,17 @@ // default pinout (GPIO Number) #if defined(ESP32) +#if defined(CONFIG_IDF_TARGET_ESP32S2) + // Layout for the ESP32-S2 mini from LOLIN. + // The pins are all lined up on the outer side of the board + // We will use HSPI + #define DEF_CS_PIN 12 + #define DEF_CE_PIN 3 + #define DEF_IRQ_PIN 5 + #define DEF_MISO_PIN 9 + #define DEF_MOSI_PIN 11 + #define DEF_SCLK_PIN 7 +#else // this is the default ESP32 (son-S) pinout on the WROOM modules for VSPI, // for the ESP32-S3 there is no sane 'default', as it has full flexibility // to map its two HW SPIs anywhere and PCBs differ materially, @@ -66,6 +77,7 @@ #define DEF_MISO_PIN 19 #define DEF_MOSI_PIN 23 #define DEF_SCLK_PIN 18 +#endif #else #define DEF_CS_PIN 15 #define DEF_CE_PIN 0 diff --git a/src/platformio.ini b/src/platformio.ini index 28c47783..35b4b177 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -149,7 +149,6 @@ monitor_filters = time ; Add timestamp with milliseconds for each new line log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory - [env:esp32-wroom32-ethernet-release] platform = espressif32 board = esp32dev @@ -173,6 +172,36 @@ build_unflags = -std=gnu++11 monitor_filters = esp32_exception_decoder +[env:esp-32-s2-mini-release] +platform = espressif32@6.3.2 +board = lolin_s2_mini +build_flags = + -D RELEASE + -std=gnu++17 + +build_unflags = -std=gnu++11 +monitor_filters = + esp32_exception_decoder + +[env:esp-32-s2-mini-debug] +platform = espressif32@6.3.2 +board = lolin_s2_mini +build_flags = + -DDEBUG_LEVEL=DBG_DEBUG + -DDEBUG_ESP_CORE + -DDEBUG_ESP_WIFI + -DDEBUG_ESP_HTTP_CLIENT + -DDEBUG_ESP_HTTP_SERVER + -DDEBUG_ESP_OOM + -DDEBUG_ESP_PORT=Serial + -std=gnu++17 +build_unflags = -std=gnu++11 +build_type = debug +monitor_filters = + time ; Add timestamp with milliseconds for each new line + log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory + + [env:opendtufusionv1-release] platform = espressif32@6.1.0 board = esp32-s3-devkitc-1 diff --git a/src/wifi/ahoywifi.cpp b/src/wifi/ahoywifi.cpp index 863ca88f..0a7d6fa0 100644 --- a/src/wifi/ahoywifi.cpp +++ b/src/wifi/ahoywifi.cpp @@ -29,7 +29,8 @@ void ahoywifi::setup(settings_t *config, uint32_t *utcTimestamp, appWifiCb cb) { mUtcTimestamp = utcTimestamp; mAppWifiCb = cb; - mStaConn = DISCONNECTED; + mGotDisconnect = false; + mStaConn = DISCONNECTED; mCnt = 0; mScanActive = false; mScanCnt = 0; @@ -69,10 +70,139 @@ void ahoywifi::setupWifi(bool startAP = false) { } +void ahoywifi::tickWifiLoop() { + static const uint8_t DISCONN_TIMEOUT = 10; + static const uint8_t TIMEOUT = 20; + static const uint8_t SCAN_TIMEOUT = 10; +#if !defined(AP_ONLY) + uint8_t timeout = (mStaConn == DISCONNECTED) ? DISCONN_TIMEOUT : TIMEOUT; // seconds + + mCnt++; + + switch (mStaConn) { + case IN_STA_MODE: + // Nothing to do + if (mGotDisconnect) { + mStaConn = RESET; + } + return; + case IN_AP_MODE: + if (WiFi.softAPgetStationNum() == 0) { + mCnt = 0; + mDns.stop(); + WiFi.mode(WIFI_AP_STA); + mStaConn = DISCONNECTED; + } else { + mDns.processNextRequest(); + return; + } + break; + case DISCONNECTED: + if (WiFi.softAPgetStationNum() > 0) { + mStaConn = IN_AP_MODE; + // first time switch to AP Mode + if (mScanActive) { + WiFi.scanDelete(); + mScanActive = false; + } + DBGPRINTLN(F("AP client connected")); + welcome(mApIp.toString(), ""); + WiFi.mode(WIFI_AP); + mDns.start(53, "*", mApIp); + mAppWifiCb(true); + mDns.processNextRequest(); + return; + } else if (!mScanActive) { + DBGPRINT(F("scanning APs with SSID ")); + DBGPRINTLN(String(mConfig->sys.stationSsid)); + mScanCnt = 0; + mCnt = 0; + mScanActive = true; +#if defined(ESP8266) + WiFi.scanNetworks(true, true, 0U, ([this]() { + if (mConfig->sys.isHidden) + return (uint8_t*)NULL; + return (uint8_t*)(mConfig->sys.stationSsid); + })()); +#else + WiFi.scanNetworks(true, true, false, 300U, 0U, ([this]() { + if (mConfig->sys.isHidden) + return (char*)NULL; + return (mConfig->sys.stationSsid); + })()); +#endif + return; + } else if(getBSSIDs()) { + // Scan ready + mStaConn = SCAN_READY; + } else { + // In case of a timeout, what do we do? + // For now we start scanning again as the original code did. + // Would be better to into PA mode + + if (isTimeout(SCAN_TIMEOUT)) { + WiFi.scanDelete(); + mScanActive = false; + } + } + break; + case SCAN_READY: + mStaConn = CONNECTING; + mCnt = 0; + DBGPRINT(F("try to connect to AP with BSSID:")); + uint8_t bssid[6]; + for (int j = 0; j < 6; j++) { + bssid[j] = mBSSIDList.front(); + mBSSIDList.pop_front(); + DBGPRINT(" " + String(bssid[j], HEX)); + } + DBGPRINTLN(""); + mGotDisconnect = false; + WiFi.begin(mConfig->sys.stationSsid, mConfig->sys.stationPwd, 0, &bssid[0]); + + break; + case CONNECTING: + if (isTimeout(TIMEOUT)) { + WiFi.disconnect(); + mStaConn = mBSSIDList.empty() ? DISCONNECTED : SCAN_READY; + } + break; + case CONNECTED: + // Connection but no IP yet + if (isTimeout(TIMEOUT) || mGotDisconnect) { + mStaConn = RESET; + } + break; + case GOT_IP: + welcome(WiFi.localIP().toString(), F(" (Station)")); + WiFi.softAPdisconnect(); + WiFi.mode(WIFI_STA); + DBGPRINTLN(F("[WiFi] AP disabled")); + delay(100); + mAppWifiCb(true); + mGotDisconnect = false; + mStaConn = IN_STA_MODE; + break; + case RESET: + mGotDisconnect = false; + mStaConn = DISCONNECTED; + mCnt = 5; // try to reconnect in 5 sec + setupWifi(); // reconnect with AP / Station setup + mAppWifiCb(false); + DPRINTLN(DBG_INFO, "[WiFi] Connection Lost"); + break; + default: + DBGPRINTLN(F("Unhandled status")); + break; + } + +#endif +} +#if 0 //----------------------------------------------------------------------------- void ahoywifi::tickWifiLoop() { #if !defined(AP_ONLY) - if(mStaConn != GOT_IP) { + if(mStaConn != IN_STA_MODE) { if (WiFi.softAPgetStationNum() > 0) { // do not reconnect if any AP connection exists if(mStaConn != IN_AP_MODE) { mStaConn = IN_AP_MODE; @@ -154,7 +284,7 @@ void ahoywifi::tickWifiLoop() { } #endif } - +#endif //----------------------------------------------------------------------------- void ahoywifi::setupAp(void) { @@ -213,7 +343,7 @@ void ahoywifi::setupStation(void) { //----------------------------------------------------------------------------- bool ahoywifi::getNtpTime(void) { - if(GOT_IP != mStaConn) + if(IN_STA_MODE != mStaConn) return false; IPAddress timeServer; @@ -314,11 +444,12 @@ bool ahoywifi::getAvailNetworks(JsonObject obj) { } //----------------------------------------------------------------------------- -void ahoywifi::getBSSIDs() { +bool ahoywifi::getBSSIDs() { + bool result = false; int n = WiFi.scanComplete(); if (n < 0) { if (++mScanCnt < 20) - return; + return result; } if(n > 0) { mBSSIDList.clear(); @@ -333,9 +464,11 @@ void ahoywifi::getBSSIDs() { } DBGPRINTLN(""); } + result = true; } mScanActive = false; WiFi.scanDelete(); + return result; } //----------------------------------------------------------------------------- @@ -346,12 +479,14 @@ void ahoywifi::connectionEvent(WiFiStatus_t status) { case CONNECTED: if(mStaConn != CONNECTED) { mStaConn = CONNECTED; + mGotDisconnect = false; DBGPRINTLN(F("\n[WiFi] Connected")); } break; case GOT_IP: mStaConn = GOT_IP; + #if 0 if (mScanActive) { // maybe another scan has started WiFi.scanDelete(); mScanActive = false; @@ -362,16 +497,20 @@ void ahoywifi::connectionEvent(WiFiStatus_t status) { DBGPRINTLN(F("[WiFi] AP disabled")); delay(100); mAppWifiCb(true); + #endif break; case DISCONNECTED: - if(mStaConn != CONNECTING) { + mGotDisconnect = true; + #if 0 + if (mStaConn != CONNECTING) { mStaConn = DISCONNECTED; mCnt = 5; // try to reconnect in 5 sec setupWifi(); // reconnect with AP / Station setup mAppWifiCb(false); DPRINTLN(DBG_INFO, "[WiFi] Connection Lost"); } + #endif break; default: diff --git a/src/wifi/ahoywifi.h b/src/wifi/ahoywifi.h index ef4f2b71..e44d6858 100644 --- a/src/wifi/ahoywifi.h +++ b/src/wifi/ahoywifi.h @@ -32,10 +32,13 @@ class ahoywifi { private: typedef enum WiFiStatus { DISCONNECTED = 0, + SCAN_READY, CONNECTING, CONNECTED, IN_AP_MODE, - GOT_IP + GOT_IP, + IN_STA_MODE, + RESET } WiFiStatus_t; void setupWifi(bool startAP); @@ -43,9 +46,11 @@ class ahoywifi { void setupStation(void); void sendNTPpacket(IPAddress& address); void sortRSSI(int *sort, int n); - void getBSSIDs(void); + bool getBSSIDs(void); void connectionEvent(WiFiStatus_t status); - #if defined(ESP8266) + bool isTimeout(uint8_t timeout) { return (mCnt % timeout) == 0; } + +#if defined(ESP8266) void onConnect(const WiFiEventStationModeConnected& event); void onGotIP(const WiFiEventStationModeGotIP& event); void onDisconnect(const WiFiEventStationModeDisconnected& event); @@ -71,6 +76,7 @@ class ahoywifi { uint8_t mScanCnt; bool mScanActive; + bool mGotDisconnect; std::list mBSSIDList; };