Wyświetlanie czasu i pogody 3 w 1 Arduino: 11 kroków
Wyświetlanie czasu i pogody 3 w 1 Arduino: 11 kroków
Anonim

Autor: Boomer48Follow Więcej autora:

Korzystanie z ATtiny85
Korzystanie z ATtiny85
Korzystanie z ATtiny85
Korzystanie z ATtiny85
Narzędzie do partycjonowania i przycinania wielokątów z zasilaniem Pi
Narzędzie do partycjonowania i przycinania wielokątów z zasilaniem Pi
Pi Powered Pie partycjonowanie i narzędzie do przycinania wielokątów
Pi Powered Pie partycjonowanie i narzędzie do przycinania wielokątów
Cyfrowe elementy sterujące ręcznego wzmacniacza audio
Cyfrowe elementy sterujące ręcznego wzmacniacza audio
Cyfrowe elementy sterujące ręcznego wzmacniacza audio
Cyfrowe elementy sterujące ręcznego wzmacniacza audio

Lubię mikrokontrolery PIC i lubię programować w asemblerze. W rzeczywistości w ciągu ostatnich kilku lat zamieściłem na mojej stronie około 40 projektów opartych na tej kombinacji. Ostatnio zamawiałem niektóre części od jednego z moich ulubionych dostawców z USA i zauważyłem Arduino Nano z kablem do programowania, za jedyne 1,20 USD więcej niż goły układ procesora ATMEGA328. Więc kupiłem kilka z nich. Następnie pobrałem Arduino IDE i odkurzyłem pamięć programowania „C ++”.

Ten projekt to połączenie zegara, który wykorzystuje GPS do pomiaru czasu i odbiornik RF, który dekoduje komunikaty pogodowe ze wspólnego czujnika AcuRite. Rezultatem jest mały wyświetlacz czasu i temperatury. Zegar GPS i procedury pogodowe są skonfigurowane jako oddzielne pliki dołączane, dzięki czemu można łatwo przejść do głównej procedury i skonfigurować ją tak, aby wykonywała tylko funkcję zegara lub tylko funkcję pogody. Po prostu odkomentuj odpowiedni „#define” na górze głównej procedury, jeśli chcesz tylko jedną z funkcji.

Jeśli używane są obie funkcje, w górnym wierszu wyświetlacza LCD wyświetlany jest czas lokalny, a w dolnym wierszu wyświetlana jest wilgotność i temperatura zarówno w stopniach Celsjusza, jak i Fahrenheita. Jeśli używana jest tylko funkcja zegara, w górnym wierszu wyświetlany jest czas lokalny, a w dolnym wyświetlany jest czas UTC. Jeśli używana jest tylko funkcja pogodowa, w górnym wierszu wyświetlany jest pierwszy odebrany czujnik, a w dolnym wierszu wyświetlany jest każdy inny odebrany czujnik. Dodałem tę możliwość, ponieważ mam dwa czujniki pogodowe.

Krok 1: Czujnik pogody

Czujnik pogody
Czujnik pogody
Czujnik pogody
Czujnik pogody
Czujnik pogody
Czujnik pogody

Zastosowany tutaj czujnik pogodowy AcuRite wysyła informacje o temperaturze i wilgotności co 16 sekund. Z tyłu widnieje numer modelu 000592TXR, ale zazwyczaj jest reklamowany jako model 06002M. Ten czujnik jest używany przez wiele różnych modeli stacji pogodowych, więc łatwo go znaleźć i udało mi się je kupić na eBayu za mniej niż 20 USD. AcuRite sprzedaje podobnie wyglądające czujniki do niektórych swoich stacji pogodowych, ale mogą, ale nie muszą, stosować ten sam protokół komunikacyjny. Istnieją pewne wskazania w Internecie, że czujnik tylko temperatury 00606 używa tego samego formatu wiadomości, ale z nieprawidłowym bajtem wilgotności.

Jak widać na pierwszym przebiegu pokazanym powyżej, komunikaty pogodowe są wysyłane w seriach z przerwą 2 ms między kolejnymi komunikatami. Drugi przebieg pokazany powyżej rozszerza część jednej wiadomości, aby zobaczyć czasy trwania bitów i wzorce. Istnieją cztery bity synchronizacji o wysokości około 600 us, po których następuje 600 us w dół. Bity danych są reprezentowane przez 400us high, po którym następuje 200us low (1) lub 200us high, po którym następuje 400us low (0).

Format wiadomości składa się z 7 bajtów danych. Pierwsze dwa bajty to ID czujnika i te się nie zmieniają (tzn. nie używają kodu zmiennego). Ostatni bajt to prosta addytywna suma kontrolna pierwszych sześciu bajtów. Trzeci bajt to wskaźnik poziomu baterii i powinien zawsze wynosić 44 hex, jeśli bateria jest dobra. Czwarty bajt to wilgotność i jest to wartość nieskalowana z zakresu od 0 do 99. Należy pamiętać, że najbardziej znaczący bit bajtów 4, 5 i 6 jest bitem parzystości i nie jest częścią pomiaru wartości. Bajty 5 i 6 to skalowana temperatura (w stopniach Celsjusza), przy czym dolne 4 bity bajtu 5 są połączone z dolnymi 7 bitami bajtu 6, tworząc wartość 11-bitową. Temperatura jest zawsze przedstawiana jako liczba dodatnia i staje się ujemna dopiero po zastosowaniu skalowania. Skalowanie to (C / 10) - 100. Dzielenie przez 10 jest wymagane, ponieważ rozdzielczość temperatury jest w dziesiątych częściach stopnia. Odejmowanie jest wymagane, ponieważ czujnik dodaje 100 w celu utrzymania przesyłanej wartości dodatniej.

Krok 2: Odbiornik RF

Odbiornik RF
Odbiornik RF
Odbiornik RF
Odbiornik RF

Moduł RF, którego używam do tego projektu, to RXB6. Jest to odbiornik super heterodynowy w przeciwieństwie do mniej pożądanych odbiorników superregeneracyjnych. Jeśli spojrzysz na tanie moduły RF, zobaczysz, że płytki nadajnika i odbiornika są często łączone w pakiety. Większość z tych odbiorników w pakiecie to odbiorniki superregeneracyjne, więc mają zwykle znacznie niższą charakterystykę wydajności (w tym zasięg) niż odbiorniki super heterodynowe. Do tego projektu potrzebujemy tylko modułu odbiornika, ponieważ będziemy otrzymywać sygnały z nadajnika czujnika pogodowego.

Krok 3: Anteny RF

Anteny RF
Anteny RF

RXB6 nie jest dostarczany z anteną. Niektóre helikalne można kupić dość tanio, ale łatwo jest też zrobić własną antenę. W rzeczywistości kabel połączeniowy płytki stykowej można wsunąć na pin antenowy modułu, jeśli nie chcesz być zbyt fantazyjny. Idealnie, antena z prostym drutem miałaby długość fali 1/4, co daje około 6,8 cala. Początkowo wykonałem przewód połączeniowy i nie miałem problemu z odebraniem czujnika zewnętrznego, mimo że mój warsztat elektroniczny znajduje się w mojej piwnicy.

Inną możliwością jest wykonanie własnej anteny śrubowej. Istnieje wiele planów w sieci, ale ten pokazany na powyższym obrazku jest tym, co zrobiłem. Użyłem drutu z litego rdzenia ze skrawka kabla Ethernet i owinąłem go wokół gładkiego trzonka wiertła 5/32 cala. Pozostaw izolację załączoną z wyjątkiem końcówki lutowanej do płyty RF. Potrzebujesz 20 tur. Możesz również użyć wiertła 7/32 cala i zamiast tego nawinąć 17 zwojów. Każdy z nich prawdopodobnie będzie działał dobrze dla zakresów, które prawdopodobnie będziesz mieć dla swoich czujników. Prawdziwym kluczem jest posiadanie dobrego odbiornika RF na początek. Czujniki AcuRite mają również dość mocne nadajniki.

Krok 4: Protokół komunikacji RF

Istnieje kilka różnych technik modulacji do przesyłania danych, ale czujniki te wykorzystują najprostszą, czyli OOK (kluczowanie z włączeniem) lub ASK (kluczowanie z przesunięciem amplitudy). Ponieważ w tym przykładzie mamy do czynienia z bitami danych 0/1, amplituda jest pełna lub całkowicie wyłączona. Tak więc dla naszych celów OOK i ASK są takie same, ponieważ OOK oznacza, że nośna RF jest albo pełna, albo całkowicie wyłączona. Format wiadomości jest ogólnie definiowany przez producenta urządzenia nadawczego i może on wykorzystywać praktycznie dowolną szybkość transmisji, dowolny styl formatowania bitów i dowolną długość wiadomości. Pasmo 433 MHz jest zatłoczone transmisjami dla takich rzeczy jak inteligentne liczniki itp., więc oprogramowanie musi być dostrojone do filtrowania tylko dla formatu wiadomości, którego chcemy użyć.

Krok 5: Dane czasowe

Dane czasowe
Dane czasowe

Używam taniego urządzenia GPS, aby uzyskać dokładne dane o czasie, które automatycznie uruchomią się ponownie po awarii zasilania. Mam kilka jednostek GPS (bez wyświetlaczy), które wyświetlają standardowe zdania NMEA, ale najmniejszą i najtańszą z posiadanych jednostek jest NEO-6M. Moduł NEO-6M jest łatwy do podłączenia do Arduino, ponieważ wykorzystuje port szeregowy na poziomie TTL. Jedyną prawdziwą różnicą jest to, że standard NMEA określa szybkość transmisji szeregowej 4800, ale NEO-6M domyślnie ma 9600 bodów. Możesz uruchomić darmowy program „u-center”, aby zmienić szybkość transmisji, ale po prostu zostawiłem go z ustawieniami fabrycznymi. Istnieje również darmowy program narzędziowy o nazwie GPSInfo (wydany przez Globalsat), który jest bardzo przydatny do przeglądania informacji GPS na komputerze. Możesz podłączyć urządzenie GPS do standardowego kabla USB do TTL w celu sprawdzenia go lub skonfigurowania za pomocą komputera. Należy pamiętać, że układ GPS w module faktycznie działa z napięciem 3,3 wolta (za pośrednictwem wbudowanego regulatora napięcia), więc jeśli chcesz podłączyć się do portu RXD, powinieneś obniżyć poziom z 5 woltów. Port TXD może łączyć się bezpośrednio z Arduino lub komputerem PC.

Krok 6: Strefy czasowe

Wyświetlanie czasu GPS jest łatwe, o ile chcesz wyświetlać tylko UTC (Universal Time Coordinated). Zdania NMEA składają się ze znaków ASCII, które mogą być bezpośrednio wyprowadzane na wyświetlacz LCD. Część czasu ma format GGMMSS. FF (godziny, minuty, sekundy i ułamki sekund). Dla naszego zegara część ułamkowa nie jest przydatna, więc wszystko, z czym musimy się zmierzyć, to sześć znaków. Problem polega na tym, że musisz przekonwertować na swój czas lokalny i 12-godzinny format AM/PM, jeśli chcesz. Ale czasami to problemy sprawiają, że życie jest interesujące, więc o to właśnie chodzi w tej części oprogramowania.

Jeśli chodzi o strefy czasowe, możesz pomyśleć, że byłoby ich po prostu 24, z czego 12 na wschód od lokalizacji UTC (strefy +) i 12 z nich na zachód od lokalizacji UTC (strefy -). W rzeczywistości jest kilka dziwnych, które są ułamkami godzin i kilka, które przekraczają 12-godzinny „limit”. Jeśli zdarzy ci się mieszkać w jednym z tych obszarów, przepraszam, ponieważ moje oprogramowanie uwzględnia tylko strefy całodobowe. Niektórzy z nas korzystają z czasu letniego przez część roku, ale nie jest to automatycznie uwzględniane w oprogramowaniu. Wymagałoby to tabeli przeglądowej przyszłych dat, dodatkowej złożoności oprogramowania i konieczności aktualizacji oprogramowania, gdyby zmieniły się tygodnie w roku przełączenia. Zamiast tego sprzęt wykorzystuje chwilowy przełącznik stykowy, aby umożliwić łatwe ustawienie strefy czasowej (przesunięcie UTC).

Krok 7: Schemat

Schematyczny
Schematyczny

Schemat pokazano powyżej i zawiera połączenia dla 4-bitowego interfejsu 1602 LCD. Dane szeregowe z odbiornika RF są na cyfrowych poziomach logicznych, więc są podłączone bezpośrednio do jednego z pinów wejściowych danych Arduino. Pin jest skonfigurowany w oprogramowaniu do wykonywania funkcji przerwania przy zmianie, dzięki czemu możemy mierzyć szerokości impulsów. Wyjście GPS TXD jest bezpośrednio połączone z wejściem Arduino RX.

Używane są dwa przełączniki. Jak wspomniano wcześniej, chwilowy przełącznik stykowy umożliwia ustawienie przesunięcia UTC. Przełącznik można nacisnąć w dowolnym momencie, aby wejść w tryb ustawień. Początkowo wyświetlacz pokaże nieprawidłowe przesunięcie UTC wynoszące „+77”. Zapoznaj się z sekcją „Oprogramowanie zegara”, aby uzyskać instrukcje dotyczące ustawiania przesunięcia UTC.

Drugi przełącznik to prosty włącznik/wyłącznik. W pozycji „off” czas będzie wyświetlany w formacie 12-godzinnym (AM/PM), a w pozycji „on” czas będzie wyświetlany w formacie 24-godzinnym. Ten przełącznik można zmienić w dowolnym momencie, aby przełączać się między formatami.

Jeśli wymagana jest tylko funkcja zegara, nie trzeba podłączać modułu odbiornika RF. Jeśli potrzebna jest tylko funkcja pogody, nie trzeba podłączać GPS i dwóch przełączników.

Krok 8: Oprogramowanie LCD

Zwykle używam jednego z dwóch typów interfejsów LCD. Jeden to standardowy 4-bitowy interfejs, a drugi to 3-przewodowy interfejs, który wykorzystuje rejestr przesuwny. Zaprojektowałem ten interfejs, kiedy pracowałem z małymi mikrokontrolerami PIC, które miały ograniczoną liczbę pinów I/O. Użyłem 4-bitowego interfejsu do tego projektu, ale mam własny plik dołączany LCD zamiast korzystania z ogólnej biblioteki Arduino LCD. Zmniejsza to zużycie pamięci i złożoność kodu, a także pozwala mi dostosować kod do konkretnych projektów, takich jak ten.

Krok 9: Oprogramowanie zegara

Odbiornik GPS wyprowadza standardowe zdania NMEA-0183, które są ciągami ASCII, które zawierają różne informacje. Do tej aplikacji wybrałem zdanie GGA, aby uzyskać informacje o czasie, ponieważ jest to zdanie, którego użyłem w poprzednim projekcie GPS. Pola informacji w zdaniach NMEA są oddzielone przecinkami, więc po wykryciu nagłówka zdania GGA, oprogramowanie normalnie policzy przecinki i wywoła odpowiednią procedurę dla każdego żądanego pola informacji GPS. Tutaj potrzebna jest tylko informacja o czasie, która znajduje się w polu po pierwszym przecinku, więc nie jest potrzebne liczenie.

Sześć cyfr czasu (GGMMSS) jest buforowanych, a następnie przetwarzanych po odebraniu wszystkich z nich. GPS może na początku wysyłać pewne niekompletne komunikaty, aby procedura buforowania sprawdzała, czy każdy znak jest wartością numeryczną ASCII. Jeśli zostanie odebrany zły znak, wiadomość jest odrzucana. Może się to również zdarzyć w rzadkich przypadkach podczas normalnej pracy, szczególnie jeśli komunikacja przez port szeregowy nieco spadnie. Widziałem to tylko raz i jedyne, co się wydarzyło, to to, że czas zatrzymał się na sekundę, a potem skoczył o dwie sekundy zamiast jednej.

