Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Arduino R4 WiFi - prosty WiFiManager DIY - parowanie z siecią, zapis haseł w EEPROM

p.kaczmarek2 04 Sep 2023 08:29 1167 0
  • Arduino R4 WiFi - prosty WiFiManager DIY - parowanie z siecią, zapis haseł w EEPROM
    Pokażę tutaj moją prostą implementację tzw. "WiFiManger" na Arduino R4, czyli mechanizmu, który pozwala parować Arduino z naszą siecią WiFi w stylu parowania Tasmoty, czyli najpierw Arduino jest w trybie otwartego access pointa, do którego można się podłączyć i wpisać dane naszej sieci WiFi, a potem Arduino dołącza do naszej sieci, jednocześnie wciąż utrzymując stronę WWW z formularzem, gdzie można zmienić namiary na WiFi (podać nowe hasło i SSID) lub wrócić do trybu AP. Dodatkowo, biblioteka też pozwala zresetować ustawienie WiFi poprzez opcjonalny przycisk na wybranym GPIO Arduino.
    Taką funkcjonalność oferuje m. in. gotowy WiFiManager z Githuba:
    https://github.com/tzapu/WiFiManager
    Tyle, że nie wspiera on na ten moment Arduino R4 WiFi, dlatego tu pokażę mój prosty odpowiednik tej biblioteki, znacznie okrojony ale wciąż funkcjonalny.

    Wymagania projektowe
    Przed implementacją warto jest postawić sobie jakieś proste cele, które będą składały się na gotowy produkt. W tym przypadku wyróżniłem:
    - Arduino musi domyślnie uruchamiać się w trybie otwartego access pointa (bądź z hasłem), by była możliwa pierwsza konfiguracja
    - Arduino musi oferować stronę, gdzie można wpisać SSID i hasło docelowego WiFi
    - Arduino musi pamiętać ustawienia po utracie zasilania, musimy więc zapisywać je do EEPROM
    - Arduino musi oferować możliwość resetu ustawień w razie awarii (np. utraty routera), przykładowo poprzez wciśnięcie przycisku na jednym z GPIO
    - strona konfiguracyjna musi pracować zarówno w trybie AP, jak i w STA, co więcej w STA też musi oferować możliwość odłączenia od wybranego WiFi (powrót do trybu AP)
    Dodatkowo dałem sobie jeszcze jeden cel, też dość ważny, choć przez początkujących pomijamy, a mianowicie całość byłoby fajnie upakować w jakiegś wygodne klasy, by można było używać tego w różnych projekatch.

    Użyta biblioteka HTTP
    W celu ułatwienia sobie zadania zamierzam użyć dodatkowej biblioteki do obsługi HTTP, a mianowicie pracy QuickSander:
    https://github.com/QuickSander/ArduinoHttpServer
    Po moich poprawkach jest ona kompatybilna z R4:
    Arduino R4 WiFi i ArduinoHttpServer - poprawki, uruchomienie, przykłady użycia

    Przykład użycia
    Tym razem zacznijmy na odwrót. Zastanówmy się, jak byśmy chcieli, by wyglądał nasz program gdy biblioteka będzie już gotowa? Wszystko musi być schowane w klasach, kodu w setup i loop chcemy mieć mało.
    Widziałbym to mniej więcej tak:
    Code: c
    Log in, to see the code

    Skutkiem uruchomienia tego na Arduino powinna być obecność AP o określonej w kodzie nazwie:
    Arduino R4 WiFi - prosty WiFiManager DIY - parowanie z siecią, zapis haseł w EEPROM
    Po podłączeniu do niego (i podaniu określonego w kodzie hasła) powinno dać się otworzyć stronę o IP 192.168.4.1, gdzie można podać namiary naszej sieci WiFi:
    Arduino R4 WiFi - prosty WiFiManager DIY - parowanie z siecią, zapis haseł w EEPROM
    Po wpisaniu danych i zatwierdzeniu Arduino powinno się do niej podłączyć:
    Arduino R4 WiFi - prosty WiFiManager DIY - parowanie z siecią, zapis haseł w EEPROM
    Teraz strona konfiguracyjna powinna być dostępna pod nowym IP przypisanym przez DHCP. Też w pewnym stopniu powinien zmienić się jej wygląd:
    Arduino R4 WiFi - prosty WiFiManager DIY - parowanie z siecią, zapis haseł w EEPROM
    Tutaj można albo odłączyć się od bieżącego WiFi (wrócić w tryb AP), albo zmienić sieć WiFi na inną.

    Implementacja ustawień
    Może zacznijmy od sposobu przechowywania ustawień w EEPROM. Potrzebna będzie struktura, najlepiej z prostą sumą kontrolną by sprawdzać jej poprawność:
    Code: c
    Log in, to see the code

    W strukturze umieściłem dane osobno dla obu trybów WiFi i dodatkowo informację, który jest teraz aktywny.
    Następnie opakowałem ją w klasę:
    Code: c
    Log in, to see the code

    W tej klasie będą metody operujące na ustawieniach. Zacząć chyba trzeba od metody liczącej prostą sumę kontrolną. Zdecydowałem się zrobić to najprościej jak się da:
    Code: c
    Log in, to see the code

    Przechodzę tutaj bajt po bajcie pola struktury i sumuję ich wartości. Pomijam ostatnie pole, czyli CRC. Przypomnę, że sizeof( ) zwraca rozmiar bajtowy danego typu, odbywa się to w czasie kompilacji.
    Teraz można użyć CRC przy odczycie i zapisie danych do EEPROM Arduino. Przy odczycie odczytujemy CRC z pamięci i też je liczymy, a potem porównujemy te wartości Jeśli będą różne, to znaczy, że coś poszło nie tak:
    Code: c
    Log in, to see the code

    Przy zapisie do EEPROM tylko liczymy aktualne CRC, by móc je zapisać:
    Code: c
    Log in, to see the code

    Takie rozwiązanie daje nam relatywnie dużą pewność, że odczytane ustawienia są poprawne, chociaż może wiązać się też z pewnymi problemami. Przykładowo dodanie tutaj kolejnego pola do tej struktury byłoby problematyczne. Może warto byłoby na jej początku umieścić jeden dodatkowy bajt informujący nas o tym, w której wersji ustawień zapisane są dane. Pozwoliłoby to w razie czego potem konwertować struktury ustawień do aktualnej wersji. Jednakże to wszystko wykracza poza zakres prostego demka WiFi Manager DIY.



    Implementacja menedżera
    Mniej więcej temat przechowywania ustawień w EEPROM jest omówiony. Samych prostych getterów i setterów dla ustawień nie omawiam, tak samo jak tego, że w razie ich zmiany trzeba ponownie zapisać ich strukturę do pamięci EEPROM, itd. Ewentualnie w czasie zmiany można ustawiać tylko flagę pokazującą, że strukturę zmodyfikowano a potem zapisywać wszystkie zmiany na raz, aby oszczędzać cykle usuwania i zapisu.
    Teraz może skupmy się na samej obsłudze prostej strony HTTP.
    Zrealizowałem ją w oparciu o mój materiał:
    Arduino R4 WiFi i ArduinoHttpServer - poprawki, uruchomienie, przykłady użycia
    Tak jak w powyższym przykładzie, w pęli sprawdzam czy pojawia się nowy klient i jeśli tak, to go obsługuję:
    Code: c
    Log in, to see the code

    Podobny kod pojawił się w moim poprzednim materiale. Samą obsługę HTTP wydzieliłem do osobnej funkcji. Oto ona:
    Code: c
    Log in, to see the code

    Tu zatrzymamy się na chwilkę dłużej. Jak widać, strona jest generowana dynamicznie. Składam całość na bieżąco z czystego HTMLa, jest to najzwyklejszy formularz. Niektóre fragmenty strony są warunkowe, przykładowo nagłówek:
    Code: c
    Log in, to see the code

    Strona zawiera w sobie prosty formularz. Formularz ten wysyła zmienne poprzez żądanie GET, więc też w kodzie muszę to obsłużyć. Jeśli coś zostaje wysłane, to przechwytuję to i odpowiednio obsługuję, dając też o tym komuniikat:
    Code: c
    Log in, to see the code

    Funkcje openAccessPoint i setupSTA są w tej chwili mało istotne. One po prostu odpowiednio zmieniają ustawienia, zapisują je w EEPROM a zmiana trybu wykonana jest z opóźnieniem:
    Code: c
    Log in, to see the code

    W przeciwnym razie po wysłaniu namiarów na nowe WiFi Arduino by automatycznie się odłączyło od nas i byśmy już nawet nie otrzymali potwierdzenia, że nasze żądanie zostało przetworzone.

    Zasadniczo to będzie na tyle. Można jeszcze spojrzeć na funkcje ustawiające tryb WiFi, ale to już jest nawet w przykładach od samego Arduino:
    Code: c
    Log in, to see the code

    Code: c
    Log in, to see the code

    No i funkcja, która startuje całego menedżera i określa który tryb pracy wybrać:
    Code: c
    Log in, to see the code



    Podsumowanie
    W temacie dokonałem pewnych dużych uproszczeń i pominąłem nieco pobocznych kwestii, ale i tak myślę, że finalne demko zapewnia niezbędne minimum funkcjonalności. W oparciu o mój sketch można budować własną aplikację na Arduino R4 a nawet można by też mój kod wydzielić do biblioteki i współdzielić między różnymi projektami. Możliwe, że potem się tym zajmę, dokończę cały kod, poprawię drobne błędy, niedociągnięcia (bezpieczeństwo rozmiaru buforów - patrz strcpy itd.) i umieszczę na Githubie jako bibliotekę. Tymczasowo tutaj macie pełną wersję:
    Spoiler:

    Code: c
    Log in, to see the code


    Jak ktoś chce go usprawnić, to zapraszam do zabawy. W przyszłości można by dodać jakiś prosty interfejs do obsługi dodatkowych zmiennych bądź podstron, może poprzez callbacki. Tak użytkownicy mogliby "wpiąć" w tę stronę swoje dodatki, takie jak wyświetlanie bieżącej temperatury i wilgotności ze stacji pogodowej DIY bądź sterowanie przekaźnikiem.

    Cool? Ranking DIY
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline