Lekce 10 - Arduino - Měření tlaku a teploty s OLED displejem
V předchozí lekci, Arduino - Sedmisegmentový displej a pole, jsme si ukázali práci se sedmisegmentovým displejem, na kterém jsme postupně rozsvítili číslice.
Dnes si v Arduino tutoriálu sestavíme a oživíme měřič teploty a tlaku s OLED displejem. Jedná se tentokrát o komponenty, které nenalezneme ve virtuálním prostředí Tinkercadu, budeme tedy tvořit reálný Arduino projekt. Výsledek bude následující:
Modul BMP280
K měření použijeme modul BMP280. Je třeba rozlišovat mezi modulem a senzorem. Modul většinou představuje desku plošných spojů (anglická zkratka je PCB), na níž je integrovaný senzor s příslušnou elektronikou - rezistory, kondenzátory, děliči napětí apod.
Modul BMP280 sestává ze senzoru BMP280 od firmy Bosch a pasivních součástek, rezistorů a kondenzátoru. Umožňuje měření teploty a tlaku a jedná se o MEMS (zkr. Micro-Electro-Mechanical Systems), tedy mechanické konstrukce velmi malých rozměrů (pod 1 mm). Samotný senzor má rozměry 2,5 mm x 2 mm x 0,95 mm.
Výrobce udává rozsahy a přesnost měření následovně:
Absolutní přesnost tlaku | ~ ±1 hPa |
---|---|
Relativní přesnost tlaku | ± 0.12 hPa |
Absolutní přesnost teploty | ~ ±1 °C |
Rozsah | 300...1100 hPa, -40...85°C |
Zdroj: https://www.bosch-sensortec.com/…mp280-1.html.
OLED displej
OLED displej sestává z organické diody emitující světlo (OLED nebo Organic LED), známé také jako organická EL (organická elektroluminiscenční). Jedná se o diodu, v níž je emisní elektroluminiscenčních vrstvou film organické sloučeniny, který vyzařuje světlo v reakci na elektrický proud.
Seznam součástek
Na zapojení projektu budeme potřebovat tyto součástky:
- Arduino Nano a USB kabel na nahrání kódu,
- modul BMP280,
- OLED displej 0x96 ,
- nepájivé pole a
- propojovací kabely.
Zapojení obvodu
Ukažme si jak vše zapojíme:
Modul BMP280 propojíme s Arduino pomocí čtyř dupont kabelů. Dva slouží k napájení (VCC → 3v3 a GND → GND) a další dva kabely na I2C komunikaci (SCL → A5 a SDA → A4). Senzor pracuje s přesností 100 Pa a 1 °C. OLED displej komunikuje prostřednictvím I2C protokolu a stačí ho tedy s Arduinem propojit stejně jako senzor.
Programování modulu a displeje
Obvod máme zapojený, můžeme tedy začít s programováním.
Knihovny
Pro kompilaci kódu budeme potřebovat tyto knihovny, které je nutné rozbalit ve složce pro knihovny:
- Adafruit_BMP280.h pro modul BMP280,
- Adafruit_SSD1306.h pro OLED displej a
- Fonts/FreeSerif9pt7b.h pro zmenšení fontu.
Hlavička programu
Na začátku vypíšeme knihovny, které budeme nutně potřebovat. Bez nich se kód nezkompiluje:
#include <Wire.h> #include <Adafruit_SSD1306.h> #include <Fonts/FreeSerif9pt7b.h> #include <Adafruit_BMP280.h>
Dále zadáme I2C adresu senzoru BMP280. Pozor, setkal jsem se se senzory, které měly jinou adresu, než bylo deklarováno výrobcem. Šlo o čínské napodobeniny. V takovém případě je nutné zjistit jejich adresu. Použijeme i příkaz na restart displeje po stisknutí resetovacího tlačítka:
#define OLED_ADDR 0x3C Adafruit_SSD1306 display(-1);
Proměnné
Poté si nadefinujeme proměnné temp
a pressure
pro teplotu a tlak a inicializujeme senzor z knihovny:
// BMP280 float temp; float pressure; Adafruit_BMP280 bmp; // I2C
Dále si vytvoříme proměnnou pro grafické zobrazení stupně u jednotky °C:
// symbol // degree for Celsius const unsigned char degree [] PROGMEM = { 0xe,0x11,0x11,0x11,0xe,0x0,0x0,0x0 };
Užitečné příkazy
Nyní si ukažme několik užitečných příkazů.
Displej vyčistíme takto:
display.clearDisplay();
Takto nastavíme kurzor na pozici x
, y
:
display.setCursor(1, 12);
Zobrazíme řetězec a proměnnou na displeji:
display.print("Nejaky text.");
display.print(nazev_promenne);
Předchozí příkazy jen nastaví to, co chceme zobrazit. Aby to displej opravdu zobrazil, musí se za příkazy zapsat:
display.display();
Pomocné funkce
Jíž víme, jak vypisovat na displej, pojďme si připravit funkce našeho programu.
Na začátku spuštění se zobrazí na displeji informace o přesnosti
senzoru. Na to slouží funkce display_info()
:
void display_info() { //display.drawPixel(120, 50, WHITE); display.clearDisplay(); display.setCursor(1, 11); display.print("Accuracy"); display.setCursor(1, 38); display.print("1 "); display.drawBitmap(20, 26, degree, 8,5 , WHITE); display.setCursor(28, 38); display.print("C"); display.setCursor(1, 57); display.print("100"); display.setCursor(50, 57); display.print("Pa"); display.display(); }
Pro zobrazení naměřených údajů slouží funkce
display_values()
:
void display_values() { // display.drawPixel(120, 50, WHITE); display.clearDisplay(); display.setCursor(1, 12); display.print("BMP280"); display.setCursor(1, 38); display.print(temp); display.drawBitmap(50, 26, degree, 8,5 , WHITE); display.setCursor(58, 38); display.print("C"); display.setCursor(1, 57); display.print(pressure); display.setCursor(85, 57); display.print("Pa"); display.display(); }
Inicializace komponent
Funkci setup()
přidáme za účelem inicializace komunikace se
senzorem a displejem. Zároveň v ní nastavíme vlastnosti textu, tj. velikost
a font a nakonec vypíšeme informace o senzoru zavoláním naší pomocné
funkce:
void setup() { bme.begin(); // setup for oled display display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); display.setTextSize(1); display.setTextColor(WHITE); display.setFont(&FreeSerif9pt7b); display.setCursor(1, 12); display_info(); delay(1500); }
Hlavní smyčka
Nyní přidáme funkci loop()
. V ní program změří a uloží
naměřené hodnoty teploty a tlaku do příslušných proměnných. Následně
zavolá funkci display_values()
, která zjištěné hodnoty
vypíše:
void loop()
{
temp = bme.readTemperature();
pressure = bme.readPressure();
display_values();
}
Celý kód
Ukažme si na závěr znovu celý kód pro zkopírování a vyzkoušení v projektu:
#include <Wire.h> #include <Adafruit_SSD1306.h> #include <Fonts/FreeSerif9pt7b.h> #include <Adafruit_BMP280.h> // OLED display #define OLED_ADDR 0x3C Adafruit_SSD1306 display(-1); // - 1 for restart display with restart button on arduino board // BMP280 float temp; float pressure; Adafruit_BMP280 bmp; // I2C // symbol // degree for Celsius const unsigned char degree [] PROGMEM = { 0xe,0x11,0x11,0x11,0xe,0x0,0x0,0x0 }; void setup() { bme.begin(); // setup for oled display display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); display.setTextSize(1); display.setTextColor(WHITE); display.setFont(&FreeSerif9pt7b); display.setCursor(1, 12); display_info(); delay(1500); } void loop() { temp= bme.readTemperature(); pressure = bme.readPressure(); display_values(); } void display_info() { //display.drawPixel(120, 50, WHITE); display.clearDisplay(); display.setCursor(1, 11); display.print("Accuracy"); display.setCursor(1, 38); display.print("1 "); display.drawBitmap(20, 26, degree, 8,5 , WHITE); display.setCursor(28, 38); display.print("C"); display.setCursor(1, 57); display.print("100"); display.setCursor(50, 57); display.print("Pa"); display.display(); } void display_values() { //display.drawPixel(120, 50, WHITE); display.clearDisplay(); display.setCursor(1, 12); display.print("BMP280"); display.setCursor(1, 38); display.print(temp); display.drawBitmap(50, 26, degree, 8,5 , WHITE); display.setCursor(58, 38); display.print("C"); display.setCursor(1, 57); display.print(pressure); display.setCursor(85, 57); display.print("Pa"); display.display(); }
Příště, v lekci Arduino - Druhy motorů a programování servo motoru, si ukážeme různé druhy motorů, které máme k dispozici a vytvoříme další projekt, v němž se naučíme zapojit a naprogramovat servo motor.