Raspberry Pi: BME280 snímač teploty, vlhkosti a tlaku

17.10.2023 Raspberry Pi #raspberrypi #bme280 #programming #python

Ukázka, jak propojit snímač BME280 s Raspberry Pi, abyste získali údaje o teplotě, vlhkosti a tlaku.


Předpoklady

Než budete pokračovat v tomto článku, zkontrolujte následující předpoklady.

  1. Seznamte se s deskou Raspberry Pi – pokud neznáte Raspberry Pi, můžete si přečíst článek základů práce s Raspberry Pi zde.
  2. Musíte vědět, jak spouštět a vytvářet soubory Python na vašem Raspberry Pi. Lez využít vzdáleného programování Raspberry Pi přes SSH pomocí rozšíření na VS Code. Podrobný návod na toto téma: Vzdálené programování Raspberry Pi pomocí VS Code (Remote-SSH).
  3. Vědět, jak používat Raspberry Pi GPIO, abyste věděli, jak správně zapojit obvod.

Představení modulu BME280

Senzorový modul BME280 čte barometrický tlak, teplotu a vlhkost. Protože se tlak mění s nadmořskou výškou, můžete také odhadnout nadmořskou výšku. Existuje několik verzí tohoto senzorového modulu. Používáme modul znázorněný na obrázku níže.

Tento senzor komunikuje pomocí komunikačního protokolu I2C, takže zapojení je velmi jednoduché. Můžete použít výchozí kolíky Raspberry Pi I2C, jak je uvedeno v následující tabulce:

BME280 Raspberry Pi
Vin 3,3 V
GND GND
SCL GPIO 3
SDA GPIO 2

Povolte I2C na Raspberry Pi

I2C komunikace není ve výchozím nastavení povolena. Musíte to povolit ručně. Otevřete okno terminálu na Raspberry Pi a zadejte následující příkaz:

sudo raspi-config

Otevře se následující nabídka. Vyberte Možnosti rozhraní.

Poté vyberte možnost I2C.

Nakonec povolte I2C výběrem Ano.

I2C by mělo být úspěšně povoleno.

Po povolení I2C restartujte Raspberry Pi spuštěním následujícího příkazu:

sudo restart

Zapojení BME280 k Raspberry Pi

Připojte BME280 k výchozím I2C pinům Raspberry Pi.

BME280 Raspberry Pi
Vin 3,3 V
GND GND
SCL GPIO 3
SDA GPIO 2

Získání adresy I2C snímače

Se snímačem připojeným k Raspberry Pi zkontrolujme, zda je snímač připojen správně, vyhledáním jeho I2C adresy.

Otevřete okno terminálu na Raspberry Pi a spusťte následující příkaz:

sudo i2cdetect -y 1

Mělo by ukazovat I2C adresu vašeho senzoru:

Nainstalujte knihovnu BME280

Existuje několik knihoven kompatibilních s Raspberry Pi pro čtení ze snímače BME280. Budeme používat knihovnu RPi.BME280 . Tuto knihovnu je možné nainstalovat prostřednictvím PIP (správce balíčků pro balíčky Pythonu).

Nejprve nainstalujte nebo upgradujte pip spuštěním následujícího příkazu:

sudo pip install --upgrade pip

Poté spusťte následující příkaz a nainstalujte knihovnu pomocí pip:

sudo pip instalace RPI.BME280

Python kód pro Raspberry Pi BME280 (teplota, vlhkost a tlak)

Následující skript získá teplotu, vlhkost a tlak ze senzoru BME280 a vytiskne naměřené hodnoty na shell Pythonu. Vytvořte nový soubor Python s názvem dle vašeho výběru, například bme280_basic.py, a zkopírujte následující kód.

import time
import smbus2
import bme280

# BME280 sensor address (default address)
address = 0x76

# Initialize I2C bus
bus = smbus2.SMBus(1)

# Load calibration parameters
calibration_params = bme280.load_calibration_params(bus, address)

def celsius_to_fahrenheit(celsius):
    return (celsius * 9/5) + 32

while True:
    try:
        # Read sensor data
        data = bme280.sample(bus, address, calibration_params)

        # Extract temperature, pressure, and humidity
        temperature_celsius = data.temperature
        pressure = data.pressure
        humidity = data.humidity

        # Convert temperature to Fahrenheit
        temperature_fahrenheit = celsius_to_fahrenheit(temperature_celsius)

        # Print the readings
        print("Temperature: {:.2f} °C, {:.2f} °F".format(temperature_celsius, temperature_fahrenheit))
        print("Pressure: {:.2f} hPa".format(pressure))
        print("Humidity: {:.2f} %".format(humidity))

        # Wait for a few seconds before the next reading
        time.sleep(2)

    except KeyboardInterrupt:
        print('Program stopped')
        break
    except Exception as e:
        print('An unexpected error occurred:', str(e))
        break

Jak kód funguje

Importujte požadované knihovny

Nejprve importujeme požadované knihovny:time, smbus2, abme280. Modul time nám umožňuje přidat zpoždění do našeho kódu, smbus2 nám pomáhá komunikovat se zařízeními I2C, jako je senzor BME280, abme280 poskytuje funkce pro snadnou interakci se senzorem.

import time
import smbus2
import bme280

Inicializujte snímač BME280

Výchozí adresu snímače BME280 jsme nastavili na 0x 76. Toto je adresa, se kterou senzor komunikuje po sběrnici I2C.

# BME280 sensor address (default address)
address = 0x76

Poté inicializujeme sběrnici I2C pomocí příkazu smbus2.SMBus(1).

# Initialize I2C bus
bus = smbus2.SMBus(1)

Poté senzor inicializujeme nastavením I2C sběrnice a její I2C adresy.

# Load calibration parameters
calibration_params = bme280.load_calibration_params(bus, address)

Převést stupně Celsia na Fahrenheita

Definujeme funkci tzvcelsius_to_fahrenheit (celsius)který převádí teplotu ze stupňů Celsia na Fahrenheita. Tuto funkci pak můžeme zavolat později v našem kódu a převést teplotu.

Získávání hodnot senzoru

Zadáme nekonečnou smyčku pomocízatímco Pravdaopakovaně číst a zobrazovat data senzoru.

while True:

Používáme funkci bme280.sample(bus, address, calibration_params) pro čtení dat senzoru.

data = bme280.sample(bus, address, calibration_params)

Získáváme z nich teplotu, tlak a vlhkost data vrácené senzorem a uložit každé čtení do proměnné: temperature_celsius, pressure a humidity.

# Extract temperature, pressure, and humidity
temperature_celsius = data.temperature
pressure = data.pressure
humidity = data.humidity

Teplotu převedeme ze stupňů Celsia na Fahrenheita pomocí funkce, kterou jsme vytvořili dříve, a uložíme ji do temperature_fahrenheit.

# Convert temperature to Fahrenheit
temperature_fahrenheit = celsius_to_fahrenheit(temperature_celsius)

dNakonec vytiskneme údaje formátované na dvě desetinná místa:

# Print the readings
print("Temperature: {:.2f} °C, {:.2f} °F".format(temperature_celsius, temperature_fahrenheit))
print("Pressure: {:.2f} hPa".format(pressure))
print("Humidity: {:.2f} %".format(humidity))

Nové naměřené hodnoty se tisknou každé dvě sekundy. Čas mezi jednotlivými vzorky můžete upravit přidáním jiného čísla v metodě sleep().

Zvládejte přerušení a výjimky

Zpracování výjimek používáme k zachycení přerušení klávesnice (když uživatel stiskne Ctrl+C) a dalších výjimek. Pokud k tomu dojde, vytiskneme chybovou zprávu a použijeme příkaz break pro vyskočení ze smyčky.

except KeyboardInterrupt:
    print('Program stopped')
    break
except Exception as e:
    print('An unexpected error occurred:', str(e))
    break

Ukázka

Uložte svůj soubor Python. Poté jej spusťte na svém Raspberry Pi. Spusťte následující příkaz v adresáři vašeho souboru Python:

python bme280_basic.py

Nové hodnoty teploty, vlhkosti a tlaku byste měli získat na Python Shell nebo na terminálu Raspberry Pi každé tři sekundy.

Spouštění programu můžete zastavit stisknutím CTRL+C.

Zaznamenávání hodnot do souboru

Instalace knihovny pytz

Knihovna RPi.280 má možnost získat časové razítko spojené s každým čtením. Toto časové razítko však bude v UTC. Pokud jej chcete převést na konkrétní časové pásmo, můžete použít knihovnu pytz . Otevřete okno terminálu na svém Raspberry Pi a spusťte následující příkaz pro instalaci knihovny pytz .

pip install pytz

Kompletní skript vychází z předchozího příkladu.

import smbus2
import bme280
import os
import time
import pytz

# BME280 sensor address (default address)
address = 0x76

# Initialize I2C bus
bus = smbus2.SMBus(1)

# Load calibration parameters
calibration_params = bme280.load_calibration_params(bus, address)

# create a variable to control the while loop
running = True

# Check if the file exists before opening it in 'a' mode (append mode)
file_exists = os.path.isfile('sensor_readings_bme280.txt')
file = open('sensor_readings_bme280.txt', 'a')

# Write the header to the file if the file does not exist
if not file_exists:
    file.write('Time and Date, temperature (ºC), temperature (ºF), humidity (%), pressure (hPa)\n')

# loop forever
while running:
    try:
        # Read sensor data
        data = bme280.sample(bus, address, calibration_params)

        # Extract temperature, pressure, humidity, and corresponding timestamp
        temperature_celsius = data.temperature
        humidity = data.humidity
        pressure = data.pressure
        timestamp = data.timestamp

        # Adjust timezone
        # Define the timezone you want to use (list of timezones: https://gist.github.com/mjrulesamrat/0c1f7de951d3c508fb3a20b4b0b33a98)
        desired_timezone = pytz.timezone('Europe/Lisbon')  # Replace with your desired timezone

        # Convert the datetime to the desired timezone
        timestamp_tz = timestamp.replace(tzinfo=pytz.utc).astimezone(desired_timezone)

        # Convert temperature to Fahrenheit
        temperature_fahrenheit = (temperature_celsius * 9/5) + 32

        # Print the readings
        print(timestamp_tz.strftime('%H:%M:%S %d/%m/%Y') + " Temp={0:0.1f}ºC, Temp={1:0.1f}ºF, Humidity={2:0.1f}%, Pressure={3:0.2f}hPa".format(temperature_celsius, temperature_fahrenheit, humidity, pressure))

        # Save time, date, temperature, humidity, and pressure in .txt file
        file.write(timestamp_tz.strftime('%H:%M:%S %d/%m/%Y') + ', {:.2f}, {:.2f}, {:.2f}, {:.2f}\n'.format(temperature_celsius, temperature_fahrenheit, humidity, pressure))

        time.sleep(10)

    except KeyboardInterrupt:
        print('Program stopped')
        running = False
        file.close()
    except Exception as e:
        print('An unexpected error occurred:', str(e))
        running = False
        file.close()

Manipulace se soubory

Následující řádek zkontroluje, zda již existuje soubor s názvem sensor_readings_bme280.txt (bude jej hledat v cestě složky projektu). Pokud soubor již existuje, soubor existujeproměnná bude true. Jinak bude false.

file_exists = os.path.isfile('sensor_readings_bme280.txt')

Poté otevře soubor v "A" (přidat) režim. Pokud soubor ještě neexistuje, před otevřením jej automaticky vytvoří.

file = open('sensor_readings_bme280.txt', 'a')

Při použití open() můžete určit různé režimy pro řízení přístupu k souboru a jeho použití. Při zápisu do souboru jsou nejoblíbenější metody "w" (zapisování) a "A" (přidávání).

Režim zápisu vs. přidávání: režim zápisu otevře soubor pro zápis a vyprázdní soubor, pokud již existuje. Režim připojení otevře soubor pro zápis a na konec souboru připojí nová data. Pokud chcete mít záznam o svých naměřených hodnotách v průběhu času, nejlepším režimem je připojení, abyste si mohli uchovat všechna svá předchozí data.

Pokud soubor ještě neexistuje, kód zapíše do souboru řádek záhlaví obsahující názvy sloupců. Nejprve uložíme datum a čas, poté teplotu ve stupních Celsia a Fahrenheita, vlhkost a nakonec tlak.

# Write the header to the file if the file does not exist
if not file_exists:
    file.write('Time and Date, temperature (ºC), temperature (ºF), humidity (%), pressure (hPa)\n')

Všimněte si, že přidáváme a \n na konci provázku. Tento řetězec \n říká Pythonu, aby začal další zobrazovaný text na dalším řádku, známém jako nový řádek.

Upravte časové pásmo

Jak jsme již uvedli, časové razítko vrátilo data objekt knihovny BME280 je standardně dodáván ve formátu UTC. Můžeme použít funkce knihovny pytz k převedení tohoto času na požadované časové pásmo.

Nejprve na následujícím řádku zadejte požadované časové pásmo (seznam všech podporovaných časových pásem naleznete zde).

desired_timezone = pytz.timezone('Europe/Prague')  # Replace with your desired timezone

Poté převeďte časové razítko na požadované časové pásmo následovně.

# Convert the datetime to the desired timezone
timestamp_tz = timestamp.replace(tzinfo=pytz.utc).astimezone(desired_timezone)

Nové časové razítko upravené pro vaše konkrétní časové pásmo se uloží do proměnné timestamp_tz.

Vytiskněte řetězec hodnot

Nakonec vytiskneme údaje formátované na dvě desetinná místa a odpovídající časové razítko:

# Print the readings
 print(timestamp_tz.strftime('%H:%M:%S %d/%m/%Y') + " Temp={0:0.1f}ºC, Temp={1:0.1f}ºF, Humidity={2:0.1f}%, Pressure={3:0.2f}hPa".format(temperature_celsius, temperature_fahrenheit, humidity, pressure))

Zápis dat do souboru

Poté použijeme funkci write() zapsání dat do souboru. Zapisujeme časové razítko, teplotu ve stupních Celsia, teplotu ve stupních Fahrenheita, vlhkost a tlak.

file.write(timestamp_tz.strftime('%H:%M:%S %d/%m/%Y') + ', {:.2f}, {:.2f}, {:.2f}, {:.2f}\n'.format(temperature_celsius, temperature_fahrenheit, humidity, pressure))

Nové hodnoty se tisknou a zapisují do souboru každých 10 sekund. Čas mezi jednotlivými vzorky můžete upravit vložením jiného čísla v metodě sleep().

time.sleep(10)

Literatura:

[1] Raspberry Pi: BME280 Temperature, Humidity and Pressure Sensor (Python). Random Nerd Tutorials [online]. Random Nerd Tutorials, 2022 [cit. 2023-10-17]. Dostupné z: https://randomnerdtutorials.com/raspberry-pi-bme280-python/

[2] Raspberry Pi with BME280: Temperature, Humidity, and Pressure Data Logger (Python). Random Nerd Tutorials [online]. Random Nerd Tutorials, 2022 [cit. 2023-10-17]. Dostupné z: https://randomnerdtutorials.com/raspberry-pi-bme280-data-logger/