From 8d1a84557c99135742374a77df1e6b4b2f6d0e6d Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Mon, 11 Dec 2023 08:34:40 -0300 Subject: [PATCH] Wifi async scan example and fix (#8981) * Create WiFiScanAsync.ino * Create .skip.esp32h2 * Create README.md * Update README.md - adds C6 * Update wifi.rst with new example * avoid timeout with Async Mode --------- Co-authored-by: Me No Dev --- docs/source/api/wifi.rst | 2 +- libraries/WiFi/examples/WiFiScan/README.md | 5 +- .../WiFi/examples/WiFiScanAsync/.skip.esp32h2 | 1 + .../WiFi/examples/WiFiScanAsync/README.md | 75 +++++++++++++ .../examples/WiFiScanAsync/WiFiScanAsync.ino | 102 ++++++++++++++++++ libraries/WiFi/src/WiFiScan.cpp | 10 +- 6 files changed, 187 insertions(+), 8 deletions(-) create mode 100644 libraries/WiFi/examples/WiFiScanAsync/.skip.esp32h2 create mode 100644 libraries/WiFi/examples/WiFiScanAsync/README.md create mode 100644 libraries/WiFi/examples/WiFiScanAsync/WiFiScanAsync.ino diff --git a/docs/source/api/wifi.rst b/docs/source/api/wifi.rst index 1fd5651f38b..c906cdaa588 100644 --- a/docs/source/api/wifi.rst +++ b/docs/source/api/wifi.rst @@ -643,7 +643,7 @@ Loads all infos from a scanned wifi in to the ptr parameters. bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel); -To see how to use the ``WiFiScan``, take a look at the ``WiFiScan.ino`` example available. +To see how to use the ``WiFiScan``, take a look at the ``WiFiScan.ino`` or ``WiFiScanAsync.ino`` example available. Examples -------- diff --git a/libraries/WiFi/examples/WiFiScan/README.md b/libraries/WiFi/examples/WiFiScan/README.md index 188ae7453a0..7a4a7ec8350 100644 --- a/libraries/WiFi/examples/WiFiScan/README.md +++ b/libraries/WiFi/examples/WiFiScan/README.md @@ -6,8 +6,8 @@ This example demonstrates how to use the WiFi library to scan available WiFi net Currently this example supports the following targets. -| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C6 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | ## How to Use Example @@ -61,4 +61,5 @@ Before creating a new issue, be sure to try the Troubleshooting and to check if * ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) * ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) * ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) * Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/WiFi/examples/WiFiScanAsync/.skip.esp32h2 b/libraries/WiFi/examples/WiFiScanAsync/.skip.esp32h2 new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/libraries/WiFi/examples/WiFiScanAsync/.skip.esp32h2 @@ -0,0 +1 @@ + diff --git a/libraries/WiFi/examples/WiFiScanAsync/README.md b/libraries/WiFi/examples/WiFiScanAsync/README.md new file mode 100644 index 00000000000..195605bce60 --- /dev/null +++ b/libraries/WiFi/examples/WiFiScanAsync/README.md @@ -0,0 +1,75 @@ +# WiFiScanAsync Example + +This example demonstrates how to use the WiFi library to scan available WiFi networks in asynchronous mode and print the results. + +## Supported Targets + +Currently this example supports the following targets. + +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C6 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | + +## How to Use Example + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file. + +## Example/Log Output + +``` +Setup done +Scan start +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... + +Scan done +17 networks found +Nr | SSID | RSSI | CH | Encryption + 1 | IoTNetwork | -62 | 1 | WPA2 + 2 | WiFiSSID | -62 | 1 | WPA2-EAP + 3 | B3A7992 | -63 | 6 | WPA+WPA2 + 4 | WiFi | -63 | 6 | WPA3 + 5 | IoTNetwork2 | -64 | 11 | WPA2+WPA3 +... +``` + +## Troubleshooting + +***Important: Be sure you're using a good quality USB cable and you have enought power source for your project.*** + +* **Programming Fail:** If the programming/flash procedure fails, try to reduce the serial connection speed. +* **COM port not detected:** Check the USB cable connection and the USB to Serial driver installation. + +If the error persist, you can ask help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try the Troubleshooting and to check if the same issue was already created by someone else. + +## Resources + +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/WiFi/examples/WiFiScanAsync/WiFiScanAsync.ino b/libraries/WiFi/examples/WiFiScanAsync/WiFiScanAsync.ino new file mode 100644 index 00000000000..9f4408cdfe1 --- /dev/null +++ b/libraries/WiFi/examples/WiFiScanAsync/WiFiScanAsync.ino @@ -0,0 +1,102 @@ +/* + This sketch demonstrates how to scan WiFi networks in Async Mode. + The API is based on the Arduino WiFi Shield library, but has significant changes as newer WiFi functions are supported. + E.g. the return value of `encryptionType()` different because more modern encryption is supported. +*/ +#include "WiFi.h" + +void startWiFiScan() { + Serial.println("Scan start"); + // WiFi.scanNetworks will return immediately in Async Mode. + WiFi.scanNetworks(true); // 'true' turns Async Mode ON +} + +void printScannedNetworks(uint16_t networksFound) { + if (networksFound == 0) { + Serial.println("no networks found"); + } else { + Serial.println("\nScan done"); + Serial.print(networksFound); + Serial.println(" networks found"); + Serial.println("Nr | SSID | RSSI | CH | Encryption"); + for (int i = 0; i < networksFound; ++i) { + // Print SSID and RSSI for each network found + Serial.printf("%2d", i + 1); + Serial.print(" | "); + Serial.printf("%-32.32s", WiFi.SSID(i).c_str()); + Serial.print(" | "); + Serial.printf("%4ld", WiFi.RSSI(i)); + Serial.print(" | "); + Serial.printf("%2ld", WiFi.channel(i)); + Serial.print(" | "); + switch (WiFi.encryptionType(i)) + { + case WIFI_AUTH_OPEN: + Serial.print("open"); + break; + case WIFI_AUTH_WEP: + Serial.print("WEP"); + break; + case WIFI_AUTH_WPA_PSK: + Serial.print("WPA"); + break; + case WIFI_AUTH_WPA2_PSK: + Serial.print("WPA2"); + break; + case WIFI_AUTH_WPA_WPA2_PSK: + Serial.print("WPA+WPA2"); + break; + case WIFI_AUTH_WPA2_ENTERPRISE: + Serial.print("WPA2-EAP"); + break; + case WIFI_AUTH_WPA3_PSK: + Serial.print("WPA3"); + break; + case WIFI_AUTH_WPA2_WPA3_PSK: + Serial.print("WPA2+WPA3"); + break; + case WIFI_AUTH_WAPI_PSK: + Serial.print("WAPI"); + break; + default: + Serial.print("unknown"); + } + Serial.println(); + delay(10); + } + Serial.println(""); + // Delete the scan result to free memory for code below. + WiFi.scanDelete(); + } +} + +void setup() { + Serial.begin(115200); + + // Set WiFi to station mode and disconnect from an AP if it was previously connected. + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + delay(100); + + Serial.println("Setup done"); + startWiFiScan(); +} + +void loop() { + // check WiFi Scan Async process + int16_t WiFiScanStatus = WiFi.scanComplete(); + if (WiFiScanStatus < 0) { // it is busy scanning or got an error + if (WiFiScanStatus == WIFI_SCAN_FAILED) { + Serial.println("WiFi Scan has failed. Starting again."); + startWiFiScan(); + } + // other option is status WIFI_SCAN_RUNNING - just wait. + } else { // Found Zero or more Wireless Networks + printScannedNetworks(WiFiScanStatus); + startWiFiScan(); // start over... + } + + // Loop can do something else... + delay(250); + Serial.println("Loop running..."); +} diff --git a/libraries/WiFi/src/WiFiScan.cpp b/libraries/WiFi/src/WiFiScan.cpp index 37e86a198df..e3604c9723f 100644 --- a/libraries/WiFi/src/WiFiScan.cpp +++ b/libraries/WiFi/src/WiFiScan.cpp @@ -141,11 +141,6 @@ void * WiFiScanClass::_getScanInfoByIndex(int i) */ int16_t WiFiScanClass::scanComplete() { - if (WiFiScanClass::_scanStarted && (millis()-WiFiScanClass::_scanStarted) > WiFiScanClass::_scanTimeout) { //Check is scan was started and if the delay expired, return WIFI_SCAN_FAILED in this case - WiFiGenericClass::clearStatusBits(WIFI_SCANNING_BIT); - return WIFI_SCAN_FAILED; - } - if(WiFiGenericClass::getStatusBits() & WIFI_SCAN_DONE_BIT) { return WiFiScanClass::_scanCount; } @@ -153,6 +148,11 @@ int16_t WiFiScanClass::scanComplete() if(WiFiGenericClass::getStatusBits() & WIFI_SCANNING_BIT) { return WIFI_SCAN_RUNNING; } + // last one to avoid time affecting Async mode + if (WiFiScanClass::_scanStarted && (millis()-WiFiScanClass::_scanStarted) > WiFiScanClass::_scanTimeout) { //Check is scan was started and if the delay expired, return WIFI_SCAN_FAILED in this case + WiFiGenericClass::clearStatusBits(WIFI_SCANNING_BIT); + return WIFI_SCAN_FAILED; + } return WIFI_SCAN_FAILED; }