6

I have searched for solution for this issue for quite a long time with no luck.

I would like NodeMCU to look for an open wifi network and connect to it. As long as the connection is available use that connection - and when the connection drops start looking for a new open network.

I live in Finland and we have free open WiFi almost on every corner. I am planning on creating something wearable/mobile that would use WiFi when available.

I am also only starting on programming, basics in C and using the Arduino IDE so no Lua language experience here.

I understand that WiFi.scanNetworks() can distinguish a secure from an unsecured SSID, but I haven't found out how I could use that to my advantage in Arduino IDE.

cagdas
  • 1,634
  • 2
  • 14
  • 27
  • 1
    one snag that comes to mind: you can't scan for APs on other channels while in STA mode. you can scan for a list, filter out the secured APs, then `WiFi.begin()` on one left over. – dandavis Jan 08 '17 at 15:10
  • "I would like NodeMCU..." - indicates you using the NodeMCU firmware. "using the Arduino IDE so no Lua language experience here" - now what? NodeMCU/Lua firmware or Arduino? – Marcel Stör Jan 08 '17 at 18:57
  • Arduino has NodeMCU board support from its device manager. But yes, it does nothing but ESP8266 + Serial to USB. – cagdas Jan 09 '17 at 05:21
  • @MarcelStör: nodemcu (to me) refers to the board, not the flaky and slow dev environ. – dandavis Jan 09 '17 at 09:55
  • @cagdas: nodemcu 1.0 also has 3.3v LDO, VIN out, 3.3v A0, extra LED, and an auto flash mode detection. – dandavis Jan 09 '17 at 10:01
  • @dandavis fair enough but then you should expect confusion if you were to state this publicly because it's exactly the other way round. "NodeMCU" by default means the firmware, the hardware are "NodeMCU devkits". Source: http://nodemcu.readthedocs.io/en/latest/en/, https://en.wikipedia.org/wiki/NodeMCU. – Marcel Stör Jan 09 '17 at 12:27
  • @dandavis It's not NodeMCU's fault that you don't like Lua. However, calling it _obscure_ is unfounded. It's actually a perfectly well suited scripting language for embedded devices. Rather than fading away we're seeing the opposite, sorry. Although a niche compared to Arduino NodeMCU is more popular than ever. – Marcel Stör Jan 09 '17 at 14:52
  • @MarcelStör: the name confusion is what irks me, not Lua or having viable alternatives to McDuino ;) – dandavis Jan 09 '17 at 14:56
  • Guys I suppose it is related with the programming habits to choose correct fw or language. We all do well with lua, arduino and open sdk. In Turkish, there is an idiom like; Each brave-man has his own way of eating yoghurt. Lets keep in touch for question. See u pals. – cagdas Jan 09 '17 at 15:31
  • Thank you for the comments! Yes - i am a beginning engineering student and the only viable way for me to get my kicks out of microcontrollers at the moment is only Arduino IDE. – taeraeyttaejae Jan 09 '17 at 17:23

1 Answers1

5

You can scan for networks also in STA mode.

The method you need is WiFi.encryptionType() after WiFi.scanNetworks() to determine whether a network encrypted or not.

I am sharing a sketch with you that I was working on for a similar project previously.

Sketch searches for WiFi networks, sorts them in order to RSSI, and performs connection on non-encrypted one with highest strength.

Here it is, good luck:

#include <ESP8266WiFi.h>

/* Serial Baud Rate */
#define SERIAL_BAUD       9600
/* Delay paramter for connection. */
#define WIFI_DELAY        500
/* Max SSID octets. */
#define MAX_SSID_LEN      32
/* Wait this much until device gets IP. */
#define MAX_CONNECT_TIME  30000

/* SSID that to be stored to connect. */
char ssid[MAX_SSID_LEN] = "";

/* Scan available networks and sort them in order to their signal strength. */
void scanAndSort() {
  memset(ssid, 0, MAX_SSID_LEN);
  int n = WiFi.scanNetworks();
  Serial.println("Scan done!");
  if (n == 0) {
    Serial.println("No networks found!");
  } else {
    Serial.print(n);
    Serial.println(" networks found.");
    int indices[n];
    for (int i = 0; i < n; i++) {
      indices[i] = i;
    }
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        if (WiFi.RSSI(indices[j]) > WiFi.RSSI(indices[i])) {
          std::swap(indices[i], indices[j]);
        }
      }
    }
    for (int i = 0; i < n; ++i) {
      Serial.print(WiFi.SSID(indices[i]));
      Serial.print(" ");
      Serial.print(WiFi.RSSI(indices[i]));
      Serial.print(" ");
      Serial.print(WiFi.encryptionType(indices[i]));
      Serial.println();
      if(WiFi.encryptionType(indices[i]) == ENC_TYPE_NONE) {
        Serial.println("Found non-encrypted network. Store it and exit to connect.");
        memset(ssid, 0, MAX_SSID_LEN);
        strncpy(ssid, WiFi.SSID(indices[i]).c_str(), MAX_SSID_LEN);
        break;
      }
    }
  }
}

void setup() {
  Serial.begin(SERIAL_BAUD);
  Serial.println("Started.");
}

void loop() {
  if(WiFi.status() != WL_CONNECTED) {
    /* Clear previous modes. */
    WiFi.softAPdisconnect();
    WiFi.disconnect();
    WiFi.mode(WIFI_STA);
    delay(WIFI_DELAY);
    /* Scan for networks to find open guy. */
    scanAndSort();
    delay(WIFI_DELAY);
    /* Global ssid param need to be filled to connect. */
    if(strlen(ssid) > 0) {
      Serial.print("Going to connect for : ");
      Serial.println(ssid);
      /* No pass for WiFi. We are looking for non-encrypteds. */
      WiFi.begin(ssid);
      unsigned short try_cnt = 0;
      /* Wait until WiFi connection but do not exceed MAX_CONNECT_TIME */
      while (WiFi.status() != WL_CONNECTED && try_cnt < MAX_CONNECT_TIME / WIFI_DELAY) {
        delay(WIFI_DELAY);
        Serial.print(".");
        try_cnt++;
      }
      if(WiFi.status() == WL_CONNECTED) {
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
      } else {
        Serial.println("Cannot established connection on given time.");
      }
    } else {
      Serial.println("No non-encrypted WiFi found.");  
    }
  }
}
dda
  • 6,030
  • 2
  • 25
  • 34
cagdas
  • 1,634
  • 2
  • 14
  • 27
  • My bad! For ESP32 only change is: ENC_TYPE_NONE to WIFI_AUTH_OPEN and import header : #include – pawisoon May 04 '17 at 14:24
  • Actually i could not get time to start to work with 32. But happy to see that you did it well. – cagdas May 04 '17 at 17:59
  • is it necessary to clear the AP first? Or can the two run simultaneous? There is a mode for doing both at once. – Scott May 07 '17 at 15:01
  • As you know esp stores the previous login credentials. It makes me relaxed to clear all configuration written on esp internal memory. – cagdas May 10 '17 at 14:56