Cel
Poznanie podstaw programowania modułu micro:bit z wykorzystaniem języka Blocks oraz umieszczonych na płytce micro:bit czujników i matrycy LED.
Wymagania
- moduł BBC Micro Bit z akcesoriami: kabel USB i koszyk na baterie (opcjonalnie).
Podstawowe składniki programów
Wszystkie dostępne w danej chwili bloki, których można użyć w programie, znajdują się w palecie komponentów (rysunek 1). Wszystkie bloki w palecie, ze względu na ich ilość, są pogrupowane tematycznie, a każda z grup ma określony kolor, który dziedziczą wszystkie bloki do niej należące. Kolorystyka ma znaczenie drugorzędne i służy jedynie pomocy wizualnej podczas pisania i analizy kodu.

Kluczowe znaczenie w tworzeniu kodu ma natomiast kształt bloków. Składając program, wszystkie bloki (z małymi wyjątkami) muszą do siebie pasować. Nie dotyczy to oczywiście samodzielnych bloków początkowych takich jak on start, forever, definiowanych własnych funkcji czy obsługi zdarzeń (w przykładowym programie umieszczono reakcję na naciśnięcie przycisku). Dodatkowymi blokami „oderwanymi” od kodu są komentarze. W przykładzie umieszczono komentarz „To jest przykładowy program”. Komentarze mają w kodzie kolor beżowy i nie mają znaczenia dla wykonania programu. Do dyspozycji piszącego jest nieograniczony obszar edycji. Położenie względne „oderwanych” bloków nie ma znaczenia, bo z ich specyfiki wynika kolejność ich wykonania.
Wszystkie instrukcje wykonywane sekwencyjnie posiadają trapezowe zatrzaski/zamki. Elementy strukturalne, takie jak warunki (widoczne w przykładzie) i pętle, oprócz zatrzasków zewnętrznych, mają także zamki wewnątrz pozwalające na utworzenie tak zwanego ciała.
Owalne zakończenia mają bloki zawierające wartości różnych typów – w przykładowym programie liczbowe. Gdy wynik wykonania jakiegoś bloku zwraca wartość jakiegoś typu, na przykład jest operacją matematyczną, to zewnętrzny kształt takiego bloku musi być owalny. Pasują one do elementów mających okrągłe otwory, czyli akceptujące wartości określonego typu. Najczęściej dopasowanie elementów niezgodnych typem, ale zgodnych kształtem jest niemożliwe, bowiem tego typu zgodność jest kontrolowana już na etapie pisania. Z tego powodu napisanie programu błędnego jest dość trudne. Ostatnia uwaga dotyczy oczywiście błędów składniowych kodu, a nie błędów polegających na niezgodnym z założeniami piszącego działania układu.
Może się jednak zdarzyć, szczególnie przy obsłudze zewnętrznych rozszerzeń, błąd niewychwycony przez edytor MakeCode. Na wyświetlaczu pojawi się wówczas smutna buźka, a za nią przełączany cyfra po cyfrze kod błędu. W diagnostyce pomocna może być wówczas strona zawierająca opis wszystkich możliwych kodów błędów microbit.org/guide/error-codes/.
Ostatnią ważną grupę bloków stanowią wyrażenia warunkowe oznaczone w kodzie blokami z ostrymi zakończeniami. Wartości tych bloków przyjmują jedynie dwie wartości „true” lub „false” (prawda lub fałsz), to znaczy stanowią wartości odpowiadające znanym z innych języków programowania typom boolean.
Powitanie
Pisanie rozpoczniemy od powitania po włączeniu micro:bita do zasilania. Rozpoczynamy od nowego, pustego projektu.

Ponieważ startowe rozmieszczenie bloków on start i forever jest jak na listingu 1, to może się okazać, że fragmenty kodów z różnych bloków będą nachodziły na siebie. Nie ma to wpływu na działanie programu, ale utrudnia jego czytanie. Można w takim przypadku przemieścić blok wraz z ciałem w inne miejsce obszaru edycji, a kiedy jest to wygodne zmienić powiększenie (zoom) przy pomocy przycisków +/- pod edytorem.
Z palety komponentów z grupy Basic, zawierającej najczęściej używane bloki, wybieramy show string i umieszczamy w bloku on start. Następnie możemy domyślny napis (string) zamienić na własny, na przykład „Witaj!” (listing 2).

Wynikiem działania programu jest wyświetlenie jednorazowo podczas startu urządzenia napisu powitalnego, co możemy obserwować w panelu podglądu lub po załadowaniu na matrycy LED micro:bita.
Należy podkreślić, że programowanie micro:bita odbywa się wysokopoziomowo. Już na przeanalizowanych przykładach widać, że API dla samej tylko matrycy LED stanowi funkcje o bardzo dużej złożoności na poziomie urządzenia. Wyświetlane poprzednio ikony były statyczne, natomiast wyświetlanie napisów ma wbudowany mechanizm przewijania tekstu.
Własna ikona
Po wyświetleniu powitania matryca wygasza się, bo blok forever jest pusty. Umieśćmy w nim jedną z gotowych ikon. W prezentowanym przykładzie jest to szachownica. Wybieramy zatem blok Basic/show icon i umieszczamy go w bloku forever. Następnie strzałką obok ikony rozwijamy listę predefiniowanych czterdziestu ikon i klikamy w nasz wybór.

Od teraz prezentowany będzie jedynie ten fragment kodu, który bezpośrednio dotyczy omawianego zagadnienia, dlatego w listingu 3 brak jest bloku on start.

Pora na wstawienie własnej ikony. W tym celu wybieramy blok Basic/show icon i umieszczamy poniżej ikony z szachownicą. Teraz możemy włączyć przy pomocy myszy wybrane diody na matrycy. W prezentowanym przykładzie zaprojektowano negatyw poprzedniej szachownicy (listing 4).

Otrzymaliśmy migającą szachownicę. Przyspieszenia migania nie da się wykonać w tym kodzie w sposób prosty, ale można je spowolnić, dodając odpowiednie przerwy Basic/pause pomiędzy zmianami (listnig 5). W czasie trwania przerwy ekran LED nie wygasza się, tak więc dodanie pauz powoduje zmniejszenie częstotliwości migania. Domyślną jednostką pauzy jest milisekunda. Z listy można wybrać predefiniowane wartości lub wpisać je wprost z klawiatury w owalne pole bloku. Zaprezentowane zastosowanie przerw w działaniu programu jest nadmiarowe, ale dosyć częsta konieczność ich stosowania, na przykład przy oczekiwaniu na jakieś zdarzenie, spowodowała umieszczenie tego bloku w grupie Basic.
Przyciski
Wyświetlanie różnego rodzaju komunikatów i obrazów na matrycę LED może być ciekawe, ale prawdziwa przygoda z systemami wbudowanymi rozpoczyna się z chwilą, gdy mogą one reagować na zmieniające się czynniki zewnętrzne lub wchodzić w interakcję z użytkownikiem.

Do naszego programu dodamy jakąś reakcję na naciśnięcie umieszczonego na przedniej stronie płytki micro:bit przycisku. Do wyboru mamy A, B oraz A+B. W ostatnim przypadku API micro:bita zwalnia nas z nieoczywistego zdefiniowania równoczesności naciśnięcia przycisków.
Jasnym jest, że określenie, czy przycisk został naciśnięty czy nie, wymaga użycia jakiegoś warunku. W tym celu użyjemy bloku Logic/if, który umieścimy w tym momencie programu, w którym chcemy, aby to zdarzenie było sprawdzone. W naszym przykładzie będzie to po drugiej półsekundowej przerwie. Następnie z grupy Input blok button A is pressed wstawiamy w warunek if w miejsce, gdzie domyślnie wpisano wartość true, a wnętrze warunku wypełniamy pojedynczym blokiem show icon i wybieramy którąś z listy ikon. W przykładowym programie jest to happy. Jeżeli warunek jest spełniony, to znaczy wciśnięto przycisk A, co jest sprawdzane jednorazowo, to przez moment na wyświetlaczu zobaczymy uśmiechniętą buźkę i układ powróci do normalnego przebiegu programu. Gdy będziemy trzymać przyciśnięty przycisk, to przy każdym przebiegu pętli forever spełniony będzie warunek naciśnięcia i zamiast migającej szachownicy będziemy widzieć w kółko powtarzający się schemat: szachownica → negatyw szachownicy → uśmiechnięta buźka → szachownica.

Możemy poprawić nasz program. Wprawdzie nadal naciśnięcie przycisku powinno pojawić się w odpowiednim momencie, ale tym razem jego przytrzymanie spowoduje zatrzymanie uśmiechniętej buźki na wyświetlaczu. Podmienimy w tym celu warunek if na pętlę while (dopóki). W tym celu usuwamy z programu warunek i wybieramy blok Loops/while i wstawiamy w to samo miejsce. Podobnie jak poprzednio ciało pętli będzie zawierało wyświetlenie ikony happy, a warunek decydujący o wykonaniu zawartości pętli będzie postaci button A is pressed.
Na listingu 7 widać ciekawą cechę edytora MakeCode. Zamiast usuwać blok if został on „wyrwany” z kodu i umieszczony obok. Ma on niezakotwiczone zamki, więc nie stanowi fragmentu wykonywanego programu i jest przez niego ignorowany. Fakt ten uwidacznia się wyszarzeniem nieczynnych bloków.
Przerwania
Często zachodzi potrzeba nagłej reakcji na zdarzenie, niezależnie od aktualnego stanu programu. Gdyby przebieg bloku-pętli forever był bardzo szybki, wówczas nie odczuwalibyśmy opóźnienia na zdarzenie przyciśnięcia przycisku. W takim schemacie często działają systemy wbudowane – odczyt wejść → przetwarzanie danych → zapis wyjść. Ponieważ jednak w poprzednim przykładzie użyliśmy dwóch półsekundowych pauz, to na reakcję musimy zaczekać, w najgorszym przypadku nawet jedną sekundę. W systemach komputerowych, a w szczególności systemach wbudowanych, żeby uniknąć takiej sytuacji, wykorzystuje się tak zwaną obsługę przerwań. Polega ona na tym, że niektóre wejścia mogą reagować na zdarzenia, przerywając nagle tok programu i oddając kontrolę specjalnym procedurom, przeważnie o ograniczonych funkcjonalności i czasie trwania. Osoby programujące inne systemy wbudowane dobrze wiedzą, jak trudny może być to temat. Na szczęście w przypadku programowania micro:bita w języku Blocks możemy taki efekt otrzymać bardzo łatwo.
Dodajmy do naszego programu pomiar temperatury inicjowany naciśnięciem przycisku B. Z palety komponentów wybieramy blok nieposiadający zewnętrznych zamków Input/On button A pressed i zmieniamy A na B. Blok ten umieszczamy w dowolnym miejscu poza głównym programem.

Wewnątrz tego bloku umieścimy wszystkie instrukcje, które wykonają się po naciśnięciu przycisku B. W powyższym przykładzie wyświetlimy liczbę, którą będzie bieżąca temperatura procesora (blok Input/temperature). Powinna być ona bliska temperaturze otoczenia. Zamiast show number można użyć bloku show string, wówczas wartość temperatury zostanie automatycznie zrzutowana na ciąg znaków i wynik wykonania będzie identyczny. Do liczby dodana została także jednostka, gdzie znak ” udaje brakujący w kodzie ASCII symbol stopnia.
Inne czujniki
Z użyciem bloków grupy Input możemy wykorzystać większość istotnych wejść i wyjść micro:bita, w tym także tych skojarzonych z odpowiednimi czujnikami i LED-ami. Wszystkie opisane zostały w rozdziale Podstawy programowania z BBC Micro Bit, gdzie zaznaczone zostały na rysunku 3. Są one dostępne jako niesamodzielne bloki zwracające wartość liczbową lub logiczną, a niektóre mogą być wykorzystane jako przerwania programowe. W takim przypadku bloki te nie posiadają zewnętrznych zatrzasków. Posiadanie przez micro:bita zarówno trójosiowego akcelerometru, jak i trójosiowego magnetometru powoduje, że urządzenie może rozpoznawać swoją orientację w przestrzeni i stan ruchu.
Jako przykład zastosowania akcelerometru zaprogramujemy urządzenie w taki sposób, aby „denerwowało się” przy próbie jego potrząsania. Z palety wybieramy blok Input/on shake, tym samym decydując się na powiązanie akcelerometru z obsługą przerwań. Możemy też sprawdzać stan akcelerometru „na żądanie”, wykorzystując blok Input/is shake gesture. Wewnątrz bloku on shake umieszczamy blok show icon wyświetlający zdenerwowaną buźkę angry. Rozwinięcie listy (strzałeczki w dół przy shake) prezentuje spektrum wbudowanych metod pozwalających na detekcję, co fizycznie dzieje się z urządzeniem, a w szczególności umożliwia rozpoznanie orientacji urządzenia względem ziemi.

Można zatem umieścić wiele niezależnych bloków rozpoznających, czy urządzenie jest w pionie czy w poziomie. Wszystkie te zdarzenia zwracają wartość logiczną true lub false i tylko takie mogą służyć jako przerwania. Gdybyśmy chcieli wykorzystać akcelerometr jako przyrząd pomiarowy, możemy mierzyć przyspieszenia niezależnie w każdej z trzech osi lub wypadkowe za pomocą bloku Input/acceleration.
Kompletny program

Po złożeniu wszystkich wyżej opisanych elementów powinniśmy otrzymać program podobny do tego z listingu 10 (względne rozmieszczenie głównych bloków nie ma znaczenia).
Modyfikacje
Informacje zawarte w tym rozdziale wystarczają do samodzielnego poznawania wszystkich fizycznych komponentów micro:bita. Ostrożności wymaga jedynie korzystanie z magnetometru, przed użyciem którego należy wykonać kalibrację czujnika.
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:
- BBC Micro Bit Main Page [https://tinyurl.com/y36runae],
- Micro Bit Let’s Code [https://tinyurl.com/y57san4c],
- Microsoft MakeCode Editor for micro:bit [https://tinyurl.com/ybarrla5],
- micro:bit support [https://tinyurl.com/rmfkwbf].
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.
