Jak działa nasz pilot z mikrofonem
Ma to na celu wyjaśnienie jak technicznie działa nasz pilot radiowy.
Opis ten może być pomocny przy diagnozowaniu problemów oraz w przypadku gdyby ktoś chciał dodać do bramki własny kontroler lub mikrofon.
Założenia wstępne
Zakładamy, że:
- posiadasz nasz pilot radiowy z mikrofonem
- przeczytałeś opis jak ten pilot działa Pilot radiowy z mikrofonem | AI-Speaker
- w razie problemów przeczytałeś FAQ Pilot FAQ | AI-Speaker
Wprowadzenie
Czym jest kontroler AI-Speker
Jest to uniwersalny kontroler który dzięki wbudowanemu mikrofonowi i fizycznym klawiszom pozwala na obsługiwanie wszystkich funkcji w systemie Asystent domowy.
Z czego fizycznie się składa kontroler
Z nadajnika (pilot) i odbiornika radiowego (klucz USB).
Transmisja odbywa się na częstotliwości 2,4 GHz (częstotliwość taka jak WiFi ale inny protokół).
Dzięki temu mamy:
- duży zasięg działania,
- nie trzeba trafiać w odbiornik,
- bardzo małe zużycie energii - podczas używania pobiera mniej niż 10 mA prądu z baterii. Gdy nie jest używana, tylko mikroamper (czyli prawie nie pobiera żadnego prądu).
Czym jest kontroler w Asystencie domowym
3 urządzeniami:
- klawiaturą bezprzewodową
- żyroskopową myszą z czujnikiem położenia
- kartą audio z mikrofonem radiowym
Jak to działa w systemie
Po włożeniu klucza USB system wykonuje tzw. Plug and Play i Jolka mówi “Dodano urządzenie…”.
Technicznie po włożeniu klucza kontrolera do portu USB, system go zasila i wykrywa urządzenie - proces ten nazywa się USB enumeration. Wyjaśnimy poniżej jak to działa.
Tryb hosta USB
Gdy urządzenie USB jest podłączone do bramki, jak pokazano na zdjęciu poniżej
Rys.1. Bramka w trybie hosta USB
wtedy bramka jest w trybie hosta USB (wbudowany host USB lub jako OTG) - w zależności od tego do którego portu podłączono urządzenie).
Bycie hostem USB oznacza, że to bramka obsługuje podłączone urządzenia USB (takie jak mikrofony, myszy, klawiatury i pendrive’y) - te urządzenia są akcesoriami.
Gdyby bramkę podłączyć do PC po USB OTG to wtedy bramka przełączyła by się w tryb “Accessory” a hostem USB był by komputer PC. Tym trybem pracy bramki nie będziemy się tu zajmować.
Istotne na rysunku powyżej jest to, że to Host USB musi zasilać podłączone urządzenie - dostarczać zasilanie 5 V (specyfikacja określa, że powinno być ono między 4,75 V a 5,25 V) i 500 mA.
Wynik wykrycia urządzenia można sprawdzić poleceniem w konsoli:
lsusb
Rys.2. Wynik komendy libusb na bramce
Może się zdażyć, że po podłączeniu urządzenia USB system nie może go wykryć z powodu problemu z zasilaniem - urządzenie do działania może wymagać więcej prądu niż magistrala USB jest mu w stanie dostarczyć (więcej niż 500 mA). W takim wypadku pomocne może być dołożenie zasilanego koncentratora USB (hub) między bramką a urządzeniem USB.
Zarządzanie urządzeniami przez system Linux
Programowo zarządzanie urządzeniami USB przez Asystenta domowego odbywa się pomiędzy jądrem systemu Linux a przestrzenią użytkownika w systemie Android.
Obrazuje to grafika poniżej.
Rys.3. Zarządzanie USB w systemie Linux / Android
W przestrzeni jądra linux (Android Kernel Space). działanie USB trybie hosta USB jest takie samo jak w głównym jądrze Linuksa (mainline Linux kernel).
W tym opisie nie będziemy wnikać jak to się dzieje, że Linux z podłączonego urządzenia robi plik w systemie. Istotne jest to, że w Linux wszystko jest plikiem - urządzenia dołączone po USB też.
W uproszczeniu można powiedzieć, że na bardzo niskim poziomie, komunikacja z każdym urządzeniem w systemie odbywa się poprzez pisanie i czytanie do plików w lokalizacji /dev
ls -l /dev/usb/*
Rys.4. Wynik komendy ls -l /dev/usb/* na bramce AIS dom
Wykrywanie urządzeń przez Asystenta domowego
Tak jak pokazano na rysunku powyżej, dla nas kluczową “warstwą” do komunikacji z urządzeniami jest system plików jądra (Kernel USB File System) oraz libusb który jest interfejsem między sterownikiem USB jądra systemu Linux a naszym programem.
Zanim dojdzie jednak do komunikacji z urządzeniem Asystent domowy jesteśmy powiadamiany przez mechanizm uevent - powiadamianie przestrzeni użytkownika o zdarzeniach. Komunikaty “zdarzenia użytkownika” (uevents) są generowane przez sterownik jądra Linuxa.
W ten sposób Jolka wie, że podłączono urządzenie zigbee, dysk czy kontroler z mikrofonem.
Rys.5. Prostą ilustracja mechanizmu uevent na bramce AIS dom
Po tym jak dostaniemy powiadomienie o podłączonym urządzeniu możemy uruchomić stosowną usługę (pm start zirbee2mqtt), podmapować dysk i automatycznie pokazać go w folderze “dyski wymienne” itd.
Po usunięciu urządzenia też jesteśmy powiadamiani i wtedy zatrzymujemy usługę itd…
Kontroler - klawiatura i myszka
Interfejsem do urządzenia są pliki /dev/input/*
ls -l /dev/input/*
Rys.6. Wynik komendy ls -l /dev/input/* na bramce AIS dom
Komunikacja nie odbywa się bezpośrednio przez plik ale przez usługę “Input Manager” która korzysta z binarki libinput.so.
Asystent domowy zdarzenia o naciśnięciu przycisku kontrolera czy ruchu myszy otrzymuje z systemu Linux jako (Input events). Za każdym razem, gdy użytkownik naciśnie przycisk na kontrolerze - generowane jest zdarzenie, które przechwytujemy w Asystencie domowym.
Aby obserwować zdarzenia które są generowane, możesz wpisać w konsoli coś takiego:
su -c getevent
Rys.6. Wynik komendy su -c getevent na bramce AIS dom
: getevent stale wyświetla nadchodzące zdarzenia, dopóki nie naciśniesz Ctrl-C.
Format zwracany przez getevent to typ zdarzenia, kod zdarzenia i wartość zdarzenia.
Dzięki temu możemy sprawdzić, czy kontroler przekazuje odpowiednie informacje do systemu Asystent domowy.
W podobny sposób możemy wysłać zdarzenie (naciśnięcie klawisza) do Asystenta domowego.
su -c "sendevent /dev/input/event7 1 330 1"
Rys.7. Wynik komendy sendevent na bramce AIS dom
Jak widać dane wyjściowe getevent są w formacie szesnastkowym (hexadecimal,), ale dane wejściowe sendevent są dziesiętne. Po naciśnięciu przycisku wysyłane jest więcej zdarzeń - jeżeli zmienimy format to w ten sposób możemy programowo symulować naciśnięcie przycisku.
Prościej można wysłać zdarzenie naciśnięcia klawisza za pomocą komendy input tu wystarczy podać 2 parametry:
input keyevent
Na bazie komendy input keyevent działa nasza usługa która może być wywołana z poziomu aplikacji Asystent domowy.
Rys.8. Usługa - emulacja naciśnięcia klawisza na kontrolerze, za pomocą input keyevent na bramce AIS dom
Kontroler - mikrofon
Urządzenia audio nie są obsługiwane bezpośrednio przez /dev/input/* ale poprzez interfejs ALSA, binarki libtinyalsa.so i libaudio.so i serwis Audio Flinger.
Po podłączeniu kontrolera jego mikrofon dodany jest jako karta dzwiękowa, co można sprawdzić komendą:
cat /proc/asound/cards
Rys.9. Wynik komendy cat /proc/asound/cards na bramce AIS dom
Kary dziękowe mogą być obsługiwane za pomocą miksera, który ma zwykle kilka kontrolek.
Żeby zobaczyć, jakie kontrolki ma nasz kotroler (karta 2), wpisujemy w konsoli taką komedę:
su -c 'tinymix -D 1'
Rys.10. Wynik komendy su -c ‘tinymix -D 1’ na bramce AIS dom
Kontroler 2 (Mic Capture Volume) odpowiada za głośność mikrofonu na kontrolerze, żeby wyświetlić jego, parametry wpisujemy w konsoli:
su -c 'tinymix -D 1 2'
Rys.11. Wynik komendy su -c ‘tinymix -D 1 2’’ na bramce AIS dom
Więcej o możliwościach tinyalsa można przeczytać na stronie projektu:
To jak to się dzieje, że po włożeniu HDMI dzwięk jest tam przekierowany a po podpięciu SPDIF tam itd to już zasługa Androida i Audio Flinger
Mam nadzieje, że powyższy opis wprowadza w temat tego jak działa kontroler w Asystencie domowym, po zgłębieniu tego tematu przy odpowiednich zdolnościach programistycznych, można dodać własny kontroler i wysyłać z niego zdarzenia do bramki.
Oczywiście prościej będzie kupić nasz kontroler, włożyć do bramki - Jolka powie, że “Podłączono pilot radiowy z mikrofonem” i niech to magicznie działa