Menu Zamknij

Wizytówka

Cel

Nauka podłączania zewnętrznych modułów do micro:bit na przykładzie wyświetlacza graficznego oraz kontrolowanie czasu działania układu.

Wymagania

  • moduł BBC Micro Bit z akcesoriami,
  • wyświetlacz Waveshare LCD 1.8″.

Zewnętrzne moduły

Pomimo że poznane w poprzednich rozdziałach, zarówno sprzętowe, jak i programowe, elementy modułu BBC Micro Bit są wystarczające do realizacji nawet bardzo skomplikowanych projektów, to czasami warto rozważyć możliwość rozszerzenia funkcjonalności modułu o dodatkowe lub lepsze czujniki. Także komunikacja z użytkownikiem przy pomocy matrycy LED o wymiarach 5 × 5 diod, pomimo że pozwala na wyświetlenie dowolnego tekstu, nie może być uznana za wydajną i estetyczną. Jeżeli moduł ma wyprowadzać dużo danych dla użytkownika, warto rozważyć podłączenie zewnętrznego wyświetlacza.

Jedną z najważniejszych grup modułów rozszerzeń są ekspandery wyprowadzeń. Ułatwiają one dostęp do fizycznych styków (pins). W micro:bicie w prosty sposób można podłączyć się jedynie do 3 pinów przy pomocy „krokodylków” lub wtyków bananowych. Rodzajów ekspanderów jest dosyć dużo, dlatego należy dokonać wyboru na podstawie analizy konkretnego projektu.

Przy zakupie różnego typu rozszerzeń warto także zwrócić uwagę na stany magazynowe polskich sklepów internetowych z artykułami przeznaczonymi do automatyki i robotyki, tak aby uniknąć kilkutygodniowego czekania na przesyłki z Dalekiego Wschodu.

Asortyment dodatków do micro:bita jest bardzo szeroki i obejmuje między innymi:

  • ekspandery wyprowadzeń,
  • dodatkowe czujniki – zarówno pojedyncze, jak i zestawy,
  • sterowniki silników i zewnętrzne przekaźniki,
  • moduły Wi-Fi,
  • różnego rodzaju wyłączniki, gamepady, a nawet proste konsole gier,
  • mikrofony, beepery, głośniki,
  • wyświetlacze i panele LED,
  • platformy robotów,
  • i inne.

Bardzo dobrym źródłem informacji, a czasami nawet inspiracji, są internetowe sklepy dla robotyków. Jeżeli nie znajdziemy tam pełnej informacji o rozszerzeniu w języku polskim, to na pewno dowiemy się, gdzie szukać dodatkowej dokumentacji w języku angielskim.

Ładowanie rozszerzeń

Praca z zewnętrznym, dodatkowym urządzeniem, przyłączanym bezpośrednio do szyny stykowej (pins) micro:bita, zaprezentowana zostanie na przykładzie zewnętrznego, dedykowanego kolorowego wyświetlacza LCD o przekątnej 1.8″ i rozdzielczości 160 × 128 pikseli. Dokumentację techniczną można znaleźć na stronie producenta Waveshare www.waveshare.com/wiki/1.8inch_LCD_for_micro:bit.

Rysunek 1. Dodatkowe bloki obsługujące wyświetlacz w palecie komponentów

Wyświetlacz komunikuje się przez interfejs SPI. Dzięki standaryzacji interfejsu może on być podłączany także do innych systemów i urządzeń. Nie będziemy musieli, na szczęście, znać protokołu SPI, aby używać tego wyświetlacza wraz z modułem micro:bit.

Najważniejsze jest, jeżeli dodatek jest wspierany przez micro:bit, spowodować, by odpowiednie bloki odpowiedzialne za obsługę modułu pojawiły się w postaci nowej grupy w palecie komponentów jak na rysunku 1. Można to uzyskać na dwa sposoby: albo rozwijając grupę Advanced i wybierając Extensions (rysunek 2a), albo w prawym górnym rogu edytora klikając More… z symbolem koła zębatego i wybierając Extensions (rysunek 2b).

