piątek, 16 kwietnia 2021

Tablica edukacyjna dla dzieci. Przykłady zastosowań elektroniki i nauka programowania w oparciu o Scratch.

Patrząc na zdobywające popularność i coraz bardziej wymyślne tablice sensoryczne dla najmłodszych, wpadłem na pomysł realizacji czegoś podobnego, ale z większym naciskiem na elektronikę i programowanie, skierowanym raczej dla starszaków. Opisywana tablica poprzez zabawę i eksperymentowanie, w przystępny sposób wprowadza w podstawy zastosowań elektroniki do monitorowania otoczenia (czujniki), sterowania (przyciski, joystick), uruchamiania elektrycznych elementów wykonawczych (serwo, silnik, elektromagnes) i prezentacji wyników: pomiarów, stanu elementów sterujących i wykonawczych (LEDy, linijki LED, wyświetlacz LCD).  Stan wszystkich elementów i interakcje między nimi można opisać (zakodować) w Scratchu na poziomie prostego przenoszenia bloczków graficznych.

Tablica
Tablica jest obsługiwana z poziomu programu mBlock 5 dla którego napisałem odpowiednie rozszerzenie (plugin) do obsługi tablicy. Do napisania pluginu, konieczne jest zarejestrowanie się na stronie mBlock 5 Extension Builder Jest to narzędzie dostępne online, umożliwiające pisanie własnych rozszerzeń do tej wersji mBlock'a z całkiem solidną dokumentacją i przykładami

Narzędzie do tworzenia rozszerzeń do mBlocka

Dashboard stanowi nową kategorię bloków. W środkowej kolumnie jest lista utworzonych bloków. Jest do wyboru 7 (aktualnie) typów bloków. Ja korzystam z kilku:
  • Polecenie (Command), np "Uruchom tablicę" za którym kryje się inicjalizacja programu. Inne użycia, to spowodowanie wykonania jakiejś funkcji.
  • Wartość logiczna (Boolean), np '"Joystick jest uruchomiony" co powoduje sprawdzenie stanu joysticka (w tym wypadku uruchomiony oznaczy jakiekolwiek wychylenie lub wciśnięcie joysticka). Ten blok używany jest w if-ach operujących na wartościach logicznych
  • Wartość liczbowa (Number), np. "Zmierz temperaturę", który to blok powoduje zwrócenie aktualnej wartości temperatury. Przydatne w if-ach oraz polecenia do wyświetlania/odczytu wartości
Każdy z tych typów bloków ma inny kształt ułatwiający wizualną identyfikację typu. Zarówno blokom jak i kategorii (Dashboard) dodatkowo można przypisać własny kolor, tak aby odróżniał się od innych kategorii (np. Kontrola, czy Wyrażenia).

Szczegóły i konfiguracja dodanego bloku widoczna jest w trzeciej kolumnie "Blocks settings". Widoczny jest tam typu bloku (Blocks category) oraz treść (Content). Jeszcze niżej są taby odpowiadające użytym specjalnym polom w treści bloku, podpowiadanym po wpisaniu znaku @ w treści. Służą one do wprowadzania własnych danych do kodu. Jednym z nich jest pole wyboru (Dropdown) pokazany poniżej dla joysticka

Wartość logiczna z polem wyboru

Można dla pola wyboru podać nazwę (Parameter name), domyślną wartość (Default value) oraz listę dostępnych wartości do wyboru. Dalej w prawej kolumnie jest sekcja o nazwie "Upload transcode" i tu można określić gdzie/jak wybrana wartość będzie użyta. W moim wypadku w polu "code" (po dwukrotnym kliknięciu) wprowadziłem instrukcję "db->isJoystickState(/*{joystickState}*/)", gdzie joystickState, to nazwa zmiennej podana w polu "Parameter name". Instrukcja ta powoduje zwraca true jeśli joystick został wciśnięty lub przesunięty w dowolną stronę (dla przypadku jak ze screena).
Poza Dropdown, korzystam jeszcze z pól typu Number i String  do wprowadzania odpowiednio: wartości liczbowych i tekstowych.
Sama sekcja "Parameter name" składa się z różnych pól tekstowych różniących się tym, że wstawiony w nie kod trafia w różne miejsca kodu wynikowego (np. loop, setup, include, itd).


