Każdy głupi może kupić gotową stację meteo z prognozą ściąganą z internetu. Co innego budowa własnej, droższej – z tym poradzi sobie nie każdy głupi. Mi się udało.
W niniejszym artykule opisuję plany, z jakimi przystąpiłem do realizacji autorskiego projektu, oraz rezultaty, które osiągnąłem przy użyciu płytki Pimoroni Badger 2040W z wyświetlaczem typu e-papier. W ramach dygresji przybliżam świat mikrokontrolerów i wskazuję, że nawet proste ich zastosowania ucząc bawią i bawiąc uczą.
Założenia
Wiele osób przed wyjściem z domu zerka na termometr, by dopasować ubranie do aury za oknem. Jedynie część z nich sprawdza prognozę pogody, co pozwala przygotować się np. na późniejsze opady deszczu lub śniegu. Mój pomysł był następujący – budowa elektronicznej pogodynki i zawieszenie jej w pobliżu drzwi, aby informowała i ostrzegała wychodzących.
Jednocześnie narzucałem sobie dość istotne ograniczenia: urządzenie miało pracować bez zasilania sieciowego, by uniknąć zasilaczy i kabli, oraz działać bezobsługowo przez wiele tygodni a najlepiej miesięcy. Takie wymagania bardzo ograniczyły możliwe do zastosowania technologie. Jedynym typem ekranu był e-papier (e-ink), znany z czytników e-książek takich, jak Kindle, Kobo czy czy Onyx. Jego unikalną cechą jest to, że pobiera prąd wyłącznie przy zmianie zawartości wyświetlacza, raz ustawiona treść nie zużywa wcale energii.
Nieco więcej opcji mamy przy wyborze jednostki obliczeniowej. Możemy wystartować od energooszczędnych procesorów typu ARM spotykanych w jednoukładowych komputerach Raspberry Pi albo Raspberry Pi Pico / Zero. Niżej znajdziemy popularne platformy ESP32 oraz STM32, wreszcie ośmiobitowe AVR. Tylko co to znaczy?
Dygresja o komputerach jednoukładowych
W roku 2012 premierę miał Raspberry Pi, jednoukładowy komputer wielkości karty płatniczej. Dlaczego jednoukładowy? Bo najważniejszy chip na płytce mieści w sobie niemal całą magię – procesor, układ graficzny, pamięć, niekiedy także kontroler urządzeń peryferyjnych.
Wśród entuzjastów „dłubania w kąkuterach” Raspberry był małym objawieniem. Po raz pierwszy urządzenie o bardzo niskiej cenie połączyło dwa środowiska: hobbystów zajmujących się systemem operacyjnym Linux oraz hobbystów zajmujących się amatorską elektroniką. Odtąd nawet osoby nie mające nic wspólnego z projektowaniem obwodów – na przykład ja – były w stanie realizować autorskie projekty takie jak opisywana na blogu fotobudka. Raspberry Pi to jednak komputer o nie tak małym zapotrzebowaniu na energię – 2.5W to moc, z jaką pracują najsłabsze ładowarki USB.
Raspberry Pi Zero obniża zapotrzebowanie na moc o połowę, nadal jednak jest to komputer o gigaherzowym taktowaniu, wyposażony w pół gigabajta pamięci RAM, port HDMI czy złącze kamery. Nie potrzebujemy żadnej z tych rzeczy, trzeba szukać niżej.
Raspberry Pi Pico przynosi kilkudziesięciokrotną oszczędność w poborze energii – przy niskim obciążeniu są to raptem dwie setne wata! Jednostką obliczeniową jest mikrokontroler RP2040, który nie potrzebuje żadnego systemu operacyjnego. Program, który w nim umieścimy, wystartuje od razu po podłączeniu zasilania i będzie działał bez końca. Brzmi interesująco – nasza stacja pogodowa ma w końcu wyłącznie pokazywać prognozę pogody.
Pamięci RAM mamy jednak raptem 264 kB, czyli dwa tysiące razy mniej. Wystarczy? Powinno. Nie zabraknie za to miejsca na składowanie programu i jego zasobów (np. obrazków), wbudowany Flash ma pojemność 2 MB. Zwróćmy uwagę na niską cenę – starszy model Pico kosztuje niespełna 20 zł.
W podobnej cenie znajdziemy płytki z mikrokontrolerami należącymi do rodziny ESP32, często bardzo małe. W ich opisie odnajdujemy niezwykłą cechę – tryb uśpienia czyli możliwość wstrzymania pracy na zadany okres czasu, podczas którego śmiesznie małe zużycie energii obniża się… tysiąckrotnie. Łatwo odgadnąć, że w tym będzie tkwił sekret długiej pracy na bateriach.
Niżej nie ma sensu schodzić. Płytki z serii Arduino Uno nadają się świetnie do nauki konstruowania układów elektronicznych, ale ich moc obliczeniowa czy pamięć operacyjna są porównywalne do parametrów Commodore 64 sprzed 40 lat. Taki sprzęt nie udźwignie obliczeń wymaganych do obsłużenia łączności HTTPS, a prognozę planujemy pobierać właśnie z internetu.
No dobra, ostatnie zdanie może nie być do końca prawdziwe, co udowadnia hardkorowy koksu Dmitry Grinberg. Pokazał on, że da się uruchomić współczesnego Linuksa na 4-bitowym procesorze Intel 4004 z roku 1971. Sam start systemu trwa jednak ponad 4.5 doby a my chcemy widzieć prognozę na bieżąco, więc sami wiecie.
Jak to się programuje
Naukę programowania zdecydowanie łatwiej zacząć na komputerze. W artykule Napisz własnego Tetrixa pokazałem, w jaki sposób można uczyć się poprzez tworzenie prostej gry działającej w trybie tekstowym. Błędy i przeoczenia były widoczne od razu – na przykład gdy klocki wylatywały poza studnię.
Programowanie mikrokontrolerów było dawniej znacznie trudniejsze. Gdy program działał niezgodnie z zamierzeniami, sprawdzenie stanu rejestrów albo prześledzenie ścieżki wykonania kodu wymagało przeprowadzania pracochłonnej diagnostyki, niejednokrotnie z użyciem oscyloskopu.
Te czasy na szczęście za nami, dziś popularne mikrokontrolery (Arduino, ESP32, RP 2040) możemy programować za pomocą środowisk programistycznych wyposażonych w konsolę, na którą program może wypisywać dowolne komunikaty. To oznacza, że do rozpoczęcia takiej przygody wystarczy podstawowa umiejętność programowania.
Same programy bywają zaskakująco krótkie. Popularny schemat wymaga obecności raptem dwóch funkcji: kod funkcji setup jest wykonywany jednokrotnie przy włączeniu urządzenia, następnie w nieskończoność wykonywany jest kod funkcji loop. Najprostszy program mrugający diodą LED może wyglądać następująco.
void setup() {
pinMode(D5, OUTPUT); // initialize digital pin D5 as an output.
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(D5, HIGH); // turn the LED on
delay(500); // wait for 500 milliseconds
digitalWrite(D5, LOW); // turn the LED off
delay(500); // wait for 500 milliseconds
}
Przykład pochodzi z tutoriala na stronie newbiely.com, tam też znajdziemy schemat połączeń na płytce prototypowej.
Czy da się prościej?
Da się! Niektórzy czytelnicy będą jeszcze pamiętać artykuł O algorytmach dla prawników, w którym pokazywałem różne metody zapisu (reprezentacji) algorytmu realizowanego przez program komputerowy. Jedną z owych metod był graficzny język programowania o nazwie Scratch.
Istnieje kilka różnych projektów, które pozwalają programować mikrokontrolery w takim właśnie środowisku graficznym, bez opuszczania przeglądarki! Powyżej widzimy program mrugający diodą, utworzony w środowisku BIPES – po podłączeniu urządzenia przez port USB będziemy mogli przenieść skompilowany kod binarny do mikrokontrolera klikając jeden przycisk!
Właściciele urządzeń z rodziny M5 mogą wypróbować pakiet UIFlow, zaś posiadacze płytek Futureboard lub Micro:bit – pakiet Kittenblock. Piper Make ma nawet ścieżkę fabularną złożoną z serii projektów o rosnącym stopniu trudności, można wypróbować ją na Raspberry Pi Pico.
PiMoroni Badger 2040 W i Micropython
Wróćmy do sprzętu. Gdy przeglądałem katalog sklepu Botland w poszukiwaniu mikrokontrolera i wyświetlacza typu e-papier, w oko wpadła mi płytka Badger 2040 W marki PiMoroni, stanowiąca rozszerzenie osadzonego na niej układu Raspberry Pi Pico W. Spełniała komplet wymagań, czyli:
- wyświetlacz e-papier o sensownych rozmiarach
- dość pamięci flash, aby pomieścić obrazki
- dość pamięci RAM, aby łatwo parsować prognozy w formacie JSON
- łączność wifi
- tryb głębokiego uśpienia
- zegar czasu rzeczywistego z opcją wybudzania z uśpienia
- osobne złącze do zasilania z baterii
- przystępna cena
Dopiero po jej odebraniu zorientowałem się, że przykładowe aplikacje napisane są w języku Micropython. Nie zetknąłem się z nim wcześniej, bo po pierwsze dawniejsze przygody z programowaniem urządzeń embedded (albo fotobudki na Raspberry Pi) realizowałem przy użyciu języka C, po drugie zaś składnia Pythona odrzuca mnie i staram się iść przez życie omijając ten język programowania.
Okazało się jednak, że – mimo instynktownego oporu – Micropython i towarzyszące mu narzędzia są… dość wygodne. Z doświadczenia wiem, że instalacja działającego środowiska do kompilacji skrośnej (czyli generowania na pececie z procesorem x86 binariów dla innej architektury) bywa problematyczna, zaś typowym produktem wyjściowym jest plik, który za każdym razem nadpisuje całą zawartość pamięci flash.
Tymczasem edytor Thonny, w połączeniu ze środowiskiem Micropythona, pozwala uruchamiać programy bez konieczności pełnego flashowania, daje też dostęp do systemu plików na płytce mikrokontrolera i potrafi kopiować pliki w obie strony. Tym samym więc debugowanie może odbywać się nie tylko poprzez konsolę, ale także w oparciu o plik z logami zapisywanymi przez program.
Micropython jest kompilowany do kodu natywnego mikrokontrolera, więc niedostępne pozostają breakpointy i wstrzymywanie pracy programu w celu podglądu wartości zmiennych. Modułowość języka Python ułatwia za to dopasowanie programu do specyfiki konkretnej płytki. Dokumentacja Badgera informuje, że micropythonowy moduł badger2040
importuje m.in. moduły odpowiedzialne za inicjalizację wifi czy komunikację z układem zegara. Można korzystać też z gotowych klocków do komunikacji po HTTPS czy dekodowania bitmap w formatach PNG/JPEG.
Dodatkową korzystną okolicznością jest fakt, że Python/Micropython ma nieprzebrane zasoby przykładów i tutoriali, w związku z czym bardzo dobrze zna się na nim… ChatGPT i inne LLM-y. Nie raz i nie dwa przyspieszałem w ten sposób pracę nad Pogodynką.
Grafika i brzydkie fonty
Badger jest wyposażony w 1-bitowy wyświetlacz o rozdzielczości 296×128 pikseli. Za rysowanie po ekranie odpowiada biblioteka Pico Graphics, oferująca dość podstawowe operacje graficzne. Możemy kreślić punkty, linie, okręgi i wielokąty czy wczytywać bitmapy.
Kształty mogą być rysowane w szesnastu „odcieniach szarości”, realizowanych poprzez czarno-biały, regularny dithering (tutaj przykładowy kod). Cecha charakterystyczna e-papieru – zawartość ekranu jest odświeżana osobną komendą, rysowanie modyfikuje jedynie bufor obrazu w pamięci. Możemy kontrolować prędkość (a więc i jakość) odświeżania obrazu. Dostępna jest także opcja częściowego odrysowania, ale zostawia ono ślady również poza wyznaczonym obszarem.
Problemem Badgera jest kiepski dobór wbudowanych fontów. Do standardowego zestawu trafiły takie dziwactwa, jak gotyk czy kursywa, które na jednobitowym wyświetlaczu – bez możliwości wygładzenia ukośnych linii – wyglądają bardzo słabo. Niewiele lepiej wypadły pozostałe fonty wektorowe (na fotce powyżej Serif), także skalowanie fontów bitmapowych nie spełniło moich oczekiwań.
Ponieważ do Pogodynki potrzebowałem dwóch głównych rozmiarów cyfr, zdecydowałem się na ich samodzielne przygotowanie. Małe cyfry do skali temperatury (wysokość 10 pikseli) narysowałem ręcznie, duże cyfry (wysokość 64 piksele) pochodzą z fontu Fira stworzonego przez Mozillę. Najmniejsze cyferki pod wykresem pochodzą z dostarczonego fontu bitmapowego, ale i tak prawie ich nie widać.
Aplikacja do pogody już tam jest!
Drugą niespodzianką, po Micropythonie, była obecna wśród aplikacji przykładowych… pogodynka (Weather). Umówmy się, że byłoby daleko posuniętym lenistwem, gdybym uruchomił tę apkę i uznał projekt za zrealizowany. Na szczęście moja wizja była nieco inna, toteż miałem okazję poprogramować samodzielnie.
Moja wersja aplikacji pogodowej realizuje następujące funkcje:
- wskazanie bieżącej temperatury (na razie z internetu, wkrótce z termometrów połączonych z Home Assistantem)
- graficzna prezentacja prognozy temperatury i opadów na nadchodzące 24h
- symboliczna prezentacja prognozy pogody na najbliższe 6h
Aby nie marnować bez potrzeby miejsca na ekranie, rozmiar wykresu dostosowuje się do szerokości napisu reprezentującego temperaturę.
Źródło danych
Prognozę pogody pobieram z darmowego API serwisu Open-Meteo, przy użyciu następującego zapytania.
Przewidywane wskazania temperatury czy opadów są oczywiste. Tabeli z zerojedynkowymi wartościami „is_day
” używam do zaznaczenia na wykresie godzin nocnych, zależnych od pory roku. Zestawem danych, którego nie znałem wcześniej, jest „weather_code
” czyli numeryczna wartość WMO Code Table 4677. Każda ze stu możliwych wartości opisuje charakterystykę pogody, przy czym wartości są uszeregowane według narastającej niedogodności dla ludzi. Przykład: ciągły deszcz ma indeks większy od opadów przelotnych, ale mniejszy od opadów nawalnych.
Aby wybrać jedną z pięciu ikonek (słońce, chmurka, deszcz, śnieg, burza), wystarczy odczytać największą wartość „weather_code
” z nadchodzących 6 godzin. W wolnej chwili planuję rozszerzyć ten zestaw o dodatkowe ikony, np. z tego zestawu. A może zrobi to ktoś z czytelników? Podzbiór wartości zwracanych przez Open-Meteo można znaleźć w dokumentacji.
Czas pracy na bateriach
Teoretyczny czas pracy na bateriach można wyliczyć wypełniając wartości w kalkulatorze online, tym razem postawiłem jednak na praktykę. Zgodnie z zaleceniem producenta, do złącza zasilania podłączyłem trzy akumulatory AA Ni-Mh. Następnie ustawiłem częstotliwość odświeżania ekranu na jedną minutę i odłożyłem zestaw na półkę. Ogniwa wystarczyły na trzy doby działania, czyli około 4300 cykli „łączenie z wifi + pobieranie danych + odświeżenie ekranu”.
Przy godzinnym interwale byłoby to jakieś pół roku działania. W praktyce będzie mniej, choćby z powodu samorozładowania ogniw. Spodziewam się kwartału pracy na jednym ładowaniu i taki wynik będzie dla mnie satysfakcjonujący.
Skąd wiadomo, że urządzenie się nie zawiesiło i nie żre baterii bez sensu? Przy wybudzeniu włączana jest dioda LED, która gaśnie po ściągnięciu prognoz i odświeżeniu ekranu. Dodatkowo podczas łączenia z wifi w rogu ekranu co około dwie sekundy rysowane są czarne kropki. W normalnych warunkach połączenie zostaje nawiązane przy 2-4 kropce, więc 10 lub więcej będzie sygnalizować jakiś problem.
Jak zainstalować Pogodynkę?
Pogodynkę można zainstalować na dwa sposoby. Pierwszy z nich to wrzucenie na Badgera plików z tego katalogu na Githubie (nadpisując istniejące pliki): github.com/tomekziel/pogodynka/tree/main/badger_os. Drugi sposób to przeflashowanie całej pamięci plikiem UF2 pobranym stąd – instrukcję flashowania znajdziesz tutaj.
W obu przypadkach konieczne będzie wyedytowanie pliku WIFI_CONFIG.py
na urządzeniu, należy wpisać tam dane dostępowe do sieci wifi. Można użyć do tego edytora Thonny. Być może da się to zrobić także przez Remote MicroPython shell, ale nie próbowałem tej metody. Jeśli mieszkasz poza Wrocławiem, możesz zechcieć zmodyfikować współrzędne w pliku pogodynka.py
.
Warto odnotować, że Github czyni budowanie obrazu do flashowania banalnie prostym. Tak naprawdę wszystko robi się samo – wrzucam zmianę do repozytorium, odpala się instancja Github Actions, dwie minuty później dostaję gotowy plik wyjściowy. Bez konieczności instalowania całego toolchaina, kompilatorów, bibliotek, dopasowywania wersji narzędzi, wszystkiego tego, co może zająć długie godziny lub nawet dni. Darmowe limity Githuba wystarczą na jakiś tysiąc buildów miesięcznie.
Podsumowanie
Pogodynkę wyposażyłem w obudowę wydrukowaną na drukarce 3D, z osadzoną parą magnesów neodymowych. Urządzenie wisi na tablicy magnetycznej niedaleko wyjścia z domu i pokazuje wszystkim zainteresowanym aktualną temperaturę i prognozowaną pogodę. Pudełko z bateriami jest schowane na półce obok.
Ktoś mógłby zarzucić, że projekt nie spełnia kryteriów „zrób-to-sam”, bo płytka jest gotowa do pracy od razu po wyjęciu z pudełka, zaś oprogramowanie oparłem na istniejącej apce pogodowej. Cóż, to po części prawda, choć kupując sprzęt nie miałem świadomości, co znajdę w przykładach. Mam jednak nadzieję, że wymyślona i zaprogramowana przeze mnie graficzna reprezentacja prognozy pogody spełnia minimalne kryteria dzieła. Ja świetnie bawiłem się podczas tworzenia projektu i zachęcam wszystkich do wypróbowania własnych sił w programowaniu czegoś nietypowego.
Jeśli ktoś chce spojrzeć, co można osiągnąć relatywnie prostymi środkami, mogę polecić trzy zasoby. Pierwszym będzie kilka alternatywnych projektów podobnych do Pogodynki – tutaj, tutaj oraz tutaj, tutaj i tutaj.
Drugi zestaw linków to opisy tworzenia kilku gierek elektronicznych o rosnącym stopniu komplikacji, autorstwa lcamtufa: tutaj, tutaj, tutaj, tutaj i tutaj.
Trzecim zasobem będzie wszystko, co publikuje na Youtube Ben Eater – ze szczególnym uwzględnieniem dwuodcinkowej serii o konstruowaniu najgorszej karty graficznej świata oraz playlisty prezentującej budowę i programowanie 8-bitowego komputera na płytce prototypowej.
Podzielcie się w komentarzach swoimi projektami i pomysłami na projekty!
O autorze: zawodowy programista od 2003 roku, pasjonat bezpieczeństwa informatycznego. Rozwijał systemy finansowe dla NBP, tworzył i weryfikował zabezpieczenia bankowych aplikacji mobilnych, brał udział w pracach nad grą Angry Birds i wyszukiwarką internetową Microsoft Bing.
10 odpowiedzi na “Pogodynka zrób-to-sam”
Brawo za opis, przymierzałem się do tego badgera, bo chcę zbudować mały barograf (wyświetlanie bieżącego ciśnienia, zmiany w ostatnich godzinach i wykres trendu) z wykorzystaniem BMP280 podpiętego za pomocą I2C. Ale badger nie oferuje I2C.
Teraz pomyślałem, że skoro jest tam RPi Pico, to może da się dolutować?
Potrzebuję urządzenie autonomiczne i energooszczędne, takie w sam raz na łódkę. Nie chcę pobierania danych po wifi, bo znika atrybut autonomiczności.
Jeśli możesz to jakoś sprawdzić, będę wdzięczny
Hej! Te wątki na forumciach sugerują, że da się:
https://forums.pimoroni.com/t/badger-2040-connections-pads/19096
https://forums.pimoroni.com/t/badger-2040-i2c-pins/19327/5
I2C jest też wspomniane na oficjalnej stronie: https://shop.pimoroni.com/products/badger-2040
Dzięki!
Teraz zwróciłem uwagę – te wyprowadzenia są w wersji 2040, tej bez wifi
Fajny projekt.
Ciekawe mnie ile wytrzyma taka pogodynka w wersji lorawan zamiast wifi.
We Wro jest kilka bramek lorawan.
Bramek = punktów styku LORA z internetem? Nie znam w ogóle tej technologii.
https://www.thethingsnetwork.org/map
Raspberry Pi Pico
Moduł LoRa kompatybilny z LoRaWAN (np. RFM95, SX1276)
biblioteka obsługującej LoRaWAN, np. pyLoRa w MicroPythonie lub odpowiedniego SDK w C/C++.
No dobra, ale czy istnieje gotowa technologia, w której mogę przy pomocy istniejącej infrastruktury wysłać żądanie HTTP GET do internetu i otrzymać odpowiedź? Bo sam ślepy broadcast ramki danych w świat to trochę za mało.
Tak, na The Things Network (TTN) można budować aplikację. Można zarówno pobierać jak i wysyłać dane.
Ale przecież tutaj pogodynka jest bramką, a nie nadawcą. To ona chce odebrać pogodę z internetu (lub z lora). Chyba, że myślisz o wysyłaniu z tego pomiarów do internetu, ale wtedy nie wiem po co ekran.