Jeśli oprogramowanie jest skonfigurowane do wyświetlania tylko czasu, pierwsza linia wyświetlacza LCD wyświetli czas lokalny, a druga linia wyświetli UTC. W przypadku UTC oprogramowanie po prostu wysyła znaki ASCII bezpośrednio do procedury wyświetlania, z odpowiednio wstawionymi dwukropkami (:).

Aby przekonwertować czas UTC na czas lokalny, należy zastosować przesunięcie UTC (strefa czasowa). Ponieważ czas UTC z GPS jest w formacie ASCII, oprogramowanie konwertuje znaki godziny ASCII na dziesiętne, a następnie dodaje przesunięcie UTC. Przesunięcie UTC jest przechowywane jako dodatnia wartość BCD z bitem znaku, więc jest najpierw konwertowana na wartość całkowitą, a następnie negowana, jeśli bit znaku jest ustawiony. Po obliczeniu wartości godziny czasu lokalnego, tabela przeglądowa jest używana do konwersji na BCD, a następnie BCD jest konwertowany z powrotem do ASCII w celu wyświetlenia. Tabela przeglądowa musi obsługiwać format 24-godzinny UTC oraz +/-12 stref czasowych. W tym celu czasy UTC od 0000 do 2300 zajmują środkowe 24 wpisy w tabeli z 12 wpisami przed i 12 wpisami po, aby uwzględnić strefy czasowe. Jedna tabela jest w formacie 12-godzinnym, więc dodałem również tabelę przeglądową dla części wyświetlacza AM/PM. Druga tabela jest w formacie 24-godzinnym. Jak wspomniano wcześniej, włącznik/wyłącznik umożliwia wybór formatu 12-godzinnego lub 24-godzinnego.

Strefa czasowa jest pobierana z pamięci EEPROM podczas inicjalizacji i krótko wyświetlana. Jeśli nie został ustawiony przynajmniej raz, wywoływana jest procedura ustawiania. Procedurę ustawień można również wywołać w dowolnym momencie, naciskając przełącznik styku chwilowego. Procedura ustawień zainicjuje wyświetlacz do „UTC OFFSET +77”. Krótkie naciśnięcie przełącznika zmieni wartość na „-00”. Jeśli wymagana jest dodatnia strefa czasowa, kolejne krótkie naciśnięcie zmieni wartość na „+00”. Długie naciśnięcie (> 1 sekunda) spowoduje przejście trybu ustawień do następnego kroku. W tym momencie każde krótkie naciśnięcie zwiększy wartość czasu maksymalnie do 12. Po osiągnięciu żądanej strefy czasowej naciśnij i przytrzymaj przełącznik przez ponad 1 sekundę, a następnie zwolnij go. Oprogramowanie zapisze następnie wartość UTC w EEPROM i na krótko wyświetli „OFFSET SAVED”. Jeśli popełnisz błąd podczas wejścia, po prostu wyjdź, a następnie ponownie naciśnij przełącznik, aby go zresetować.

NEO-6M nie wymaga dobrego ustalenia pozycji w celu wyprowadzenia czasu, więc powinien wysyłać komunikaty, gdy tylko otrzyma jednego satelitę. Do tego czasu na wyświetlaczu pojawi się napis „BRAK DANYCH”.

Krok 10: Oprogramowanie pogodowe

Mikrokontroler PIC ma możliwość włączania i wyłączania timera za pomocą zewnętrznego impulsu. Ten sam impuls wejściowy może być również użyty jako zewnętrzne przerwanie sygnalizujące odczyt czasu trwania impulsu. Arduino nie ma takiej dokładnej możliwości, więc użyłem funkcji przerwania przy zmianie. Na jednej krawędzi impulsu wiadomości RF bieżący czas w mikrosekundach jest zapisywany przez procedurę obsługi przerwań. Na przeciwległej krawędzi obliczany jest upływ czasu w celu określenia szerokości impulsu.

Oprogramowanie posiada definicję „DEBUG”, która pozwala na wyświetlanie surowego formatu danych odbieranych komunikatów. Istnieje również definicja określająca pin wejściowy Arduino dla strumienia szeregowego z odbiornika RF. Oprogramowanie jest skonfigurowane do obliczania odpowiednich ustawień rejestru przerwań przy zmianie w oparciu o tę definicję. Obliczenia działają tylko dla cyfrowych pinów Arduino. Zamiast tego można użyć pinu analogowego, ale wymagałoby to twardego kodowania wartości rejestru.