Utworzone rozszerzenie (plik z rozszerzeniem *.mext) można pobrać na własny komputer i dodać do otwartego programu, przenosząc i upuszczając pobrany plik nad okno programu. Wcześniej jednak trzeba wybrać urządzenie, w tym wypadku "Arduino Mega2560" - jest ono podane w konfiguracji pluginu.  Wśród grup instrukcji  powinna się pojawić grupa o nazwie "Dashboard" z zestawem instrukcji dla opisywanej tablicy. Teraz, przenosząc tylko bloki można utworzyć własny program, bez potrzeby zgłębiania C/C++ oraz znajmości "pinologi" używanych modułów ;)


Zestaw instrukcji dla tablicy

Patrząc na tablicę od strony interfejsu graficznego i wspomnianych bloczków, kładłem nacisk na maksymalną prostotę. Z racji na "zwartość" rozwiązania, odpadł problem ustawiania portów (te już są z góry przypisane do modułów w kodzie).  Dla LED-ów RGB nie zmuszam do oddzielnego podawania trzech składowych RGB, tylko z listy można wybrać kilka zdefiniowanych z góry, nazw kolorów. Dla serwa, nie każę ustawiać konkretnego kąta obrotu, tylko daję możliwość wskazania jakiegoś obrazka z listy. U mnie są to naklejki z emotkami, wyrażające jakieś emocje - na przykład uśmiech dla temperatury bliskiej pokojowej ;)

Pomysł na serwo ;)

Przy tablicy użyłem w zasadzie tylko gotowych modułów, które zalegały mi od dłuższego czasu w szufladzie. Normalnie, DHT11 już bym nie użył w termometrze z racji na jego niedokładność, ale tu jest wystarczająca. Podobnie miała się sprawa z modułami zasilaczy na LM317 i LM7805, które już dobre 5 lat leżały na swoje użycie w jakimś układzie.


Elementy tablicy

Sterowanie:
  1. Joystick (4-pozycyjny & przycisk)
  2. Włączniki monostabilne (4 szt., różne kolory)
  3. Sensor dotykowy

Czujniki:
  1. Odległości - HC-SR04
  2. Czujnik odbiciowy
  3. Transoptor szczelinowy
  4. Fotorezystor (LDR)
  5. Temperatury i wilgotności - DHT11
  6. Dźwięku - mikrofon
  7. Ruchu - PIR
  8. Pola magnetycznego - kontaktron
  9. Pola magnetycznego - moduł Halla
  10. Czujniki wstrząsów SW-420
  11. Czujnik przechyłu
  12. Czujnik płomienia/ognia

Wyświetlacze:
  1. Wyświetlacz alfanumeryczny LCD 2x16
  2. Linijka LED RGB, 8szt. WS2812B
  3. Okrąg LED RGB, 16szt. WS2812B

Elementy wykonawcze:
  1. Silnik DC
  2. Elektromagnes trzymający, 6V (i LED sygnalizujący działanie)
  3. Serwo SG-90
  4. Buzzer piezo - pasywny
  5. Elektromagnes ciągnący (i LED sygnalizujący działanie)

Elementy pomocnicze:
  1. Wyłącznik zasilania
  2. LED sygnalizujący zasilanie
  3. Zasilacze:
    1. 5V - czujniki, przyciski, serwo
    2. 6V - silnik, elektromagnesy
  4. Moduł wykonawczy MOSFET IRF520 dla każdego z elektromagnesów
    • dwie diody 1N4007 dla ochrony przed przepięciami
    • dwa LED'y sygnalizujące włączenie każdego z elektromagnesów
  5. Arduino Mega i shield dla czujników
  6. Mostek H MX1508 do sterowania silnikiem DC

Montaż

Bazą do montażu całej tej kolekcji powyżej, była sklejka trójwarstwowa o wymiarach 32x45cm. Stanowi ona front tablicy do której zamontowałem/przymocowałem wszystkie elementy i moduły. Tył/dół zamyka inny pięciowarstwowa sklejka o tych samych rozmiarach połączona z frontem  przy użyciu tulejek dystansowych. Odległość między płytami to ok. 5cm. W sumie łączników jest sześć, co wystarczająco ogranicza uginanie się frontowej sklejki.

Widok połączeń

Z racji na znaczną liczbę czujników, użyłem tu Arduino Mega, dysponującym większą (niż Arduino Uno)  liczbą pinów oraz odpowiedniego shield'a dedykowanego podłączaniu czujników, który znacznie ułatwia podpięcie takiej liczby modułów. Zdecydowana większość modułów jest zasilana i sterowana właśnie z tego shield'a. Do połączeń między shieldem a modułem używałem różnokolorowych taśm przewodów, aby jakoś zapanować nad tym gąszczem połączeń ;)

Shield do Arduino Mega


Wyjątek stanowią elektromagnesy sterowane za pośrednictwem włączników MOSFET oraz silnik - sterowany przy użyciu mostka H. Są one zasilane odrębnym napięciem 6V.


Zasilanie

Zasilacz zewnętrzny 9V o wydajności 5A. Zasilanie dostarczone jest do dwóch wewnętrznych zasilaczy o napięciach wyjściowych 5V i 6V i wydajności prądowej 2A. 

Zasilacz 6V (LM317) jest dedykowany dla wszystkich elementów indukcyjnych: silniczka oraz elektromagnesów. Z racji na wygodę  przy podłączeniu serwa do shield'a, darowałem sobie jego zasilanie napięciem 6V. 

Drugi zasilacz 5V (LM7805) zasila pozostałem elementy/moduly. Celem tej separacji jest uniknięcie ewentualnych problemów z zakłóceniami ze strony elementów indukcyjnych.

Płytka Arduino jest zasilana ze złącza USB.

Zasilanie tablicy

Użyte zasilacze nie są specjalnie wydajne jeśli chodzi o prąd wyjściowy. Nominalnie mają po 2A. W praktyce ten na 5V nagrzewał się po włączeniu wszystkich LEDów, więc asekuracyjnie obniżyłem programowo jasność ich świecenia do 100. Szczegóły są w opisie funkcji Adafruit_NeoPixel::setBrightness. Dodam tylko, że maksimum jasności przypada na wartość 255. Mimo to jasność LED-ów jest wystarczająca. Podobnie, okazało się, że elektromagnes ciągnący jest prądożerny (ok. 0,7A) i do tego dość mocno się nagrzewa. W tym przypadku przyjąłem strategię ograniczenia czasu włączenia obu elektromagnesów maksymalnie na 5 sekund. Dodatkowo, przy elektromagnesach zamontowałem zielone LED-y informujące o ich załączeniu. Te wszystkie, dodatkowe obostrzenia co do poboru prądu, wzięły się z obserwacji prądu pobieranego przez układ. Po prostu w fazie uruchamiania, podpiąłem pod wyjścia obu zasilaczy amperomierze i "organoleptycznie" sprawdzałem temperaturę temperaturę radiatorów przy włączonych na dłuższy czas, prądożernych elementach tablicy (LED-y, elektromagnesy, silnik).


Kod

Do obsługi modułów tablicy użyłem kilkanaście różnych bibliotek. Mordęgą byłoby upchanie obsługi tego wszystkiego w kreatorze, który dostarcza mBlock. Dlatego właśnie, utworzyłem prostą fasadę "DashboardFacade", która zajmuje się inicjacją tych wszystkich modułów oraz dostarcza zestaw prostych do użycia funkcji do ich obsługi. Funkcji tych następnie używam w pluginie mBlock'a. 

