Watch. Zegarek naręczny. cz. 1

Watch. Zegarek naręczny. cz. 1
Pobierz PDF Download icon
Współczesny świat pędzi szybciej, niż kiedykolwiek wcześniej. Szybki rozwój technologii, elektroniki i najnowsze obszary ich zastosowań powodują, że już nie wyobrażamy sobie życia bez wielu urządzeń, które jeszcze do niedawna uważalibyśmy za zbędne gadżety. Rekomendacje: własnoręcznie wykonany smartwatch przyciągnie spojrzenie wielu ciekawskich oczu.

Listing 1. Funkcje odpowiedzialne za obsługę programowego interfejsu SPI

Po fazie euforii dotyczącej telefonii komórkowej nadeszła era wszechobecnych smartfonów, które to bardziej przypominają przenośne komputery niż telefony. Przychodzi mi na myśl obraz poranka w komunikacji miejskiej, gdy większość osób spogląda na ekrany swoich smartfonów, by w ten sposób być ciągle online i nie wypaść "z obiegu".

Wszak nie bez powodu powstało obiegowe stwierdzenie, że "jeśli nie masz konta na portalu społecznościowym... to po prostu nie istniejesz". Jako anegdotę mogę opowiedzieć, że mój dobry znajomy informatyk, wykształcony i posiadający wiele branżowych certyfikatów, na jednym z portali związanych z rozwojem kariery zawodowej, które to dają możliwość zaprezentowania własnego CV, w zakładce "Inne osiągnięcia" umieścił wpis "Brak konta na Facebook'u". Znamienne!

Nową falą wspomnianej mody, moim zdaniem napędzaną chęcią zysku producentów elektroniki użytkowej, jest moda na tak zwane smartwatch'e, czyli ni mniej, ni więcej, tylko mniejsze wersje smartfonów, które to udają zegarki naręczne.

Listing 2. Definicja nowego typu danych odpowiedzialnego za przechowywanie parametrów bieżącej czcionki ekranowej

Nie rozumiem tego pędu i tęsknię za czasami, gdy ludzie wysyłali do siebie zwyczajne, papierowe listy, zaś wymianom poglądów towarzyszyły normalne spotkania. Mam nadzieję, że wróci to wcześniej czy później, tak jak wraca moda na urządzenia w stylu retro, czy tęsknota za tym, co miało swój styl i jakość.

W świetle tego, tym bardziej nie rozumiem, po co w naręcznym zegarku integrować funkcjonalność telefonu komórkowego i komputera w jednym. Czyż nie wystarczyłoby, żeby był to po prostu zwykły, acz efektowny zegarek elektroniczny? Tak, jak za dawnych czasów, tylko we współczesnym wykonaniu?

Listing 3. Funkcja odpowiedzialna za ustawienie bieżącej czcionki ekranowej

Idąc tym właśnie tropem postanowiłem zbudować takie urządzenie, które to nazwałem po prostu "Watch". Nie ukrywam, iż przyczynkiem do powstania tego projektu było natknięcie się na doskonałej jakości, niewielki wyświetlacz OLED o przekątnej 0,96" i rozdzielczości 128×64px, który to można kupić za tak niewygórowaną kwotę, że grzechem byłoby niewykorzystanie go w swoich konstrukcjach.

Jakby tego było mało, na portalach aukcyjnych dostępne są "wygodne" moduły wykorzystujące tenże element, wyposażone w złącze goldpin (o różnej liczbie wyprowadzeń, w zależności od zastosowanego interfejsu komunikacyjnego SPI lub I²C), co znacznie ułatwia implementację we własnych urządzeniach.

Listing 4. Funkcja odpowiedzialna za inicjalizację sterownika SSD1306

Sam wyświetlacz jest oferowany w różnych kolorach i wersjach, gdzie dla przykładu, pierwsze 16 linii (licząc od góry) jest w kolorze żółtym, a kolejne 48 w kolorze seledynowym (cyjan), co czyni go jeszcze bardziej atrakcyjnym wizualnie i właśnie tego typu element wykorzystano w opisywanym projekcie.

Sterownikiem ekranu, zastosowanym w każdej wersji tegoż wyświetlacza, jest układ firmy Solomon Systech Limited typu SSD1306. Sterownik ten jest łatwy w obsłudze programowej, choć warto zaznaczyć, że w wersji z interfejsem SPI (nasz przypadek) umożliwia wyłącznie zapis do sterownika ekranu, bez możliwości odczytu (wynika to z wyprowadzeń dostępnych na złączu goldpin).

Co ważne, wybierając konkretny moduł dostępny w handlu należy zakupić wersję wyposażoną w następujące sygnały sterujące: CLK (sygnał zegarowy magistrali SPI), MOSI (wejście danych magistrali SPI), RST (wejście zerowania sterownika SSD1306) oraz DC (wejście, decydujące o charakterze wysyłanych danych: 1 → dane pamięci obrazu, 0 → rozkaz sterujący).

Listing 5. Funkcje narzędziowe sterownika SSD1306

Równie ważne jest rozmieszczenie sygnałów zasilających, jako że moduły dostępne w handlu mają częstokroć zamienione miejscami sygnały zasilania (VCC) i masy (GND). Reasumując, konfiguracja sterownika SSD1306 sprowadza się do ustawienia niezbędnych rejestrów sterujących, które to odpowiedzialne są za sprzętowe parametry układu wynikające z organizacji pamięci obrazu jak i właściwości obsługiwanego panelu OLED.

Przechodząc do konkretów, zamieszczę w pierwszej kolejności funkcje odpowiedzialne za programową obsługę interfejsu SPI, w świetle wysyłania danych do pamięci obrazu i rozkazów sterujących, których to ciała pokazano na listingu 1.

Aby umożliwić obsługę zdefiniowanych przez użytkownika czcionek ekranowych wprowadzono nowy typ danych, którego definicję pokazano na listingu 2. Bazując na zdefiniowanej strukturze, wprowadzono funkcję, która korzystając z globalnej zmiennej static FontDescription CurrentFont pozwala na ustawienie bieżącej czcionki ekranowej, której ciało pokazano na listingu 3.

Listing 6. Funkcje odpowiedzialne za rysowanie prostych elementów graficznych (obrazków i znaków)

Na listingu 4 pokazano z kolei funkcję, która pozwala na inicjalizację sterownika OLED naszego panelu. Dalej, na listingu 5 pokazano funkcje narzędziowe odpowiedzialne za: ustawienie aktywnego obszaru ekranu, w ramach którego przeprowadzany jest zapis do pamięci ekranu sterownika SSD1306, funkcję pozwalającą na ustawienie kontrastu wyświetlacza OLED oraz funkcję odpowiedzialną za wymazanie zawartości pamięci ekranu sterownika w zakresie współrzędnych zdefiniowanych argumentami wywołania tejże funkcji.

Czas na funkcje odpowiedzialne za rysowanie prostych elementów graficznych, to jest funkcję odpowiedzialną za wyświetlanie obrazków na ekranie wyświetlacza oraz funkcję pozwalającą na rysowanie znaków, z użyciem bieżącej czcionki ekranowej.

Listing 7. Funkcja pozwalająca na animację znaków

Wspomniane funkcje pokazano na listingu 6. Na koniec dość nietypowa funkcja, której zadaniem jest wyświetlenie znaku, którego wzorzec przesunięty jest o zdefiniowaną parametrem wywołania funkcji liczbę pixeli w pionie (uint8_tpixelShift).

Pozwala ona na "przewijanie" znaków na ekranie, dzięki czemu w dość łatwy sposób możemy uzyskać efekt animacji przypominający swoim działaniem pracę starych liczników mechanicznych, gdzie zmianie znaku towarzyszyło przesunięcie się jednego znaku w górę i "wskoczenie" na jego miejsce znaku kolejnego (w przypadku liczników były to oczywiście cyfry).

Listing 8. Listing pliku nagłówkowego związanego z obsługą wyświetlacza OLED opartego o sterownik ekranu SSD1306

Efekt taki wykorzystano w implementacji funkcji stopera naszego urządzenia i muszę przyznać, że wygląda to nadspodziewanie efektowanie. Ciało funkcji zamieszczono na listingu 7. Na koniec listing pliku nagłówkowego związanego z obsługą naszego wyświetlacza OLED, bez którego trudno byłoby zrozumieć działanie wcześniej przedstawionych funkcji. Zawartość wspomnianego pliku nagłówkowego pokazano na listingu 8.

To tyle, jeśli chodzi o obsługę naszego, niezmiernie ciekawego wyświetlacza OLED. Przejdźmy zatem do tytułowego urządzenia, w którego konstrukcji musiałem zmierzyć się z kilkoma istotnymi kwestiami wynikającymi z przyjętych założeń konstrukcyjnych, jeśli chodzi o jego docelową funkcjonalność. Podstawowe założenia, jakie sobie postawiłem były następujące:

  • Mały pobór mocy zapewniający długą pracę bez potrzeby ładowania wbudowanego akumulatora.
  • Autonomiczne zasilanie akumulatorowe i możliwość ładowania z portu USB.
  • Niewielkie wymiary.
  • Nieskomplikowana budowa i mały koszt implementacji.
  • Integracja następującej funkcjonalności: zegar, kalendarz, stoper, budzik (z planem tygodniowym), barometr, termometr, prognoza pogody.
  • Łatwość obsługi przy udziale minimalnej liczby elementów sterujących.

Rysunek 1. Schemat ideowy urządzenia Watch.

Tak oto powstał projekt urządzenia "Watch", którego schemat ideowy pokazano na rysunku 1. Jego "sercem" jest niewielki mikrokontroler Atmega168 taktowany wewnętrznym, wysokostabilnym generatorem RC o częstotliwości 1 MHz (dla zmniejszenia poboru mocy) odpowiedzialny za realizację pełnej, założonej funkcjonalności urządzenia.

Mikrokontroler steruje pracą wyświetlacza OLED, zaś za pomocą wbudowanego interfejsu I²C (nazywanego TWI w wykonaniu firmy Atmel) realizuje współpracę ze scalonym barometrem firmy Bosch Sensortec pod postacią układu scalonego BMP180.

Wybór tego, konkretnego typu scalonego barometru z szerokiej palety układów dostępnych na rynku podyktowany był faktem, iż w jego obudowie zintegrowano dokładny termometr scalony.

Wykaz elementów

Rezystory: (SMD 0603)
R1, R8: 10 kΩ
R2: 100 kΩ
R3: 12 kΩ
R4: 5,1 kΩ
R5: 47 kΩ
R6, R7: 4,7 kΩ

Kondensatory: (SMD 0603)
C1, C7...C13: 100 nF (X7R)
C2...C4, C6: 10 mF/10 V (SMD "A")
C5: 10 nF (X7R)

Półprzewodniki:
U1: MCP73832 (SOT-23-5)
U2: APE8865Y5-27-HF-3 (SOT-23-5)
U3: ATmega168PA (TQFP32)
U4: BMP180 (LGA7)
T1: AP2301AGN (SOT23)
D1: MBR0520L (SOD123)

Inne:
OLED: wyświetlacz graficzny OLED 0,96" ze sterownikiem SSD1306
L1: dławik 10 mH (SMD 0805)
Q1: rezonator 40 kHz
MENU, EXIT: przyciski SMD typu DTSM-31N
USB: gniazdo micro USB-B typu ATTEND 207A-BBA0-R
PIEZZO: sygnalizator piezoelektryczny LD-BZPN-2030
ACCU: akumulator Li-Po 3,7 V/250 mA CELLEVIA BATTERIES L502030

