Dzisiaj przedstawię bardzo tani (raptem 10-15 zł) moduł oferujący wyświetlacz 7-segmentowy (8 cyfr) z kropkami oraz dodatkowo z diodami nad każdą cyfrą oraz klawiaturę z 8 przyciskami. Wszystko możliwe do wysterowania przez SPI. Pokazywany tu TM1638 to zasadniczo TM1637 w wersji SPI, w związku z czym polecam tu lekturę tematu gdzie omawiałem TM1637:
Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
Widać to łatwo jak spojrzymy na rejestry:
Różnica jest tylko w samej komunikacji - 2 vs 3 linie:
Z tego wynika, że nie ma dużo co zmieniać w naszym kodzie z poprzedniego tematu:
Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
Ale czy na pewno?
Zmodyfikujmy TM1637_WriteByte z poprzedniego tematu. Dla uproszczenia założyłem, że jeśli w strukturze pomocniczej z pinami indeks STB jest różny od -1, to używamy SPI:
Kod: C / C++
Powyższy kod jest z mojego projektu OBK, ale zakładam, że funkcje ustawiające stany na pinach są zrozumiałe po samej nazwie i każdy może sobie na ich miejsce dać np. digitalWrite...
Pora na testy!
Testy z kodem sterownika TM1637
A więc zaktualizowaliśmy już kod wysyłania danych (poszczególne bajty), nic więcej nie zostało zmienione. Czy TM1638 ruszy? Sprawdźmy.
Przypomina, testy wykonywałem w swoim środowisku:
https://github.com/openshwprojects/OpenBK7231T_App
Działa ono na platformach:
- BK7231T (WB3S, WB2S, WB2L, itd.)
- BK7231N (CB2S, CB2L, WB2L_M1, itd.)
- BK7231M, to wersja BK7231N bez Tuya z kluczami 00000000, czasami w wersji BL2028
- T34 (T34 oparty jest na BK7231N)
- BL2028N (BL2028N to wersja BK7231N od Belon)
- XR809 (XR3, itd.)
- BL602 (SM-028_V1.3 itd.)
- LF686 (wersja BL602)
- W800 (W800-C400, WinnerMicro WiFi & Bluetooth), W801
- W600 (od WinnerMicro), W601 (WIS600, ESP-01W, TW-02, TW-03, itd.)
- LN882H od Lightning Semi
- Windows, przez symulator
Stanowisko testowe:
Pierwszy, testowy skrypt. Tak, moje środowisko pozwala wywoływać funkcje C z poziomu tekstowego skryptu, który kod w C wczytuje i wykonuje. Wszystkie GPIO poprawnie ustawione. Komenda TMGN_Test zapala losowe bity z rejestrów:
startDriver TM1638
TMGN_Test
Coś działa, więc podstawa komunikacji jest:
Sprawdźmy coś bardziej zaawansowanego. Spróbujmy wyświetlić tekst. Na TM1637 to działało. Argumenty TMGN_Print to offset pierwszego znaku na który piszemy, drugi argument to limit znaków, a trzeci to łańcuch znaków do wyświetlenia.
startDriver TM1638
TMGN_Clear
TMGN_Print 0 8 8
To powinno wyświetlić znak 8, ale zapala kropki
Coś jest nie tak, tylko co?
Sprawdźmy podobny kod:
startDriver TM1638
TMGN_Clear
TMGN_Print 1 9 8
To zapala środkowe segmenty
Z tego można wyciągnąć prosty wniosek - zamienione są wiersze z kolumnami.
Ale po zaglądnięciu do kodu zorientowałem się, że sam je zamieniłem już, w celu wsparcia innego modułu wyświetlacza:
Kod: C / C++
Dla pokazywanego tutaj modułu g_doTM1638RowsToColumnsSwap ma być ustawione na 0. Jest to o tyle ciekawe, że w przypadku TM1638 z jednego z produktów Tuya, to ustawienie trzeba było włączyć:
Postęp w rozwoju sterownika TM1638: Aktualizacje modułu, kodu i funkcji
Teraz kwestia mapowania znaków na bajty. O dziwo pomiędzy wszystkimi TM1637, TM1638, TM1650, HD2015, itd, standard jest trzymany:
Kod: C / C++
Natomiast mapowanie rejestrów na cyfry jest tu inne niż popularne ustawienie, które mam w kodzie:
Kod: C / C++
Jest 16 bajtów, 8 cyfr. Co drugi bajt to cyfra. Bajty nieparzyste to diody. Do zmiany mapowania mam u siebie funkcję: TMGN_Map.
stopDriver TM1638
startDriver TM1638 0
TMGN_Clear
TMGN_Map 0 2 4 6 8 10 12 14
TMGN_Print 0 8 01234567
To jeszcze trzeba uruchomić diody. One są w nieparzystych rejestrach. Mój system pozwala łatwo to wykorzystać i rozwinąć mapowanie. Po zmapowaniu dalszych znaków na nieparzyste rejestry użycie TMGN_Print z offsetem 8 pozwoli zapalić diody.
stopDriver TM1638
startDriver TM1638 0
TMGN_Clear
TMGN_Map 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
TMGN_Print 0 8 01234567
TMGN_Print 8 16 88888888
Rezultat:
Kropki działają poprawnie.
Bardziej zaawansowane demo
Omawiany w poprzednim temacie sterownik TM1637 po zastosowaniu pokazanych wcześniej poprawek jest w stanie w pełni obsłużyć TM1638. U mnie w OpenBeken wywołania funkcji są opakowane w prosty język skryptowy, co pozwala na dynamiczne zmiany wyświetlanych danych. W ten sposób można zrobić demo-odliczanie:
stopDriver TM1638
startDriver TM1638 0
TMGN_Clear
TMGN_Map 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
TMGN_Print 0 8 01234567
setChannel 10 1000
setChannel 11 2345
again:
delay_s 1
TMGN_Print 0 4 $CH10
TMGN_Print 4 4 $CH11
addChannel 10 1
addChannel 11 1
goto again
Powyższy kod odlicza dwie wartości (stopniowo zwiększa je o 1). Są one odpowiednio wyświetlane na połówkach wyświetlacza.
Rezultat: film
Wszystko działa, ale jak wyświetlana by była wartość typu "123", bez jednej cyfry?
Tutaj wchodzi do gry kolejny argument (równanie do prawej i wypełnianie zerami). Patrz funkcja TMGN_Print:
stopDriver TM1638
startDriver TM1638 0
TMGN_Clear
TMGN_Map 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
TMGN_Print 0 8 01234567
setChannel 10 1
setChannel 11 2
again:
delay_s 1
TMGN_Print 0 4 $CH10 1
TMGN_Print 4 4 $CH11 1
addChannel 10 1
addChannel 11 1
goto again
Rezultat:
Obsługa przycisków
Z przyciskami analogicznie. Trzeba tylko zmienić funkcję odczytu danych:
Kod: C / C++
U mnie w środowisku skanowanie przycisków uruchamiany komendą która bierze za argument czas pomiędzy poszczególnymi skanami. To dlatego, że nie ma tutaj dodatkowego pinu przerwania w momencie zdarzenia na klawiaturze. Musimy sami odpytywać i szukać zmian.
TMGN_SetupButtons 50
W moim środowisku jest możliwość podpięcia komendy do zdarzenia powiązanego z przyciskiem, ale na razie sprawdźmy czy w ogóle one działają:
Przycisk pierwszy:
Indeksy nie są po kolei ale działa:
Tak wygląda skrypt-demko interakcji:
stopDriver TM1638
startDriver TM1638 0
TMGN_Clear
TMGN_Map 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
TMGN_Print 0 8 01234567
TMGN_SetupButtons 50
addEventHandler OnCustomDown 0 addChannel 10 1
addEventHandler OnCustomDown 8 addChannel 10 -1
addEventHandler OnCustomDown 16 addChannel 10 10
addEventHandler OnCustomDown 4 addChannel 10 -10
addEventHandler OnCustomDown 12 addChannel 10 100
addEventHandler OnCustomDown 28 addChannel 10 -100
setChannel 10 1
setChannel 11 2
again:
delay_s 1
TMGN_Print 0 4 $CH10 1
TMGN_Print 4 4 $CH11 1
addChannel 11 1
goto again
Powyższy skrypt po prostu podpina zmianę wartości zmiennych pod przyciski. W praktyce można pod to podpiąć wiele różnych komend, w tym:
- przełączanie przekaźników
- wyzwalanie bądź ustawianie timera
- wysyłanie komend przez MQTT do np. Home Assistant lub przez HTTP do innych urządzeń
Prezentacja:
Trochę tu zawaliłem, wyświetlacz odświeża się wolno, bo... a zresztą - może ktoś wie? Oczywisty błąd, łatwy do poprawki.
Kropka i dosuwanie do prawej
Ostatnią rzeczą do rozważenia jest obsługa kropki. Kropka znajduje się w obrębie tego samego rejestru co poprzedzająca ją cyfra. Trzeba to uwzględnić przy mapowaniu napisu na rejestry. U mnie jest po prostu:
Kod: C / C++
Nie zakładam sytuacji gdzie łańcuch znaków zaczyna się od kropki.
Sprawdźmy jak to działa w praktyce - wraz z równaniem do prawej strony wyświetlacza:
stopDriver TM1638
startDriver TM1638 0
TMGN_Clear
TMGN_Map 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15
TMGN_Print 0 8 3.145 1
Wartość z przecinkiem jest wyświetlana poprawnie.
Wnioski
Bardzo fajny i tani moduł. Łatwy do uruchomienia. Z konkretów to udało mi się określić, że:
- adresy rejestrów i ogólnie sposób komunikacji z TM1637 jest zgodny
- mapowanie znaków na rejestry niestety nie jest ustandaryzowane, ten konkretny moduł nie ma zamienionych "kolumn z wierszami", ale niektóre tak mają
- same kody bajtowe znaków zdają się być takie same, bez względu na typ wyświetlacza, TM1638, TM1637, HD2050, GN6932, itd.
- mapowanie rejestrów cyfr na kolejne cyfry nie zawsze jest zgodne
Podsumowując, TM1638 da się łatwo uruchomić razem z TM1637 w jednym sterowniku, ale trzeba mieć na uwadze te drobne problemy, które też zależą nawet nie od danego układu scalonego, lecz od konkretnej płytki.
A jak ktoś nie chce kombinować to zawsze można użyć też gotowca:
https://github.com/search?q=TM1638&type=repositories
Czy korzystaliście już z TM1638 a jeśli tak to do jakich projektów?
Fajne? Ranking DIY Pomogłem? Kup mi kawę.
