Raspberry Pi i AppInventor (+mój „Ambient Light”)

Od dłuższego czasu pracuję nad projektem dynamicznego podświetlenia telewizora w stylu „Ambient Light”. Pomysł polega na umieszczeniu za telewizorem taśm LED. Ich kolor ma się zmieniać w zależności od tego, co jest wyświetlane na ekranie.

small_IMG_0089Do sterowania diodami postanowiłem wykorzystać telefon z Androidem i aplikację zbudowaną z pomocą AppInventora.

Wszystkie fazy projektu podświetlenia opisałem: Doświadczenia z taśmami LED i Raspberry Pi

Poniższe rozważania dotyczą konkretnego przypadku wykorzystania telefonu z Androidem do sterowania budowanego przeze mnie systemu podświetlenia telewizora. Wiele z poniższych sposobów możecie jednak wykorzystać w innych projektach.

W Fazie 1 projektu, sterowałem kolorem diod manualnie za pomocą pilota dostarczonego w zestawie z taśmami. W Fazie 2, sterowanie przejął zainstalowany na Raspberry Hyperion. OSMC (system multimedialny na Raspberry) wyświetla wideo. Hyperion je analizuje i wysyła instrukcje co do koloru i jasności diod po USB do zamontowanego z tyłu telewizora Arduino. Arduino interpretuje instrukcje z Hyperiona, przetwarza je na sygnał PWM i za pomocą zestawu tranzystorów odpowiednio steruje diodami na taśmie.
Protokół Hyperiona (pi-blaster) rozszerzyłem o możliwość manualnego sterowania diodami (instrukcje „ov=…”). W ten sposób uzyskałem efekt podobny jak w Fazie 1. Zamiast automatycznych kolorów zsynchronizowanych z obrazem, mogę ustawić sobie dowolny kolor podświetlenia. Dodałem też przekaźnik, który pozwala mi na włączanie i wyłączanie zasilania dla diod. Z konsoli na Raspberry wystarczy wysłać: „echo ‚ov=0.0’ a zasilanie dla diod zostanie odcięte.
Oczywiście podawanie komend z konsoli jest mało wygodne. Postanowiłem więc wykorzystać do tego telefon z Androidem i aplikację napisaną za pomocą AppInventora.

Kroki

Mój OSMC działa na Raspberry Pi 3. Ten model Raspberry ma wbudowany moduł Bluetooth. Postanowiłem więc go wykorzystać do komunikacji ze smartphon’em. W kolejnych krokach:

  1. AppInventor: napiszę aplikację w AppInventor. Aplikacja ta będzie działała na telefonie z Androidem. Interfejs aplikacji będzie umożliwiał włączenie/wyłączenie diod oraz zmianę ich koloru („nadpisując” instrukcje z Hyperiona),
  2. Telefon z Androidem: uruchomię funkcje developerskie; na potrzeby testowania, uruchomię aplikację z AppInventor na telefonie podłączonym do komputera przez kabel USB.
  3. Raspberry: inicjalizacja Bluetooth,
  4. Raspberry: tworzenie portu szeregowego po Bluetooth (rfcomm) prze starcie,
  5. Gotową aplikację zainstaluję na telefonie

Aplikacja na telefonie z Androidem połączy się z Raspberry po Bluetooth. Po wciśnięciu klawisza na ekranie telefonu,  aplikacja wyśle odpowiednią instrukcję do Raspberry – np. „ov=0.0” żeby wyłączyć diody. Raspberry: odbierze instrukcje z Androida i wyśle je na port szeregowy Arduino.

Punkty te omówię w szczegółach poniżej.

1. MIT App inventor

AppInventor jest darmowy, ale do jego używania konieczne jest posiadanie konta google.

AppInventor najlepiej działa z przeglądarką Chrome (Chrominium na Linuxie). Nie jest kompatybilny z przeglądarkami Microsoft’a.

Po rejestracji, logujemy się na stronę: http://ai2.appinventor.mit.edu i możemy tworzyć nowe projekty.

screen_00W trybie „Designer” (przycisk w prawym górnym rogu AppInventora) budujemy wygląd aplikacji wybierając z dostępnych elementów interfejsu. Oprócz podstawowych przycisków (button), etykiet (label) i list rozwijanych, znajdziecie również bardziej zaawansowane moduły, np. interesujący nas klient Bluetooth.

Budowanie aplikacji polega na przeciąganiu obiektów z lewego menu na obszar ekranu (środkowa kolumna). Następnie z listy po prawej możemy wybierać elementy i zmieniać ich właściwości.

Gdy skończycie budowanie wyglądu aplikacji, czas przełączyć się na tryb „Blocks” i napisać procedury obsługi elementów graficznych.

screen_01Programowanie do złudzenia przypomina Scratcha. Składamy kolorowe bloczki, które odzwierciedlają kolejne funkcje. Bloczki są tak zbudowane, że nie można tego zrobić źle. Wyglądają jak puzzle, których wypustki muszą pasować.

