c++esp32arduino-esp32

Can I go from failing to connect, to scanning for ssids, without turning the wifi off and on again inbetween?


My objective is to turn on my microcontroller (esp32-devkit-v1) and have it reconnect to the last wifi it was connected to prior to being turned off. If that SSID isn't in range, scan for new ones and list them, so I can pick a new one to connect to.

Problem

In the following code I have deliberately given wrong credentials to trigger the listing of SSIDs, but after the connection fails, the scan never gets triggered.

As far as I can tell WiFi.scanNetworks() never sets status to -1, and the scan is never initiated (also, it sets uint8_t n; to 254).
If I want everything to work as intended I need to turn the wifi off and on again before the scan.

In order for me to not fill this query with unnecessary stuff that has nothing to do with my question, I've distilled my code down to the following:

#include <Arduino.h>
#include <WiFi.h>

const char* ssid     = "blehbleh";
const char* password = "blahblah";
uint8_t n;

bool connectingToLast() {
  Serial.printf("Trying to connect to %s\n", ssid);
  WiFi.begin(ssid, password);
  int8_t status = WiFi.waitForConnectResult(20000);
  if (status != WL_CONNECTED)
  {
    Serial.printf("Not connected! Err: %i\n", status);
    return false;
  } else return true;
}

void wifiScan() {
  Serial.print("Scanning networks.");
  WiFi.scanNetworks(true);
  while (WiFi.scanComplete() == -1)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  delay(1000);

  n = WiFi.scanComplete();
  Serial.printf("Amount of networks found: %d\n", n);
  for (uint8_t i = 0; i < n; i++)
  {
    Serial.printf("%2d. %s\n", i+1, WiFi.SSID(i));
  }
  Serial.println("");
}

void setup() {
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  if (connectingToLast())
  {
    Serial.println("Connected!");
  }
  else
  {
    WiFi.mode(WIFI_OFF); //  IS IT POSSIBLE TO NOT
    WiFi.mode(WIFI_STA); //  NEED THESE TWO LINES?
    wifiScan();
  }
}

void loop () {}

Solution

  • Turns out this was just a case of not remembering the manual all that well.
    As explained in the documentation, failing to connect to an AP, the ESP tries to reconnect by calling its connect function over and over again. And since connecting takes priority over scanning, the scanning never takes place.

    Fix
    A simple call to disconnect, as soon as the connection attempt to the AP fails, was all it needed to successfully scan.
    ...
    if (status != WL_CONNECTED)
      {
        Serial.printf("Not connected!");
        WiFi.disconnect(); //    <--   This dude right here.
        return false;
      } else return true;
    ...