Rysunek 2. Metody ładowania rozszerzeń z poziomu edytora MakeCode

Takie działanie spowoduje wywołanie okna dodawania rozszerzeń (rysunek 3a), gdzie możemy wybrać biblioteki obsługi dla najpopularniejszych dodatków. Różnego typu rozszerzeń, wspieranych przez różne grupy oraz przez społeczność, jest bardzo dużo, dlatego nie jest możliwe umieszczenie ich wszystkich na jednej stronie.

W polu Search or enter project URL… możemy spróbować odnaleźć dodatki po słowie kluczowym lub wprost wpisać adres, gdzie przechowywane są źródła rozszerzeń. Cały kod dodatków jest utrzymywany przez system kontroli wersji Git. Jeżeli posiadamy konto w serwisie github.com, możemy dołączyć do społeczności micro:bita i tworzyć nowe, a nawet modyfikować istniejące dodatki. Rozszerzenia dla naszego wyświetlacza znajdują się w repozytorium https://github.com/waveshare/WSLCD1in8, wpisujemy więc jego adres w pole Search or enter project URL… i zatwierdzamy. Dla tak zdefiniowanego filtru pasuje tylko jeden dodatek (rysunek 3b). Możemy się dodatkowo dowiedzieć, że ten dodatek jest dostarczony przez użytkownika i nie zatwierdzony przez Microsoft. Po jego wybraniu zostaniemy automatycznie przekierowani z powrotem do edytora MakeCode.

Rysunek 3. Okno zarządzania dodatkami zwanymi zamiennie rozszerzeniami

Inicjalizacja wyświetlacza

Rysunek 4 Micro:bit z podłączonym kolorowym wyświetlaczem1,8″

Często obsługa zewnętrznych dodatków nie jest intuicyjna i wymaga zerknięcia do dokumentacji technicznej. W przypadku omawianego wyświetlacza zastosowanie funkcji rysunkowych wydaje się oczywiste, ale z samej zawartości grupy LCD1IN8 nie można wywnioskować, jakie wstępne kroki należy podjąć, aby urządzenie zaczęło działać, ani czy wyświetlacz będzie reagował na bieżąco.

Pracę rozpoczynamy od podpięcia wyświetlacza do złącza stykowego micro:bita. Niestety złącze jest symetryczne i zewnętrzne moduły można podłączyć na dwa sposoby, na szczęście błędne założenie nie grozi uszkodzeniem czegokolwiek, bo czynne są styki tylko po jednej stronie modułu, po prostu rozszerzenie nie będzie działało. Prawidłowe podłączenie jest zaprezentowane na rysunku 4. Widać, że dzięki wykorzystaniu innych wyjść dla komunikacji SPI, można nadal niezależnie korzystać z matrycy LED micro:bita.

Pierwszą rzeczą, jaką należy zrobić, żeby korzystać z wyświetlacza, jest jego inicjalizacja w bloku on start. Służy do tego blok LCD1IN8/LCD1IN8 Init i jest to jedyny blok konieczny w bloku on start.

Listing 1

Oczywiście w bloku on start mogą znaleźć się także inne bloki ustalające początkowe ustawienia wyświetlania, jak na przykład stopień jasności (w skali od 0 do 10) podświetlenia ekranu LCD1IN8/set back light level (listing 1). Jeżeli tego nie zrobimy, ekran będzie czarny, pomimo przyjmowania poleceń wyświetlających. Ten jednak blok może znajdować się w dowolnym miejscu programu, niekoniecznie na początku, możemy bowiem w trakcie mieć potrzebę zmiany intensywności podświetlania, na przykład pisząc wygaszacz oszczędzający baterię. Przed wysłaniem jakiejkolwiek informacji do wyświetlacza dobrze jest go wyczyścić blokiem LCD1IN8/Clear screen and cache. Można zatem przyjąć za regułę, że ten blok też powinien znajdować się w on start, czego nie ujęto na listingu 1.

Ogólny schemat pracy z wyświetlaczem

Omawiany wyświetlacz, podobnie jak matryca LED micro:bita, buforuje informację, to znaczy po wysłaniu obrazu pozostaje on na ekranie do chwili wyczyszczenia lub wysłania nowych informacji i w tym stanie nie wymaga odświeżania programowego. Czyszczenie ekranu wywołamy przez umieszczenie bloku LCD1IN8/Clear screen and cache. Narysowane obiekty, w dowolnej ilości, nie są widoczne na ekranie do czasu wywołania bloku LCD1IN8/Send display data. Dorysowywanie polega na definiowaniu nowych obiektów i wysyłaniu ich na wyświetlacz, przy czym nowe nakładane są na stare, w taki sposób, że nadpisywane są tylko piksele, które ulegają zmianie, zaś cała reszta obrazu pozostaje bez zmian. Można w taki sposób wykasować tylko część rysunku lub zmienić kolor jakiegoś obiektu przez nadpisanie go. Szeregowa komunikacja z wyświetlaczem sprawia, że odświeżanie zawartości jest dość wolne, co może powodować pewne niedogodności w projektach, w których kontrola czasu działania jest istotna.

1,12,1    .     .     .160,1
1,22,2    .     .     .160,2
. . .. . .    .           .                 .. . .
1,1282,128    .     .     .160,128
Rysunek 5. Współrzędne pikseli na ekranie wyświetlacza

Same polecenia rysowania są czytelne. Mamy do dyspozycji między innymi bloki wstawiania: punktu, linii, prostokąta i okręgu. Każdy obiekt ma jasno zdefiniowane własności, takie jak: kolor, rodzaj linii, wypełnienie oraz współrzędne, przy czym punkt (1,1) znajduje się w lewym górnym rogu. Uwaga: nie zaczynamy liczenia, naturalnego w informatyce, od (0,0)! Jest to wyświetlacz typowo graficzny, posiada on jednak możliwość wyświetlania znaków i liczb. Służą do tego bloki LCD1IN8/Show string i LCD1IN8/Show number. Niestety do wyboru mamy tylko jeden domyślny krój czcionki, jedną wielkość 8 pikseli i, co najgorsze, brak polskich znaków. Wytrwały programista może „ogonki” polskich znaków dodać ręcznie, ale jest to bardzo uciążliwe.

Dodatkowym utrudnieniem może być fakt braku obsługi tego wyświetlacza w panelu podglądu, co nie jest regułą jeżeli chodzi o różnego rodzaju rozszerzenia.

Dane do wizytówki

Zamieszczone poprzednio informacje są wystarczające do wykonania prostej, statycznej wizytówki. Zaczniemy jednak projekt od określenia zmiennych typu „string” (łańcuchów znakowych), zawierających nazwane informacje o użytkowniku wizytówki, takie jak: imię, nazwisko, dane adresowe itp. Da nam to pewną uniwersalność przy próbie modyfikacji informacji i jest zdecydowanie bardziej eleganckie od strony programistycznej czytelności kodu. W tej pracy zaprojektujemy wizytówkę dla „sławnej” Janiny Nowak z Gniezna.

Zacznijmy od zadeklarowania (Variables/Make a Variable) zmiennych o nazwach: Imię, Nazwisko, Ulica, Numer_domu, Kod_Pocztowy, Miejscowość, Firma lub dowolnych innych, zależnie od własnych pomysłów i nadajmy im wartości Variables/set typu string text/’ ’. W Blocks, ze złożonych typów danych, mamy bezpośredni dostęp do tablic i dynamicznych list, nie ma za to potencjalnie przydatnych w tym przykładzie rekordów.

Listing 2

Gdybyśmy chcieli zaprojektować statyczną wizytówkę, jej projekt umieścilibyśmy w całości w bloku on start. Dla zwiększenia czytelności oraz ze względu na dużą obszerność obsługę kodu związanego z rysowaniem można przenieść do zewnętrznej funkcji wyświetlającej.

Tryby pracy

Listing 3

Wprowadźmy od naszej wizytówki możliwość wyświetlania co najmniej dwóch różnych ekranów z różnymi danymi i/lub w innym widoku. Przełączanie pomiędzy ekranami będziemy wykonywać za pomocą przycisku A. Wykorzystamy w tym celu dodatkową zmienną trybu pracy. W przykładowym programie będzie ona przyjmować jedynie dwie wartości (0 i 1), ale można łatwo zwiększyć jej zakres.

Na listingu 3 można zauważyć jeszcze dwie modyfikacje: usunięto blok Clear screen and cache oraz wprowadzono nową logiczną zmienną Czy_odświeżyć. Widać z listingu, że wstępnie nadano jej wartość true, co pozwala nam się domyślić, że będziemy gdzieś w programie – bloku forever – wysyłać informacje na ekran. Zmiana jej wartości na false pozwoli pominąć odświeżanie, gdy nie będzie to konieczne. Nie ma przecież sensu odświeżać buforowanego wyświetlacza w każdym przebiegu bloku forever (listing 4).

Listing 4

W pętli forever na początku sprawdzamy warunek Czy_odświeżyć. Jeżeli jest spełniony to wykonujemy instrukcje wewnątrz warunku, gdzie po kolei: czyścimy ekran, wykonujemy bloki rysowania w osobnej funkcji Wyświetl_Tryb,wysyłamy dane na ekran i ustawiamy zmienną Czy_odświeżyć na false. To ostatnie działanie zapewni nam nie wykonywanie ciała warunku przy następnym wejściu do bloku forever.

Listing 5

Oznacza to, że ponowne odświeżenie może wykonać się tylko w innym bloku lub zewnętrznej modyfikacji zmiennej Czy_odświeżyć. Zmienną tę przywrócimy do wartości true przy okazji zmiany trybu, a dokonamy tego w bloku on button A pressed (listing 5). Działanie tego przerwania polega na zwiększaniu zmiennej Tryb, po każdym naciśnięciu przycisku A, aż do wartości maksymalnej, po czym następuje jej wyzerowanie. W naszym przykładzie, ze względu na to, że mamy tylko dwa tryby pracy, wyzerowanie następuje dla wartości równej 2. Na koniec ustawiamy zmienną Czy_odświeżyć na wartość true, co zapewni nam odświeżenie wyświetlania w bloku forever za każdym naciśnięciem przycisku.

Listing 6

Pozostaje tylko definicja wyglądu wizytówki, którą przekazaliśmy do bloku funkcji z parametrem liczbowym Wyświetl_Tryb(num) przedstawiona na listingu 6.

Jak widać funkcja Wyświetl_Tryb wywołuje dwie inne bezparametrowe funkcje: Wyświetl_Adres i Wyświetl_Firmę. Wydawać się to może nadmiarowe, ale dokładne dopasowanie zamków w języku Blocks nie pozwala na dowolność w formatowaniu kodu. Jedyną możliwość dekompozycji na mniejsze fragmenty daje użycie funkcji. W tym przykładzie można docenić takie działanie, bo tworzenie obrazu z pojedynczych bloków powoduje rozrost programu w pionie, co utrudnia jego czytanie i edycję. Listing 6 zawiera jedynie początek funkcji wyświetlających.

Wyświetlanie napisów

Wyświetlacz ten jest wyświetlaczem graficznym, stąd ograniczona jest niestety obsługa wyświetlania znaków, o czym była mowa wcześniej. Każdy znak ma 8 pikseli wysokości, a szerokość wraz z odstępem między znakami wynosi 7 pikseli. Położenie łańcucha znakowego, wyświetlanego blokiem LCD1IN8/Show String, wyznaczają współrzędne lewego górnego narożnika pierwszego znaku.

Listing 7

Dane osobowe zawarte w bloku on start czasami podczas wyświetlania muszą być pogrupowane w dłuższe łańcuchy. Żeby uniknąć ciągłego ustalania współrzędnych dla każdego elementu osobno, można użyć bloku łączącego stringi (wykonanie konkatenacji łańcuchów). Do tego celu używamy bloku Advanced/Text/join i znakami +/- ustalamy liczbę łańcuchów znakowych do sklejenia, jak na listingu 7 stanowiącym fragment funkcji Wyświetl_Adres. W polach join mogą być zarówno zmienne, jak i łańcuchy znakowe wpisane wprost (pomiędzy zmiennymi Ulica i Numer_Domu jest spacja).

Wygaszacz

Ciągłe zasilanie wyświetlacza w przypadku urządzenia przenośnego nie jest wydajne. Spróbujmy dopisać mechanizm wygaszający ekran po pewnym, powiedzmy pięciosekundowym, okresie bezczynności. Dla ułatwienia wybudzenia będziemy dokonywać przyciskiem B.

Systemy wbudowane wyposażone są z reguły w wewnętrzne zegary. Micro:bit mierzy czas od startu urządzenia w milisekundach, a wynik przechowuje w rejestrze w postaci 32-bitowej liczby całkowitej. Oznacza to, że „przekręcenie” licznika nastąpi po około 50 dniach, czyli dopiero taka bezczynność i próba wybudzenia po takim czasie może działać w sposób nieoczekiwany. Dostęp do tego rejestru umożliwia blok Input/more/running time.

Listing 8

Na początku dodamy zmienną przechowującą aktualny czas pracy urządzenia, nazwiemy ją Znacznik_czasu i nadamy w bloku on start wartość running time, co jest widoczne na fragmencie bloku on start na listingu 8.

Listing 9

W pętli forever dodamy dodatkowy warunek na końcu, sprawdzający czy od ustawienia znacznika do aktualnego czasu minęło więcej niż 5000 ms. Jeżeli warunek będzie spełniony, wygaszamy podświetlenie, które odpowiada za największe zużycie energii w układzie (listing 9).

Listing 10

Powrót do poprzedniego podświetlenia będzie możliwy po spełnieniu dwóch warunków: zmiany Set back light level na 10 i ustawienia Znacznik_czasu na aktualny running time. Zgodnie z zapowiedzią te czynności umieścimy w przerwaniu on button B pressed (listing 10).

Cały program

Pełny tekst programu zamieszczony jest na listingu 11, a wynik jego działania na rysunku 6. Przełączenie pomiędzy ekranami uzyskujemy przez naciśnięcie przycisku A, co powoduje zmianę zmiennej Tryb.

Rysunek 6. Dwa tryby pracy wizytówki


Listing 11

Modyfikacje

Tworzenie jakiejkolwiek grafiki na wyświetlaczu może samo w sobie być ciekawe. Zmusza do orientowania się we współrzędnych pikseli na ekranie.

Fragment programu zaprezentowany na listingu 9 ma tę niedogodność, że spełnienie warunku running time – Znacznik_czasu > 5000 powoduje sprzętowe wygaszenie podświetlenia za każdym przebiegiem forever po pięciu sekundach. Dobrze byłoby tak poprawić program, aby zapisanie do set back light wartości 0 następowało tylko wówczas, gdy jego poprzednią wartością było 10.

Można tak zaprojektować wizytówkę, aby osobnym zdarzeniem zmieniać dane wyświetlane na ekranie, a innym zdarzeniem oprawę graficzną, ale z zachowaniem zawartości.

Innym proponowanym usprawnieniem może być tylko częściowe czyszczenie ekranu podczas zmiany trybu. Przecież imię i nazwisko pozostają takie same, a ramkę można nadpisać linią w innym kolorze.

Najciekawszą modyfikacją będzie jednak wykorzystanie innych czujników. Szczególnie wart uwagi jest akcelerometr. Stan wygaszenia czy tryb może być przecież zależny od potrząśnięcia układem lub jego orientacji względem ziemi. Można w ten sposób sprawdzać, czy wizytówka jest zorientowana w pionie czy poziomie. Po co zasilać podświetlenie, gdy ekran jest „twarzą” w dół. Można, co już jest bardzo trudne, uzależnić intensywność podświetlenia od natężenia oświetlenia mierzonego matrycą LED mico:bita, albo zaingerować w wygląd, przełączając automatycznie na widok nocny.

Literatura

Powtórzenie zaprezentowanych projektów nie wymaga studiowania dodatkowej literatury. Dopiero wprowadzenie modyfikacji może wiązać się z koniecznością uzupełnienia wiedzy. Najlepszym źródłem informacji w przypadku jakiegoś konkretnego problemu jest internet. Książka pisana swoją wyższość ukazuje dopiero jako podręcznik czy przewodnik.

Informacje bibliograficzne dotyczące źródeł internetowych zamieściłem bezpośrednio w tekście, przy zagadnieniach, których dotyczą.

Do zapisu linków, tylko w tym spisie, wykorzystywana jest metoda skracania adresów (URL shortening). W tym skrypcie wybrano serwis TinyURL. Dostęp do wszystkich internetowych zasobów został przetestowany 27.02.2020.

Bibliografia zawiera tylko materiały pomocnicze do projektów, których dotyczą, a pominięto literaturę o charakterze ogólnoinformatycznym. Dobór materiałów do nauki kodowania, czy obsługi programów narzędziowych, pozostaje po stronie nauczyciela.

Literatury dotyczącej micro:bita jest niewiele, szczególnie w stosunku do najbardziej popularnych systemów wbudowanych. Nie można liczyć niestety na wiele informacji w języku polskim. Najbardziej godne polecenia, gromadzące także dużo społeczności są strony oficjalnego wsparcia:

oraz

Literatura uzupełniająca

W niektórych projektach nie wszystko da się podłączyć za pomocą pasujących do siebie wtyków i złącz. Należy wówczas wykonać takie podłączenia samodzielnie. Wymaga to nieco umiejętności majsterkowania i elektroniki. Bardzo ciekawą książką dla początkujących majsterkowiczów jest:

  • Roberts Dustyn, Wpraw to w ruch. Proste mechanizmy dla wynalazców, majsterkowiczów i artystów [e-book], tłum. Krzysztof Sawka, Helion, 2015.

Znajdziemy w niej oprócz podstaw elektroniki także dużo elementarnej mechaniki i materiałoznawstwa.

Majsterkowanie z użyciem systemów wbudowanych, tam gdzie nie wszystko pasuje do siebie za pomocą dedykowanych styków, wymaga elementarnej wiedzy z elektroniki. Niezmiennie najważniejszą książką na półce elektronika jest:

  • Horowitz Paul, Hill Winfield, Sztuka elektroniki, tłum. Bogusław Kalinowski, Grażyna Kalinowska, t. 1–2, wyd. 12 zmienione, WKŁ, Warszawa 2018.

Jednakże jest to pozycja dla wymagającego czytelnika. Podobnym standardem, ale skierowanym do początkujących jest:

  • Platt Charles, Elektronika. Od praktyki do teorii. Wydanie II [e-book], tłum. Konrad Matuk, Helion, 2016.

Na uwagę zasługuje ponadto, w moim przekonaniu bardzo dobra, książka polskiego autora:

  • Górecki Piotr, Wyprawy w świat elektroniki, t. 1, WKŁ, Warszawa 2006.
  • Górecki Piotr, Wyprawy w świat elektroniki. Wyższy stopień wtajemniczenia, t. 2, WKŁ, Warszawa 2011.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *