
Przedstawiam projekt inteligentnej stacji meteorologicznej. Jest to nietypowa konstrukcja, zdolna do przewidywania temperatury powietrza atmosferycznego na kolejne 24 godziny.
Wykorzystałem do tego celu sztuczną sieć neuronową.
Stacja rejestruje co minutę wartość temperatury oraz prezentuje na wyświetlaczu w formie graficznej rozkład temperatury z dwóch ostatnich dni. Poza tym oblicza godziny wschodu i zachodu Słońca oraz fazę Księżyca.
Poniższy obrazek tłumaczy trochę to, co widać na wyświetlaczu:

Cel:
Głównym założeniem projektowym było stworzenie rozbudowanego i autonomicznego rejestratora temperatury. Zależało mi też na jakimś wykresie (histogramie) pokazującym zmianę wartości temperatur w ciągu kilkudziesięciu ostatnich godzin. Innym założeniem była możliwość podłączenia zewnętrznego bardziej odległego czujnika (do kilkudziesięciu metrów). Najtrudniejszym celem była prognoza temperatury. Wykorzystałem w tym celu sztuczną inteligencję.
Stacja mierzy na razie tylko temperaturę. Możliwe, że kiedyś dołożę do niej czujniki ciśnienia i/lub wilgotności.
Hardware:
Mikrokontroler: ATmega128 pracująca z częstotliwością 16MHz
Pamięć: 64KB XRAM (64KB z 128KB) + 74HC573
Zegar: DS1307N
Termometr: DS18B20
Odbiornik: RX433
Wyświetlacz: GLCD 128*240
Gniazdo kart pamięci: RS-MMC/SDHC
Stacja zasilana napięciem 5V podczas pracy pobiera około 150mA prądu.
Software:
Nad projektem pracowałem rok czasu z licznymi przerwami. Wypełniłem moją ATmegę w 80%. Kod źródłowy składa się z 5800 linijek (i działa). Poniżej opiszę niektóre podprogramy i bloki funkcjonalne urządzenia.
SYSTEM PLIKÓW:
Programową obsługę systemu plików zapewnia AVR-DOS.
Do komunikacji z kartą pamięci wykorzystałem czytnik RS-MMC/SDHC komunikujący się z mikrokontrolerem poprzez programowy interfejs komunikacyjny SPI.
Przed każdym zapisem na karcie pamięci sprawdzana jest jej fizyczna obecność. Jeśli karty nie ma lub włożona karta posiada błędy fizyczne lub logiczne - sygnalizowany jest błąd w postaci przekreślonej ikonki z kartą. W takiej sytuacji zapis jest pomijany. Dla każdej doby jest tworzony oddzielny plik tekstowy (np. 22-05-11.txt), w którym co minutę dopisywana jest średnia arytmetyczna z 60 próbek temperatury dokonywanych co jedną sekundę. Każdy plik kończony jest krótkim raportem, wskazującym temperaturę minimalną, maksymalną oraz średnią dobową.
Dodatkowo tworzony jest plik error.txt, w którym zapisują się daty i godziny wszystkich startów lub resetów systemu ze wskazaniem miejsca w programie, przy którym reset wystąpił.
CZUJNIK TEMPERATURY:
Do pomiaru temperatury wykorzystałem cyfrowy czujnik temperatury DS18B20 firmy Dallas Semiconductor. Komunikuje się on z mikrokontrolerem magistralą 1-WIRE. Czujnik umożliwia pomiar temperatur w zakresie -55C do +125C z rozdzielczością 0,0625C. Zmierzona temperatura zostaje zaokrąglona do 0,1C, choć średnia dokładność pomiaru to +/- 0,5C. Przed każdym pomiarem sprawdzana jest obecność czujnika. W razie jego braku przekreślana jest odpowiednia ikonka na wyświetlaczu. W razie wykrycia błędów w komunikacji z czujnikiem (kontrola CRC) również ikonka zostaje przekreślona. W obu przypadkach wynik aktualnego pomiaru temperatury nie zostanie wyświetlony,
a do statystyk podkładany jest wynik ostatniej, poprawnie zmierzonej temperatury. Temperatura jest mierzona co sekundę, a wartość pomiaru wyświetlana jest z dokładnością 0,1C na w odpowiednim miejscu na wyświetlaczu. Czujnik jest podłączony do stacji kilkumetrowym przewodem.
Daje to możliwość umieszczenia go na zewnątrz (np za oknem).
RADIOWY CZUJNIK:
Alternatywnie do czujnika przewodowego powstał czujnik bezprzewodowy - radiowy. Chodziło o zwiększenie mobilności stacji (możliwość postawienia jej gdziekolwiek). Sonda działa sprawnie w zasięgu do ok. 15m z kilkoma ścianami po drodze. Maksymalnym zmierzonym zasięgiem na otwartym powietrzu była odległość 120m. Częstotliwość nadawania to 433MHz. Dane wysyłane są UARTem z prędkością 1200 baud.
Aby zminimalizować błędy zastosowałem transmisję pakietową. Co minutę wysyłane są 4 identyczne pakiety. W każdym pakiecie znajduje się 8 bajtów.
Dwa bajty rozbiegowe, dwa bajty adresowe, dwa bajty z wartością temperatury,
bajt statusu baterii oraz bajt kontrolny CRC.
Odbiornik, a konkretniej podprogram odbioru odrzuca pakiet, jeśli nie spełnia on wymogów (adres, CRC).
W czasie 20 dniowego testu sprawdzającego poprawność przesyłanych danych okazało się, że przedarło się tylko kilka fałszywych pakietów, co jest zadowalającym rezultatem. Bez transmisji pakietowej fałszywe wartości docierały nawet kilka razy w ciągu sekundy.
Poniższy obrazek przedstawia przebieg danych w pakiecie o długości 6 bajtów.

Część nadawcza składa się z mikrokontrolera ATtiny2313, nadajnika TX433 (Velleman), czujnika temperatury DS18B20 i stabilizatora 78L05. Zasilanie stanowi bateria 9V. Z obawy o niską efektywność baterii zimą (zamarzanie i szybkie zużycie baterii) czujnik radiowy jest teraz zastąpiony wersją przewodową.
ZEGAR:
Do pomiaru czasu wykorzystałem zegar czasu rzeczywistego DS1307N. Komunikuje się on magistralą I2C. Do układu podłączona jest bateria podtrzymującą pracę zegara (przez kilka lat) w razie braku zasilania głównego.
Układ dysponuje pamięcią RAM (56B), w której przechowuję informacje dotyczące czasu letniego / zimowego.
CZAS LETNI/ZIMOWY:
Dwa razy w roku urządzenie samoczynnie zmienia czas z zimowego na letni lub odwrotnie.
KALENDARZ:
Czas wyświetlany jest w formie cyfrowej i analogowej. Na wyświetlaczu wyświetlane są dwa zegary oraz dwa kalendarze: tekstowy i tabelkowy.
Na potrzeby wersji tabelkowej dodatkowo obliczane są lata przestępne.
Aktualny dzień wskazywany jest migającym prostokątem.
FAZY KSIĘŻYCA:
Każdego dnia obliczana jest aktualna faza Księżyca. Prezentowana jest ona w postaci 1 z 8 ikonek przedstawiających Księżyc. Obok ikonki widnieje przybliżona jasność Księżyca wyrażana w procentach (0% - nów , 100% - pełnia). Algorytm obliczający fazę opiera się na średniej wartości miesiąca synodycznego.
WSCHODY I ZACHODY:
Kolejnym algorytmem astronomicznym jest algorytm obliczający godzinę wschodu i zachodu Słońca. Oblicza on pozycję Ziemi względem Słońca, uwzględniając ruch wirowy i obrotowy Ziemi. Godzina wschodu i zachodu Słońca obliczana jest dla konkretnych współrzędnych geograficznych i wyświetlana na wyświetlaczu.
REGULACJA PODŚWIETLENIA:
Stacja zmienia automatycznie poziom podświetlenia wyświetlacza. Posiada dwa tryby jasności podświetlenia: dzienny i nocny. Zamiast wykorzystać czujnik poziomu oświetlenia, wykorzystałem "wiedzę" stacji dotyczącą godzin wschodów i zachodów Słońca. Zmiana trybu następuje tuż po wschodzie lub zachodzie.
BUFOR RAMKI:
Cała zawartość ekranu przed wyświetleniem jest buforowana w zewnętrznej pamięci XRAM. Do wyświetlania tekstów wykorzystałem trzy różne typy czcionek.
Do wyświetlania całej reszty użyłem zmodyfikowanej implementacji algorytmu Bresenhama.
XRAM:
W zewnętrznej pamięci XRAM przechowywany jest bufor ekranu i bufor wykresu temperatury. Przechowywane są też dane niezbędne do "przywrócenia systemu"
po chwilowym zaniku energii lub resecie oraz kilka bajtów kontrolnych.
PRZYWRACANIE SYSTEMU:
Na wypadek przypadkowych resetów lub zawieszeń programu dodałem opcję "przywracania systemu". System po prostu wykrywa, jak dawno przed uruchomieniem działał poprawnie. Jeśli to było wiele godzin temu, to wykonywane jest pełne uruchomienie (kasowanie wszystkich zmiennych).
Jeśli natomiast przerwa w działaniu systemu była np. kilkunastosekundowa,
to system wraca do pracy, wykorzystując zmienne z pamięci XRAM. Weryfikuje wcześniej poprawność danych tej pamięci poprzez porównanie zmiennych kontrolnych w niej zawartych z wartościami oczekiwanymi.
IKONY:
W prawym górnym rogu ekranu widać kilka ikon.
Pokazują one status karty pamięci (działa / nie działa / zapis) i czujnika temperatury (działa / nie działa).
Ikona termometru z antenką wskazuje obecność i poziom sygnału czujnika radiowego. Poziom sygnału jest liczony na podstawie dzielenia liczby pakietów odebranych przez liczbę pakietów spodziewanych.
Ikonka z baterią pokazuje poziom napięcia zasilania z ewentualnej baterii.
Na razie jest nieaktywna, gdyż układ zasilany jest z zasilacza sieciowego.
WYKRES TEMPERATURY:
W dolnej części ekranu rysowany jest wykres temperatury. Właściwie jest on podzielony na dwa różne wykresy połączone ze sobą: wykres historyczny o zakresie 46 godzin i wykres prognozowany na kolejne 24 godziny.
Część historyczna prezentuje wartości temperatur z dwóch ostatnich dni.
Przewija się w miarę upływu czasu w lewo, a nowe wartości pojawiają się przy pionowej linii oddzielającej oba wykresy. Ten wykres przesuwany jest o jeden punkt w lewo co 20 minut. Wtedy dodawany jest kolejny punkt o wartości reprezentującej średnią arytmetyczną z 1200 ostatnich próbek temperatury dokonywanych co jedną sekundę (średnia 20-minutowa). Wykres jest rysowany metodą wielu połączonych ze sobą odcinków (dokładnie 138).
Podczas każdej aktualizacji wykresu wykonywane jest autoskalowanie. Ustalane są wtedy wartości górnych i dolnych podziałek, a rozdzielczość pionowa ulega zmianie.
Wykresy są rysowane poprawnie dla wartości temperatur od -40C do +100C.
PROGNOZA:
Jednym z najtrudniejszych etapów tworzenia tego projektu i najbardziej czasochłonnym było było opracowanie stosunkowo skutecznej metody prognozy temperatury.
Najpierw myślałem nad metodą opartą na wykrywaniu trendów. Jednak efekty tej metody nie zadowalały mnie. Ostatecznie do prognozowania temperatury wykorzystałem sztuczną inteligencję.
SZTUCZNA INTELIGENCJA:
Mechanizmem sztucznej inteligencji w tym projekcie jest sztuczna sieć neuronowa.
Pierwotnie chciałem stworzyć samouczącą się sztuczną inteligencję, opartą na behawioryzmie, uczeniu maszynowym lub sieci neuronowej. Ostatecznie zdecydowałem się na jednorazowo uczoną sztuczną sieć neuronową, ponieważ proces nauczania takiej sieci przebiega o wiele szybciej.
Sieć neuronowa jest zbudowana z 48 neuronów i 512 synaps.
Jest to perceptron wielowarstwowy, uczony metodą wstecznej propagacji błędów.
Warstwa sensoryczna posiada 24 neurony. Warstwa synaptyczna (ukryta) posiada 16 neuronów. Warstwa wyjściowa posiada 8 neuronów.
Sieć neuronowa uczona była z 10 letniej bazy danych klimatologicznych, zebranych dla miasta Wrocław.
Do nauki przygotowałem na podstawie wymienionej bazy zestaw ok. 30 000 przykładów uczących (treningowych). Przykłady uczące były wstępnie losowo mieszane. Pozwoliło to osiągnąć zauważalnie lepsze wyniki. Proces uczenia sieci dla zbioru danych uczących z okresu 10 lat powtarzany był 50 000 razy. Nie zauważyłem efektu przeuczenia sieci (wyuczenia wzorców na pamięć). Całkowity czas uczenie sieci trwał 3 tygodnie. W tym czasie sprawdzałem wiele różnych modeli i wybrałem najbardziej optymalny.
Zmieniałem liczbę neuronów w różnych warstwach, metodę uczenia sieci neuronowej, liczbę epok i inne drobiazgi.
Efekty uczenia uznałem za zadowalające. Nie mam za bardzo możliwości porównania z innymi systemami, więc opieram się na własnych metodach weryfikacji.
Poniżej wykres przedstawiający kompozycję danych prognozowanych i zmierzonych dla 9 dni (nie jest to prognoza 9 dniowa).

Po sprawdzeniu poprawności prognozy temperatury dla różnych miesięcy okazało się, że średni błąd prognozy wynosi 1.7°C, a średni błąd względny wynosi 6.7%.
Współczynnik korelacji Pearsona między danymi prognozowanymi a zmierzonymi osiągnął 0.96.
Weryfikując funkcjonowanie sieci zauważyłem, że trochę lepiej ona sobie radzi latem niż zimą. Być może chodzi o gwałtowne skoki temperatur, występujące czasem w okresie zimowym.
Modyfikacje:
Planuję włożyć całość w odpowiednią obudowę i doinstalować kolejne czujniki. Myślę o czujnikach wilgotności, ciśnienia i czystości powietrza (najlepiej cyfrowych). Chcę zmienić baterię w czujniku zewnętrznym, najlepiej na jakąś niezamarzającą i wysokopojemną lub odpowiedni akumulatorek, zasilany małym panelem słonecznym.
Cool? Ranking DIY