Do obsługi sensora wielkości fizycznej zaprojektowany został układ pomiarowy bazujący na mikrokontrolerze. Jednostkę centralną układu pokazuje rysunek 1. Jest to typowa aplikacja mikrokontrolera z rodziny AVR. Sam procesor jest taktowany sygnałem zegarowym generowanym w oparciu o rezonator kwarcowy (X101, rysunek 1), którego częstotliwość jest tak dobrana, by uzyskać znormalizowaną prędkość transmisji szeregowej. W obwodzie tym dodane są, zalecane przez producenta, dwa kondensatory C102 i C103.
Kolejnym istotnym elementem jest zespół odpowiedzialny za wygenerowanie impulsu zerowania w momencie włączenia zasilania dla mikrokontrolera. Składa się on z rezystora R101 i kondensatora C101. Istnieje możliwość asynchronicznego wygenerowania impulsu zerującego po naciśnięciu mikroprzycisku SW101. Element ten daje możliwość „zawrócenia procesora ze źle obranej drogi” w trakcie tworzenia oprogramowania.
Nie jest tajemnicą, że opracowanie oprogramowania jest procesem dosyć złożonym i zdarzają się sytuacje, że coś pójdzie nie tak. W takiej sytuacji naciśnięcie przycisku generuje sygnał zerowania dla procesora, co sprowadza go na właściwe tory. Dodanie złącza programującego (P101) tworzy kompletną aplikację jednostki centralnej. Pozostało jedynie uzbroić ją w dodatkowe wyposażenie, by uzyskać środowisko do realizacji pomiarowych.
To dodatkowe wyposażenie to zespół lampek sygnalizujących określone zdarzenia występujące w trakcie działania modułu pomiarowego, którego schemat pokazuje rysunek 2. Wybrane wyjścia portu C (rysunek 1) poprzez rezystory R301 – R304 oraz złącza P301 i P302 sterują pracą LED-ów. Obciążenie prądowe nie jest zbyt duże, toteż w torze sygnałowym nie występują żadne komponenty zwiększające wydajność prądową.
Kolejnym elementem wyposażenia jednostki centralnej jest interfejs szeregowy. Jego schemat pokazuje rysunek 3. Ze względu na to, że moduł pomiarowy, z punktu widzenia komunikacji, jest elementem typu SLAVE, zastosowany jest układ interfejsu współpracującego z magistralą RS485 (U401). Z jednej strony jest on przyłączony do złącza P401, które stanowi styk modułu ze światem zewnętrznym.
Oprócz samych sygnałów transmisji szeregowej (T+/R+ oraz T-/R-), wybrane styki w złączu doprowadzają napięcie zasilające dla modułu. Użyte złącze jest 6-pinowe ze względu na kompatybilność z dotychczasowymi rozwiązaniami. Z drugiej strony układ interfejsu jest połączony z mikrokontrolerem. Oprócz sygnałów transmisji szeregowej występuje tu sygnał sterowania kierunkiem transmisji.
Połączenie mikrokontrolera z odpowiednimi sensorami ilustruje schemat pokazany na rysunku 4. Odpowiednie wyprowadzenia mikrokontrolera, reprezentowane przez etykiety DATA i CLK, wychodzą na złącze, poprzez które moduł łączy się z pozostałymi elementami systemu. Ten jest dedykowany do obsługi czujnika temperatury o symbolu DS18S20+ lub czujnika wilgotności o symbolu SHT11. W przypadku pomiaru wilgotności niezbędna jest mała płytka, gdyż sam element pomiarowy jest przeznaczony do montażu powierzchniowego i ma wiele wyprowadzeń. Tu warto zwrócić uwagę na zastosowanie elementów zabezpieczających D201 i D202 na płycie głównej modułu pomiarowego.
Zabezpieczają one elementy elektroniczne przed przepięciami, które mogą pojawić się w przewodzie łączącym moduł z elementem pomiarowym. Identyczny zestaw występuje „po drugiej stronie kabla” na niewielkiej płytce adaptera elementu pomiarowego. Długi przewód łączący moduł z odpowiednim sensorem może być umieszczony w elektrycznie agresywnym środowisku, obok linii energetycznych czy wentylatora, który jest włączany i wyłączany, generując jednocześnie jakieś zakłócenia.
Jedna z linii mikrokontrolera (o etykiecie DATA) zawiera rezystor (R201) wymuszający odpowiedni potencjał elektryczny na wyprowadzeniu. Jest to niezbędny element w przypadku obsługi sensora DS18S20+, w wariancie SHT11 rezystor ten może być pominięty, jednak jego istnienie nie wnosi żadnych zakłóceń. Drugi sygnał, o charakterze sterującym (etykieta CLK), jest przewidziany do synchronizacji przesyłania danych w przypadku wykorzystania elementu SHT11 (w przypadku DS18S20+ nie jest używany).
Komunikacja z komponentem DS18B20+ oparta jest o technikę 1-wire (opracowaną przez firmę DALLAS), gdzie wymiana informacji pomiędzy mikrokontrolerem a elementem pomiarowym odbywa się za pośrednictwem jednej linii. Pozostałe dwie są przeznaczone do zasilania oddalonego elementu pomiarowego.
Całość uzupełnia stabilizator napięcia, którego schemat pokazuje rysunek 5. Zastosowane jest rozwiązanie z układem impulsowym ze względu na wymaganą dużą sprawność przetwarzania energii, należy pamiętać, że moduł jest przeznaczony do pracy ciągłej i są minimalizowane straty energii. Wykorzystany jest popularny układ o symbolu L4978. Jego aplikacja jest zgodna z zaleceniami producenta i zawiera dodatkowe elementy, jak dioda D501 oraz zworka P501. Wspomniana dioda zabezpiecza układ przed niewłaściwą polaryzacją.
Człowiek jest istotą popełniającą pomyłki, które zdarzają się wszystkim, toteż wspomniana dioda może czasami uratować układ stabilizatora przed uszkodzeniem. Drugim elementem o charakterze zabezpieczającym jest zworka P501. Zawsze występuje ryzyko błędów montażu, toteż zworka ta umożliwia uruchomienie modułu etapami, bez obawy uszkodzenia całości, gdyby coś poszło nie tak.
Do powyższego schematu została opracowana płytka PCB, której widok pokazują rysunki 6 i 7. Komplet płytek składa się z płytki modułu głównego, niewielkiego panelu na diody LED oraz adaptera dla określonego elementu pomiarowego.
Kompletny, zmontowany moduł pomiarowy prezentuje fotografia 1 a same sondy pomiarowe – fotografia 2.
O ile zrozumienie konstrukcji modułu pomiarowego nie powinno stanowić problemu, o tyle niewielkiego wyjaśnienia wymaga tor pomiarowy wielkości analogowych.< Jak zostało wspomniane wcześniej, zostały tu przewidziane dwa warianty, jeden do pomiaru temperatury z elementem aktywnym o symbolu DS18B20+ oraz drugi jako sensor pomiarowy SHT11 mierzący wilgotność względną powietrza.
Obsługa układu STH11 wymaga dwóch sygnałów cyfrowych: jeden z nich jest linią danych, drugi jest sygnałem taktującym przesyłanie danych. Komunikacja z tym elementem pomiarowym ma charakter cyfrowy. Odmienna filozofia obowiązuje w przypadku wymiany danych z elementem w standardzie 1-wire. Przesyłanie danych, w obu kierunkach, odbywa się za pośrednictwem „jednego druta” a informacją użytkową jest stan logiczny w ściśle określonych chwilach czasowych. By w pełni zrozumieć ideę działania interfejsu 1-wire, warto rozpatrzyć następującą ilustrację (rysunek 8, rozważania są uproszczone, niemniej oddają ideę).
Wyobraźmy sobie wyjście portu mikrokontrolera (ATMEGA88) jako układ z otwartym kolektorem. W rzeczywistości budowa pinu jest bardziej złożona. Wyprowadzenie może być skonfigurowane jako czyste wejście (bez wewnętrznych rezystorów determinujących określony stan logiczny). Taki wariant nic nie wnosi na wyprowadzenie portu, nie wymusza jakiegokolwiek poziomu logicznego. Rzeczywisty stan logiczny panujący na „drucie” może wynikać „z drugiej” strony, elementu sensora. Układ DS18S20+ analogicznie może nic nie wymuszać na linii łączącej. W takim przypadku stan logiczny widziany na połączeniu wynika z istnienia rezystora (na rysunku 8) podciągającego do napięcia Vcc.
Inną możliwością jest wysterowanie widocznego tranzystora do stanu nasycenia, co daje stan logicznego zera. W ten sposób układ DS18S20+ ma możliwość przesłania jednego bitu do mikrokontrolera. Warto zauważyć, że zagadnienie jest symetryczne. Jeżeli układ DS18S20+ nie wysteruje swojego tranzystora, czyli nie wniesie na linię komunikacyjną własnego sygnału, to wartość napięcia panująca na linii jest determinowana przez mikrokontroler → powstaje możliwość przesłania jednego bitu do układu DS18S20+. W tym rozwiązaniu do szczęścia niezbędny jest jeszcze jeden element: synchronizacja. By odbiorca przesyłanych danych wiedział, w jakim momencie należy „odebrać” dane, niezbędny jest impuls „zaczepny”. Przed przesłaniem danych zawsze występuje krótki impuls oznaczający początek sekwencji transmisyjnej. Jeżeli dokładniej się temu przyjrzeć, można dostrzec pewne analogie do komunikacji typu MASTER – SLAVE.
Algorytmy i rozwiązania dotyczące obsługi transmisji szeregowej czy rozpoznawania poleceń były wystarczająco wyjaśnione przy okazji opisu działania innych elementów systemu. W oprogramowaniu tego modułu nowym elementem jest obsługa sensora temperatury pracującego z magistralą 1-wire. Prostota sprzętowa jest okupiona pewną złożonością w obsłudze wysyłania danych do sensora i w przypadku odczytu danych.
Powszechnie stosowane rozwiązania opierają się na przesyłaniu danych w sposób szeregowy (po jednym bicie) oraz użyciu dodatkowego sygnału do taktowania przesyłanych danych. W przypadku techniki określanej jako 1-wire nie występuje sygnał taktujący, a jedynie linia danych. Powoduje to kilka utrudnień, gdyż funkcjonalność sygnału taktującego musi zostać rozwiązana w inny sposób, w tej roli występuje wspomniany impuls zaczepny.
By wymiana danych pomiędzy mikrokontrolerem a układem DS18B20+ mogła być właściwie rozumiana, musi być zachowany określony czas trwania poszczególnych faz związanych z komunikacją, do których można zaliczyć trzy różne operacje. Pierwsza z nich związana jest z resetowaniem sensora przed przesłaniem danych. Jako efekt dodatkowy tej operacji istnieje możliwość stwierdzenia obecności samego sensora. Tę ideę wyjaśnia rysunek 9. Przedstawia ona sygnał występujący na magistrali 1-wire w funkcji czasu.
W początkowej fazie mikrokontroler, sterując pracą wybranego pinu portu (jako wyjście ze stanem logicznego zera), wymusza wymagany stan linii (impuls zaczepny), który musi trwać minimum 480μs. Po upływie tego czasu następuje przełączenie wyprowadzenia portu do funkcji pinu wejściowego, co implikuje, że stan na tej linii jest teraz determinowany przez rezystor (R201, rysunek 4). Ta swoista cisza komunikacyjna, gdyż ani mikrokontroler, ani sensor temperatury nie wpływa na stan linii, trwa określony czas, po upływie którego sensor wymusza stan niski trwający również określony czas.
Jeżeli mikrokontroler w odpowiedniej chwili stwierdzi obecność na linii stanu niskiego, to oznacza, że jest przyłączony sensor temperatury. W innym przypadku, gdzie „nikt” nie wpłynie na stan linii, włączony rezystor pozostawi na linii napięcie bliskie napięciu zasilającemu, co mikrokontroler odczyta jako stan logicznej jedynki. Ma to swoje odbicie w algorytmie sprawdzającym obecność sensora w przestrzeni mikrokontrolera pokazanym na listingu 1. (Uwaga! Wszystkie listingi dostępne są w Elportalu wśród materiałów dodatkowych do tego numeru.)
Zapis oraz odczyt informacji z sensora DS18B20 jest operacją szeregową, a każdy bajt danych jest rozłożony na pojedyncze zapisy poszczególnych bitów (0, 1). Transmisja zaczyna się od wymuszenia przez mikrokontroler stanu logicznego zera na magistrali komunikacyjnej (impuls zaczepny), co pozwoli układowi sensora temperatury na synchronizację czasową, gdyż operacja również jest uwarunkowana czasowo. Przypadek zapisu bitu o wartości „0” lub „1” pokazuje rysunek 10.
Przy zapisie logicznego zera mikrokontroler utrzymuje niski stan na linii danych przez czas wystarczająco długi, by sensor stwierdził właściwy stan. Jego badanie rozpocznie się po upływie 15μs od wymuszonego przez mikrokontroler zbocza synchronizującego. Tolerancja czasu odczytu stanu linii jest duża. Sensor ma na to czas do 30μs (typowo trwa to 15μs).
Chcąc zapisać bit o wartości „1”, mikrokontroler odpowiednio wcześnie musi przestać wymuszać stan niski na linii, co zostanie stwierdzone przez sensor po upływie określonego interwału czasu. Algorytm zapisu pojedynczego bitu pokazuje listing 2. Ze względu na krótkie czasy trwania poszczególnych faz operacji zapisu, by obsługa przerwań nie wniosła zaburzeń czasowych, operacja jest realizowana z zablokowanymi przerwaniami.
Podobne rozwiązanie występuje przy odczycie przez mikrokontroler danych z magistrali 1-wire (rysunek 11). Operacja jest zainicjowana przez procesor w wyniku wymuszenia zbocza synchronizującego na linii. Po upłynie krótkiego czasu procesor przechodzi do stanu odczytu przez przestawienie wyprowadzenia pinu portu do funkcji wejściowej. To pozwoli na wymuszenie stanu na linii przez rezystor lub przez układ sensora, w zależności od wartości przekazywanego bitu.
Ma to swoje odzwierciedlenie w algorytmie pokazanym na listingu 3.
Obie operacje, zapisu i odczytu, wymagają właściwej kolejności bitów: poczynając od pozycji najmniej znaczącej. Ujmuje to zarówno algorytm zapisu, jak i odczytu pokazany na listingu 4. W programowej pętli wysyłany jest najmniej znaczący bit i po wykonaniu operacji przesunięcia kolejny bit danych znajdzie się na pozycji najmniej znaczącej oraz przy odczycie modyfikowany jest stan najbardziej znaczącego bitu danych wynikowych oraz również wykonana jest operacja przesunięcia. Finalnie pierwszy odczytany bit po serii przesunięć znajdzie się na pozycji najmniej znaczącej danych wyjściowych.
Komplet działań związanych z odczytem bieżącej temperatury z sensora jest synchronizowany upływem czasu. Zegar, odliczając określoną liczbę przerwań ustawia flagę (zmienna _1WireEvent), która aktywuje wymagane działania dotyczące sensora temperatury.
Obsługa interfejsu RS485 jest identyczna jak w każdym dotychczasowym modelu o funkcjonalności SLAVE. Jeżeli sterownik otrzymał wcześniej jakiekolwiek polecenie, które generuje informację zwrotną, zostaje ona zapisana w buforze cyklicznym i oczekuje na rzeczywiste wysłanie. Otrzymanie zezwolenia na transmisję aktywuje odpowiednią funkcję, gdzie występuje sprawdzenie, czy bufor cykliczny zawiera jakiekolwiek informacje. W sytuacji, gdy jest coś do wysłania, wywołana jest funkcja, której zadaniem jest rzeczywiste wysłanie zgromadzonych danych. W przeciwnym wypadku wysyłany jest komunikat, który informuje, że aktualnie sterownik nie ma nic do wysłania, jako bezpośrednia transmisja do układu UART.
W module realizującym odczyt temperatury przewidziana jest możliwość autonomicznego wysyłania danych pomiarowych. Z odpowiednim interwałem czasu sterownik sam podejmuje procedurę wysłania bieżących danych. Realizacja opiera się na zmiennych będących wskaźnikami do odpowiednich funkcji (zmienna AutoSendService). Przy zaistnieniu zdarzenia upłynięcia odpowiedniego interwału czasu wywoływana jest funkcja (TimeEventNotify), która zlicza liczbę jej wywołań.
W przypadku osiągnięcia określonego limitu w koniunkcji z warunkiem aktywowania autonomicznego wysyłania danych modyfikowana jest zawartość zmiennej (AutoSendService), która typowo zawiera wartość 0 (będącą pustym wskaźnikiem), co wyłącza jej wywołanie w pętli funkcji main (wywołanie jest poprzedzone odpowiednią instrukcją warunkową). Nowe, ewentualne wskazanie dotyczy funkcji SendYourselfData.
Oznacza to, że w dalszej realizacji instrukcji pętli głównej funkcji main dojdzie do wywołania funkcji wskazywanej przez zawartość tej zmiennej. Jej postać pokazuje listing 5. Nowe dane dołączane są do bufora cyklicznego, który przechowuje je do momentu wysłania. By nie przekroczyć pojemności tego bufora, dane są dołączane tylko w przypadku, gdy jest on pusty, nie ma sensu generować nowych danych, jeżeli poprzednie nie zostały wytransmitowane.
W przypadku obsługi czujnika wilgotności (co nie zawsze daje się przewidzieć, konieczne jest użycia mikrokontrolera z większą pamięcią programu FLASH, mikrokontroler ATMEGA88 należy zamienić na ATMEGA168) wszystkie elementy oprogramowania są identyczne jak w przypadku sensora temperatury 1-wire, ale sam element pomiarowy jest obsługiwany w odmienny sposób. Pierwszą różnicą jest to, że jego przyłączenie wymaga czterech przewodów.
Oprócz dwóch zasilających, występuje dwukierunkowa linia danych (jest użyta ta sama co w przypadku sensora DS18B20+) oraz wyjściowa (z punktu widzenia mikrokontrolera) linia do taktowania przesyłania danych. Sama transmisja już nie jest tak ściśle uwarunkowana czasowo jak w przypadku obsługi 1-wire i każdy impuls taktujący może trwać przez okres kilku instrukcji maszynowych mikrokontrolera. Sposób generowania sygnałów na linii danych i zegara do układu SHT11 jest zawarty w dokumentacji i jego odtworzenie nie jest operacją złożoną.
Podobnie jak w poprzednim przypadku sensora, istnieje możliwość stwierdzenia, że czujnik nie jest przyłączony do mikrokontrolera. Kompletną obsługę pokazuje listing 6. Po odczytaniu danych pomiarowych konieczne jest dokonanie odpowiednich obliczeń zmiennoprzecinkowych według wzorów zawartych w dokumentacji. Mierzona wilgotność jest względną określoną w procentach. Wartość ta może być skompensowana temperaturowo (wzory również są zawarte w dokumentacji). Z tego powodu moduł pomiarowy wysyła dwie wartości (druga jako dodatkowy parametr oddzielona znakiem kropki od poprzedniego).
Z punktu widzenia konfiguracyjnego, w obu przypadkach struktura bloku danych określająca szczegóły jest identyczna. Obok pól występujących w każdym opisanym już module (jak własny identyfikator, czy hasło do konfiguracji) występują pola specyficzne dla realizowanej funkcji. Należą do nich (listing 7):
- ParamName – identyfikator mierzonej wielkości fizycznej jako ciąg składający się maksymalnie z 8 znaków, domyślnie jest puste,
- AutoMeansTimeInterval – określa interwał czasu, z jakim realizowany jest pomiar autonomiczny,
- AutoMode – określa, czy pomiary są realizowane autonomicznie, czyli moduł samodzielnie z określonym interwałem czasowym inicjuje czynności pomiarowe lub, w przeciwnym wypadku, dokonuje tego na żądanie (zapytanie), domyślnie funkcjonalność autonomiczna jest wyłączona.
W obu przypadkach moduł pomiarowy rozpoznaje polecenia zawarte w tabeli 1. (Uwaga, tabele dostępne są w Elportalu wśród materiałów dodatkowych do tego numeru)
Większość zastosowanych elementów jest przystosowana do montażu powierzchniowego. Może to stanowić pewne utrudnienie dla początkujących, jednak przy odrobinie staranności uruchomienie nie powinno nastręczać kłopotów. Po zmontowaniu układu, przed pierwszym uruchomieniem, tradycyjnie należy odłączyć stabilizator od reszty układu.
Dopiero po sprawdzeniu, że układ zasilający działa poprawnie, można założyć zworkę P501 i przejść do kolejnego kroku związanego z zaprogramowaniem pamięci FLASH mikrokontrolera. Wcześniej jednak wymaganą operacją jest właściwe ustawienie przełączników FUSE w zastosowanym mikrokontrolerze. Bity konfiguracyjne dla mikrokontrolera ATMEGA88 i ATMEGA168 są identyczne. Ich właściwe ustawienie było już wielokrotnie opisywane przy okazji innych modułów.
Po pierwszym uruchomieniu modułu w jego pamięci nieulotnej zostaną zapisane domyślne wartości parametrów konfiguracyjnych. Te parametry wymagają korekty w każdym module pomiarowym. Tradycyjnie najprościej moduł jest przyłączyć do laboratoryjnego zestawu uruchomieniowego i za pomocą znanego już programu konfiguracyjnego dokonać właściwych korekt wartości parametrów. W tabeli 2 jest pokazana konfiguracja modułu pomiarowego wilgotności, pozostałe moduły pomiarowe konfigurowane są identycznie, a jedyne różnice dotyczą własnego identyfikatora oraz symbolu mierzonej wielkości.
W systemie przewidzianych jest kilka modułów pomiarowych. Każdy z nich musi zawierać indywidualne wartości parametrów konfiguracyjnych, które są nadawane im w procesie konfiguracji w identyczny jak wyżej opisany sposób. Identyfikatory modułów oraz symbole wielkości pomiarowych są już określone w oprogramowaniu (występują w oprogramowaniu serwera www w pliku o nazwie dataservice.c – można sięgnąć do tego pliku, który był udostępniony kilka miesięcy temu). Pozostałe moduły pomiarowe (w wariancie z użyciem sensora DS18S20+) powinny mieć następujące parametry (lista odbiorców identyczna jak w tabeli 2):
- pomiar temperatury wody w piecu – moduł o symbolu TMPS01, symbol zmiennej T01,
- pomiar temperatury wewnątrz pomieszczenia – moduł o symbolu TMPS02, symbol zmiennej T02,
- pomiar temperatury na zewnątrz domu – moduł o symbolu TMPS05, symbol zmiennej T05.
W kolejnym odcinku będzie opisany inny moduł pomiarowy.