2. Debuggowanie na telefonie z Androidem

Podczas budowania aplikacji warto byłoby wypróbować, czy działa poprawnie. Do tego będzie potrzebować:

  • Telefon z Androidem, skonfigurowany w trybie developerskim,
  • Aplikację na telefon MIT Ai2 Companion: do pobrania z google play tutaj,
  • Skonfigurowany komputer.

Kod AppInventora można załadować na telefon Androidowy na kilka sposobów:

  • Podczas pisania aplikacji:
    • Za pomocą sieci WiFi: telefon musi być w tej samej sieci, co komputer, na którym budujecie aplikację (w przeglądarce),
    • Na telefon podłączony do komputera kablem USB,
    • Na emulator Androida.
  • Gotową aplikację: jako plik APK wgrany do pamięci telefonu.

Dla mnie najwygodniejsze było podłączenie telefonu to kablu USB. Telefon musi być w trybie developerskim. Ja używam myPhone Infinity II LTE z Androidem 5.1. Żeby przełączyć telefon w tryb developerski:

  • Wybierzcie „Settings” a potem „About phone”,
  • Kliknijcie 10 razy element „Build Number”,
  • W „Settings” pojawi się nowy element „Developer Options” – przejdźcie tam,
  • Zaznaczcie:
    • „Stay awake”: ekran nie wygasa gdy telefon jest podłączony do USB (opcja, ale wygodne),
    • „USB debugging”: debuggowanie po USB (konieczne).
  • Do załadowania skończonej Aplikacji na telefon musicie uruchomić:
    • „Settings/Security”,
    • Włączcie „Unknown Sources” – pozwoli to na zainstalowanie Waszej aplikacji w systemie,
    • Teraz wystarczy pobrać skompilowaną aplikację apk na komputer, podłączyć telefon do komputera, przekopiować aplikację – a później uruchomić jej plik – zainstaluje się automatycznie.

„Settings/Security/Unknown Sources” pozwala na instalację dowolnego oprogramowania. Włączcie tą możliwość jedynie na czas instalacji Waszej aplikacji.

Teraz czas na załadowanie aplikacji MIT Ai2 Companion na Wasz telefon: do pobrania z google play tutaj. Po prostu pobierzcie ja na telefon i zainstalujcie.

Na komputerze, którym piszecie oprogramowanie musi nim działać „aiStarter”. Narzędzie to stanowi rodzaj mostu między przeglądarką, a Waszym telefonem. Instrukcje do instalacji znajdziecie tutaj:

Następnie:

  • Podłączcie telefon do komputera,
  • Na komputerze uruchomcie aiStarter; przykładowo dla linuxa:
  • Na komputerze, w przeglądarce otwórzcie AppInventora i Wasz projekt.

Interesuje nas menu „Connect”:

appInventor_screen_02Wybierzcie opcję „USB”. Po chwili na telefonie powinna się uruchomić Wasza aplikacja.

Kilka uwag:

  • AppInventor powinien odświeżać aplikację za każdą zmianą. Niestety tak się nie dzieje.  Żeby odświeżyć aplikację zazwyczaj… przenoszę jakiś jej element graficzny (tryb „Designer”) trochę w inne miejsce. W ten sposób zmuszam AppInventora to załadowania nowego kodu na telefon,
  • Element „AiCompanion” umożliwia podłączenie telefonu przez sieć WiFi. AppInventor wyświetla kod QR, należy go zeskanować telefonem i wtedy aplikacja (powinna) uruchomić się na telefonie. U mnie działało to słabo – rzadko udawało się ustanowić połączenie a jeżeli już – często się rwało. Zrezygnowałem z tej możliwości na rzecz kabla USB,
  • „Emulator” to specjalne oprogramowanie, które „udaje” telefon. Nie jest to prawdziwy telefon, a więc Wasza aplikacja może się zachowywać trochę inaczej na prawdziwym sprzęcie niż emulatorze. Mimo kilku prób, oficjalny emulator androida nie uruchomił się na moim laptopie – na razie porzuciłem tą opcję.

3. Inicjalizacja usług Bluetooth na Raspberry

Wbudowany moduł Bluetooth (BT) to jedna z nowości, która pojawiła się razem z Raspberry Pi 3. Jego obsługa jest nowością dla Rasbiana, a tym bardziej dla OSMC. Zacznijcie od sprawdzenia, czy Wasz moduł działa (OSMC uruchamia go domyślnie). Zalogujcie się do konsoli OSMC (np. ssh osmc@192.168.1.5) i wywołajcie komendę:

Narzędzie bluetoothctl to bardzo przydatna aplikacja, do zarządzania modułem BT. Po jego wywołaniu, znajdziecie się w osobnej powłoce. Wywołajcie komendę help żeby zobaczyć listę dostępnych opcji. Możecie sprawdzić stan modułu za pomocą komendy show:

B8:27:EB:BF:9D:96 to identyfikator mojego modułu Bluetooth – Wasz może być całkiem inny.

Widać stąd, że moduł BT Raspberry nie będzie widziany przez inne urządzenia Bluetooth. Możecie to zmienić:

Jeżeli chcecie, żeby Wasz moduł BT był zawsze widoczny po restarcie, zmieńcie zawartość pliku /var/lib/bluetooth/XX:XX:XX:XX:XX:XX/settings na:

Z narzędzia bluetoothctl możecie wyjść komendą quit.

Teraz zajmiemy się dodaniem usługi portu szeregowego BT. W tym celu użyjemy narzędzia sdptool. Wydajcie komendę:

Oj, coś poszło nie tak… Na szczęście jest to znany problem, który łatwo poprawić (opis tutaj):

  • Otwórzcie w edytorze plik:

    Dodajcie opcję „-C” (–compat) na końcu linijki:

    …która teraz powinna wyglądać tak:
  • Zrestartujcie usługi:

    A jeżeli to nie zadziała:

Teraz powinno być już dobrze:

Niestety na liście brakuje portu szeregowego. I najlepiej, żeby jego inicjalizacja następowała tuż po starcie Raspberry. Zrobimy to w następnym kroku.

4. RFCOMM przy starcie Raspberry

Jak widać z wydruku sdptool, port szeregowy nie jest tworzony przy starcie usługi bluetoothd. Potrzebny będzie również skrypt, nasłuchujący danych przychodzących z telefonu. Inicjalizacja będzie wymagała więc kilku kroków:

  • Dodamy usługę SP (portu szeregowego) bluetooth,
  • Zainicjujemy nasłuchiwanie na porcie,
  • W przypadku połączenia: odbierzemy dane z portu bluetooth i wyślemy je na Arduino.

Ostatnie wersje OSMC oparte są na Jessie – wersji Debiana dostępnej również dla Raspberry. W tej wersji inicjalizację zgodną z SystemV zastąpiono SystemD. Podstawowa różnica jest taka, że SystemV inicjował moduły sekwencyjnie. SystemD robi to konkurencyjnie – wiele pakietów może być uruchamiany równolegle. Znacznie skraca to czas startu, ale wymaga dokładniejszego rozpatrzenia zależności między modułami.

Zaczniemy od uzupełnienia systemu o skrypt startowy:

  • W katalogu: /etc/systemd/system stwórzcie plik appInventor.service:

    Type=idle sprawia, że usługa ta uruchomi się jako ostatnia. Zwróćcie uwagę na linijkę, która dodaje usługę portu szeregowego:

    …oraz wywołanie skryptu:

  • Dodamy teraz skrypt: /home/osmc/appInventor_link.sh. Stwórzcie go:

    i wypełnijcie:

    Skrypt ten pilnuje pojawienia się urządzenia /dev/rfcomm0. Urządzenie to pojawi się w momencie, kiedy aplikacja AppInventor na telefonie podłączy się do Raspberry.
    Nie zapomnijcie o nadaniu praw do wykonania skryptu:

  • Teraz pozostaje napisać skrypt pythona, który będzie przesyłał dane z portu rfcomm0 (Bluetooth) do portu ttyACM0 (Arduino); stwórzcie go:

    …i wypełnijcie (używam tutaj moduły pyserial – trzeba go doinstalować):

  • Dodamy nasz nowy serwis do systemu:

Teraz wystarczy restart:

Po restarcie, sprawdźcie listę usług Bluetooth:

Usługa appInventor.service powinna działać (kropka przy appInventor.service powinna być zielona):

5. Instalacja aplikacji na telefonie

Czas zainstalować aplikację na telefonie:

Podsumowanie

AppInventor umożliwia sterowanie programami na Raspberry za pomocą telefonu z Adroidem. W przypadku OSMC wydaje mi się to bardzo wygodny sposób.

Napisanie samej aplikacji nie jest problemem, również jej testowanie na telefonie. Oczywiście pracując z AppInventorem musicie sobie zdawać sprawę, że oprogramowanie to nie bez powodu jest w wersji beta. Innymi słowy – zdarzają się różne wpadki, problemy z odświeżaniem, konieczność wielokrotnego podłączania się – nie wszystko działa tak, jak powinno.

Również wbudowany Bluetooth jest nowością dla Raspberry. Niektóre elementy nie do końca działają, dokumentacja nie jest kompletna. To sprawia, że zrobienie czegokolwiek wymaga spędzenia wiele czasu nad różnymi forami.

Przyznaję – że złożenie powyższego systemu zajęło mi ponad pół dnia. Z drugiej strony – efekty są bardzo zachęcające. Wydaje mi się, że warto opanować te technologie.

 Źródła

Dodaj komentarz