Your link to the official example is on the master branch. This could change at any time. It's better to click on the branch/tag switcher in the top left, and choose the latest permanent-looking tag, like the most recent Release Candidate 3.0.0-rc1. BTW, this example is part of version 3 -- not yet released -- and not present in version 2.
Anyway... yeah, it doesn't work reliably for me either. Try replacing the loop function with this different version, along with some supporting code
int16_t apCount = WIFI_SCAN_RUNNING;
uint32_t wifiScanCount;
void resetWifiScanCounters() { // Can move these statements to startWiFiScan
apCount = WIFI_SCAN_RUNNING;
wifiScanCount = 0;
}
void wifiScanLoop() {
wifiScanCount++;
apCount = WiFi.scanComplete();
switch (apCount) {
case WIFI_SCAN_FAILED:
Serial.printf("WiFi: scan failed after %d scan loops\n", wifiScanCount);
//fallthrough
case WIFI_SCAN_RUNNING:
delay(155); // yield while scanning, a little longer for demo
break;
case 0:
Serial.printf("WiFi: no access points found after %d scan loops\n", wifiScanCount);
break;
default:
Serial.printf("WiFi: found %d APs after %d scan loops\n", apCount, wifiScanCount);
}
}
enum {
WIFI_SCAN,
MAIN,
} what_am_i_doing;
bool scanRepeatedly = true;
void loop() {
switch (what_am_i_doing) {
case WIFI_SCAN:
if (apCount < 0) {
// Haven't settled on number of APs yet; keep checking
wifiScanLoop(); // does its own delay()
Serial.printf("Just to prove scan is async at %lu...\n", millis());
} else { // Found Zero or more Wireless Networks
printScannedNetworks(apCount); // this does WiFi.scanDelete!
if (scanRepeatedly) {
resetWifiScanCounters();
startWiFiScan(); // start over...
} else {
what_am_i_doing = MAIN;
}
}
break;
case MAIN:
// what's next
Serial.printf("Loop running at %lu...\n", millis());
delay(2500); // longer for demo
break;
}
// Could also do something here regardless of `what_am_i_doing`
}
It also helps to, under the Tools menu, set Core Debug Level to Debug.
With scanRepeatedly true, the first time it usually works without errors
Just to prove scan is async at 2401...
Just to prove scan is async at 2556...
Just to prove scan is async at 2711...
[ 2775][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 1 - SCAN_DONE
Just to prove scan is async at 2866...
WiFi: found 21 APs after 18 scan loops
Just to prove scan is async at 2866...
Scan done
21 networks found
(Note the [D] debug message.) But the second time
Just to prove scan is async at 8987...
Just to prove scan is async at 9142...
WiFi: scan failed after 40 scan loops
Just to prove scan is async at 9297...
WiFi: scan failed after 41 scan loops
Just to prove scan is async at 9452...
WiFi: scan failed after 42 scan loops
Just to prove scan is async at 9607...
WiFi: scan failed after 43 scan loops
Just to prove scan is async at 9762...
WiFi: scan failed after 44 scan loops
Just to prove scan is async at 9917...
WiFi: scan failed after 45 scan loops
Just to prove scan is async at 10072...
WiFi: scan failed after 46 scan loops
[ 10104][D][WiFiGeneric.cpp:1039] _eventCallback(): Arduino Event: 1 - SCAN_DONE
Just to prove scan is async at 10227...
WiFi: found 23 APs after 47 scan loops
Just to prove scan is async at 10227...
Scan done
23 networks found
it returns WIFI_SCAN_FAILED for a while before completing successfully. This might be due to the aforementioned slight version mismatch between the underlying code in the board. I'm using version 2 of the library, which actually corresponds with version 4 of ESP-IDF; while version 3 is version 5.1 or thereabout.
I use the async, and just let it finish.