Jako ostatnią omówimy funkcję obsługi przerwania od porównania zawartości licznika Timer2 z zawartością rejestru OCR2A tegoż modułu, która to wywoływana co 10ms (czyli 100 razy na sekundę) realizuje całą, założoną funkcjonalność programowego zegara RTC. Funkcję pokazano na listingu 12. Wspomniana powyżej funkcja obsługi przerwania TIMER2_COMPA_vect korzysta ze zmiennych globalnych modułu, których definicje przedstawiają się następująco:timerType Timer; clockTypeClock; alarmType Alarm;
To tyle, jeśli chodzi o realizację zegara czasu rzeczywistego z wykorzystaniem asynchronicznego trybu pracy układu czasowo- licznikowego Timer2. Prawda, że proste? Pora na przedstawienie ostatniego elementu naszego urządzenia, którym jest scalony barometr Bosch BMP180. Jego parametry użytkowe idealnie wpisują się w założenia projektu, a jedynym problemem, który możemy napotkać stosując wspomniany element, jest jego dość niewygodna w montażu ręcznym obudowa LGA7.
Jak to zwykle bywa, obsługa elementów tego typu polega na zapisie/odczycie wielu, specjalnych rejestrów konfiguracyjnych lub też rejestrów danych, przy których udziale, po pierwsze, możemy zainicjować proces pomiarowy, a po drugie, dokonać odczytu wartości "surowego" ciśnienia atmosferycznego i temperatury otoczenia. Dlaczego użyłem słowa "surowego"?
Otóż, każdy element BMP180 przechodzi na etapie produkcji proces kalibracji, który zapewnia osiągnięcie założonej dokładności pomiarów niezależnie od właściwości elementu piezo-rezystancyjnego, który stanowi w nim przetwornik ciśnienia na napięcie.
Proces ten kończy się ustaleniem szeregu (dokładnie 11) specjalnych współczynników korekcyjnych (zapisanych w pamięci EEPROM elementu), dzięki którym możliwe staje się obliczenie skompensowanej wartości ciśnienia atmosferycznego i temperatury. Jest to dość typowe rozwiązanie stosowane przez wielu producentów w przypadku elementów tego rodzaju, które przechodzą proces kalibracji na ostatnim etapie produkcji.
Biorąc to pod uwagę, pierwszą czynnością, jaką należy wykonać w przypadku obsługi barometru BMP180 jest odczyt jedenastu, 16-bitowych rejestrów, które przechowują wartości współczynników korekcyjnych. Następnie wysyłamy do układu BMP180 rozkaz inicjujący pomiar ciśnienia lub temperatury by po pewnym czasie (zależnym od wartości, którą chcemy odczytać, jak i preferowanej dokładności pomiaru) odczytać "surową" (czyli nieskompensowaną) wartość interesującego nas parametru.
Dalej, na podstawie dość skomplikowanych wzorów dostarczonych przez producenta układu, obliczamy wartość skompensowanego ciśnienia atmosferycznego lub temperatury otoczenia. Firma Bosch Sensortec dostarcza gotowy driver do obsługi swojego czujnika, co znacznie upraszcza proces implementacji własnego oprogramowania.
Pora na szczegóły implementacyjne. Zacznę od pliku nagłówkowego związanego z obsługą barometru, którego zawartość pokazano na listingu 13. Uważny Czytelnik zapewne zwróci uwagę na dość ciekawą konstrukcję struktury danych przechowującej współczynniki korekcyjne.
Jest to połączenie unii z tak zwaną strukturą anonimową, dzięki czemu, co zobaczymy za chwilę, w dość prosty sposób odczytamy z pamięci układu BMP180 wszystkie współczynniki korekcyjne (korzystając z pola index wspomnianej unii). Zatem przejdźmy do wspomnianej funkcji, którą pokazano na listingu 14.
Kolejne dwie funkcje, które przedstawiono na listingu 15, pozwalają na odczyt "surowych" wartości ciśnienia atmosferycznego i temperatury otoczenia (funkcje te inicjują stosowny pomiar, a następnie po niezbędnym czasie konwersji, odczytują żądane wielkości). I na sam koniec, na listingu 16, funkcja, dzięki której obliczymy rzeczywiste, skompensowane wartości interesujących nas wielkości fizycznych.
W tym miejscu warto wspomnieć jeszcze o jednej funkcjonalności naszego urządzenia, którą jest możliwość prognozowania pogody. Aby jednak zrozumieć zasadę działania zastosowanego mechanizmu nie sposób choćby po krótce nie omówić podstawowych zagadnień związanych z pojęciem ciśnienia atmosferycznego.
Z definicji, ciśnienie atmosferyczne jest stosunkiem wartości siły, z jaką słup powietrza atmosferycznego naciska na powierzchnię Ziemi, do powierzchni, na jaką ten słup naciska. Wynika z tego, że dla przykładu ciśnienie atmosferyczne w górach jest niższe a na nizinach wyższe, ponieważ słup powietrza ma w tych rejonach różne wysokości.
Zależność ta ma w przybliżeniu charakter wykładniczy, co pokazano na rysunku 2. Wartość ciśnienia atmosferycznego dla standardowych warunków pogodowych dla wysokości h (n.p.m.) możemy, zatem wyznaczyć z uproszczonej zależności opisanej wzorem:
gdzie
ph - ciśnienie na wysokości h n.p.m. dla standardowych warunków pogodowych
p0 - ciśnienie ma poziomie morza równe 1013,25 hPa
h - wysokość n.p.m.
Właśnie na podstawie średniej wartości ciśnienia atmosferycznego na Ziemi na poziomie morza wprowadzono (dla pogodowych warunków standardowych), nieużywaną już, jednostkę atmosfery równą 1013,25 hPa. Jak jednak wiadomo, ciśnienie atmosferyczne ulega ciągłym zmianom, które to zależne są od zmiany warunków pogodowych w związku z czym na podstawie zmian ciśnienia na założonej wysokości n.p.m. możemy z pewnym prawdopodobieństwem określić tendencję zmian pogody.
Dla przykładu, w umiarkowanych szerokościach geograficznych powolne obniżanie się ciśnienia oznacza zbliżanie się niżu, czyli pogorszenia pogody (wystąpienie chmur, opadów, w lecie - ochłodzenia, w zimie - ocieplenia) zaś wzrost ciśnienia łączy się z poprawą pogody (ustąpieniem mgły/zachmurzenia, osłabieniem wiatru itp.).
Ciśnienie wyższe o kilka hPa od ciśnienia ph dla danego rejonu zwiastuje utrwalenie się ładnej pogody, jednak z drugiej strony, szybki wzrost ciśnienia może także zwiastować burzę. Co ciekawe, na podstawie gradientu zmian ciśnienia można dość dokładnie określić spodziewaną siłę wiatru.
Pomimo tych, wydawałoby się prostych zależności, przewidywanie zmian pogody jest procesem bardzo skomplikowanym (zwłaszcza przygotowywanie prognoz długookresowych) i obarczonym pewnym błędem, o czym niejednokrotnie możemy się przekonać słuchając prognoz pogody nadawanych przez stacje radiowy czy telewizyjne.
Jednak dla prostych aplikacji możemy posiłkować się algorytmami, z jakich korzysta większość elektronicznych stacji pogodowych, a które oparte są li tylko na śledzeniu zmian ciśnienia atmosferycznego. Z uwagi na charakter zachodzących zmian prognozowanie pogody jest znacznie utrudnione dla obszarów położonych wysoko n.p.m.
Na koniec, warto podkreślić istotną różnicę pomiędzy wartością bezwzględnego ciśnienia atmosferycznego dla danej miejscowości (ciśnienia tam panującego) a wartością ciśnienia podawanego w prognozach pogody. To ostatnie jest ciśnieniem, jakie wystąpiłoby danego dnia w danej miejscowości, gdyby znajdowała się ona na poziomie morza, czyli de facto jest to bezwzględne ciśnienie atmosferyczne dla tego rejonu przeliczone dla poziomu morza. Tego typu konwersja ułatwia zorientowanie się, co do warunków pogodowych dla różnych wysokości n.p.m.
Pora na przedstawienie prostego algorytmu prognozowania pogody. Generalnie, w nieskomplikowanych konstrukcjach stacji pogodowych, które do prognozowania pogody wykorzystują wyłącznie wartość mierzonego ciśnienia atmosferycznego, korzysta się z dwóch rodzajów algorytmów.
Pierwszy z nich śledzi zmiany ciśnienia atmosferycznego i po upływie pewnego czasu (zwykle 6 do 12 godzin) na podstawie gradientu zmian jest w stanie określić oczekiwany stan pogody. Drugi z algorytmów, z którego korzysta nasze urządzenie, oblicza wzorcowe ciśnienie dla danej wysokości n.p.m. (na której to się znajdujemy) dla dobrych warunków pogodowych (wspomniany wcześniej wzór na ph) i na podstawie różnicy ciśnienia mierzonego i wzorcowego określa prognozę pogody niwelując potrzebę oczekiwania na zmiany gradientu ciśnienia.
Oczywiście, prognozy takie mogą być obarczone dużym błędem, lecz wykonanie bardziej wiarygodnej prognozy pogody wymagałoby dysponowania większa liczbą wielkości wejściowych. Dla naszego urządzenia przyjęto następujące wartości kryterialne:
Jak łatwo się domyślić, urządzenie nasze udostępnia możliwość określenia wysokości nad poziomem morza, na jakiej to się znajdujemy by zapewnić realizację funkcjonalności prognozowania pogody. W tym celu przewidziano odpowiednią funkcjonalność systemu Menu.
Znając już wszystkie, programowe szczegóły implementacyjne, powróćmy jeszcze na chwilę do schematu naszego urządzenia, gdyż kilka słów uwagi należy się blokowi zasilającemu, który to zbudowano z wykorzystaniem specjalizowanego układu ładowania akumulatorów litowo-jonowych i litowo-polimerowych MCP73832 produkcji firmy Microchip.
Układ ten integruje w sobie kompletny system ładowani. Idealnie nadaje się on do zastosowania w prostych aplikacjach ładowarek ogniw litowo-jonowych i litowo-polimerowych, gdyż w pełni automatycznie nadzoruje proces ładowania takiego akumulatora wybierając odpowiedni tryb ładowania oraz mechanizm kontroli, zaś jedynym "zmartwieniem" użytkownika jest wybór prądu ładowania szybkiego, którego dokonujemy dobierając wartość rezystora podłączonego pomiędzy wyprowadzenie PROG a masę. Prąd ten dobieramy według poniższej zależności:
IREG = 1000 V/RPROG
gdzie wielkości: IREG wyrażono w mA, zaś RPROG w kΩ.
W tym urządzeniu rezystor RPROG (R1) ma wartość 10 kΩ, co ustawia prąd ładowania szybkiego na 100 mA. Nie bez powodu ustawiono tego typu prąd ładowania, wszak pamiętać należy, iż dla wygody do zasilania naszego urządzenia przewidziano podłączenie go do portu USB komputera (lub popularnego zasilacza sieciowego z portem USB przeznaczonego do ładowania telefonów komórkowych) zaś ten pozwala na maksymalny pobór prądu rzędu 500 mA w trybie high-power, zaś typowo ok. 100 mA. Kilka dodatkowych słów uwagi wymaga także opcjonalny układ współdzielenia obciążenia zbudowany przy użyciu tranzystora T1 typu MOSFET z kanałem P, diody Schottky D1 oraz rezystora R2.
Dlaczego niezbędna była implementacja tego rodzaju rozwiązania? Otóż, układ MCP73832 nie posiada w swojej strukturze odpowiednich bloków funkcjonalnych odpowiedzialnych za współdzielenie obciążenia, to znaczy odpowiedzialnych za uwzględnienie w procesie ładowania faktu, iż w czasie, gdy układ nadzoruje proces ładowania akumulatora tenże akumulator zasila urządzenie, które pobiera z niego prąd.
Taka sytuacja, po pierwsze powoduje w najlepszym wypadku wydłużenie samego procesu ładowania, zaś w skrajnych wypadkach może go zaburzyć czy też spowodować, iż proces ładowania nigdy nie dobiegnie końca (gdyż odbiornik pobierając nieustannie prąd z ogniwa, a więc de facto z układu nadzorującego nie pozwoli tym samym na skuteczną detekcję końca procesu ładowania).
Aby temu zapobiec zastosowano prosty "przełącznik" w postaci tranzystora MOSFET, którego bramkę podłączono bezpośrednio do napięcia USB zasilającego ładowarkę. W przypadku obecności napięcia USB (czyli de facto stanu wysokiego na bramce tranzystora) tranzystor T1 przechodzi w stan wyłączenia (brak przewodzenia pomiędzy drenem a źródłem) odłączając tym samym ładowany akumulator od obciążenia.
W tym samym czasie obciążenie, jakim jest w naszym wypadku urządzenie "Watch", zostaje zasilone bezpośrednio z napięcia portu USB, a dokładnie rzecz ujmując, poprzez diodę D1. W przypadku odłączenia naszego urządzenia od napięcia zasilającego USB, bramka tranzystora T1 zostaje ściągnięta do masy (poprzez rezystor R2) powodując przewodzenie tegoż tranzystora a więc tym samym zasilenie naszego urządzenia z akumulatora ACCU.
W tym przypadku dioda D1 pełni nieco inną funkcję, a mianowicie zabezpiecza przed przepływem prądu wstecznego tj. z akumulatora w kierunku źródła napięcia zasilającego (USB). W ten prosty sposób zbudowano prosty i w pełni funkcjonalny układ współdzielenia obciążenia, który czasami występuje w innych typach scalonych kontrolerów ładowania produkcji firmy Microchip.
Dalej, wyjście z układu ładowania wprowadzono na wejście stabilizatora LDO typu APE8865Y5-27-HF-3, który zapewnia stały poziom napięcia zasilającego system mikroprocesorowy (2,7 V) niezależnie od stanu układu ładowania.
Już zupełnie dla porządku dodam, że aplikacja układu "Watch" korzysta również z wbudowanego w strukturę mikrokontrolera przetwornika ADC (wejście ADC1), przy którego udziale (za pomocą dzielnika rezystorowego R3/R4) jest mierzony poziom napięcia akumulatora zasilającego, co pozwala na "zgrubne" określenie stanu naładowania tegoż elementu.
Jest to oczywiście rozwiązanie dość proste, gdyż dokładne określenie stanu naładowania akumulatora wymagałoby zastosowania specjalizowanego kontrolera wielkości gromadzonego i traconego ładunku, jednak w tak prostych systemach wydaje się w zupełności wystarczające.
Montaż
Schemat montażowy pokazano na rysunku 3. Jak widać, zaprojektowano "zgrabną", niewielką płytkę drukowaną, która kształtem przypomina zegarek naręczny umożliwiając też zamocowanie typowego paska utrzymującego ją na nadgarstku (przewidziano odpowiednie, podłużne otwory montażowe).
Montaż urządzenia rozpoczynamy od przylutowania scalonego barometru BMP180. Proces ten najłatwiej wykonać przy użyciu stacji lutowniczej na gorące powietrze (tzw. Hot Air) i odpowiednich stopów lutowniczych. Następnie lutujemy pozostałe elementy półprzewodnikowe, potem rezystory i kondensatory jak i inne elementy bierne, a na końcu przyciski, gniazdo USB i rezonator kwarcowy.
Z uwagi na zagęszczenie wyprowadzeń układów scalonych przed pierwszym podłączeniem układu do zasilania należy jeszcze raz sprawdzić jakość wykonanych połączeń, aby nie dopuścić do ewentualnych zwarć. Wspomniana kontrola będzie znacznie łatwiejsza, jeśli zmontowaną płytkę przemyjemy alkoholem izopropylowym w celu wypłukania nadmiaru kalafonii lutowniczej.
Na samym końcu, do tak przygotowanej płytki, montujemy wyświetlacz OLED, zwyczajnie lutując jego wyprowadzenia w przeznaczone do tego celu pola lutownicze (należy sprawdzić polaryzację zasilania), gdyż połączenia te zapewniają mu jednocześnie wystarczający montaż mechaniczny. Akumulator zasilający podłączamy do wyprowadzeń ACCU (zachowując, co oczywiste odpowiednią polaryzację) i podklejamy do płytki urządzenia od strony BOTTOM.
Podobnie postępujemy z sygnalizatorem piezoelektrycznym, który za pomocą krótkich przewodów podłączamy do przeznaczonych do tego celu wyprowadzeń (oznaczonych "PIEZZO"), zaś sam element umieszczamy pomiędzy płytką urządzenia a płytką zastosowanego modułu OLED. Poprawnie zmontowany układ powinien działać od razu po podłączeniu zasilania.
Obsługa
Jako, że urządzenie "Watch" jest z założenia medium mobilnym, które to może być obsługiwane w nieoptymalnych warunkach rzeczywistych, ergonomia i prostota obsługi układu jak i czytelność interfejsu użytkownika była podstawowym kryterium przy konstruowaniu stosownych procedur sterujących. Zgodnie z tymi podstawowymi założeniami, na płytce sterownika przewidziano wyłącznie 2 przyciski sterujące (Menu i Exit), przy czym każdy z nich obsługuje zdarzenie krótkiego (ok.100 ms) jak i długiego (powyżej 500 ms) naciśnięcia.
Diagram obrazujący sposób obsługi urządzenia pokazano na rysunku 4 (symbole przycisków wypełnione kolorem czarnym symbolizują długie naciśnięcie wybranego elementu), zaś widok dostępnych funkcji Menu urządzenia na rysunku 5.
Już zupełnie dla porządku dodam, iż urządzenie "Watch" wyposażono w prosty mechanizm redukcji poboru mocy, którego działanie polega na automatycznym wyłączeniu wyświetlacza OLED po czasie około 20 sekund bezczynności (braku działań po stronie użytkownika). Aktywacja wyświetlacza następuję z chwilą przyciśnięcia dowolnego z elementów sterujących. Ten prosty mechanizm jest na tyle skuteczny, iż pozwala na ponad tygodniową pracę systemu bez potrzeby ponownego ładowania wbudowanego akumulatora zasilającego.
Robert Wołgajew, EP