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

Zegar / termometr z matrycą LED 8x8

master_pablo 16 Feb 2014 15:35 10146 11
Renex
  • Zegar / termometr z matrycą LED 8x8

    Mając do dyspozycji jedną matrycę 8x8 czerwonych diod LED o boku 60,2mm oraz mikrokontroler ATtiny861 pozostałe po innych projektach postanowiłem zbudować to, co każdy elektronik chociaż raz w życiu zbudować musi: zegar ;). Ze względu na charakter wyświetlacza miał to być zegar binarny, ale dzięki Gigantorowi dowiedziałem się o istnieniu czcionki BIT.TRIP, w której wszystkie znaki ASCII mają rozmiar 4x4 piksele, a cyfry można zmieścić w 3x4, tak więc dodałem wykorzystujący ją tryb wyświetlania. Ponadto, zegar wyświetla temperaturę mierzoną przez jeden lub dwa czujniki na magistrali 1-Wire kompatybilne z DS18S20/DS18B20.

    W trybie binarnym wyświetlane są zawsze wszystkie możliwe informacje: w górnej linii (czterech pikselach) godzina, minuta, sekunda i pomiar z termometru "wewnętrznego", a w dolnej rok (bez stulecia), miesiąc, dzień i pomiar z termometru "zewnętrznego" lub, jeśli go nie ma, numer dnia tygodnia.
    Piksele odpowiadające bitom nieużywanym (np. dwa starsze dla dziesiątek godzin) są wygaszone, a bitom wyzerowanym - mają minimalną jasnośc, co ułatwia odczyt.
    Zegar / termometr z matrycą LED 8x8

    W trybie BIT.TRIP przez pierwsze 30 sekund każdej minuty wyświetlana jest godzina i minuta, następnie przez 10 sekund miesiąc i dzień, a przez ostatnie 20 sekund temperatury/-a. Wartości w górnej i dolnej linii są względem siebie różnie przesunięte, aby można było rozróżnić, co jest w danej chwili wyświetlane. Dodatkowo temperatury jednocyfrowe mają większy znak niż dwucyfrowe.
    Wzory wszystkich używanych znaków można znaleźć w załączonym arkuszu.
    Zegar / termometr z matrycą LED 8x8 Zegar / termometr z matrycą LED 8x8 Zegar / termometr z matrycą LED 8x8 Zegar / termometr z matrycą LED 8x8

    Myślę, że o czytelności nie ma co dyskutować. Każdy zegar binarny ma ją z założenia małą. Mógłbym zastosować więcej matryc lub inny wyświetlacz, ale nie takie były założenia. Ja z czytelności w obu trybach jestem zadowolony.

    Podczas programowania wykorzystywany jest tryb binarny. Wartości, które jeszcze nie zostały zmienione przez użytkownika są na bieżąco odczytywane z RTC, a więc można szybko przestawić zegar pomiędzy czasem zimowym a letnim.

    Zegar miganiem matrycy informuje użytkownika, że jest nieustawiony.

    Prawy przycisk wchodzi/wychodzi z trybu programowania po długim naciśnięciu lub przełącza pomiędzy trybem binarnym a BIT.TRIP po krótkim.
    Lewy przycisk inkrementuje wybraną wartość podczas programowania lub przełącza jasność wyświetlacza pomiędzy sześcioma poziomami.

    Zależność prądu [A] przepływającego przez diodę LED od współczynnika wypełnienia PWM [%] jest liniowa. Zależność światłości [cd], a więc i luminancji [cd/m2] diody LED od przepływającego przez nią prądu również jest liniowa. Natomiast zależność ludzkiego postrzegania jasności od luminancji opisuje funkcja potęgowa (J = 1.0 * L ^ (1 / 2.2)). Z tego względu wykonuje się korekcję gamma, w przypadku tego zegara bardzo prostą: każdy z ośmiu poziomów jasności tablicowany jest na jedną z 16 wartości współczynnika wypełnienia PWM.

    Zegar oparty jest o mikrokontroler Atmel ATtiny861. Ze względu na małą liczbę wyprowadzeń wykorzystałem dekoder 74HC138, a magistrala 1-Wire współdzieli wyprowadzenie z prawym przyciskiem (niemożliwe jest zasilanie pasożytnicze). Odmierzaniem czasu zajmuje się PCF8563 z podtrzymaniem bateryjnym. Ponieważ chciałem zachować symetrię rozłożenia elementów pod wyświetlaczem, to jeden czujnik DS18x20 w obudowie TO-92 przylutowany jest od strony druku. Drugi można podłączyć do polaryzowanego złącza Molex KK. Zasilanie dostarczane jest przez standardowe współosiowe gniazdo 5,5/2,1mm. Ja wykorzystują starą transformatorową ładowarkę Nokii bez stabilizacji napięcia (12V bez obciążenia, 3,7V pod obciążeniem nominalnym :D).

    Matryca LED to Foryard FYM-23881DUHR-21 (kolor czerwony ultrajasny, kolumny to katody, wiersze to anody) z Seguro. Niestety okazuje się, że ma ona niestandardowy rozkład wyprowadzeń, inny niż wszystkie matryce dostępne w TME, Farnellu czy Maritexie...
    Rezystory 470R ograniczają prąd diod LED do ok. 5mA i jest to aż nadto pomimo multipleksowania.
    Na zdjęciach włączone piksele wyglądają na białe, ale w rzeczywistości oczywiście mają ładny czerwony kolor.

    Płytka drukowana (jednowarstwowa z trzema zworami drutowymi) została wykonana na frezarce LPKF Protomat S62 (niestety bez użycia narzędzia end mill, więc powierzchnie miedzi niepodłączone do żadnego potencjału pozostały na laminacie) i po lutowaniu zabezpieczona plastikiem w sprayu.
    Zegar / termometr z matrycą LED 8x8

    "Obudowa" to pleksiglas o grubości 4mm. Większy kawałek z marketu budowlanego przyciąłem wyrzynarką na najwolniejszych obrotach i równie wolno nawierciłem otwory. Następnie miejsce zgięcia naciąłem nożem do tapet i grzałem lutownicą na gorące powietrze, aż pleksiglas ugiął się pod własnym ciężarem do wymaganego kąta. Na koniec dodałem cztery samoprzylepne stopki o średnicy 11,1mm i wysokości 5,0mm zakupione na Allegro.
    Zegar / termometr z matrycą LED 8x8 Zegar / termometr z matrycą LED 8x8

    Ja praktycznie wszystkie elementy miałem, ale myślę, że zakupy powinny się zamknąć w kwocie 30-40zł.

    W załączonym projekcie płytki drukowanej są poprawki w stosunku do mojej wersji:
    - dodane zostały pady do przylutowania przewodów z programatora,
    - "uszy" nie wystają z płytki wzdłuż przekątnych, tylko z góry i z dołu, dzięki czemu jest ona węższa i łatwiejsza w domowym wykonaniu, a prawe dolne ucho i "obudowa" nie kolidują z kątowym wtykiem zasilającym.
    "Gęstość zaludnienia" jest na tyle mała, że po zmianie padów matrycy z podłużnych na okrągłe możliwe byłoby zmniejszenie szerokości płytki tak, by zrównała się z matrycą.

    Firmware napisany jest w C i zajmuje 98,5% z 8kB pamięci flash. Nie było jednak żadnych kompromisów (wręcz przeciwnie), po prostu tyle wyszło :), chociaż musiałem zastosować LTO (patrz niżej). Można go w Atmel Studio lub używając samego avr-gcc, przy czym makefile gryzie się z GNU CoreUtils z Cygwina.

    Najwyższy priorytet ma przerwanie od timera, w którym następuje multipleksowanie matrycy LED. Jego częstotliwość to 9kHz ((16 poziomów wypełnienia PWM - 1) * 8 kolumn * odświeżanie 75Hz). Zastosowane zostało potrójne buforowanie (jeden bufor jest aktualnie wyświetlany, drugi jest przygotowany i zostanie wyświetlony, gdy zacznie się kolejny cykl odświeżania, a trzeci edytujemy). Dzięki temu część wyświetlająca i zapisująca bufor nie muszą być ze sobą zsynchronizowane, co ułatwia programowanie kosztem zużycia pamięci.

    Przerwanie to może zagnieżdżać się przerwaniu od drugiego timera wywoływanym z częstotliwością 100Hz, w którym jest odczytywany stan zegara po I2C (RTC nie przytrzymuje SCL, a AVR jest jedynym urządzeniem nadrzędnym na magistrali, więc transmisja jest deterministyczna czasowo), są obsługiwane przyciski i jest aktualizowany wyświetlacz.

    W pętli głównej są wykonywane najbardziej czasochłonne operacje, czyli komunikacja z termometrami przez 1-Wire oraz aktualizacja EEPROM-u. Ponieważ 1-Wire wymaga blokowania przerwań ze względu na wymagania czasowe, komunikacja została na poziomie bitowym zsynchronizowana z multipleksowaniem matrycy LED, aby zapobiec wyraźnie dostrzegalnemu migotaniu. Program uwzględnia współdzielenie wyprowadzenia 1-Wire z przyciskiem i generalnie nie stanowi to większego problemu. Identyfikatory czujników są zapamiętywane automatycznie.

    Warte uwagi i łatwe do wykorzystania w innych projektach są w szczególności biblioteki do obsługi przycisków oraz EEPROM-u.

    Ta pierwsza (btn) zapewnia duży stopień abstrakcji od sprzętu (użytkownik sam implementuje funkcje, które odczytują stan wejść; przeniesienie kodu na jakiegoś ARM-a to tylko kwestia przygotowania odpowiednika <util/atomic.h> z avr-libc) i ma duże możliwości (debouncing, wykrywanie krótkich i długich naciśnięć, powtarzanie akcji dla przytrzymanego przycisku ze zmienną częstotliwością, np. im dłużej trzymamy przycisk, tym szybciej inkrementuje się parametr, a gdy zbliżamy się do granicy, to inkrementacja zwalnia).

    Ta druga (eecb) traktuje EEPROM jak bufor kołowy i zamiast zapisywać dane ciągle do tych samych komórek wykorzystuje równomiernie całą pamięć. Dodatkowo dane są zabezpieczone CRC, więc nie trzeba ręcznie sprawdzać ich poprawności oraz obsługiwana jest sytuacja, gdy aktualizacja danych zostanie przerwana przez zanik zasilania. W przypadku tego zegara użyteczność tej biblioteki jest dosyć dyskusyjna, ale miałem ją już gotową.

    C-iekawostki:

    LTO to optymalizacja programu w czasie linkowania. Jest to w GCC następca optymalizacji -fwhole-program, która też odbywa się na całości programu. Według mnie jej najlepszym efektem jest wstawienie w miejsce wywołania funkcji, które są wywoływane tylko raz, a przy których kompilator w normalnych warunkach nie zrobiłby tego ze względu na ich rozmiar.
    Niestety dodanie flagi -flto w tradycyjnym makefile'u powodowało przekroczenie rozmiaru sekcji .text i błąd, tak więc musiałem go tak zmodyfikować, żeby kompilowanie i konsolidacja odbywały się w jednym kroku, bez generowania pośrednich plików obiektowych.

    static_assert to słowo kluczowe z C++11, które umożliwia sprawdzanie na etapie kompilacji różnych warunków, które nie są możliwe do sprawdzenia za pomocą dyrektywy preprocesora #if. W C11 jego odpowiednikiem jest _Static_assert, a dla poprzednich standardów można stworzyć makro o tej samej funkcjonalności, którego również można używać w dowolnym miejscu programu:
    Code: c
    Log in, to see the code

    Przykład wykorzystania:
    Code: c
    Log in, to see the code

    Jeśli static_assert jest obsługiwany natywnie to zobaczymy błąd kompilacji:
    
    error: static assertion failed: "struct s musi zawsze mieć dwa bajty!"
    error: static assertion failed: "enum ma złe wartości!"
    

    W przeciwnym przypadku niespełniony warunek jest wykrywany, ale komunikat ignorowany:
    
    error: size of array 'static_assert_at_line_<n>' is negative
    error: size of array 'static_assert_at_line_<n+1>' is negative
    

    Cool? Ranking DIY
    About Author
    master_pablo
    Level 16  
    Offline 
    Has specialization in: elektronika cyfrowa, programowanie
    master_pablo wrote 276 posts with rating 30, helped 11 times. Been with us since 2005 year.
  • Renex
  • #2
    szczodros
    Level 19  
    Bardzo ciekawy projekt. Ile to zjada prądu przy takiej ilości diod?
    PS.: mina znajomych gdy w tajemniczy sposób rozszyfrowujesz dane na wyświetlaczu w trybie binarnym - bezcenna :D
  • Renex
  • #3
    r-maniac
    Level 15  
    Bardzo fajny projekt, starannie wykonany i bardzo dobrze opisany, aż miło się czyta :) Fajnie byłoby pokusić się o zasilanie bateryjne i uwolnić od kabelków, lecz problemem byłby tu czujnik temperatury zewnętrznej...
  • #4
    domints
    Level 13  
    Rozwiązaniem na czujnik jest jakiś moduł bezprzewodowy, ale musiałbyś zoptymalizować kod lub zmienić procka i założyć drugiego przy czujniku zewnętrznym.
  • #5
    master_pablo
    Level 16  
    Zmierzyłem pobór prądu i wynosi on od 40 do 180mA w zależności od ustawionej jasności i liczby zapalonych pikseli. Szczerze mówiąc ciężko mi to wytłumaczyć, biorąc pod uwagę, że w jednym momencie może być włączona tylko jedna kolumna, czyli osiem diod, z których każda ma rezystor 470R ograniczający prąd do teoretycznie ok. 5mA. Tak więc uwzględniając pobór prądu przez pozostałe elementy spodziewałbym się 50mA przy zapalonych wszystkich pikselach. Być może impulsowy pobór prądu zakłóca pomiar...

    Kolegom pragnącym budować urządzenia zasilanie bateryjne w celu uświadomienia polecam obliczenie sobie, ile działałoby z baterii np. 1000mAh urządzenie pobierające non-stop 10mA i podpowiadam, że matryce LED słabo się do nich nadają :).
  • #6
    daroslav15
    Level 16  
    A mi się nie podoba. Oba tryby wyświetlania są szalenie nieczytelne. Ja na takiej matrycy zrobiłbym wyświetlanie w trybie marquee, czyli przesuwającego się tekstu.
  • #7
    Steryd3
    Level 33  
    Projekt od strony elektronicznej mi się podoba nie mniej idea wyświetlania binarnego jest dla mnie jakąś pomyłką. Jest to oczywiście jakaś forma prezentacji informacji (w obliczu braku innych możliwości też zdarzało mi się ją roboczo stosować) ale czemu ona ma służyć?? Chyba tylko uświadamiania reszcie ludzkości, iż takie coś jak system binarny istnieje i pokazanie, że twórca lub posiadacz takiego gadżetu się na nim zna(jaki jestem mądry). Zegar czy termometr jest po to by jednym rzutem ocenić która godzina czy jaka temperatura a nie by dekodować w głowie liczby binarne. Dlaczego w samolocie pilot do dyspozycji ma wskaźniki wskazówkowe- by jednym rzutem oka mógł ocenić czy dany parametr mieści się w normie. W prostszych konstrukcjach też trzeba zwracać uwagę na ergonomię.
    Walory elektroniczne, dekoracyjne oraz edukacyjne oceniam wysoko natomiast użytkowe marnie.
  • #8
    master_pablo
    Level 16  
    daroslav15 wrote:
    A mi się nie podoba. Oba tryby wyświetlania są szalenie nieczytelne. Ja na takiej matrycy zrobiłbym wyświetlanie w trybie marquee, czyli przesuwającego się tekstu.

    Myślałem o tym, ale w przypadku trybu binarnego odczyt jest wystarczająco trudny, gdy wszystko stoi w miejscu.

    Natomiast w przypadku trybu BIT.TRIP wymusiłoby to zastosowanie większych znaków, a wtedy w jednym momencie byłoby widoczne może z półtora znaku, co wydaje mi się niezbyt dobrym pomysłem.

    Poza tym takie ciągłe przesuwanie byłoby rozpraszające, gdyby zegar znajdował się w polu widzenia użytkownika robiącego coś innego.

    PS. Zdjęcia są dosyć marne, w rzeczywistości kontrast pikseli jest dużo lepszy.
  • #9
    ololukiXP
    Level 19  
    master_pablo wrote:
    Natomiast w przypadku trybu BIT.TRIP wymusiłoby to zastosowanie większych znaków, a wtedy w jednym momencie byłoby widoczne może z półtora znaku, co wydaje mi się niezbyt dobrym pomysłem.

    W tym wypadku jednocześnie wyświetlane jest niecałe półtora znaku i myślę, że jest czytelne, można zrobić regulację szybkości przesuwania. Matryca 8x7

    master_pablo wrote:
    Poza tym takie ciągłe przesuwanie byłoby rozpraszające, gdyby zegar znajdował się w polu widzenia użytkownika robiącego coś innego.

    Z tym się zgadzam, choć zmieniające się sekundy też rozpraszają. Jednak nawet statyczny obraz wyświetlany na multipleksowanym wyświetlaczu potrafi zirytować, gdyż widać migotanie przy szybkim ruchu gałek ocznych.
  • #10
    master_pablo
    Level 16  
    ololukiXP wrote:
    W tym wypadku jednocześnie wyświetlane jest niecałe półtora znaku i myślę, że jest czytelne, można zrobić regulację szybkości przesuwania.

    Fajny zegar, faktycznie nie wygląda źle ten przesuwany tekst. Bardzo mi się podoba, że podczas ustawiania przesunięcie do kolejnej pozycji jest stopniowe, a nie natychmiastowe.
    ololukiXP wrote:
    Z tym się zgadzam, choć zmieniające się sekundy też rozpraszają. Jednak nawet statyczny obraz wyświetlany na multipleksowanym wyświetlaczu potrafi zirytować, gdyż widać migotanie przy szybkim ruchu gałek ocznych.

    Ja na co dzień korzystam z trybu BIT.TRIP, więc obraz zmienia się tylko trzy razy na minutę. A częstotliwość odświeżania wynosi 75Hz (mogłaby i więcej), więc nie ma też problemu z migotaniem.
  • #11
    Gigantor
    Level 19  
    Dzień dobry,

    bardzo się cieszę, że kogoś zainspirowalem. Projekt piękny i martwienie się czytelnością cyfr nie ma sensu (przynajmniej w tym przypadku). Mógłbyś pokusić się o zastosowanie matrycy LED 8x8 z diodami kwadratowymi. Jest trudno dostępna, ale w tym przypadku wygladałaby świetnie.

    Pozdrawiam!