Listing 9. Listing pliku nagłówkowego związanego z realizacją zegara czasu rzeczywistego

Dociekliwy Czytelnik zapewne dostrzeże fakt braku jakiegokolwiek układu realizującego funkcjonalność zegara czasu rzeczywistego (RTC), który to przecież jest podstawową funkcjonalnością, jaką realizuje nasz projekt. Rzeczywiście, na etapie projektowania systemu zastanawiałem się nad zastosowanie jednego ze znanych i tanich układów zegarów RTC pracujących na magistrali I²C, lecz ostatecznie zrezygnowałem z tego pomysłu z kilku istotnych powodów.

Po pierwsze, zastosowanie zewnętrznego zegara RTC zwiększyłoby koszt i pobór mocy całego układu, co nie wpisywałoby się w założenia projektu. Po drugie i najważniejsze, jakikolwiek z dostępnych na rynku układów realizujących funkcjonalność zegara RTC nie zapewniałby możliwości zrealizowania funkcjonalności stopera, która to była jednym z założeń projektu.

Jak rozwiązałem tenże problem? Bardzo prosto! Skorzystałem z możliwości wbudowanego w strukturę mikrokontrolera Atmega168 układu czasowo-licznikowego Timer2, która to pozwala na jego asynchroniczną pracę i taktowanie zewnętrznym, wysokostabilnym, zegarkowym rezonatorem kwarcowym (w naszym przypadku o częstotliwości 40 kHz) dołączonym do wyprowadzeń TOSC1/TOSC2.

Dzięki temu, moduł Timer2 taktowany jest za pomocą wspomnianego rezonatora kwarcowego zupełnie niezależnie od sygnału zegarowego (1 MHz) taktującego procesor, co zapewnia realizację bardzo dokładnego zegara czasu rzeczywistego.

Co oczywiste, w takim wykonaniu niezbędne było napisanie odpowiednich funkcji, które realizują całą, założona funkcjonalność zegara. Nie było to zbyt trudne, więc tym bardziej dziwnym wydaje się fakt, iż nie spotkałem się dotychczas z tego typu rozwiązaniem wertując dziesiątki stron internetowych, więc zacznę od zaprezentowania pliku nagłówkowego związanego z modułem RTC, którego zawartość pokazano na listingu 9.

Teraz, pora na przedstawienie kilku kluczowych funkcji. Pierwsza z nich odpowiedzialna jest za inicjalizację Timera2 realizującego funkcjonalność zegara RTC oraz Timera0, który wykorzystany jest w naszym urządzeniu do generowania periodycznego przebiegu o częstotliwości 3 kHz (na wyprowadzeniu OC0B mikrokontrolera) w celu obsługi prostego sygnalizatora piezoelektrycznego (tzw. blaszkowego) używanego do emitowania dźwięku budzika.

Ciało wspomnianej funkcji pokazano na listingu 10. Kolejna z funkcji, niezbędna przy realizacji zaawansowanego zegara RTC, to funkcja, która na podstawie argumentów wywołania (rok i miesiąc) ustala liczbę dni miesiąca uwzględniając fakt, czy dany rok jest rokiem przestępnym czy tez nie. Funkcję pokazano na listingu 11.

Funkcja getMonthDaysLimit() korzysta ze zmiennej monthsDays[] umieszczonej w pamięci programu, której to definicja jest następująca: const uint8_t months-Days[12] PROGMEM = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

Robert Wołgajew, EP

Artykuł ukazał się w
Elektronika Praktyczna
grudzień 2015
DO POBRANIA
Pobierz PDF Download icon
Materiały dodatkowe

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik kwiecień 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio marzec - kwiecień 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje marzec 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna kwiecień 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich kwiecień 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów