Pokażę tu projekt zegara zbudowanego na ESP8266 i wyświetlaczu opartym na MAX7219, dodatkowo wzbogaconego o moduł przekaźników na MCP23017. PCB pod ESP będzie pochodzić z sieci, moduł przekaźników z kolei projektowałem sam. Firmware złożę samodzielnie w PlatformIO z gotowych bibliotek. Czas pobierany będzie z internetu poprzez NTP.
Użyte tu główne PCB pod ESP12 jest autorstwa "kbprogram" i było udostępniane na jego blogu, a jedną jego sztukę wysłał mi jeden z moich czytelników (wraz z paczką innych części).
Z reguły gotowych zestawów (tzw. kitów) nigdy nie składam i nie składałem - nawet moje pierwsze układy robione 6 czy więcej lat temu były DIY - łącznie przykładowo np. z trawieniem TQFP, czy tam z moją płytką PIC32, czy też z moimi próbami Ethernet na PICu z wbudowanym wszystkim co trzeba.
W tym jednak przypadku skoro już otrzymałem PCB od jednego z czytelników, to po prostu postanowiłem go użyć. Oto zawartość całej otrzymanej paczuszki (postaram się coś jeszcze z niej opisać w przyszłości):
Dziękuję za paczkę!
Jeśli chodzi o wspomniany z kolei moduł przekaźników, to początkowo w zamyśle była to nakładka na ten projekt:
Sterownik przekaźników kompatybilny z Home Assistant/Tasmota HTTP + obudowa
Ale zamawiając płytki dostałem 10 sztuk, więc trochę zostało ich do innych projektów.
Tyle wstępu, zaczynamy.
Lutowanie płytki
Płytka ta stanowi dziwny mix THT i SMD. Nie wiem, czemu akurat autor tak sobie ją wymyślił, może to miał być złoty środek między rozmiarem a trudnością lutowania? Dokumentację projektu macie na stronie autora podanej na płytce. W zasadzie nie ma tu co omawiać. Blok zasilania z LDO 3.3V (użyłem TC1264), ESP12, blok zegara z koszyczkiem na baterie, linie I2C z rezystorami pull up, pamięć EEPROM też na I2C i w zasadzie tyle.
Te tranzystory SMD na spodzie płytki to tylko potrzebne jak chcemy resetować układ liniami z UART. Sam resetowałem i wprowadzałem w stan programowania przyciskami.
Moduł WiFi lutowałem robiąc kropelkę spoiwa na jednym padzie, chwytając go za ten pad i potem lutując już pozostałe.
Kondensatory odsprzęgające 100nF miałem w nieco mniejszych obudowach:
Prawie gotowe, można programować:
Jeszcze dolutowałem elementy, niestety otwory na nóżki koszyka na baterię zegarkową do podtrzymania czasu były za małe, musiałem wiercić:
ArduinoOTA, czyli wygodne wgrywanie wsadu przez WiFi
Do programowania wybrałem platformę PlatformIO. Wcześniej nie miałem z nią styczności:
https://platformio.org/
Opis instalacji dla VSCode:
https://platformio.org/install/ide?install=vscode
Instalacja odbywa się w dwóch etapach. Najpierw VSCode, a potem PlatformIO addon. Poszło bezproblemowo.
Do wgrywania wsadu wybrałem ArduinoOTA - czyli wgrywanie wsadu przez WiFi.
Oto użyty plik platform.ini:
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
monitor_speed = 115200
lib_deps =
me-no-dev/ESP Async WebServer@^1.2.3
[env:d1_mini_ota]
extends = env:d1_mini
upload_protocol = espota
upload_port = 192.168.0.124
lib_deps =
me-no-dev/ESP Async WebServer@^1.2.3
Szkielet aplikacji OTA z dopisanym na dziko blink LED na GPIO2, czyli LED na pokładzie samego modułu WiFi który miałem:
Kod: C / C++
Ten wsad trzeba wgrać raz 'kabelkowo', potem już można wgrywać przez WiFi.
Wsad trzeba uzupełnić o SSID i hasło naszej sieci WiFi.
Ważne jest również ustawienie takiego IP jak w konfiguracji OTA - u mnie po prostu jest to zrobione przez rezerwację IP dla MAC mojego ESP.
Wszystko bezproblemowo. Już można programować ESP8266 przez WiFi.
Do lepszej konfiguracji naszej sieci WIFi można by podpiąć bibliotekę WiFiManager:
https://www.arduino.cc/reference/en/libraries/wifimanager/
Pozwoliłaby ona resetować konfigurację WiFi i cofać urządzenie do trybu konfiguracyjnego AP prostym przyciskiem, a potem w trybie AP wpisywać nasze SSID i hasło, które potem jest pamiętane po wyłączeniu. Troszkę tak jak w Tasmocie.
Ale tego jeszcze w tym projekcie nie zrealizowałem.
Biblioteka MD_Parola
Do sterowania MAX7219 wybrałem bibliotekę MD_Parola. Można ją bardzo łatwo zainstalować przez PlatformIO. Zasadniczo tylko trzeba ją wyszukać i przeklikać proces instalacji. Wszystko automatycznie.
Po wyszukaniu biblioteki można wybrać jej wersję i kliknąć "Add to Project".
Użycie MD_Parola jest naprawdę bardzo proste. Dokumentacja jest tutaj:
https://github.com/MajicDesigns/MD_Parola
Definiujemy typ wyświetlacza oraz piny jego SPI (chociaż u niego niego jest to okrojone, komunikacja jest w jedną stronę):
Kod: C / C++
Potem go inicjujemy poprzez Begin:
Kod: C / C++
A potem, już w pętli możemy go kontrolować i animować.
Kod: C / C++
Poniżej mój kod z załączoną biblioteką:
Kod: C / C++
Efekt:
NTP czyli czas z internetu
O własnym kliencie NTP pisałem m. in. tutaj, ale w przypadku PlatformIO i gotowych bibliotek Arduino nie trzeba nawet wiedzieć czym jest UDP - tu też jest gotowiec.
Załączamy nagłówek klienta:
Kod: C / C++
Tworzymy klienta NTP, składa sie on z dwóch części:
Kod: C / C++
Adres serwera czasu można zmienić. Ustawiamy strefę czasową i rozpoczynamy działanie NTP:
Kod: C / C++
W pętli aktualizujemy jego pracę:
Kod: C / C++
Jeszcze trzeba przenieść czas na wyświetlacz, ale pomoże nam w tym wbudowana już w klasę Parola funkcja Printf:
Kod: C / C++
Wystarczyło dopisać kilka linijek kodu i o proszę - mamy wyświetlanie czasu:
Kod: C / C++
UWAGA: to godzinę pierwszą pięć wyświetli jaki 1:5, nie ma tu dodawania dodatkowych zer.
W podobny sposób można z NTP dostać bieżącą datę, więc bardzo łatwo jest rozwinąć poprzedni przykład i uzyskać taki efekt:
Poniżej pełny kod mojego wyświetlania daty, dodatkowo bazujący na pomocniczej funkcji która formatuje liczbę dodając poprzedzające ją zero (by np. 5 minut po 10 wyświetłało się jako 10:05 a nie 10:5):
Kod: C / C++
Kod: C / C++
Nie bawiłem się tu w sprawdzanie rozmiaru bufora, aczkolwiek należy o tym i tak wspomnieć. Jeśli podany bufor do sprintf nie ma wystarczającego rozmiaru to działanie sprintf daje niezdefiniowane efekty, będzie nadpisywało dalszą zawartość pamięci. Należy rozważyć użycie jego bezpiecznego odpowiednika, sprawdzającego rozmiar docelowego bufora, przykładowo sprintf_s.
Warto podkreślić, że sam tekst do wyświetlacza wysyła ta linijka:
Kod: C / C++
ona również włącza animację. Oczywiście są też inne rozwiązania, można użyć gotowej funkcji do zamiany czasu na napis:
Kod: C / C++
Plusem tej funkcji jest to, że nie przekroczy ona rozmiaru bufora, więc jest bezpieczniejsza.
Płytka z przekaźnikami - MCP23017
Jak już wspominałem, ta płytka jest mojego autorstwa i na pokładzie zawiera expander portów (16-bitowy) MCP23017 z interfejsem I2C. Do jego sterowania potrzebne są dwie linie - SDA i SCL. Dodatkowo potrzebujemy VDD - tu 3.3V oraz zasilania przekaźników - 5V. Część wyprowadzeń MCP23017 jest wyprowadzona na goldpiny, gdyż nie zmieściłem na PCB aż 16 przekaźników. Dodatkowo na płytce są pady pozwalające wybrać sobie adres expandera (trzy piny adresowe - A0, A1, A2), mamy tu do wyboru aż 2^3 kombinacji adresów, więc trochę tych expanderów można na magistralę I2C podłączyć.
Pora na lutowanie - SMD lutowałem tak, że najpierw nakładałem spoiwo na jeden pad (z topnikiem), potem pozycjonowałem element pesetą i roztapiałem to spoiwo grotem, a potem lutowałem drugą jego nóżkę.
Zworki ze spoiwa do wyboru adresu:
Użyłem tranzystorów S9014 montowanych powierzchniowo:
Prawie gotowe:
Obsługa MCP23017
Tak jak wcześniej - mamy gotową bibliotekę.
https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library
Instalujemy ją:
Załączamy nagłówek:
Kod: C / C++
Tworzymy obiekt:
Kod: C / C++
Biblioteka domyślnie zakłada, że wszystkie piny adresowe podłączyliśmy do masy, tak jak też to zrobiłem, więc nawet nie trzeba podawać adresu.
Też mnie to naprawdę zaskoczyło, tu jest wszystko uproszczone do absolutnego minimum, to jest tak bardzo przyjazne początkującym, że początkujący nie musi nawet wiedzieć o adresach I2C by użyć MCP...
Zostaje jeszcze zmodyfikować mój warunek migania w głównej pętli:
Kod: C / C++
Tak - wystarczy naprawdę tyle, samo mcp.digitalWrite!
Rezultat (potrzeba włączyć audio):
Słychać pracę przekaźnika - blink działa.
Serwer WWW
Następnie przygotowałem prosty serwer WWW do konfiguracji zegara oraz przekaźników w oparciu o AsyncWebServer, ale... szczegóły umieszczę w następnej części. Docelowym planem jest opracowanie prostego kalendarzyka na panelu WWW, gdzie możemy ustawić kiedy załącza się jaki przekaźnik, najlepiej z uwzględnieniem też dni tygodnia. Oczywiście będzie też budzik oparty o buzzer. Ale to dopiero za jakiś czas.
Podsumowanie
Projekt zasadniczo zacząłem tylko z ciekawości, dla czytelnika, bo po prostu przysłał mi pod niego części. Nawet płytka pod ten zegar nie była moja, tylko gotowiec z sieci. Całość poszła (bądź idzie, bo jeszcze nie jest gotowy) bardzo sprawnie i przyjemnie. Gotowe biblioteki pod ESP oraz masa przykładów sprawiają, że wszystko składa się z gotowych komponentów, bez potrzeby jakiegokolwiek głębszego zrozumienia co i jak działa. To zupełnie co innego niż to, co zazwyczaj robię, typu projekt zegar na PIC18F2550. W tamtym projekcie większość rzeczy musiałem uruchomić samodzielnie, wiedząc mniej więcej jak one działają, a tu nawet nie trzeba wiedzieć z jakiego protokołu korzysta MAX7219 by wyświetlić na nim tekst! Tylko czy to jest dobre dla początkujących? Zdania pewnie są podzielone...
Fajne? Ranking DIY Pomogłem? Kup mi kawę.



