Skip to main content

4.6.3 Senzory BME a BMP

Vzhľadom k tomu, že senzory BMP a BME majú veľmi malé rozmery, prakticky sa stretneme s nimi len vo forme modulov. Tie majú vždy vyvedenú zbernicu I²C, niektoré navyše aj SPI.

senzory BME280 a BMP280.webpZákladné senzory BMP a BME

Senzory BMP180BMP280 sa líšia len rozsahom merania teploty (0 až 65 °C a -40 až 85 °C), okrem teploty merajú aj tlak. Senzor BME280 navyše meria i vlhkosť. Senzor BMP180 používa I²C identifikátor 0x77, novšie BMP280 a BME280 majú identifikátor 0x76.

Pre všetky varianty sú potrebné rozširujúce knižnice. Senzor BMP180 používa iný protokol pre komunikáciu, preto je preň iná knižnica ako pre BMP280 a BME280 (tie majú spoločnú).

Ceny modulov sú približne (CN / SK): BMP180 0,50 / 3 €, BMP280 0,50 / 8 €, BME280 2 / 10 €.

Ukážkový program pre BME280

Jednoduchý program pre BME280, merajúci v slučke:

# senzor-bme280.py
from machine import I2C, Pin, Signal

i2c = I2C(0, scl = Pin(26), sda = Pin(0))
zariadenia = i2c.scan()
print(i2c, zariadenia)

if 0x76 in zariadenia:
    from bme280 import BME280
    from time import sleep_ms
    senzor = BME280(i2c = i2c)
    tlacidlo = Signal(37, Pin.IN, invert = True)
    while not tlacidlo():
        try:
            teplota = senzor.temperature
            tlak = senzor.pressure
            vlhkost = senzor.humidity
        except Exception:
            print("Nastala chyba pri meraní!")
            sleep_ms(1000)
        else:
            print(f"Teplota: {teplota} °C, tlak: {tlak} hPa, vlhkosť: {vlhkost} %", end = "      \r")
            sleep_ms(100)
else:
    print("Nie je pripojený správny senzor!")

Tento program bude fungovať aj pre senzor BMP280, stačí odstrániť meranie a výpis vlhkosti.

Senzor BME680

Vyspelejším je senzor BME680 (I²C identifikátor 0x77, cena modulu približne 7 / 25 €) - vychádza z BME280, no je preň potrebná iná knižnica a navyše poskytuje aj údaj o prchavých organických látkach VOC (Volatile Organic Compounds).

Organické látky môžu byť rôzne, senzor ich nerozlišuje. Zachytí síce aj bežný oxid uhličitý, reaguje aj na jedovatý oxid uhoľnatý, ale aj na skutočne organické látky, ako sú napríklad alkoholy, aldehydy, benzén, styrén a formaldehyd. Tieto látky môžu byť vo vzduchu prítomné napríklad z nového nábytku, lepidiel, rozpúšťadiel a náterov a sú pre ľudský organizmus jedovaté, niektoré aj karcinogénne.

Senzor VOC vracia nameraný odpor - čím je nižší, tým je viac VOC. Dalo by sa teda zjednodušene povedať, že senzor meria čistotu vzduchu.

Meranie VOC

Meranie VOC nie je také jednoduché ako meranie teploty, tlaku a vlhkosti. Senzor je silne závislý od teploty a jeho štruktúra sa mení i v čase. Preto je nový senzor potrebné najskôr nechať „zahorieť“ - niekoľko dní ním bez prerušenia merať. Merané hodnoty by sa mali časom stabilizovať.

Senzor sa pri každom meraní VOC mierne zahreje. Teplota význame ovplyvňuje výsledok - pri nižšej teplote bude nižšia nameraná hodnota odporu. Po dlhšej prestávke v meraní je potrebný rozbeh aspoň pol hodiny na stabilizovanie teploty. Prípadne je vhodné pred každým jedným meraním nechať senzor zahriať - môžeme to riešiť tak, že budeme v cykle opakovane merať, kým nameraná hodnota stúpa. Toto je samozrejme energeticky výrazne náročnejšie, čo môže byť problém pri napájaní z batérie.

Z toho všetkého vyplýva, že pokiaľ senzorom BME680 meriame VOC, nemôžeme ním zároveň merať aj teplotu, pretože bude vždy vyššia! Podobne bude ovplyvnená aj vlhkosť.

Prípadne môžeme merať bez zahrievania senzora a počítať s tým, že prvé hodnoty sú nižšie. Ak nemeriame príliš často, teplota senzora sa zvyšovať nebude a namerané údaje by mali byť konzistentné.

Praktickým problémom je aj to, že každý kus senzoru BME680 dáva iné hodnoty VOC. Výsledky je teda potrebné brať v relatívnom zmysle a normalizovať voči nejakej referenčnej úrovni (napríklad čistému vonkajšiemu vzduchu pri rovnakej teplote).

Ukážkový program pre BME680

Nasledujúci program v cykle meria všetky dostupné parametre:

# senzor-bme680-i2c.py
from machine import Pin, I2C

# ESP32-C3 Super Mini
Pin(9, Pin.OUT, value = 1, drive = Pin.DRIVE_1)
Pin(10, Pin.OUT, value = 0)
i2c = I2C(0, scl = Pin(20), sda = Pin(21), freq = 100_000)
zariadenia = i2c.scan()
print(i2c, zariadenia)

if 0x77 in zariadenia:
    from bme680 import BME680_I2C
    from time import sleep_ms
    senzor = BME680_I2C(i2c = i2c)
    try: senzor.gas # prvé meranie nedáva správny výsledok
    except: pass
    while True:
        sleep_ms(1000)
        try:
            teplota = senzor.temperature
            vlhkost = senzor.humidity
            tlak = senzor.pressure
            vzduch = senzor.gas / 1000
        except Exception:
            print("Nastala chyba pri meraní!")
        else:
            print(f"Teplota: {teplota:.2f} °C, vlhkosť: {vlhkost:.2f} %, tlak: {tlak:.2f} hPa, kvalita vzduchu: {vzduch:.2f} kΩ")
else:
    print("Nie je pripojený správny senzor BME680!")

Druhá verzia programu je zameraná na VOC - vždy pred meraním najskôr zahrieva senzor:

# senzor-bme680-i2c-zahrievanie.py
from machine import Pin, I2C

# ESP32-C3 Super Mini
Pin(9, Pin.OUT, value = 1, drive = Pin.DRIVE_1)
Pin(10, Pin.OUT, value = 0)
i2c = I2C(0, scl = Pin(20), sda = Pin(21), freq = 100_000)
zariadenia = i2c.scan()
print(i2c, zariadenia)

if 0x77 in zariadenia:
    from bme680 import BME680_I2C
    from time import sleep_ms
    senzor = BME680_I2C(i2c = i2c)
    try: senzor.gas # prvé meranie nedáva správny výsledok
    except: pass
    while True:
        sleep_ms(1000)
        try:
            teplota = senzor.temperature
            vlhkost = senzor.humidity
            tlak = senzor.pressure
            vzduch = senzor.gas / 1000                      
        except Exception:
            print("Nastala chyba pri meraní!")
        else:
            plyn_max = 0
            while True:
                try: plyn = senzor.gas / 1000
                except Exception: pass
                else:
                    print(f"Zahrievam senzor: {plyn:.2f} kΩ", end = "\r")
                    if plyn <= plyn_max: break
                    plyn_max = plyn
                sleep_ms(100)
            vzduch = plyn_max
            print(f"Teplota: {teplota:.2f} °C, vlhkosť: {vlhkost:.2f} %, tlak: {tlak:.2f} hPa, kvalita vzduchu: {vzduch:.2f} kΩ")
else:
    print("Nie je pripojený správny senzor BME680!")