Arduino (cz. 2) – budujemy stację pogody

W tym odcinku opiszę, jak zbudować prostą stację pogody z zegarem czasu rzeczywistego. Nasze urządzenie będzie dość ubogie, ale przez to proste w wykonaniu i zaprogramowaniu. Będzie ono mierzyć jedynie temperaturę oraz wilgotność oraz wyświetlać na wyświetlaczu naprzemiennie – datę, godzinę oraz temperaturę oraz wilgotność. Do wykonania urządzenia wykorzystamy kilka tanich i powszechnie dostępnych modułów, które można łatwo połączyć i uruchomić. Do budowy urządzenia niezbędne będą także podstawy języka C.

Na początek należy zgromadzić następujące elementy:

  1. Arduino Uno (https://botland.com.pl/arduino-moduly-glowne/1060-arduino-uno-rev3-a000066-8058333490090.html lub https://botland.com.pl/plytki-zgodne-z-arduino-pozostale/11599-velleman-atmega328-uno-modul-kompatybilny-z-arduino-5410329656430.html). Można także poszukać tańszych zamienników na Allegro. Niczym się one nie różnią.
  2.  Czujnik temperatury i wilgotności DHT11 lub DHT22. Proszę zakupić gotowy moduł, nie sam czujnik, bowiem czujnik wymaga dodatkowego rezystora. Moduł ma tylko 3 wyjścia i taki został użyty w tym projekcie  – https://botland.com.pl/czujniki-temperatury/3030-czujnik-temperatury-i-wilgotnosci-dht11-modul-niebieski.html
  3. Wyświetlacz LCD 2×16 koniecznie z modułem I2C – https://botland.com.pl/wyswietlacze-alfanumeryczne-i-graficzne/2351-wyswietlacz-lcd-2×16-znakow-niebieski-konwerter-i2c-lcm1602.html?search_query=wyswietlacz+2×16&results=60
  4. Moduł zegara RTC DS3231 – https://abc-rc.pl/modul-czasu-rtc-ds3231
  5. Przewody połączeniowe typu żeńsko/męski – https://botland.com.pl/przewody-polaczeniowe/1021-przewody-polaczeniowe-zensko-zenskie-20cm-40szt.html

A oto wszystkie zgromadzone elementy:

Zestaw niezbędnych elementów

Po zgromadzeniu podzespołów, należy wszystkie części podłączyć do Arduino UNO.

Podłączenie wyświetlacza LCD

Wyświetlacz posiada 4 piny: zasilanie (5V, masa, SDA oraz SCL).

  • Masę łączymy z dowolnym pinem GND w Arduino,
  • VCC z pinem 5V,
  • SDA z pinem o nazwie A4,
  • SCL z pinem A5.

To wszystko, można teraz wypróbować działanie wyświetlacza. Po podłączeniu Arduino przewodem USB do komputera, wyświetlacz powinien się zaświecić.

Zatrzymajmy się na chwilę, by omówić magistralę I2C, która jest wyprowadzona w Arduino UNO na pinach A4 oraz A5. Do tych pinów (magistrali I2C) można podłączać wiele urządzeń, zaś każde z nich będzie miało własny adres. Dla modułu LCD 2×16 będzie to adres 0x3F lub 0x27.

Po otwarciu Arduino IDE należy utworzyć nowy projekt i wpisać kod programu:

#include <Wire.h>
#include <LCD.h>   
#include <LiquidCrystal_I2C.h>
 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
 
void setup() {
lcd.begin(16,2);   // Inicjalizacja wyświetlacza
 
  lcd.backlight(); // włącz podświetlenie 
  lcd.setCursor(0,0); // Kursor na pozycji 0,0
  lcd.print("Test!!!");
  delay(500);
  lcd.setCursor(0,1); // Kursor w pozycji 0,0
  lcd.print("Witamy");
}
 
void loop() {
 lcd.backlight(); // włącz podswietlenie
   delay(2000);
lcd.noBacklight(); // wyłącz podświetlenie
delay(1000);
}

Po wklejeniu kodu prawdopodobnie nie zostanie on poprawnie skompilowany i wyświetli się błąd:

error: LiquidCrystal_I2C.h: No such file or directory
compilation terminated.
exit status 1
LiquidCrystal_I2C.h: No such file or directory

Kompilator zachował się jak najbardziej właściwie,  bowiem nie została dodana biblioteka LiquidCrystal, odpowiadająca za sterowanie wyświetlaczem. Należy zatem pobrać bibliotekę z załącznika pod tym artykułem i dodać ją do projektu (szkicu): w menu Szkic->Dołącz bibliotekę->Dodaj bibliotekę ZIP i wskazać pobrany skompresowany plik biblioteki LiquidCrystal_I2C-1.1.2.zip. Tym razem kompilacja się powiedzie, zatem można zaprogramować układ.

Jeśli wystąpią problemy z programowaniem Arduino i problemy nie dotyczą błędu w programie, należy skonfigurować Arduino IDE dla modułu UNO:

  • Narzędzia->płytka: wybierz: Arduino/Genuino UNO
  • Narzędzia->port: właściwy port COM lub inny port w Mac OS/Linux (Arduino)
  • Narzędzia->programator: AVRISP mkII

Najważniejsze elementy biblioteki do obsługi ekranu:

  • lcd.setCursor(x,x) – ustawia kursor na określoną w nawiasie pozycję
  • lcd.print(„xxxxx”) – wyświetla na ekranie tekst xxxxx
  • lcd.clear(); – czyści ekran
  • lcd.backlight() – załącza podświetlenie
  • lcd.noBacklight() – wyłącza podświetlenie

Podłączenie czujnika temperatury DHT11 lub DHT11

Wybór typu czujnika zależy od zakresów parametrów, które należy mierzyć. W wersji podstawowej i tańszej wystarczy wersja DHT11, jednakże w przypadku, gdy zajdzie potrzeba badania szerszego zakresu, należy wybrać wersję DHT22. Zasada działania czujników polega na wykorzystaniu komunikacji i synchronizacji poprzez interfejs szeregowy przy wykorzystaniu formatu danych Single-bus.  Jeden cykl komunikacji trwa około 4ms, zaś pin, do którego podłączony jest czujnik jest przełączany podczas pomiaru jako wejście i wyjście. W tym projekcie wykorzystałem DHT11 gdyż był po prostu tańszy. Czujniki występują jako moduł oraz jako sam czujnik (obrazek poniżej).

Po lewej – gotowy moduł wykorzystany w tym projekcie, po prawej – „goły” czujnik

Można zakupić sam czujnik, jednak należy go wówczas podłączyć do Arduino w następujący sposób:

źródło: http://mikrokontroler.pl/2014/10/06/aplikacja-arduino-czujniki-wilgotnosci-i-temperatury-dht11-i-dht22/

Jeśli zaś zakupimy gotowy moduł, to jego podłączenie odbywa się bez użycia lutownicy:

  • + do zasilania 5V w Arduino
  • do dowolnego wyjścia masy GND
  • out do 2 2 (digital).

Choć wersja DHT22 jest bardziej precyzyjna, należy brać pod uwagę, że żaden z tych czujników nie nadaje się do warunków laboratoryjnych. Świadczy o tym choćby tolerancja odczytu rzędu ±1, błąd powtarzalności oraz upływność, która w skali roku mieści się w zakresie ±0,3°C. Jeśli chodzi o pomiar wilgotności, to mieści się ona w zakresie 0 do 99,9%RH z dokładnością ±3%RH oraz z powtarzalnością ±1%RH. Producent zaleca, by długość przewodu od mikrokontrolera do czujnika nie przekroczyła 20m oraz informuje, by pierwszy pomiar po włączeniu zasilania dokonywać po upłynięciu 1 sekundy.

Podstawowe parametry sensorów DHT11 i DHT22

DHT11 DHT22
Napięcie zasilania 3…5,5 V 3,3…6 V
Pomiar temperatury Zakres 0…+50°C -40…+80°C
Rozdzielczość 1°C 0,1°C
Dokładność 1°C 0,2°C
Pomiar wilgotności Zakres 20…90% 0…100%
Rozdzielczość 1% 0,1%
Dokładność 4% 2%
Czas pomiaru 1 s 0,5 s

Po podłączeniu czujnika DHT11, należy wpisać program:

#include <Wire.h>   
#include <LCD.h>
#include <LiquidCrystal_I2C.h> 
#include <dht.h>
#define DHTPIN 2 // PIN 2 - czujnik DHT11
 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
 
dht DHT;
 
void setup() {
  lcd.begin(16,2);   // Inicjalizacja wyświetlacza
  lcd.backlight(); // włącz podwietlenie 
  delay(1000);
}
 
void loop() {
 int readData = DHT.read11(DHTPIN); 
    lcd.clear(); // Wyczysc
    lcd.setCursor(0,0); // Ustawienie kursora w pozycji 0,0 (pierwszy wiersz, pierwsza kolumna)
    lcd.print("Temper: ");
    lcd.print(DHT.temperature);
    lcd.print((char)223);
    lcd.print("C");
    lcd.setCursor(0,1); //Ustawienie kursora w pozycji 0,1 (drugi wiersz, pierwsza kolumna)
    lcd.print("Wilgot: ");
    lcd.print(DHT.humidity);
    lcd.print("%");
    delay(2000);
}

Po wgraniu programu do mikrokontrolera na wyświetlaczu powinny się pojawić informacje o temperaturze oraz wilgotności. Jeśli zamiast tego, ponownie zostanie wyświetlony komunikat o błędzie, należy jak poprzednio dodać bibliotekę dht.h, lecz tym razem za pomocą opcji Szkic->Dodaj bibliotekę->Zarządzaj bibliotekami i wyszukać bibliotekę DHT.

Działające urządzenie

Zegar czasu rzeczywistego DS3231

Ostatnim elementem jest podłączenie modułu zegara DS3231, który będzie wyświetlał na wyświetlaczu aktualną datę oraz czas. Moduł zegara łączymy następująco:

  • GND – do dowolnego pinu GND w Arduino
  • VCC – do pinu zasilania 3.3V
  • SDA – do pinu A4
  • SCL – do pinu A5

Jak można zauważyć, piny A4 i A5 są już wykorzystane przez wyświetlacz działający na magistrali I2C. Ale jak pisałem wcześniej, moduły można łączyć równolegle, zaś będą one dostępne pod innymi adresami. Moduł DS3231 posiada wyjścia/wejścia po obu stronach, zatem linie SDA i SCL wyświetlacza można podpiąć po prostu do tego modułu zamiast podpinać po dwa przewody do Arduino. Na pewno spowoduje to nieco mniejszy „chaos kabelkowy”. W przypadku DS3231, będzie on dostępny prawdopodobnie pod adresem 0x68, ale o to nie należy się martwić, bowiem wszystko wykona za nas biblioteka. Nie będzie też pomiędzy dwoma modułami żadnego konfliktu. W niektórych przypadkach niezbędne niezbędne jest wykorzystanie rezystorów podciągających, jednakże testy wykazały, że moduły pracują prawidłowo bez nich (być może moduły te mają już rezystory zamontowane fabrycznie). Po podłączeniu wystarczy wgrać do mikrokontrolera program:

#include <DS3231.h>
#include <Wire.h>   
#include <LCD.h>
#include <LiquidCrystal_I2C.h> 
#include <dht.h>
 
#define DHTPIN 2 // PIN 2 - czujnik DHT11
 
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
DS3231  rtc(SDA, SCL);
dht DHT;
 
void setup() {
  Serial.begin(9600);
  rtc.begin();
  lcd.begin(16,2);   // Inicjalizacja wyświetlacza
  lcd.backlight(); // włącz podświetlenie
  //rtc.setDOW(FRIDAY);     // Ustaw dzień tygodnia
  //rtc.setTime(15, 2, 0);  // Ustaw czas 12:00:00 (format 24 godziny)
  //rtc.setDate(26, 10, 2018); // Dzień, miesiąc, rok
  delay(1000);
}
 
void loop() {
 int readData = DHT.read11(DHTPIN); 
    lcd.clear(); // Wyczysc
    lcd.setCursor(0,0); // (pierwszy wiersz, pierwsza kolumna)
    lcd.print("Temper: ");
    lcd.print(DHT.temperature);
    lcd.print((char)223);
    lcd.print("C");
    lcd.setCursor(0,1); // (drugi wiersz, pierwsza kolumna)
    lcd.print("Wilgot: ");
    lcd.print(DHT.humidity);
    lcd.print("%");
    delay(2000);
    lcd.clear(); // Wyczysc
    lcd.setCursor(0,0);
    lcd.print("Time: ");
    lcd.print(rtc.getTimeStr());
    lcd.setCursor(0,1);
    lcd.print("Date: ");
    lcd.print(rtc.getDateStr());
    delay(2000);
}

Jeśli wszystko zostało zmontowane prawidłowo, na wyświetlaczu pojawić się powinna data i czas, a następnie temperatura i wilgotność.

Uwaga – choć moduł DS3231 zawiera baterię podtrzymującą datę i czas, należy przy pierwszym użyciu programu przesłać aktualną datę oraz czas do modułu. Służą do tego 3 linijki w naszym programie (należy je odkomentować i podać właściwe parametry):

rtc.setDOW(FRIDAY); // Ustaw dzień tygodnia
rtc.setTime(15, 2, 0); // Ustaw czas 12:00:00 (format 24 godziny)
rtc.setDate(26, 10, 2018); // Dzień, miesiąc, rok

Następnie przesłać program do Arduino. Po uruchomieniu i upewnieniu się, że wyświetla się prawidłowa data oraz czas, ponownie należy te 3 linie zakomentować i ponownie przesłać program do Arduino. Tym razem będzie wyświetlany poprawny czas, bowiem zegar DS3231 posiada baterię podtrzymującą.

Gotowe urządzenie

Jeśli wymagane jest, by oprócz wyświetlacza, informacje pojawiały się także na porcie szeregowym, co umożliwi np. pobieranie ich przez port USB do komputera, wszędzie, gdzie wyświetlana jest wartość na wyświetlaczu, można przesłać ją dodatkowo na port szeregowy dodając komendy:

Serial.println(DHT.temperature);
Serial.println(DHT.humidity);
Serial.println(rtc.getTimeStr());
Serial.println(rtc.getDateStr());

Np. modyfikując funkcję loop() w następujący sposób:

void loop() {
 int readData = DHT.read11(DHTPIN); 
    lcd.clear(); // Wyczysc
    lcd.setCursor(0,0); // (pierwszy wiersz, pierwsza kolumna)
    lcd.print("Temper: ");
    lcd.print(DHT.temperature);
    lcd.print((char)223);
    lcd.print("C");
    lcd.setCursor(0,1); // (drugi wiersz, pierwsza kolumna)
    lcd.print("Wilgot: ");
    lcd.print(DHT.humidity);
    lcd.print("%");
    delay(2000);
    lcd.clear(); // Wyczysc
    lcd.setCursor(0,0);
    lcd.print("Time: ");
    lcd.print(rtc.getTimeStr());
    lcd.setCursor(0,1);
    lcd.print("Date: ");
    lcd.print(rtc.getDateStr());
    delay(1200);
    Serial.println(DHT.temperature);
    Serial.println(DHT.humidity);
    Serial.println(rtc.getTimeStr());
    Serial.println(rtc.getDateStr());
    delay(1200);  
}

Opóźnienia delay(1200) są konieczne, bowiem czujnik może odczytywać dane raz na sekundę. Oczywiście program można zoptymalizować, wprowadzając zmienne, lecz to pozostawiam czytelnikom.

Po wgraniu programu do Arduino, wystarczy otworzyć monitor portu szeregowego, by ujrzeć pobrane parametry (obrazek poniżej). A dzięki temu, można połączyć Arduino z komputerem.

Na koniec ciekawostka: poniższy program można wgrać do Arduino i w monitorze portu szeregowego odczytać wszystkie znalezione adresy urządzeń podpiętych do magistrali I2C. Z pewnością się przyda podczas rozbudowy urządzenia o kolejne moduły, gdy trzeba będzie zainicjalizować moduł podając jego adres:

#include <Wire.h>   
void setup()  
{
 Wire.begin();
 
 Serial.begin(9600);
 while(!Serial);
 Serial.println("\nI2C Skanowanie");
}
 
void loop() 
{
 byte error, address;
  int nDevices;
  Serial.println("Szukam...");
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0)
    {
      Serial.print("Znaleziono urządzenie pod adresem 0x");
      if (address<16)
      Serial.print("0");
      Serial.println(address,HEX);
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Błąd");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("Brak podłączonych urządzeń do magistrali I2C\n");
  else
    Serial.println("gotowe\n");
  delay(5000);          
}

To wszystko na dziś. Mam nadzieję, że pomogłem nieco w poznawaniu tajników Arduino. Przykładowy kod można dowolnie rozbudować, dodając nowe funkcjonalności, lecz to pozostawiam wyobraźni czytelników.

1592total visits,7visits today

Tagi .Dodaj do zakładek Link.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

12 + = 18

This site uses Akismet to reduce spam. Learn how your comment data is processed.