@@ -302,6 +302,16 @@ void fillStr2MAC(uint8_t *mac, const char *str) {
302302 for (int i = 0 ; i < 6 ; i++) { *--mac = MAC & 0xFF ; MAC >>= 8 ; }
303303}
304304
305+ #ifdef ARDUINO_ARCH_ESP32
306+ // Shim class to allow access to protected members of WiFiScanClass so we can extend the timeout
307+ namespace {
308+ struct WifiScanAccessor : public WiFiScanClass {
309+ static uint32_t & scanStarted () { return WiFiScanClass::_scanStarted; }
310+ static uint32_t & scanTimeout () { return WiFiScanClass::_scanTimeout; }
311+ static uint16_t & scanCount () { return WiFiScanClass::_scanCount; };
312+ };
313+ }
314+ #endif
305315
306316#ifndef WLED_DISABLE_ESPNOW
307317void initESPNow (bool resetAP) {
@@ -389,28 +399,39 @@ int findWiFi(bool doScan) {
389399
390400 if (doScan || status == WIFI_SCAN_FAILED ) {
391401 DEBUG_PRINTF_P (PSTR (" WiFi: Scan started. @ %lus\n " ), millis ()/1000 );
392- WiFi.scanNetworks (true ); // start scanning in asynchronous mode (will delete old scan)
393- } else if (status > 0 ) { // status contains number of found networks (including duplicate SSIDs with different BSSID)
402+ WiFi.disconnect (); // make sure we're not trying to reconnect to a network while scanning
403+ status = WiFi.scanNetworks (true ); // start scanning in asynchronous mode (will delete old scan)
404+ #ifdef ARDUINO_ARCH_ESP32
405+ // the Arduino core can be overly aggressive with its scan timeout if we're busy with the CPU. Be more generous.
406+ if (status == WIFI_SCAN_RUNNING ) {
407+ WifiScanAccessor::scanTimeout () += 5000 ;
408+ }
409+ #endif
410+ }
411+
412+ if (status >= 0 ) { // status contains number of found networks (including duplicate SSIDs with different BSSID)
394413 DEBUG_PRINTF_P (PSTR (" WiFi: Found %d SSIDs. @ %lus\n " ), status, millis ()/1000 );
395414 int rssi = -9999 ;
396415 int selected = selectedWiFi;
397416 for (int o = 0 ; o < status; o++) {
398417 DEBUG_PRINTF_P (PSTR (" SSID: %s (BSSID: %s) RSSI: %ddB\n " ), WiFi.SSID (o).c_str (), WiFi.BSSIDstr (o).c_str (), WiFi.RSSI (o));
399- for (unsigned n = 0 ; n < multiWiFi.size (); n++)
418+ for (unsigned n = 0 ; n < multiWiFi.size (); n++) {
400419 if (!strcmp (WiFi.SSID (o).c_str (), multiWiFi[n].clientSSID )) {
401420 bool foundBSSID = memcmp (multiWiFi[n].bssid , WiFi.BSSID (o), 6 ) == 0 ;
402421 // find the WiFi with the strongest signal (but keep priority of entry if signal difference is not big)
403- if (foundBSSID || ((int )n < selected && WiFi.RSSI (o) > rssi-10 ) || WiFi.RSSI (o) > rssi) {
422+ // essentially give a bonus to higher priority wifis
423+ if (foundBSSID || ((WiFi.RSSI (o) + ((int )n < selected ? 10 : 0 )) > rssi)) {
404424 rssi = foundBSSID ? 0 : WiFi.RSSI (o); // RSSI is only ever negative
405425 selected = n;
406426 }
407427 break ;
408428 }
429+ }
409430 }
410431 DEBUG_PRINTF_P (PSTR (" WiFi: Selected SSID: %s RSSI: %ddB\n " ), multiWiFi[selected].clientSSID , rssi);
411432 return selected+1 ;
412433 }
413- // DEBUG_PRINT(F ("WiFi scan running.") );
434+ // DEBUG_PRINTF_P(PSTR ("WiFi scan running: %d. @ %lus\n"), status, millis()/1000 );
414435 return status; // scan is still running or there was an error
415436}
416437
0 commit comments