Felderítés (Scan)

Mobiltelefon hot spothoz való csatlakoztatásához általában meg kell nyitnia a Wi-Fi beállítások alkalmazást, listázni kell az elérhető hálózatokat, majd kiválasztani a kívánt hot spotot. Felsorolhatja a hálózatokat az ESP8266-tal is, és itt van a módja.


Tartalomjegyzék


Egyszerű felderítés

Ez a példa azt a minimális kódot mutatja be, amely az elérhető hálózatok listájának ellenőrzéséhez szükséges.


Szétkapcsolás

Kezdésként engedélyezze a modult állomás módban, majd szüntesse meg a kapcsolatot.


WiFi.mode(WIFI_STA);
WiFi.disconnect();

A WiFi.disconnect() futtatása leállítja a kapcsolatot egy olyan hozzáférési ponttal, amelyet a modul esetleg automatikusan létesített a korábban elmentett hitelesítő adatok segítségével.


Hálózatok keresése

Némi késleltetés után, hogy hagyja, hogy a modul lecsatlakozzon, folytassa az elérhető hálózatok keresésével:


int n = WiFi.scanNetworks();

Most csak ellenőrizze, hogy az n értéke nagyobb-e, mint 0, és sorolja fel a talált hálózatokat:


for (int i = 0; i < n; i++)
{
  Serial.println(WiFi.SSID(i));
}

Ez ilyen egyszerű.


Teljes példa

A vázlatban kötelező az #include <ESP8266WiFi.h>, és a következőképpen néz ki:


#include <ESP8266WiFi.h>

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

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
}

void loop()
{
  Serial.print("Scan start ... ");
  int n = WiFi.scanNetworks();
  Serial.print(n);
  Serial.println(" network(s) found");
  for (int i = 0; i < n; i++)
  {
    Serial.println(WiFi.SSID(i));
  }
  Serial.println();

  delay(5000);
}


Példa akcióban

Töltse fel ezt a vázlatot az ESP modulba, és nyisson meg egy soros monitort. Ha a közelben vannak hozzáférési pontok (biztos, hogy vannak), hasonló listát fog látni ismételten kinyomtatva:


Scan start ... 5 network(s) found
Tech_D005107
HP-Print-A2-Photosmart 7520
ESP_0B09E3
Hack-4-fun-net
UPC Wi-Free

Amikor megpillantja a Scan start ... szöveget kijelezve, észre fogja venni, hogy észrevehető időbe telik, amíg az n network(s) found szöveg megjelenik. Ennek az az oka, hogy a WiFi.scanNetworks() végrehajtása időt vesz igénybe, és a programunk megvárja a befejezést, mielőtt a következő kódsorra lépne. Mi van, ha ugyanakkor azt szeretnénk, hogy az ESP olyan kritikus folyamatokat (pl. animációt) futtasson, amelyet nem szabad megzavarni?

Kiderül, hogy ezt meglehetősen könnyű megtenni a hálózatok aszinkron módban történő vizsgálatával.

Nézze meg az alábbi példában, amely bemutatja az elérhető hálózatok egyéb paramétereinek kinyomtatását is az SSID-n kívül.


Aszinkron felderítés

Amit szeretünk csinálni, az az, hogy elindítjuk a hálózatok keresésének folyamatát, majd visszatérünk a loop()-on belüli kód végrehajtásához. Miután a szkennelés befejeződött, egy megfelelő időpontban ellenőrizzük a hálózatok listáját. Az "időkritikus folyamatot" egy periódikusan, 250 ms-onként villogó LED szimulálja.

Szeretnénk, ha a villogó mintát soha ne zavarják meg.


Nincs delay()

Az ilyen funkciók megvalósításához tartózkodnunk kell a delay() használatától a loop()-on belül. Ehelyett meghatározzuk azt az időszakot, amikor egy adott műveletet el kell indítani. Ezután a loop()-on belül ellenőrizzük a millis()-t (belső óra, amely ezredmásodperceket számol), és elindítjuk a műveletet, ha az időszak lejár.

Kérjük, ellenőrizze, hogy ez hogyan történik a BlinkWithoutDelay.ino példavázlaton. Ugyanaz a technika használható a Wi-Fi hálózatok periódikus keresésének indítására.


Beállítás

Először is definiáljuk a vizsgálati periódust és a lastScanMillis belső változót, amely az utolsó vizsgálat elvégzésének időpontját tartalmazza.


