logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi

p.kaczmarek2 08 Gru 2023 14:22 2049 2
REKLAMA
  • Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi
    Przedstawię tu jak można zrobić własny bezprzewodowy gamepad w oparciu o Arduino R4 WiFi i Joystick shield. Nasz kontroler będzie łączył się z naszą siecią WiFi i wysyłał na nasz serwer dane o wciśniętych klawiszach poprzez protokół bezpołączeniowy UDP, co zapewni nam szybką reakcję na wciskane klawisze.

    Potrzebne nam będzie zasadniczo tylko tytułowe Arduino R4 WiFi i tytułowy joystick shield, do kupienia za jakieś kilkanaście złotych:
    Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi
    Tu już trzeba zaznaczyć, że ten shield oferuje dwa rodzaje sterowania:
    - sam joystick pozwala sterować analogowo, mam przez to na myśli, że odczytana z jego potencjometrów wartość wiernie odzwierciedla wychylenie gałki
    - przyciski, jak to przyciski, dają nam tylko informacje booleowską, true lub false, wciśnięte lub nie
    Możliwość sterowania analogowego joystickiem pozwala nam na lepszą precyzję w poruszaniu tym, czym akurat sterujemy.
    Joystick shield pasuje na Arduino R4, gdyż ma ono tę samą formę co poprzednie Uno R3:
    Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi

    Uruchomienie joystick shield
    Zacznijmy od samego uruchomienia shielda. Na szczęście, tak jak to w środowisku Arduino bywa, mamy już gotowy do tego sketch.
    Klasa JoystickShield sprytnie ukrywa odczyt przycisków i ADC za ładnymi, dobrze opisanymi funkcjami.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Wgrywamy, testujemy:
    Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi
    Wszystko działa, a wychylenia mamy w zakresie od -100 do 100, czyli nie są to zwykłe przyciski - o to właśnie chodziło, to pozwala sterować danym urządzeniem w precyzyjny sposób.


    Upakowujemy we własną strukturę
    Tak zebrane dane trzeba jakoś przekazać dalej. W tym celu warto upakować jest je w strukturę. Przyciski mogą być w jednym polu typu integer (a nawet może się zmieszczą w bajcie) jako poszczególne bity. Tak oszczędzamy miejsce. Natomiast wychylenie musi być już jako liczba całkowita ze znakiem. Dodatkowo dodałem sobie ID pakietu, które jest jego zasadniczo kolejnym indeksem, zwiększanym z każdą wysyłką danych.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Tak wygląda wypełnianie struktury. Zmienna globalna odlicza kolejne pakiety.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Jeszcze trzeba wypełnić przyciski. W tym celu dodałem enumerację określającą, który indeks bitu odpowiada za który przycisk:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Potem trzeba zapalać odpowiedni bit, gdy dany przycisk jest wciśnięty. Aby zamienić indeks bitu na maskę trzeba użyć przesunięcia bitowego, a aby zapalić ten bit, używamy OR.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    Wysyłamy dane przez UDP
    Teraz trzeba wysłać naszą strukturę przez sieć. Zdecydowałem się na protokół bezpołączeniowy UDP. On co prawda może gubić pakiety, ale przynajmniej przesyłać je będzie szybko. Uznałem, że to ważniejsze, niż rzetelność połączenia, którą oferuje TCP.
    Przeanalizujmy zatem demko z samego Arduino R4, klienta UDP usługi NTP:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Zasadniczo musimy wykorzystać pokazane powyżej wysyłanie:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Należy pamiętać, że wysyłamy dane na konkretny adres IP i port. Na tym adresie IP i porcie musi nasłuchiwać serwer.
    Modyfikacja powyższego kodu jest bardzo prosta. Po prostu usuwamy wysyłanie wedle protokołu NTP i zamiast tego wysyłamy naszą strukturę. Gotowe.

    Odbiór danych na komputerze
    Teraz trzeba jeszcze odebrać wysłane dane. Posłuży nam do tego serwer UDP. Serwer UDP można bardzo prosto utworzyć w C# przy użyciu klasy UdpClient.
    Ważne, by nasłuchiwać na tym samym porcie na który wysyłamy dane.
    Potem możemy odbierać w pętli pakiety i je przetwarzać za pomocą BinaryReader. Nie musimy się tu martwić o fragmentację, tak małe pakiety nie są dzielone, mieszczą się w całości w jednej ramce:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Odpalamy oba programy, zarówno joystick jak i serwer.... upewniamy się, czy są w tej samej sieci WiFi i... sukces:
    Arduino R4 WiFi i Joystick shield - własny bezprzewodowy kontroler na WiFi
    Nasz program poprawnie odbiera dane z kontrolera.

    Podsumowanie
    Prosty i przyjemny projekt. Już zasadniczo można czymś sterować na PC.
    Analogicznie można postawić serwer UDP na drugim Arduino, ESP bądź czymkolwiek innym i tam odbierać pakiety z inputem użytkownika.
    Również można by rozwinąć moją aplikację napisaną w C# tak by wysyłała Windowsowe wciśnięcia klawiszy czy tam ruszała myszką, wtedy nasz Arduino gamepad pozwoliłby nawet nam sterować naszym PC.
    Możliwości są bardzo duże.
    Czy widzicie jakieś zastosowanie dla takiego DIY?
    Na koniec przypomnę też mój wcześniejszy gamepad, który realizowałem na PIC:
    Gamepad USB/HID na PIC18F45K50 (z dodatkowym trybem myszki oraz CDC)
    PS: Jeśli nie zależy nam na szybkiej reakcji sterowanego urządzenia, ale zależy nam na tym, by każdy pakiet docierał do celu, należy przerobić przykład tak by korzystał z rzetelnego, połączeniowego TCP. TCP gwarantuje, wysłane pakiety dotrą (chyba, że całkiem zostanie zerwane połączenie) i w razie problemu je wysyła ponownie, a UDP wysyła je na ślepo bez sprawdzania odbioru)

    Fajne? Ranking DIY
    Pomogłem? Kup mi kawę.
    O autorze
    p.kaczmarek2
    Moderator Smart Home
    Offline 
  • REKLAMA
  • #3 20853049
    p.kaczmarek2
    Moderator Smart Home
    Aby zbadać opóźnienia, pewnie bym chciał zaimplementować własny mechanizm "ping", tj. numerować wysłane pakiety oraz pamiętać ich czasy wysłania na Arduino (chociażby ostatnich N wysłanych), a w kliencie w C# odsyłać jakiś prosty ACK też z numerem pakietu. Potem na Arduino, w momencie odebrania ack można by znaleźć czas nadania danego pakietu i odjąć go od bieżącego czasu, by otrzymać RTT (Round Trip Time, czas komunikacji w obie strony).
    Można by wtedy dać wyświetlanie tego RTT w ogóle do funkcjonalności programu, tak jak wyświetlają niektóre inne usługi.
    Co do samych wartości opóźnień, to pewnie dużo by zależało, jak to z reguły bywa, co do samego WiFi...
    Też inna sprawa, że dla największej responsywności trzeba by zoptymalizować logikę wysyłania pakietów, nie wysyłać ich zawsze co stały czas, tylko wysyłać w miarę możliwości od razu jak nastąpi jakaś zmiana oraz co jakiś stały czas jeśli nie ma zmiany.
    Na pewno przedstawione demko daje dużo pole popisu do usprawnień i rozwoju
    Pomogłem? Kup mi kawę.
REKLAMA