Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół

p.kaczmarek2 04 Mar 2023 08:47 1689 13
Diolut
  • Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Zapraszam na krótki test i demonstrację użycia popularnych modułów wyświetlacza 7-segmentowego opartych na TM1637. Uruchomię taki moduł najpierw z Arduino, a potem bez użycia żadnej biblioteki, na koniec również pokażę alternatywną, eliminującą zbędne opóźnienia bibliotekę przeznaczoną do sterowania tymi modułami.

    Zakup układu
    Może tym razem temat zaczniemy od kwestii finansów. Ile kosztuje ten moduł?
    Tym razem poszukiwania zrealizowałem na polskim serwisie aukcyjnym.
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Można kupić zarówno samą kość, nawet za 2.5zł, jak i gotowe moduły.
    Moduł 4-cyfrowy kosztuje jakieś 6zł, a 6-cyfrowe moduły są za ponad 15zł:
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Przesyłka też będzie kosztować około 10 zł, chyba, że ma się wykupione darmowe przesyłki, z których sam na tym portalu korzystam. Niestety obowiązują dopiero od około 40/45zł kwoty zamówienia, więc coś jeszcze trzeba do koszyka włożyć.

    Trochę teorii...
    A raczej krótka lektura noty katalogowej. Na początek witają nas wyprowadzenia układu, ale mamy gotowy moduł, więc to nam nie jest potrzebne:
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Układ potrafi też obsługiwać klawiaturę, ale nasze moduły tego nie wspierają.
    Wyprowadzenia:
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    6 gridów, 8 segmentów.
    Czyli 6 cyfr 7-segmentowych z np. dodatkową kropką lub z dwukropkiem.
    Te CLK, ACK, brzmią trochę jak I2C, ale...
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Niestety I2C to nie jest. Nie ma nawet wspieranego adresowania układów, czyli nie można (tak jak by można było w I2C) na jedną magistralę podłączyć kilku urządzeń. Słabo.
    Przykładowa aplikacja:
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Przyciski są podłączone do specjalnych portów K2 i K1, czyli nie odbierają nam wyświetlaczy. Warto będzie rozważyć wykorzystanie tego w przyszłosci, choć tutaj tego nie opiszę. Tych przycisków też jest dość dużo, więc można by zrobić na tym ładną klawiaturkę.
    Parametry użytych wyświetlaczy (prąd na segment, itd.) są w nocie katalogowej.

    Przykład w Arduino
    Większość popularnych modułów już posiada ogólnodostępne, darmowe biblioteki do Arduino. Tak jest i w tym przypadku. Wszystko na Githubie:
    https://github.com/avishorp/TM1637
    Bibliotekę można też znaleźć w kreatorze bibliotek Arduino i dołączyć automatycznie.
    Oto pełny przykładowy kod z tej biblioteki:
    Code: cpp
    Log in, to see the code

    Ale całość można nieco uprościć.
    Code: cpp
    Log in, to see the code

    Konstruktor TM1637Display bierze dwa argumenty - indeks pinu CLK i DIO. Funkcja setBrightness ustawia poziom jasności (od 0 do 15) oraz włącza segmenty (true by je włączyć, false wyłączyć).
    Wartość dziesiętną pokazuje showNumberDec.
    Oprócz tego mamy dostęp bezpośrednio do segmentów (funkcja setSegments) oraz możliwość wyświetlenia liczby z kropką (funkcja showNumberDecEx). Funkcja setSegments oferuje argumenty, za pomocą których można dostać się do wybranego znaku (np. zaktualizować tylko dwa znaki na pozycjach 4 i 5), pierwszy argument to indeks pierwszego znaku, a drugi to ilość znaków.

    Przykład "na piechotę"
    Protokół wyświetlacza jest znany i opisany w nocie katalogowej:
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Zgodnie z protokołem, aby wysłać write data to display register najpierw musimy nadać:
    Code: c
    Log in, to see the code

    Potem, po stop i ponownym start nadajemy komendę ustawienia rejestru do którego zapisujemy, czyli:
    Code: c
    Log in, to see the code

    Z 4 najmłodszymi bitami ustawionymi na adres pierwszego znaku, który aktualizujemy. Zazwyczaj będzie to 0.
    Potem nadajemy kolejne bajty (dane segmentów).

    Na koniec chcemy nadać display control ze stanem On/Off (bit 3) oraz poziomem jasności (bity 2, 1 i 0):
    Code: c
    Log in, to see the code

    Wpisując to w kod otrzymujemy:
    Code: c
    Log in, to see the code

    Uzupełniając, powstawanie danych trzeciej komendy już opisywałem (bit on/off oraz 3 bity poziomu jasności), powstaje ona tak:
    Code: c
    Log in, to see the code

    Zostają jeszcze nasze 3 pomocnicze funkcje, czyli warunek startu, stopu oraz wysyłanie bajtu.
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Zaczynamy od stanów wysokich, potem DIO przechodzi w stan niski, jak również i zegar.
    Code: c
    Log in, to see the code

    Potem, dla każdego bitu, ustawiamy jego wartość na DIO, a ona jest odczytywana przez układ w momencie rosnącego zbocza CLK (czyli jak CLK przechodzi ze stanu false na true, niskiego na wysoki).
    Code: c
    Log in, to see the code

    Potem, kontynuując funkcję wysyłania bajtu, mamy:
    Code: c
    Log in, to see the code

    Zegar wykonuje kolejny cykl. Pin DIO wchodzi w tryb wejścia. To jest ten moment, który na diagramie jest oznaczny jako The chip is automatically lowered at ACK low level (pomiędzy opadającym zboczem 8-go cyklu zegara i zakończeniem 9-go cyklu zegara). Czekamy moment i odczytujemy wartość z DIO. To jest odpowiedź ACK. Na jej bazie można sprawdzić, czy układ odpowiada. Potem DIO wraca do trybu wyjścia.
    Na koniec wracamy do stanów wysokich.
    Code: c
    Log in, to see the code

    To tyle. Oczywiście, nie zdefiniowałem tu rzeczywistych map segmentów które są wymagane by poprawnie wyświetlić cyfry, ale to można już zrobić we własnym zakresie.

    Prędkość komunikacji
    Problem braku rzeczywistego I2C już omawiałem, ale niestety to nie jest jedyna niemiła niespodzianka tutaj. Po zaglądnięciu do źródła TM1637Display.cpp widzimy, że kod komunikacji usłany jest delay'ami (a dokładniej tam: bitDelay), domyślnie 100us. Jest to na tyle dużo, że warto coś z tym zrobić. Sam w moim kodzie (zacytowanym powyżej) trochę eksperymentowałem ze zmniejszaniem tych opóźnień, ale w sieci też jest gotowe na to rozwiązanie:
    https://github.com/cphouser/TM1637-no-delay
    Biblioteka TM1637-no-delay zaimplementowana jest bez użycia funkcji takich jak delayMicroseconds. Posiada interfejs pozwalający odświeżyć wyświetlacz bez blokowania pętli zdarzeń. Wymaga dodatkowego wywoływania funkcji update co 100us.
    Poniżej przykład użycia tej biblioteki (skopiowany z ich Githuba):
    Code: c
    Log in, to see the code

    Po dokładne wymagania co do timingu należy zajrzeć do noty katalogowej.


    Mały problem z kolejnością setSegments
    Na koniec chciałbym dać jeszcze małą uwagę/przestrogę co do ustawiania segmentów. Nie wiem, czy to jest częsty problem, ale w moim przypadku cyfry wyświetlacza były tak podłączone, że wysłanie do niego kodów znaków w tej kolejności:
    
    1 2 3 4 5 6
    

    Skutkowało wyświetleniem:
    
    3 2 1 6 5 4
    

    Aby to naprawić, trzeba albo fizycznie przepiąć połączenia GRID (jak na schemacie umieszczonym wyżej w tym temacie), albo programowo remapować segmenty poprzez tablicę:
    Code: c
    Log in, to see the code

    Indeksy w C/CPP itd zaczynamy od 0.


    Galeria efektów
    Niezbyt wiem co można tu pokazać. Chyba najlepiej zacząć od kontroli poziomów jasności:
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Klasyka, odliczanie:
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół
    Test cyfr:
    Wyświetlacze 7-segmentowe na TM1637 - 4 i 6 cyfr - Arduino, protokół

    Podsumowanie
    Przed bliższym zapoznaniem moduł wydawał się być bardziej atrakcyjny. Po dokładniejszym poznaniu jego działania uznałem, że jest nieco gorszy niż myślałem. Nie powinieniem narzekać, bo i tak kupiłem go na prośbę kolegi z Ukrainy, aby móc dla niego go uruchomić na BK7231N, ale naprawdę nie rozumiem, czemu producent nie użył w tym wyświetlaczu normalnego I2C. Możliwość użycia jednej linii komunikacyjnej (no dobra, dwóch linii - SDA i SCL) dla wielu urządzeń jest naprawdę bardzo przydatna, a co by producentowi to jedno więcej odebranie bajtu zmieniło? I czemu ta komunikacja jest taka wolna? Dobrze, że w sieci są gotowe biblioteki dla niego pod Arduino, zarówno w wersji blokującej jak i tej bez opóźnienień.
    Czy korzystał ktoś z tego wyświetlacza w projektach? A może ktoś zna równie tani moduł, ale z interfejsem I2C?

    Cool? Ranking DIY
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
  • Diolut
  • #2
    krzbor
    Level 25  
    Mam pytanie - czy na najniższej jasności w idealnej ciemności nie świeci zbyt jasno? Często mam wrażenie, że producenci nie doceniają logarytmiczności ludzkiego oka. Gdy robiłem ramkę wyświetlającą temperaturę Link stwierdziłem, że w ciemnym pomieszczeniu treść jest widoczna przy PWM wynoszącym 5/1000. To bardzo mało. W dodatku przy tak małym wypełnieniu musiałem drastycznie zwiększyć częstotliwość, aby migotanie nie było widoczne.
    Przyłączam się też do pytania Autora - jak te moduły sprawdzają się w dłuższym okresie czasu? Cena tych modułów jest często taka sama jak samego układu scalonego. Nie wróży to nic dobrego dla jakości (trwałości) wyświetlacza.
  • #3
    p.kaczmarek2
    Moderator Smart Home
    Z chęcią to sprawdzę w nocy. Na ten moment tylko wiem, że najniższy poziom jasności, wg. noty katalogowej, to 1/16 pulse width, a pełna wygląda na 14/16.

    Co do długowieczności modułu wyświetlacza to chyba to sprawdzę, zrobię na BK7231T/WB2S prosty DIY termometr czy cokolwiek (TC74 mam już wspierany), jeszcze z głębokim snem i aktualizacją co ileśtam czasu i zobaczę. Odłożę na półkę i będziemy czekać.
  • #4
    karwo
    Level 27  
    Tak na szybko na 4 cyfrowym takim module +modul do belek tensomettgcznych +arduino mini zrobiłem testera do szybkiego sprawdzania belek tensometrycznych. Użyty kilka razy leży w szufladzie już ze 3-4 lata. Nie wiem jak z trwałością.
    U mnie nie było problemu z kolejnością wyświetlania.
  • #5
    Chivo
    Level 25  
    Oczywiście też wykorzystuję taki wyświetlacz. Na biurku mam zbudowany termometr na TM1637+STM32F030F4P6+BMP280.
  • #6
    krzbor
    Level 25  
    Chivo wrote:
    Oczywiście też wykorzystuję taki wyświetlacz. Na biurku mam zbudowany termometr na TM1637+STM32F030F4P6+BMP280.
    Rozumiem, że świeci non-stop. Jak długo już pracuje?
  • #7
    krru
    Level 33  
    >>20468593

    Ostatnio bawiłem się modułami opartymi na MAX7219 - driver na 8 wyświetlaczy 7 segmentowych (albo jego własne wzory cyfr, albo niezależne sterowanie segmentami) lub jednej matrycy 8*8 - w sumie to na jedno wychodzi. Interfejs SPI, można połączyć "potokowo" - wyjścia jednego do wejść drugiego. Nie potrzeba wtedy linii wybierania układu, jedynie transfery są większe/dłuższe. Dostępne na allegro - linków nie podaje bo nie wolno, wystarczy poszukać po nazwie układu.
  • #8
    p.kaczmarek2
    Moderator Smart Home
    MAX7219 w postaci 8x8 uruchamiałem kiedyś na PIC18F45K50 i umieściłem na forum kod sterowania:
    https://www.elektroda.pl/rtvforum/topic3594728.html
  • #9
    Chivo
    Level 25  
    Termometr działa non stop od lipca
  • #10
    noel200
    Level 26  
    W lutownicy wstawiłem taki układ. Jeszcze nie było gotowych tanich wyświetlaczy na MAX7219. Pisałem jeszcze w bascom i musiałem sporo się nakombinować, żeby to ogarnąć.
    Wyświetlacze na MAX wydają się znacznie bardziej przyjazne. Przynajmniej z mojego punktu widzenia. Jasność jest mocno nie liniowa. Na 2 już świeci bardzo jasno, a na 1 w nocy też jest za mocno.
  • #11
    krzbor
    Level 25  
    noel200 wrote:
    Na 2 już świeci bardzo jasno, a na 1 w nocy też jest za mocno.
    A wystarczyłoby, gdyby producenci zastosowali skalę logarytmiczną. Przy 16 poziomach wystarczy, aby każdy był wielkości 2/3 poprzedniego. Wówczas najniższa jasność wynosiła by 0,002 jasności maksymalnej.
  • #12
    tmf
    Moderator of Microcontroller designs
    krzbor wrote:
    A wystarczyłoby, gdyby producenci zastosowali skalę logarytmiczną. Przy 16 poziomach wystarczy, aby każdy był wielkości 2/3 poprzedniego. Wówczas najniższa jasność wynosiła by 0,002 jasności maksymalnej.

    Zastanów się jak na poziomie sprzętowym jest realizowana tego typu funkcja, bo w oderwaniu od sprzętu można sobie snuć różne wizje, niemniej, logika projektu narzuca pewne rozwiązania i w efekcie funkcjonalność.
  • #13
    krzbor
    Level 25  
    tmf wrote:
    krzbor wrote:
    A wystarczyłoby, gdyby producenci zastosowali skalę logarytmiczną. Przy 16 poziomach wystarczy, aby każdy był wielkości 2/3 poprzedniego. Wówczas najniższa jasność wynosiła by 0,002 jasności maksymalnej.

    Zastanów się jak na poziomie sprzętowym jest realizowana tego typu funkcja, bo w oderwaniu od sprzętu można sobie snuć różne wizje, niemniej, logika projektu narzuca pewne rozwiązania i w efekcie funkcjonalność.

    Masz rację - chyba za bardzo na takie specjalizowane układy patrzę przez pryzmat możliwości MCU.
  • #14
    jarekgol
    Level 31  
    Co do żywotności, zrobiłem sobie "miernik" co2 i ostrzegacz czadu, chodzi 24/7 od wielu miesięcy. Mam wersję 2x4 wyświetlacze + 8 mikro przycisków.