Serwisy partnerskie:
Close icon
Serwisy partnerskie

Kurs Arduino odcinek 4 - czujnik BME280 (pomiar ciśnienia, wilgotności i temperatury)

W czwartym odcinku kursu wskoczymy w głęboką wodę: wykorzystamy nowoczesny czujnik BME280, który mierzy trzy ważne wielkości: ciśnienie, wilgotność i temperaturę. Wykorzystamy gotowy maleńki chiński moduł, pokazany na fotografii 1.
Article Image
1. Kurs Arduino: wprowadzenie 2. Kurs Arduino odcinek 1 - co to jest i jak zacząć? (sprzęt, schematy, programowanie) 3. Kurs Arduino odcinek 2 - termometry: 'diodowy', pokojowy oraz 'scalony' analogowy 4. Kurs Arduino odcinek 3 - moduł wyświetlacza LCD (HD44780) 5. Kurs Arduino odcinek 4 - czujnik BME280 (pomiar ciśnienia, wilgotności i temperatury) 6. Kurs Arduino odcinek 5 - biblioteki do trzyfunkcyjnego czujnika BME280 7. Kurs Arduino odcinek 6 - wykorzystanie łącza I2C (TWI) 8. Kurs Arduino odcinek 7 - wykorzystanie łącza SPI (karty pamięci, MAX31865, MAX31855) 9. Kurs Arduino odcinek 8 - wykorzystanie czujnika dwutlenku węgla (MH-Z19) 10. Kurs Arduino odcinek 9 - wykorzystanie modułów do odmierzania czasu 11. Kurs Arduino odcinek 10 - wykorzystanie czujników temperatury (DS18B20) 12. Kurs Arduino odcinek 11 - budowa loggera (rejestratora danych) 13. Kurs Arduino odcinek 12 - rejestracja i prezentacja danych oraz obsługa karty SD 14. Kurs Arduino odcinek 13 - rejestracja danych (wykorzystanie modułu OpenLog) 15. Kurs Arduino odcinek 14 - czym zastąpić płytkę Arduino Uno? 16. Kurs Arduino odcinek 15 - budowa rejestratora (chiński klon Arduino Pro Mini) 17. Kurs Arduino odcinek 16 - problemy z kwadratowym modułem Strong 18. Kurs Arduino odcinek 17 - czujniki do pomiaru wilgotności gleby (instalacja, konfiguracja) 19. Kurs Arduino odcinek 18 - protokół MODBUS i łącze RS-485 20. Kurs Arduino odcinek 19 - wyświetlacze od podstaw (matrycowe, 7-segmentowe, MAX7219) 21. Kurs Arduino odcinek 20a - wyświetlacze matrycowe i biblioteki MD_MAX 22. Kurs Arduino odcinek 20b - przyciski i biblioteki do obsługi wyświetlaczy 23. Kurs Arduino odcinek 20c - biblioteki do obsługi wyświetlaczy graficznych 24. Kurs Arduino odcinek 21 - moduł wyświetlacza OLED 25. Kurs Arduino odcinek 22 - moduł wyświetlacza 1,3 cala 26. Kurs Arduino odcinek 23 - przygotowanie bitmap do wyświetlania 27. Kurs Arduino odcinek 24 - omówienie fontu podstawowego (Adafruit GFX) 28. Kurs Arduino odcinek 25 - font podstawowy biblioteki Adafruit GFX 29. Kurs Arduino odcinek 26 - wykorzystanie bitmapowych fontów GFX 30. Kurs Arduino odcinek 27 - polskie znaki w glcdfont.c 31. Kurs Arduino odcinek 28 - zmiana ulepszonych fontów GFX

Dołączenie go do płytki Arduino jest banalnie proste – wystarczą cztery kabelki, jak na fotografii 2.

Czujnik ten ma interfejs I2C (I2C), który jest w pełni kompatybilny z TWI (Two Wire Interface) oraz SMBus. Procesor ATmega328P, a więc i Arduino Uno, ma wbudowany sprzętowy interfejs TWI (I2C). Linia SDA to nóżka A4 Arduino, linia SCL to nóżka A5, które są też wyprowadzone na dodatkowe piny w pobliżu pinu AREF jak pokazuje rysunek 3.

Fot.1 Chiński moduł z czujnikiem BME280
Fot.2 Podłączenie modułu do płytki Arduino

Potrzebny moduł czujnika można kupić w kraju za 20...30zł plus koszty przesyłki, albo ściągnąć z Chin, gdzie kosztuje około 3 dolarów (ok. 10zł) z darmową przesyłką (3...4 tygodnie czekania).

Tytułem wyjaśnienia warto dodać, że oprócz „potrójnego” czujnika BME280, dostępne są też pokrewne „podwójne”, oznaczone BMP, które nie mierzą wilgotności, a tylko ciśnienie i temperaturę. Nowsza wersja BMP280 jest zdecydowanie bardziej dokładna niż wcześniejsza dość popularna BMP180. Zasady wykorzystania „podwójnych” BMP280/180 są bardzo podobne jak omawianego „potrójnego” BME280.

Rys.3 Wyprowadzenia SDA i SCL

I jeszcze jeden ważny szczegół: same czujniki BMP i BME, w tym BME280, nie mogą być zasilane napięciem wyższym niż 3,6V. My bez obaw zasililiśmy moduł z fotografii 1 i 2 napięciem 5V gdyż oprócz układu BME280, na drugiej stronie płytki (fotografia 4) zawiera on stabilizator 3,3V oraz układ translacji poziomów 5V/3,3V.

Fot.4 Druga strona płytki modułu

Rysunek 5 pokazuje schemat wykorzystanego modułu BME280. W dwukierunkowym translatorze poziomów (który był wyczerpująco omówiony w ramach rozwiązania konkursu Jak to działa? w EdW 4/2018 str 69...71) pracują dwa tranzystory MOSFET typu BSS138. Są dostępne wersje w podwójnej obudowie sześcionóżkowej i taka wersja występuje w wykorzystanym module. Warto wiedzieć, że na rynku są też inne moduły z czujnikiem BME280 i pokrewnymi.

Rys.5 Schemat wykorzystanego modułu BME280

Fotografia 6 pokazuje wersję produkowaną przez Adafruit (w kraju dostępna za około 100zł), gdzie schemat jest praktycznie taki sam, ale zastosowano dwa oddzielne MOSFET-y. Na rynku są też inne moduły z kostkami BME280 i BMP180/280, które nie zawierają stabilizatora i translatora poziomów. Przykład z fotografii 7 to „podwójny” moduł z BMP280, dostępny też w sklepie AVT (kod handlowy: ARD-7206, cena poniżej 15zł).

Takie moduły, zawierające „goły czujnik”, nie mogą pracować w obwodach zasilanych napięciem 5V! Przy ich współpracy z Arduino Uno trzeba wykorzystać dostępne na płytce zasilanie 3,3V i potrzebny jest translator poziomów.

Fot.6 Moduł z kostką BME280 (Adafruit)
Fot.7 'Podwójny' moduł z BMP280

W każdym przypadku aby w Arduino wykorzystać interfejs TWI (I2C), potrzebna jest też biblioteka, np. zawarta w pakiecie Arduino IDE biblioteka o niefortunnej nazwie Wire (niefortunnej, bowiem bardziej kojarzy się z interfejsem 1-Wire, niż z I2C i z TWI – Two Wire Interface).

W naszym przypadku nie musimy mieć jakiejkolwiek wiedzy o interfejsie I2C, ani o drobnych różnicach między I2C oraz TWI i SMBus/PMBus; nie trzeba też niczego instalować. Trzeba natomiast zainstalować dodatkową bibliotekę, która obsłuży „podtrójny” czujnik BME280.

Nie musimy szukać takiej biblioteki „na piechotę”. W tym celu w pakiecie Arduino możemy wybrać: Szkic – Dołącz bibliotekę – Zarządzaj bibliotekami (Sketch – Include Library – Manage Libraries) według rysunku 8. W okienko wyszukiwania wpisujemy BME280 i, jak pokazuje rysunek 9, po chwili mamy do dyspozycji sześć różnych bibliotek.

Rys.8 Wyszukiwanie biblioteki
Rys.9 Dostępne biblioteki

Ja na początek zainstalowałem wskazaną czerwonymi strzałkami bibliotekę Tylera Glenna, ponieważ realizuje ona dodatkowo interesujące mnie obliczenia „środowiskowe” (m.in. punktu rosy i wilgotności bezwzględnej). Po kliknięciu „More Info” instalujemy domyślną, najnowszą dostępną tam wersję (2.3.0).

Od tej chwili w pakiecie Arduino dostępna jest nie tylko sama biblioteka, ale też gotowe przykładowe szkice – programy. Znajdziemy je wybierając Plik – Przykłady (File – Examples) i po przewinięciu listy, na samym dole: BME280, gdzie mamy szereg przykładów. Wybieramy gotowy szkic BME_280_I2C_Test (rysunek 10).

Otwieramy w komputerze monitor szeregowy (Ctrl+Shift+M) i zgodnie z ustawieniami w szkicu, zmieniamy prędkość łącza Serial z 9600 na 115200 – rysunek 11.

Rys.10 Wybór szkicu
Rys.11 Zmiana prędkości łącza Serial

Kompilujemy program i notujemy, że program zajął 34%, czyli jedną trzecią pamięci FLASH i 32% pamięci RAM – rysunek 12.

Gdy wgramy program do procesora, na konsoli monitora zobaczymy wyniki pomiaru jak na rysunku 13. Po chuchnięciu na czujnik temperatura i wilgotność zdecydowanie rosną, jak pokazuje rysunek 14, co potwierdza, że czujnik jest sprawny. REWELACJA! Dosłownie w ciągu kilku minut zrealizowaliśmy stację meteo!

Rys.12 Program po skompilowaniu
Rys.13 Wyniki pomiarów

Zainstalowana biblioteka BME280 oferuje też dodatkowe możliwości.

Wróć do przykładów z rysunku 10 i otwórz gotowy program – szkic Environment_Calculations.ino. Gdy go uruchomisz, rozszerz okno monitora, bo wypisuje on wiele dalszych parametrów wyliczonych na podstawie dokonanych pomiarów, jak pokazuje rysunek 15.

Rys.14 Wyniki pomiarów

I tak oprócz temperatury, wilgotności względnej i ciśnienia, w oknie monitora mamy wysokość (Altitude), wyliczoną na postawie aktualnego ciśnienia, Dew Point, czyli tak zwany punkt rosy oraz ciśnienie przeliczone na wartość na poziomie morza.

Wyliczenia punktu rosy wyrażone w stopniach Celsjusza są miarodajne i absolutne (w sumie jest to parametr bardziej wartościowy i przydatny w praktyce, niż podawana w procentach wartość wilgotności względnej: % RH). Natomiast obliczenia wysokości i przeliczonego ciśnienia są przykładowe i należałoby je dostosować do konkretnych warunków, zmieniając w programie pewne parametry.

Rys.15 Różne wykorzystanie informacji z czujnika BME280

W każdym razie rysunek 15 udowadnia, że informacje z czujnika BME280 można wykorzystać w różny sposób, także do budowy wysokościomierza (altimetru), co może być przydatne nie tylko w modelarstwie lotniczym, ale też na przykład... w grach. Z uwagi na ogromną rozdzielczość pomiaru ciśnienia, można wykrywać zmiany wysokości nawet rzędu centymetrów! Wtedy trzeba zastosować uśrednianie i filtrowanie pomiarów. Te szczegóły wykraczają jednak poza ramy tego odcinka kursu.

Zachęcam Cię do przeanalizowania kodu w tych dwóch wykorzystanych gotowych plikach .ino. Zasadniczo nie jest on trudny do analizy, ale zastosowano specyficzny sposób wyprowadzania danych przez łącze szeregowe do konsoli komputera. Kwestiami tymi będziemy zajmować się później. W programach występują też inne zagadkowe szczegóły (choćby obecność w zmiennych float "wartości" NAN, nie reprezentujących wartości liczbowych), które mogą namącić w głowie. A na razie spróbujmy napisać własny program prościutkiej stacji meteo, żeby opanować podstawowe sposoby korzystania z czujnika BME280.

Złóż układ według rysunku 16. Do zestawu z poprzedniego odcinka z wyświetlaczem znakowym LCD dodajemy czujnik BME280 (usuwając diodę, która była wcześniej czujnikiem temperatury). Zasilanie modułu BME280 bierzemy z pinu IOREF, gdzie w płytce Arduino Uno występuje napięcie zasilania +5V.

Rys.16 Sposób złożenia układu z BME280

Program naszej stacji meteo znajdziesz na listingu 1 (A0401). Na początku masz dyrektywy dla kompilatora, dołączające biblioteki: BME280I2C (czujnik BME280 z komunikacja przez I2C), Wire oraz LiquidCrystal. Następnie tworzymy i od razu konfigurujemy dwa obiekty. Jeden (lcd) to stary znajomy wyświetlacz LCD, podłączony dokładnie tak, jak w poprzednim odcinku. Drugi obiekt to reprezentacja w programie naszego modułu pomiarowego. Obiekt ten utworzy prościutka instrukcja:

BME280I2C czujnik;

BME280I2C to nazwa biblioteki (klasy) i na podstawie tej biblioteki zostanie stworzona "programowa reprezentacja" modułu BME280, którą w naszym programie – szkicu nazwałem swojsko: czujnik. Celowo w wielu miejscach będę stosował polskie nazwy (ale bez „polskich” liter), by odróżnić to, co wynika z wymagań programu, a co jest naszym wyborem. W instrukcji BME280I2C czujnik; nie ma dodatkowych parametrów, więc bez naszej wiedzy czujnik na początku pracy programu zostanie skonfigurowany domyślnie, co jest jak najbardziej odpowiednie dla naszej stacji meteo.

W naszym programie mamy zadeklarowane trzy zmienne globalne typu float, o krótkich nazwach nawiązujących do polskich określeń mierzonych wielkości (temperatury, wilgotności i ciśnienia). W jednorazowo wykonywanej funkcji setup() musimy zainicjalizować urządzenia. Standardowo realizujemy to dla wyświetlacza LCD (lcd.begin(16, 2);) i łącza I2C (Wire.begin();). Inicjalizacja naszego czujnika jest bardziej złożona. Zasadniczo wystarczyłoby analogiczne polecenie: czujnik.begin(); Ale zaczerpnęliśmy z przykładów sposób, w którym program sprawdza, co zwraca funkcja – metoda czujnik.begin().

Jeśli wszystko jest w porządku, zwraca ona wartość true (1). Jeśli nie ma kontaktu z czujnikiem, zwraca false (0), co powoduje wyświetlenie napisu: brak kontaktu z sensorem.

Jeśli czujnik reaguje, program wykonuje funkcję – metodę czujnik.chipModel(), która odczytuje informacje o modelu układu scalonego. Program rozróżnia kostki BME280 i BMP280 i wyświetla stosowny napis. Następnie przechodzi do pętli loop(), gdzie mamy trzy główne elementy:

  • odczyt zmierzonych wartości z czujnika,
  • wyświetlenie tych wartości
  • sekundę opóźnienia.

Dwa ostatnie są jasne. Wyjaśnienia wymaga pierwszy: odczyt wartości z czujnika. Można to zrobić na kilka sposobów, co widać w programie, gdzie mamy szereg zakomentowanych linii z rozmaitymi sposobami odczytu. Na pierwszy rzut oka wygląda to dość groźnie. Aby zrozumieć istotę sprawy, trzeba wrócić do czujnika BME280. Jest to maleńki (2,5 x 2,2 x 1mm) układ z ośmioma wyprowadzeniami.

Jak pokazuje rysunek 17 zawiera trzy czujniki i układy współpracujące z zasilaczem i stabilizatorem, multiplekser, przetwornik ADC oraz bloki logiki i interfejsu. Układ ma dwie oddzielne końcówki zasilania VDD i VDDIO. Układ logiki jest dość rozbudowany. Kostka może pracować z interfejsem SPI albo I2C i wtedy może mieć jeden z dwóch adresów (0x76, 0x77), co pozwala na współpracę dwóch czujników BME280 na jednym łączu I2C.

Rys.17 Układ z ośmioma wyprowadzeniami

Układ zawiera wewnątrz szereg rejestrów – komórek pamięci, co pokazane jest na rysunku 18. Nie trzeba wgłębiać się w te szczegóły dzięki gotowej bibliotece Arduino. Ale trzeba wiedzieć, że z układem BME280 jest nieco inaczej, niż z innymi prostszymi czujnikami. Mianowicie w wielu czujnikach wystarczy po prostu odczytać odpowiednie wartości z rejestrów i tak uzyskane liczby są finalnymi wartościami mierzonych wielkości. Tu sytuacja jest znacznie bardziej skomplikowana. Owszem, trzeba odczytać wartości z rejestrów, gdzie zawarte są aktualne dane z przetwornika ADC.

Rys.18 Układ BME280 - rejestry

Ale liczby te należy w dość skomplikowany sposób przetworzyć, wykorzystując współczynniki kalibracyjne, też odczytane z danego egzemplarza czujnika. Biblioteka Arduino podczas pracy po pierwsze odczytuje dane z rejestrów czujnika, i po drugie wykonuje dość skomplikowane obliczenia. W efekcie uzyskiwane są wyniki o zaskakująco dużej rozdzielczości i dość dużej dokładności bezwzględnej. Z punktu widzenia naszego programu stacji meteo, wygląda to bardzo prosto: wykorzystujemy biblioteczną funkcję – metodę:

czujnik.read()

która hurtowo odczytuje co trzeba, oblicza co trzeba i wpisuje do trzech zmiennych typu float wartości ciśnienia, temperatury i wilgotności względnej. Wilgotność względna wyrażana jest w procentach i tu nie ma wątpliwości. Natomiast ciśnienie i temperaturę ta funkcja - metoda może nam podać w różnych jednostkach.

Wykorzystując biblioteczną funkcję – metodę czujnik.read(), trzeba przede wszystkim podać jej nazwy zmiennych typu float, do których zostaną zapisane wyniki pomiarów, a dodatkowo też podać, w jakich jednostkach mają być wyrażone temperatura i ciśnienie.

Do określenia jednostek można wykorzystać pewne zdefiniowane stałe, np. widoczne w szkicu TempUnit_Celsius czy PresUnit_hPa. Ale można też "pójść na skróty": otóż takim stałym przyporządkowane są kolejno liczby. począwszy od zera (wykorzystano do tego tryb wyliczeniowy enum).

I tak temperaturę można uzyskać w:

  • 0 - stopniach Celsjusza,
  • 1 - stopniach Fahrenheita.

A ciśnienie uzyskamy do wyboru w:

  • 0 - paskalach (Pa),
  • 1 - hektopaskalach (hPa),
  • 2 - calach słupa rtęci (inHg),
  • 3 - atmosferach (atm),
  • 4 - barach (bar),
  • 5 - torach (torr)
  • 6 - funtach na cal kwadratowy (psi - pound per square inch).

Dlatego w naszym programie mamy polecenie – instrukcję:

czujnik.read(cis,tmp, wilg, 0, 1);

która do zmiennej cis wpisuje wartość ciśnienia w hektopaskalach, do zmiennej tmp wartość temperatury w stopniach Celsjusza i do zmiennej wilg – wartość wilgotności względnej w procentach.

Jeśli podamy tylko nazwy zmiennych:

czujnik.read(cis, tmp, wilg);

to zostaną zastosowane wartości domyślne (0, 0), czyli ciśnienie będzie podane w paskalach, a temperatura w stopniach Celsjusza. W programie masz gotowe, tylko zakomentowane różne inne opcje - zachęcam do ich przetestowania.

Fot.19 Arduino z czujnikiem BME280

Po skompilowaniu i wgraniu programu mój model podczas pracy wyglądał jak na fotografii 19. I tak oto wykorzystanie znakomitego czujnika BME280 okazało się banalnie proste!

W następnym odcinku nadal będziemy zajmować się pomiarami ciśnienia, temperatury i wilgotności. Jeśli chcesz, zajrzyj do poszczególnych plików biblioteki BME280, wtedy łatwiej przyswoisz sobie dalsze informacje.

Do pobrania
Download icon Materiały do: Kurs Arduino odcinek 4 - czujnik BME280 (pomiar ciśnienia, wilgotności i temperatury)
1. Kurs Arduino: wprowadzenie 2. Kurs Arduino odcinek 1 - co to jest i jak zacząć? (sprzęt, schematy, programowanie) 3. Kurs Arduino odcinek 2 - termometry: 'diodowy', pokojowy oraz 'scalony' analogowy 4. Kurs Arduino odcinek 3 - moduł wyświetlacza LCD (HD44780) 5. Kurs Arduino odcinek 4 - czujnik BME280 (pomiar ciśnienia, wilgotności i temperatury) 6. Kurs Arduino odcinek 5 - biblioteki do trzyfunkcyjnego czujnika BME280 7. Kurs Arduino odcinek 6 - wykorzystanie łącza I2C (TWI) 8. Kurs Arduino odcinek 7 - wykorzystanie łącza SPI (karty pamięci, MAX31865, MAX31855) 9. Kurs Arduino odcinek 8 - wykorzystanie czujnika dwutlenku węgla (MH-Z19) 10. Kurs Arduino odcinek 9 - wykorzystanie modułów do odmierzania czasu 11. Kurs Arduino odcinek 10 - wykorzystanie czujników temperatury (DS18B20) 12. Kurs Arduino odcinek 11 - budowa loggera (rejestratora danych) 13. Kurs Arduino odcinek 12 - rejestracja i prezentacja danych oraz obsługa karty SD 14. Kurs Arduino odcinek 13 - rejestracja danych (wykorzystanie modułu OpenLog) 15. Kurs Arduino odcinek 14 - czym zastąpić płytkę Arduino Uno? 16. Kurs Arduino odcinek 15 - budowa rejestratora (chiński klon Arduino Pro Mini) 17. Kurs Arduino odcinek 16 - problemy z kwadratowym modułem Strong 18. Kurs Arduino odcinek 17 - czujniki do pomiaru wilgotności gleby (instalacja, konfiguracja) 19. Kurs Arduino odcinek 18 - protokół MODBUS i łącze RS-485 20. Kurs Arduino odcinek 19 - wyświetlacze od podstaw (matrycowe, 7-segmentowe, MAX7219) 21. Kurs Arduino odcinek 20a - wyświetlacze matrycowe i biblioteki MD_MAX 22. Kurs Arduino odcinek 20b - przyciski i biblioteki do obsługi wyświetlaczy 23. Kurs Arduino odcinek 20c - biblioteki do obsługi wyświetlaczy graficznych 24. Kurs Arduino odcinek 21 - moduł wyświetlacza OLED 25. Kurs Arduino odcinek 22 - moduł wyświetlacza 1,3 cala 26. Kurs Arduino odcinek 23 - przygotowanie bitmap do wyświetlania 27. Kurs Arduino odcinek 24 - omówienie fontu podstawowego (Adafruit GFX) 28. Kurs Arduino odcinek 25 - font podstawowy biblioteki Adafruit GFX 29. Kurs Arduino odcinek 26 - wykorzystanie bitmapowych fontów GFX 30. Kurs Arduino odcinek 27 - polskie znaki w glcdfont.c 31. Kurs Arduino odcinek 28 - zmiana ulepszonych fontów GFX
Tematyka materiału: czujnik BME280
AUTOR
Źródło
Elektronika dla Wszystkich czerwiec 2018
Udostępnij
UK Logo