#define SCAN_PERIOD 5000
long lastScanMillis;


Mikor kezdje

Ezután a loop()-n belül ellenőrizzük, hogy a SCAN_PERIOD lejárt-e, tehát ideje elindítani a következő vizsgálatot:


if (currentMillis - lastScanMillis > SCAN_PERIOD)
{
  WiFi.scanNetworks(true);
  Serial.print("\nScan start ... ");
  lastScanMillis = currentMillis;
}

Kérjük, vegye figyelembe, hogy a WiFi.scanNetworks(true) egy extra true paraméterrel rendelkezik, amely a fenti, korábbi példában nem szerepelt. Ez egy utasítás az aszinkron módban történő kereséshez, azaz indítsa el a keresési folyamatot, ne várja meg az eredményt (a feldolgozás a háttérben történik), és lépjen a következő kódsorra. Aszinkron módot kell használnunk, különben a 250 ms-os LED villogási mintázatát megzavarná, mivel a szkennelés 250 ms-nál tovább tart.


Ellenőrizze, mikor kész

Végül rendszeresen ellenőriznünk kell a szkennelés befejeződését, hogy az eredményt kinyomtassuk. Ehhez a WiFi.scanComplete() függvényt fogjuk használni, amely befejezésekor visszaadja a talált hálózatok számát. Ha a szkennelés még folyamatban van, a -1 értéket adja vissza. Ha a vizsgálat még nem indult el, akkor -2-t ad vissza.


int n = WiFi.scanComplete();
if(n >= 0)
{
  Serial.printf("%d network(s) found\n", n);
  for (int i = 0; i < n; i++)
  {
    Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i+1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i),
      WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : "");
  }
  WiFi.scanDelete();
}

Kérjük, vegye figyelembe a WiFi.scanDelete() funkciót, amely törli a szkennelés eredményét a memóriából, így az nem kerül kinyomtatásra újra és újra minden loop() futtatásakor.


Teljes példa

A teljes vázlat lent található. A setup()-on belüli kód megegyezik az előző példában leírtakkal, kivéve egy további pinMode()-t, amely konfigurálja a LED kimeneti kivezetését.


#include <ESP8266WiFi.h>

#define BLINK_PERIOD 250
long lastBlinkMillis;
boolean ledState;

#define SCAN_PERIOD 5000
long lastScanMillis;


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

  pinMode(LED_BUILTIN, OUTPUT);

  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
}

void loop()
{
  long currentMillis = millis();

  // blink LED
  if (currentMillis - lastBlinkMillis > BLINK_PERIOD)
  {
    digitalWrite(LED_BUILTIN, ledState);
    ledState = !ledState;
    lastBlinkMillis = currentMillis;
  }

  // trigger Wi-Fi network scan
  if (currentMillis - lastScanMillis > SCAN_PERIOD)
  {
    WiFi.scanNetworks(true);
    Serial.print("\nScan start ... ");
    lastScanMillis = currentMillis;
  }

  // print out Wi-Fi network scan result upon completion
  int n = WiFi.scanComplete();
  if(n >= 0)
  {
    Serial.printf("%d network(s) found\n", n);
    for (int i = 0; i < n; i++)
    {
      Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i+1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i),
        WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : "");
    }
    WiFi.scanDelete();
  }
}


Példa akcióban

Töltse fel a fenti vázlatot az ESP modulba, és nyisson meg egy soros monitort. Hasonló listát kell látnia 5 másodpercenként kinyomtatva:


Scan start ... 5 network(s) found
1: Tech_D005107, Ch:6 (-72dBm)
2: HP-Print-A2-Photosmart 7520, Ch:6 (-79dBm)
3: ESP_0B09E3, Ch:9 (-89dBm) open
4: Hack-4-fun-net, Ch:9 (-91dBm)
5: UPC Wi-Free, Ch:11 (-79dBm)


Következtetés

A scan osztály API átfogó metóduskészletet biztosít a szinkron és aszinkron módban történő szkenneléshez. Így egyszerűen implementálhatunk olyan kódot, amely a háttérben szkennel, anélkül, hogy megzavarná az ESP8266 modulon futó egyéb folyamatokat.

A szkennelési mód kezeléséhez biztosított funkciók listáját a Scan osztály dokumentációjában találja.


© Copyright 2017, Ivan Grokhotkov Revision 02c1a502. Fordította: Maczák András