
Witam,
w końcu i ja postanowiłem zaprezentować swoje dokonania na elektrodzie. To mój pierwszy post w DIY, proszę o wyrozumiałość.

(for english click here)
1. Pomysł
Dla mnie, człowieka urodzonego pod koniec lat 70, zawsze wzorem zegara był zegar Teleexpressu. Te 60 diod sekundnika były dla mnie magnesem. Jednak sterowanie 60-ma diodami za pomocą multiplekserów, ekspanderów portów nigdy do mnie nie przemawiało. A już tym bardziej ówczesne diody dwukolorowe, bo liczba kanałów rosła do 120. Wreszcie w grudniu 2013 znajomy pokazał mi swój pasek LEDowy WS2812B. Gdy go zobaczyłem od razu wiedziałem, że to jest to, czego zawsze potrzebowałem – zamiast wielu układów cyfrowych wystarczy jeden pin procesora. No i pasek jest w wersji 60 diod – to aż się prosiło o zegar. Jeszcze w ten sam dzień odwiedziłem powszechny portal aukcyjny i zamówiłem pasek 60 diod prosto z dalekiego wschodu. Dziś mija już ponad 13 miesięcy i uważam, że można co nieco pokazać.
2. Założenia
Głównym założeniem jest wygoda obsługi. A najlepiej – kompletny brak obsługi, tj. żadnych przycisków – zegar ma po prostu bezobsługowo zawsze pokazywać aktualny czas.
a. Ustawianie zegara
Nie wiem, jak jest u was, ale mnie męczy ręczne przestawianie zegar(k)ów w domu co najmniej dwa razy do roku (zmiany czasu na letni lub zimowy). Jako, że od dawna jestem fanem wzorca czasu DCF-77, postanowiłem postawić na tą technologię. Z alternatywnych rozwiązań można by było rozważyć GPS, czy też synchronizację przez internet. Jednak ze względu na prostotę, zasięg w budynkach, no i zamiłowanie do transmisji o prędkości 1 bit na sekundę, postawiłem na DCF-77.
b. Sterowanie jasnością diod
Biorąc pod uwagę, że jasność w pokoju zmienia się w znacznym stopniu (noc/słoneczny dzień) zdecydowałem, że zegar trzeba wyposażyć w czujnik oświetlenia, by na jego podstawie dobrać jasność LEDów. Zegar nie spełniłby swego zadania, gdyby w dzień był nieczytelny (zbyt ciemny), bądź oślepiał w noc (zbyt jasny).
3. Realizacja – sprzęt (hardware)
Do wysterowania będzie potrzebny mikrokontroler. Jako, że jestem fanem małych płytek (małe jest piękne), no i sterowanie WS2812B jest wygodne od strony hardware‘u, zdecydowałem się na mały procesor. Myślałem o AVR i PIC i ostatecznie, jako, że nigdy wcześniej nie bawiłem się AVRami postawiłem na Attiny85. Sześć nóżek niepełnego Portu rozdysponowałem następująco:
a. Pierwsza nóżka (PB5), RESET pozostała nie użyta, gdyż posiadam tylko programator ISP - usbasp z alternatywnym firmwarem USB AVR LAB (link). Swoją drogą polecam ten firmware każdemu, bo dzięki niemu nasz programator usbasp może udawać następujące narzędzia: programator AVRISPmkII, programator STK500v2, programator OpenOCD, programator JTAGICEmkII, prosty oscyloskop, interfejs boundary scan, logger I2C, konwerter USB-UART, konwerter USB-RS232/485. I jakby było mało, no to na deser jeszcze standardowy programator usbasp. Autor zrobił ciekawy bootloader, dzięki czemu wybór programatora z listy powyżej odbywa się bez przeprogramowywania firmware’u – po prostu jest programik na PC, w którym wybieramy, jakie urządzenie ma naśladować nasz hardware’owy usbasp, i wszczepienie firmware’u następuje przez USB. Ja zdecydowałem się na opcję STK500v2, która świetnie współpracuje z moim AVR Studio 4.19 – po prostu Studio widzi usbasp jako STK500, więc wszystkie funkcje (no może poza updatem softu STK500 J z pozycji AVR Studio) są dostępne. Tak, wiem, AVR Studio 4.19, to stary soft, ale mi wystarcza i nie mam ochoty instalować giganta Atmel Studio 6.
b. Dwie nóżki (PB3, PB4) poświęciłem na kwarc 8 MHz. Może ktoś zapyta – po co kwarc, masz przecież wewnętrzny oscylator, a do tego masz przecież synchronizację DCF-77. Tak, ale jestem fanatykiem dokładności – zegar ma pokazywać zawsze dokładny czas, odchyłka ma być zawsze poniżej sekundy. Dlatego wybrałem kwarc z dokładnością dziesiątek ppm zamiast wewnętrznego oscylatora o dokładności w granicach procentów. Żeby być w pełni zadowolonym, pobawiłem się w dokładne obliczenie wartości kondensatorów obciążających kwarc – chodzi o to, by zminimalizować niedokładność. Tutaj uwaga – te kondensatory trzeba obliczyć, bo one zależą od konkretnego kwarcu. Błędem jest branie wartości prosto ze schematu, jeżeli mamy inny rodzaj kwarcu niż na schemacie. Jeśli temat obliczeń jest interesujący, mogę go rozwinąć.
c. Czwarta nóżka (PB1) steruje linijką diod. Od strony hardware‘u wstawiłem tylko podwójną diodę D1, by sygnał danych dla linijki nigdy „nie wyszedł” poniżej masy i powyżej napięcia zasilania.
d. Do piątej nóżki (PB0) dociera sygnał DCF-77 z moduliku, który wyciąłem (dosłownie wyciąłem brzeszczotem fragment płytki drukowanej) z jednego z zegarków. Modulik ma rozmiary 17 na 14 mm, podłączona jest do niego oryginalna antena ferrytowa. Moduł ten dostarcza mi impulsy 200/100/0 ms, które są dekodowane przez mikrokontroler. Aby poprawić jakość odbioru, zestroiłem obwód rezonansowy anteny dokładnie na 77,50 kHz. Do tego celu zbudowałem na innym pręcie ferrytowym prowizoryczną antenkę nadawczą, którą podłączyłem do generatora 77,5 kHz. Następnie do anteny odbiorczej modułu DCF zbudowałem wzmacniaczyk na pojedynczym tranzystorze J-FET i jego wyjście skierowałem na oscyloskop. Równolegle do anteny odbiorczej przykładałem różne kondensatory 1...150 pF obserwując, przy którym maksimum rezonansu wystąpi przy 77,5 kHz. Ostatecznie stanęło na kondensatorze kilkadziesiąt pF. No cóż, tak to już dziś jest, że się oszczędza na wszystkim – oryginalny moduł powinien mieć trymer do tego celu.
Jako, że moduł pochodzi z zegarka zasilanego jedną baterią AA, na schemacie pojawił się regulator 1,5 V dla modułu DCF. Aby dopasować amplitudę sygnału wyjściowego z 1,5 V do 5 V wykorzystałem T1.
e. Do ostatniej, szóstej nóżki mikrokontrolera (PB2) podłączyłem fotodiodę PD1, która generuje spadek napięcia na R5. Jasność odczytuję za pomocą wewnętrznego przetwornika AD.
W trakcie uruchamiania okazało się, że linijka pracująca z sygnałami 800 kHz potrafi zagłuszyć odbiornik DCF. Z tego powodu przewidziałem opcję odłączenia linijki LED na czas synchronizacji. Niestety wszystkie nóżki procesora już wykorzystane, tak więc trzeba było jakąś funkcję zdublować. Wybór padł na sygnał z fotodiody. W momencie, gdy chcę wygasić linijkę LED, pin PB2 staje się wyjściem, wysyłam na niego stan wysoki, który to rozłącza tranzystor T2 i pozbawia linijkę napięcia zasilania. Sygnałowi z fotodiody to nie przeszkadza, no bo linijka i tak jest w tym czasie wyłączona. Z drugiej strony sygnał z fotodiody też nie jest w stanie wyłączyć T2 w trakcie normalnej pracy, gdyż na R5 odkłada się napięcie 0...3 V, a więc Vgs tranzystora T2 mieści się wówczas w przedziale 5...2 V. To za mało, by go wyłączyć (Vgsth max = 0,95 V).
W roli złącza do programowania wykorzystałem małe 5-pinowe gniazdo.
Ostatecznie hardware został zrealizowany na dwustronnej płytce drukowanej o wymiarach 40 na 20 mm, na której zamontowany jest również moduł odbiorczy DCF. To moja pierwsza próba termotransferu w domu. Z wyników jestem zadowolony – ścieżki pod elementami 0603 są przyzwoitej jakości. Płytka jest co prawda dwustronna, ale trawiłem tylko jedną stronę, a druga strona została niewytrwiona i pełni funkcję ekranu przeciwzakłóceniowego. Jest ona połączona z masą za pomocą przelotek, które wstawiałem, gdzie tylko się dało. Wszystkie elementy poza modułem DCF oraz kwarcem zostały zamontowane na stronie TOP. Płytka oraz antena zostały przyklejone z pomocą kleju na gorąco do tylnej, niewidocznej strony zegara.
Z uwagi na linijkę LED, całość jest zasilana napięciem 5 V. U mnie jest to mały zasilaczyk z gniazdem USB A. Doprowadzenie zasilania wykonywałem za pomocą cienkiego drutu nawojowego 0,1, aby był on możliwie niewidoczny dla oka mojej żony (w przeciwnym wypadku żona zezwoliłaby mi na powieszenie zegara co najwyżej w piwnicy bądź garażu

4. Realizacja – oprogramowanie
Program napisałem AVR Studio 4.19 w języku C. Kod wynikowy zajmuje około 5 kB, zużyłem około 200 bajtów RAMu. Program jest tak skonstruowany, że co 20 milisekund następuje przerwanie od timera, w którym to: (i) sprawdzam stan na linii wejściowej od modułu DCF, (ii) pobieram próbki z fotodiody i przeliczam ja na pożądaną jasność, (iii) obliczam aktualny czas, (iv) wyświetlam aktualny czas na linijce. Tak więc można powiedzieć, że odświeżanie wyświetlacza zegara wynosi 50 Hz. Wszystko to zajmuje około 4 milisekund, po czym procesor idzie „spać” w tryb IDLE czekając na kolejne przerwanie. Nad całością czuwa watchdog o okresie przepełnienia 32 ms.
Sporo zabawy dało mi zdekodowanie sygnału DCF-77. Jako że mym mottem było stwierdzenie „lepiej nie wyświetlać żadnego czasu, aniżeli niepoprawny” zadałem sobie trochę trudu, by napisać kod sprawdzający spójność odebranych danych na wielu poziomach. Przykładowo – mimo, że wyświetlam tylko godziny, minuty i sekundy, odbierane są również dni tygodnia, miesiąc oraz rok, które są sprawdzane pod względem spójności (np. nr dnia musi być pomiędzy 1...31). Sprawdzam oczywiście dostępne bity parzystości, początku minuty, początku danych o czasie. Dodatkowo przed wyświetleniem czasu zbieram dane z dwóch minut, sprawdzam spójność i dopiero wtedy wyświetlam. Do sprawdzenia poprawności odebranych danych korzystałem ze (STRONY), którą polecam, bo prezentuje ona na żywo odebrane sygnały DCF, a także posiada pokaźne archiwum sygnału DCF.
Tak jak pisałem, linijka LED potrafi zakłócić standardową synchronizację, która ma się odbywać co godzinę. Jeżeli nastąpiło bezpośrednio po sobie 12 nieudanych synchronizacji, wówczas 10 sekund przed godziną 3 w nocy następuje odcięcie zasilania linijce LED, zaprzestanie wysterowania linijki, dzięki czemu sygnał DCF jest odbierany poprawnie. A dlaczego robię to o 3 w nocy? Bo niezależnie od dnia w roku (zwykły dzień bądź przestawienie na czas letni, bądź przestawienie na czas zimowy), o godzinie 3 na naszej długości geograficznej mamy już aktualny czas. Poza tym o 3 w nocy raczej rzadko korzystam z zegara, więc nie szkodzi, że wyświetlacz zostanie wyłączony na 2-3 minuty.
Do linijki wykorzystałem gotowy sterownik „light weight WS2812 lib”, który wzbogaciłem o korektę gamma. Ostatecznie, w celu dopasowania jasności spędziłem popołudnie i wieczór (różne oświetlenie), aby skorelować odczytane wartości oświetlenia z jasnością, jaką sobie życzę. Ostatecznie naniosłem zebrane dane do arkusza kalkulacyjnego, zrobiłem aproksymację funkcją eksponencjalną i wygenerowałem 256-elementową tablicę, którą to ostatecznie zaimplementowałem w kodzie.
5. Realizacja – obudowa
Obudowa została wykonana ze stali o grubości 1 mm i składa się z dwóch części. Pierwszą jest pasek o średnicy około 32 cm (1m/∏) i szerokości 1,5 cm, do którego przykleiłem metrową linijkę LED. Druga część to tarcza wycięta na CNC, która w praktyce służy tylko do przykrycia płytki i anteny. Obie części są ze sobą zespawane. Na koniec całość pomalowana lakierem w sprayu na kolor srebrny.
6. Odczyt czasu.
Przyporządkowanie kolorów jest następujące: kolor czerwony – wskazówka godzinowa, zielony – minutowa, niebieski – sekundnik. Aby ułatwić orientację „w terenie” wstawiłem znaczniki; białe na godzinach 12, 3, 6, 9 oraz wskaźniki żółte na pozostałych godzinach. Wskaźnik na godzinie 6 może dodatkowo przyjąć kolor różowy – jest to informacja, że w danej godzinie nastąpiła poprawna synchronizacja czasu. Na deser małe animacje cieszące oko – stopniowe wygaszanie wskazówek oraz obieg wokoło tarczy przy zmianie jakiejkolwiek wskazówki – najlepiej widać to na filmiku.
Po bezpośrednim podłączeniu zasilania wyświetlana jest również animacja „spadającej kulki” (miałem ochotę na zabawę z cosinusem), po czym wyświetlacz jest wygaszany i następuje odbiór sygnału wzorca czasu.
Zapraszam do komentowania.









Cool? Ranking DIY