WiFi Manager w PlatformIO - wygodna konfiguracja WiFi dla ESP8266 i ESP32 - tutorial
TL;DR
- Integruje WiFiManager z projektem na ESP8266/ESP32 w PlatformIO, pokazując wygodną konfigurację WiFi przez portal AP zamiast sztywno wpisanych SSID i hasła.
- Wywołanie autoConnect tworzy konfiguracyjny Access Point, a przycisk na pinie AP_TRIGGER_PIN z INPUT_PULLUP pozwala wrócić do trybu parowania.
- Portal działa pod adresem 192.168.4.1, a WiFiManager umożliwia też dodawanie własnych parametrów, np. przesunięcia czasu dla klienta NTP.
- Ponieważ parametry nie zapisują się same, przykład używa emulowanej EEPROM w Flash i prostej sumy kontrolnej, by wykryć pierwszy start i zachować ustawienia po restarcie.
- Po konfiguracji ESP zapamiętuje dane sieci, łączy się automatycznie przy kolejnych uruchomieniach i udostępnia stronę /info ze stanem urządzenia.
Wygenerowane przez model językowy.
WiFiManager to biblioteka oferująca gotowy system parowania z naszym WiFi a jej konfiguracja to raptem kilka linijek kodu. Parowania dokonuje się w trybie AP (sieci WiFi emitowanej przez ESP) a potem, po podaniu namiarów na naszą sieć, system sam je zapamiętuje i korzysta z nich przy kolejnych uruchomieniach. Konfiguracyjny Access Point można opcjonalnie zabezpieczyć hasłem. WiFiManager oferuje również możliwość przywrócenia urządzenia do trybu parowania z poziomu kodu, np. po wciśnięciu przycisku, co pozwala na łatwe jego przeniesienie na inne WiFi w przyszłości.
Tutaj pokażę krok po kroku jak wygląda przykładowa integracja WiFiManager z gotowym projektem. W tym celu użyję programu zegara ze starszego tematu:
Zegar na ESP12 i wyświetlaczu MAX7219 - tutorial - część 1, ArduinoOTA, podstawy
Mam już tam skonfigurowane ArduinoOTA czyli mechanizm aktualizacji wsadu przez WiFi, ale nie ma jeszcze WiFiManager...
Cały kod jest w zalinkowanym temacie - wraz z wytłumaczeniem działania OTA itd.
Użyję tutaj WiFiManager by tzapu, dokumentacja jest dostępna tutaj.
Podstawowa integracja WiFiManager
Moje projekt realizuję w oparciu o PlatformIO ze względu na prostotę i dostępność tego środowiska. Preferuję je ponad ArduinoIDE. A więc najpierw dodajemy WiFiManager przez PlatformIO/Libraries:
W naszym programie, kolejno:
- wyrzucamy stary kod łączenia się z WiFi, razem z wpisanym na sztywno naszym hasłem i SSID
- załączamy nagłówek Managera
Kod: C / C++
- tworzymy globalnie obiekt jego klasy
Kod: C / C++
- uruchamiamy parowanie bądź połączenie z zapamiętanym WiFi
Kod: C / C++
autoConnect ma dwa argumenty - nazwa WiFi konfiguracyjnego (ESP utworzy sieć o takiej nazwie) oraz, opcjonalnie, hasło
Te wywołanie jest blokujące - program się zatrzyma dopóki WiFi nie zostanie skonfigurowane.
To by było w zasadzie tyle, ale warto jeszcze dać opcję odparowania na wypadek gdybyśmy zmieniali naszą sieć. A więc, w głównej pętli:
Kod: C / C++
Wcześniej jeszcze na starcie trzeba ustawić pin AP_TRIGGER_PIN w tryb wejścia, a sprzętowo zadbać o to, by był tam dostępny przycisk zwierający go do masy. Sam użyłem trybu pinMode(AP_TRIGGER_PIN, INPUT_PULLUP); aby nie musieć podłączać rezystora podciągającego do napięcia zasilania, a więc na pinie domyślnie jest stan wysoki (1) dopóki ktoś nie wciśnie przycisku.
Pełen kod po zmianach:
Kod: C / C++
Teraz pora sprawdzić, czy to działa. Skompilowałem, wgrałem i oto ukazała się sieć konfiguracyjna:
Po podłączeniu się do niej można odwiedzić stronę o adresie 192.168.4.1:
Można tam uzyskać listę sieci WiFi widzianych przez ESP oraz podłączyć się do jednej z nich:
ESP zapamiętuje podane hasło i po chwili dołącza do mojego WiFi:
Sukces!
Sprawdziłem też zachowanie przycisku - poprawnie uruchamia z powrotem tryb AP a w celu zakomunikowania o tym użytkownikowi, dodałem wtedy wyświetlanie na ekranie napisu Config:
Podstawowa funkcjonalność działa, ale to nie wszystko.
Parametry w WiFiManager
WiFiManager oferuje jednak więcej niż tylko konfiguracja naszego SSID i hasła. Zasadniczo mamy tutaj cały dodatkowy system parametrów, które są automatycznie pokazywane na stronie WWW, wyświetlane oraz edytowane. Nowy parametr dodajemy tworząc obiekt klasy WiFiManagerParameter. Poniżej zademonstruję to na przykładzie przesunięcia czasu (stref czasowych), przesunięcie będzie wyrażone w sekundach. Najpierw globalnie:
Kod: C / C++
Potem, w funkcji setup, dodajemy utworzony parametr i pobieramy jego zawartość po konfiguracji:
Kod: C / C++
atoi zamienia ciąg znaków na liczbę całkowitą. Analogicznie, jeśli wspieramy konfigurację w trakcie działania programu (w loop), to wtedy też po niej musimy odświeżyć wartość parametru. Potem można go przekazać do klienta NTP, by ustawić przesunięcie czasu.
Kod: C / C++
Cały kod po integracji parametru:
Kod: C / C++
Od teraz parametr jest widoczny na stronie konfiguracyjnej:
Testujemy, wszystko działa, a potem nagle restartujemy ESP i.... niespodzianka - parametr się zresetował.
Wyjaśnienie tego zjawiska jest w samej dokumentacji WiFiManager:
WiFiManager niestety ich nie zapisuje, musimy to zrobić sami.
Prosty zapis parametrów
Musimy samodzielnie zapisywać zawartość przesunięcia strefy czasowej. Na ESP nie mamy pamięci EEPROM, ale mamy pamięć Flash, do której można się dostać poprzez klasę o nazwie.... EEPROM. To chyba w celu zachowania zgodności nazw z innymi platformami Arduino, gdzie faktycznie używa się EEPROM. W przypadku ESP (w tym NodeMCU) klasa EEPROM emuluje pamięć EEPROM w części pamięci Flash. Dzięki temu możemy zapisywać dane trwałe, które pozostaną po restarcie urządzenia.
To teraz trzeba zastanowić się, co musimy dodać. W teorii potrzeba:
- odczytu ustawień na starcie z EEPROM i wysłania ich do WiFiManagera
- po konfiguracji w WiFiManager trzeba zapisać te ustawienia z powrotem do EEPROM
W praktyce jednak pojawia się problem "pierwszego uruchomienia", tj. pierwsze włączenie płytki wczyta w tym przypadku z EEPROM jakieś losowe dane, będzie to to, co akurat się tam trafiło w pamięci...
W tym celu dodatkowo liczę prostą sumę kontrolną (pochodną ustawień) i sprawdzam czy ona się zgadza, ponieważ szanse na to, że przez przypadek dane z EEPROM będą miały sumę zgodną z obliczoną są naprawdę małe i w praktyce pozwoli to wykryć "pierwszy start".
Przykładowa implementacja:
Kod: C / C++
Pozostałe funkcje (z dodanym wywołaniem odczytu/zapisu):
Kod: C / C++
Od teraz przesunięcie czasu jest pamiętane nawet po utracie zasilania. Zegar pokazuje poprawną godzinę:
Strona informacyjna
Warto jeszcze dodać, że WiFiManager oferuja prostą stronę informacyjną o naszym urządzeniu. Można tam sprawdzić stan ESP oraz sieci do której jest podłączony. Dostępna jest ona pod adresem zasobu /info.
Podsumowanie
Bardzo prosta i wygodna w użyciu biblioteka. Zdecydowanie warto jej używać, dzięki takiemu prostemu systemu parowania z WiFi nasze projekty stają się użyteczne nawet lata po tym, jak zmieni dane naszej bieżącej sieci WiFi i nie trzeba ich osobno kompilować by uruchomić je z innym routerem. Dodatkowo całość bezproblemowo działa z ArduinoOTA, więc moim zdaniem obie te biblioteki powinny być jako pierwsze uruchamiane w naszych projektach.
Oczywiście pokazany kod to jest tylko przykład i można by go zoptymalizować pod kątem redukcji zużycia flash (nie zapisywać jak nie nastąpiła zmiana), przepisać w sposób uniwersalniejszy (lepsze liczenie sumy kontrolnej itd), ale nie to było tu celem. Być może w ogóle w osobnym temacie zaprezentuję lepsze rozwiązania - LittleFS - i wtedy wrócę do tematu zapisu ustawień.
Czy korzystaliście w swoich projektach z WiFiManager, czy też może macie inne rozwiązania by nie musieć zapisywać danych WiFi na sztywno w kodzie?
Komentarze
Dodam, że parametry w WiFiManager mogą być bardzo przydatne przy konfiguracji MQTT. Od razu konfigurujemy naszą sieć i dodatkowo dostęp do MQTT. [Czytaj dalej]
Fajny przykład, w sumie mój kod można by o to ulepszyć, widzę że oni użyli: wifiManager.setSaveConfigCallback(saveConfigCallback); do wywołania zapisu, a ja w kodzie tematu zapisuję na ślepo.... [Czytaj dalej]
No dobra, ja mam problem z tą biblioteką pod kątem, przywracania połączenia po jego utraceniu, znacznie lepiej się sprawdza prosta logika wyłączająca i przywołująca połączenie, ale pewnie to ja coś źle... [Czytaj dalej]
Fajne, dodaj jeszcze opis jak tworzyć wygodnie inne strony, jakbyśmy chcieli chociażby wyklikać z WebUI timezone - wtedy opis byłby dla mnie w pełni kompletny :) Ewentualnie, jak zrobić odpalanie WiFi... [Czytaj dalej]