Obsługa przerwań określa, czy przechwycona liczba jest wystarczająco długa, aby być impulsem startowym. Jak wspomniano wcześniej, przerwa między wieloma wiadomościami wynosi 2 ms, więc tego właśnie szuka oprogramowanie. Ze względu na cały ruch 433 MHz, wstępne skanowanie w oprogramowaniu zapewnia, że zmierzony czas wynosi co najmniej 1,8 ms, ale nie więcej niż 2,4 ms. Po wykryciu startu oprogramowanie szuka bitów synchronizacji (600us) i liczy, aby upewnić się, że zostały odebrane cztery z nich. Po przejściu tych testów oprogramowanie szuka właściwych czasów bitowych 200us i 400us.

Odebrane bity są formowane w bajty, a każdy bajt jest zapisywany. Po odebraniu siedmiu bajtów suma kontrolna wiadomości jest weryfikowana przed zezwoleniem na dalsze przetwarzanie. Jeśli mają być wyprowadzane surowe bajty (tryb debugowania), to bajty są konwertowane na znaki ASCII i wysyłane na wyświetlacz LCD. Jeśli pożądane są wyjścia wilgotności i temperatury, to wykonywane są odpowiednie konwersje.

Dwa bajty danych Celsjusza w komunikacie RF są łączone ze sobą, tworząc wartość 11-bitową. Dolna część jest przesunięta w lewo o jeden bit, aby wyeliminować bit parzystości i wyrównać go z bitami w górnej części. Dwa bajty są formowane w 16-bitową zmienną słowa, a następnie całość jest przesuwana w prawo o jeden bit, aby uzyskać końcowe wyrównanie bitów. Słowo zmienna jest następnie konwertowana na zmienną zmiennoprzecinkową do obliczeń matematycznych.

Jedną z wielkich zalet używania C++ na Arduino w porównaniu z językiem asemblera na PIC jest uproszczenie obliczeń matematycznych. Jak wspomniano wcześniej, konwersja w stopniach Celsjusza wynosi (C/10) -100. Wynik jest konwertowany na ciąg i wysyłany do wyświetlacza LCD w celu wyświetlenia. Obliczenie w stopniach Fahrenheita to (C * 1,8) + 32. Wynik jest ponownie konwertowany na łańcuch i wysyłany na wyświetlacz LCD w celu wyświetlenia. W obu przypadkach konwersja String zawiera znak minus (jeśli jest to konieczne) i kropkę dziesiętną. Sprawdza się kropkę dziesiętną, aby upewnić się, że tylko jeden znak po przecinku jest wysyłany na wyświetlacz. To sprawdzenie jest potrzebne, ponieważ ciąg może mieć długość od 3 do 5 znaków.

Mam dwa czujniki AcuRite, więc dodałem sprawdzenie w oprogramowaniu, aby upewnić się, że dane dla jednego nie nadpisują danych dla drugiego, jeśli oprogramowanie jest ustawione tylko na funkcję pogodową. Pierwszy czujnik odebrany po włączeniu wyświetla się w wierszu 1, a drugi w wierszu 2. Używając trybu debugowania, mogę zobaczyć, jaki jest identyfikator dla każdego czujnika, więc mogę zrobić proste sprawdzenie kodu, jeśli tylko chciał przetworzyć dane jednego z nich.

Oprogramowanie monitoruje stan baterii (bajt3) i wyświetla komunikat, jeśli wskazuje niski poziom baterii. Ten komunikat nadpisuje wszystkie inne dane dla tego czujnika.

Krok 11: Wyświetlacze

Wyświetlacze
Wyświetlacze
Wyświetlacze
Wyświetlacze
Wyświetlacze
Wyświetlacze

Oto kilka przykładowych ekranów dla różnych funkcji. Mam kilka innych instrukcji, ale większość moich projektów mikrokontrolerów PIC można znaleźć na mojej stronie internetowej: www.boomerrules.wordpress.com