Na przykład funkcja sterująca liniami LED wygląda następująco (kod z plugina mBlock'a):
db->setLedBarOneColor(/*{ledNo}*/, /*{ledColor}*/, /*{ledType}*/);
Instancją (obiektem) klasy DashboardFacade  jest db. Funkcja setLedBarOneColor ustawia dla danego numeru LED (ledNo) jeden ze zdefiniowanych z góry kolorów (ledColor - stała z nazwą koloru wskazująca na indeks tablicy z wartościami RGB kolorów) na określonej linii LED (ledType - linia lub okrąg LED). Wewnątrz setLedBarOneColor dopiero są wywoływane odpowiednie funkcje z biblioteki Adafruit_NeoPixel, realizujące tą funkcjonalność, tj. setPixelColor()show(). Co więcej, bierze pod uwagę liczbę ledów na danej linii LED i np. dla linijki ignoruje odwołania np. do 9tego LED'a.  Ten przykład pokazuje, jak w jednej funkcji (z prostym jednolinijkowym wywołaniem w pluginie mBlocka) można zrealizować więcej zadań związanych z obsługą danej funkcjonalności.

Kod fasady umieściłem w repo DashboardFacade na bitbucket.

Działanie

Do uruchomienia tablicy, konieczne jest podpięcie zasilania i kabla USB do PC. W mBlocku, w panelu urządzenia trzeba wybrać jako urządzenie Arduino Mega2560 i nawiązać połączenie (przycisk Połącz) po porcie na którym jest widoczne podłączone Arduino.

Przykładowy program

Potem składa się dowolny program przez przenoszenie bloczków kodu (polecenia, stan czujników, stan przycisków, itp). Po lewej jest widoczny wygenerowany kod na podstawie ułożenie bloczków. 

Z tą dowolnością trochę przesadziłem. Jest jedno ograniczenie, mianowicie, dla elementów wykonawczych (silnik, elektromagnesy) konieczne jest użycie w pętli "zawsze" bloczka "Sprawdź i wyłącz elementy wykonawcze". Za tym hasłem kryje się kod, który w pętli sprawdza, czy nie upłynął czas działania wymienionych, włączonych elementów. Z tego co pamiętam, na poziomie tworzenia pluginu, nie dało się wrzucić, do generowanej przez mBlocka pętli loop kodu, który by ogarniał z automatu ten problem. Brak tej instrukcji może powodować problemy z elektromagnesami, które są prądożerne, a ten mały jeszcze niepokojąco się nagrzewa ;) Stąd w menu bloczka maksymalny czas uruchomienia wynosi 5s.


Alternatywy

Zabierając się za opisywaną tu tablicę, nie znalazłem na rynku rozwiązania, które mogłoby ją zastąpić. 
Ostatnio jednak znalazłem coś obiecującego na Ali o nazwie "keyestudio kidsbits Maker coding box V1.0 starter kit for Arduino STEM Education 7+". Jest to "zwarta", gotowa konstrukcja przypominająca tablicę, tyle, że z mniejszą liczbą elementów. W opisie można znaleźć m.in., że: " Coding box is a programming tool specially designed for children over 6 years old. Integrated some of the most basic devices such as LED, light, sound, infrared, temperature, buttons, motor, etc. Combined with MIXLY graphical programming software". Minus tego box'a to mniej elementów oraz interfejs (najpewniej) po angielsku - choć to chyba plus ;) Ponoć śmigło zamontowane na silniku potrafi zahaczyć o ramię serwa - co wyczytałem w komentarzach. Plus tego rozwiązania jest taki, że jest to gotowe do użycia rozwiązanie.
Bardzo fajnym rozwiązaniem z keystudio jest też Keyestudio Smart Home Kit with PLUS Board for Arduino DIY STEM. Jest to sprzedawany do złożenia dom (z czegoś w stylu sklejki)  z zestawem modułów (czujniki, lcd, sterowanie). Moduły/czujniki mają za cel automatyzację zmontowanego domu. Jest to jednak konstrukcja zdecydowanie skierowana dla starszaków, którzy ogarną pinologię i spięcie kablami całości.

Naszła mnie też refleksja, że można na początek wykonać znacznie uproszczoną wersję tablicy - bez Arduino i bez korzystania z mBlocka (brak konieczności pisania pluginu).  W zasadzie każdy z modułów z czujnikiem ma LED informujący o zadziałaniu czujnika. To oznacza, że w uproszczonej wersji, można zamontować tylko moduły czujników. W wyniku oddziaływania zewnętrznego (np magnesu na moduł z kontaktronem) będzie widoczny efekt w postaci zapalonego LED'a na płytce modułu. W tym wypadku, wystarczy tylko zapewnić zasilanie modułom.


Źródła:


Brak komentarzy:

Prześlij komentarz