Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WiFiScan.ino ported to CoopTask libraries doesn't find any networks #7969

Closed
dok-net opened this issue Apr 9, 2021 · 0 comments · Fixed by #7148
Closed

WiFiScan.ino ported to CoopTask libraries doesn't find any networks #7969

dok-net opened this issue Apr 9, 2021 · 0 comments · Fixed by #7148

Comments

@dok-net
Copy link
Contributor

dok-net commented Apr 9, 2021

Preparation (MCVE)

Let's trivially port the libraries\ESP8266WiFi\examples\WiFiScan\WiFiScan.ino to the Arduino CoopTask library, like so:

/*
    This sketch demonstrates how to scan WiFi networks.
    The API is almost the same as with the WiFi Shield library,
    the most obvious difference being the different file you need to include:
*/

#include <ESP8266WiFi.h>
#include <CoopTask.h>

void loop1() {
    String ssid;
    int32_t rssi;
    uint8_t encryptionType;
    uint8_t* bssid;
    int32_t channel;
    bool hidden;
    int scanResult;

    for (;;) {
        Serial.println(F("Starting WiFi scan..."));

        scanResult = WiFi.scanNetworks(/*async=*/false, /*hidden=*/true);

        if (scanResult == 0) {
            Serial.println(F("No networks found"));
        }
        else if (scanResult > 0) {
            Serial.printf(PSTR("%d networks found:\n"), scanResult);

            // Print unsorted scan results
            for (int8_t i = 0; i < scanResult; i++) {
                WiFi.getNetworkInfo(i, ssid, encryptionType, rssi, bssid, channel, hidden);

                Serial.printf(PSTR("  %02d: [CH %02d] [%02X:%02X:%02X:%02X:%02X:%02X] %ddBm %c %c %s\n"),
                    i,
                    channel,
                    bssid[0], bssid[1], bssid[2],
                    bssid[3], bssid[4], bssid[5],
                    rssi,
                    (encryptionType == ENC_TYPE_NONE) ? ' ' : '*',
                    hidden ? 'H' : 'V',
                    ssid.c_str());
                yield();
            }
        }
        else {
            Serial.printf(PSTR("WiFi scan error %d"), scanResult);
        }

        // Wait a bit before scanning again
        delay(5000);
    }
}

BasicCoopTask<CoopTaskStackAllocatorAsMember<1600>> task1("l1", loop1);

void setup() {
  Serial.begin(115200);
  Serial.println(F("\nESP8266 WiFi scan example"));

  // Set WiFi to station mode
  WiFi.mode(WIFI_STA);

  // Disconnect from an AP if it was previously connected
  WiFi.disconnect();
  delay(100);

  task1.scheduleTask();
}

void loop() {
    runCoopTasks();
}

Without additional tasks, this looks a bit lost, but the utility is obvious if you consider that one can add additional tasks, and as long as they don't need to guard shared resources, it's basically copy&paste from example code and there you go, without stackless coroutines, async programming or anything advanced. [full disclosure: I am the author/maintainer of CoopTask]

Issue

In master, no networks are found:

Starting WiFi scan...
No networks found
Starting WiFi scan...
No networks found
Starting WiFi scan...
No networks found

Resolution

The PR #6782 fixes this.

mcspr pushed a commit that referenced this issue Oct 16, 2021
esp_yield() now also calls esp_schedule(), original esp_yield() function renamed to esp_suspend().

Don't use delay(0) in the Core internals, libraries and examples. Use yield() when the code is
supposed to be called from CONT, use esp_yield() when the code can be called from either CONT or SYS.
Clean-up esp_yield() and esp_schedule() declarations across the code and use coredecls.h instead.

Implement helper functions for libraries that were previously using esp_yield(), esp_schedule() and
esp_delay() directly to wait for certain SYS context tasks to complete. Correctly use esp_delay()
for timeouts, make sure scheduled functions have a chance to run (e.g. LwIP_Ethernet uses recurrent)

Related issues:
- #6107 - discussion about the esp_yield() and esp_delay() usage in ClientContext
- #6212 - discussion about replacing delay() with a blocking loop
- #6680 - pull request introducing LwIP-based Ethernet
- #7146 - discussion that originated UART code changes
- #7969 - proposal to remove delay(0) from the example code
- #8291 - discussion related to the run_scheduled_recurrent_functions() usage in LwIP Ethernet
- #8317 - yieldUntil() implementation, similar to the esp_delay() overload with a timeout and a 0 interval
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment