NodeMCU – Praca w trybie AP, czyli własne WiFi

Przeglądając różne tutoriale o ESP8266/NodeMCU w internecie w praktycznie każdym można spotkać się z zahardcodowanymi danymi o sieci do której ma łączyć się nasz moduł. Na początkowych etapach projektu ma to sens, bo testujemy wszystko głównie w jednym środowisku z konkretną działającą siecią. Co jednak jeżeli chcielibyśmy, aby nasze urządzenie mogło łączyć się z dowolną siecią WiFi bez konieczności flashowania nowego firmware? W tym artykule dowiemy się jak ugryźć ten temat zaczynając od udostępnienia własnej sieci, a w kolejnych pokażę Wam jak w łątwy sposób sprawić, aby nasze urządzenie było w pełni konfigurowalne. Zaczynajmy więc :)

Na wstępie zaznaczę, że będziemy pracowali w Arduino IDE w języku C++, dlatego przed wykonaniem czynności w artykule należy doinstalować sobie zestaw płytek opartych o ESP8266 do naszego środowiska. Instrukcję jak to zrobić możecie znaleźć tutaj.

A komu to potrzebne? A dlaczego?

W tym miejscu chciałbym też objaśnić po co w ogóle mamy udostępniać swoją sieć WiFi. Jak wiemy chcemy dokonać wstępnej konfiguracji, czyli przekazania do modułu ESP8266 przynajmniej takich danych jak nazwa sieci i hasło. Myślę, że najprostszym scenariuszem z punktu widzenia użytkownika będzie taki, kiedy po podłączeniu naszego urządzenia zobaczy sieć WiFi z którą może się połączyć i np. na stronie WWW lub przez aplikację mobilną będzie mógł wpisać wymagane dane. Po zapisaniu konfiguracji urządzenie uruchomi się ponownie i wtedy już połączy się z właściwą siecią w której może udostępniać swoje usługi lub uzyskać dostęp do internetu.

Podstawowy kod

Zacznijmy od tego, że aby móc korzystać z funkcji modułu WiFi w naszym procesorze musimy załączyć bibliotekę ESP8266WiFi. W tym celu na samym początku kodu programu wpisujemy

#include <ESP8266WiFi.h>

Teraz w funkcji setup() należy wywołać metodę softAP klasy WiFi:

void setup() {
    WiFi.softAP("Nettigo Config");
}

I na tym w zasadzie moglibyśmy zakończyć artykuł, bo po skompilowaniu takiego kodu nasze ESP8266 będzie rozgłaszało otwartą sieć o nazwie „Nettigo Config„. Zagłębmy się jednak w temacie trochę bardziej.

Parametry metody softAP

Pełna sygnatura tej metody wygląda następująco:

WiFi.softAP(ssid, password, channel, hidden)

Widać tutaj, że poza nazwą sieci możemy podać też hasło do niej, a jeżeli chcemy iść jeszce dalej możemy ręcznie wybrać kanał na którym będzie rozgłaszana oraz czy ma być ukryta (chociaż ukrycie sieci raczej nie ułatwi konfiguracji :) )

Ustalenie adresu IP

Ok mamy sieć, ale w jaki sposób możemy komunikować się z modułem? Musimy znać jego adres IP. Domyślnym adresem ESP będzie 192.168.4.1, jednak moim zdaniem warto dla pewności samemu go ustalić na jakiś bardziej typowy (np. bardzo często spotykany 192.168.0.1 lub 192.168.1.1). W tym celu musimy utworzyć sobie trzy zmienne typu IPAddress.

IPAddress localIp(192,168,1,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

Są to kolejno adres IP urządzenia, adres bramy oraz maska podsieci.

Mając takie trzy zmienne przed utworzeniem sieci należy ją skonfigurować:

WiFi.softAPConfig(localIp, gateway, subnet);

Na chwilę obecną nasz kod powinien wyglądać tak:

void setup() {
  IPAddress localIp(192,168,1,1);
  IPAddress gateway(192,168,1,1);
  IPAddress subnet(255,255,255,0);
  
  WiFi.softAPConfig(localIp, gateway, subnet);
  WiFi.softAP("Nettigo Config");
}

Resetowanie ustawień

Wspomnę tu jeszcze o jednej rzeczy, której można nie zauważyć na początku. Kiedy implementowałem tę funkcjonalność w swoim projekcie przy testach zauważyłem, że w momencie kiedy urządzenie zaczęło rozgłaszać swoją sieć, a następnie zostało zresetowane programowo to w dalszym ciągu ta sieć była rozgłaszana (pomimo braku jej bezwarunkowej inicjalizacji w funkcji setup()). Dlatego też warto na początku tejże funkcji dopisać takie 3 linijki:

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

Spowodują one przełączenie modułu WiFi w tryb STA, a tym samym rozłączenie wszystkich istniejących połączeń i rozgłaszanych sieci. 100 ms przerwa zagwarantuje nam, że moduł WiFi który działa asynchronicznie do reszty procesora zdąży wyłączyć wszystkie sieci.

Ostatecznie dobry kod za pomocą któego możemy uruchomić własną sieć WiFi w module powinien wygląać w ten sposób:

#include <ESP8266WiFi.h>

void setup() {
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  
  IPAddress localIp(192,168,1,1);
  IPAddress gateway(192,168,1,1);
  IPAddress subnet(255,255,255,0);
  
  WiFi.softAPConfig(localIp, gateway, subnet);
  WiFi.softAP("Nettigo Config");
}

void loop() {
  
}

Na późniejszych etapach dodamy do niego uruchomienie serwera konfiguracyjnego, zaimplementujemy funkcje zapisu i odczytu konfiguracji oraz napiszemy aplikację na Androida do konfiguracji sieci tak, żeby proces ten był jak najbardziej intuicyjny dla użytkownika końcowego.