Umweltsensor
#BME280 – Temperatur, Luftfeuchtigkeit & Luftdruck
Kombinierter Umweltsensor für präzise Messungen von Temperatur, relativer Luftfeuchtigkeit und barometrischem Druck.
- BME280 – Temperatur, Luftfeuchtigkeit & Luftdruck
- Übersicht
- Technische Daten
- Pinbelegung & Anschluss
- Funktionsweise
- Beispielcode
- Tipps & häufige Fehler
- Weiterführende Links
#Übersicht
Der BME280 von Bosch ist ein vielseitiger Umweltsensor, der drei Messgrößen in einem kompakten Gehäuse vereint. Er eignet sich hervorragend für Wetterstationen, Raumklimaüberwachung, Höhenmessung (über den Luftdruck) und IoT-Anwendungen. Der Sensor zeichnet sich durch geringen Stromverbrauch und hohe Genauigkeit aus.
#Technische Daten
| Eigenschaft | Wert |
|---|---|
| Temperaturbereich | -40 °C bis +85 °C |
| Temperaturgenauigkeit | ±1.0 °C |
| Luftfeuchtigkeitsbereich | 0 % bis 100 % RH |
| Luftfeuchtigkeitsgenauigkeit | ±3 % RH |
| Druckbereich | 300 hPa bis 1100 hPa |
| Druckgenauigkeit | ±1 hPa |
| Versorgungsspannung | 1.8 V bis 3.6 V |
| Stromverbrauch | 1.8 µA (1 Hz Messrate) |
| Protokoll | I²C / SPI |
| I²C-Adresse | 0x76 |
| Betriebstemperatur | -40 °C bis +85 °C |
#Pinbelegung & Anschluss
#Anschlussschema (I²C)
| Sensor-Pin | ESP32-C6 Pin | Beschreibung |
|---|---|---|
| VCC | 3.3V | Versorgung |
| GND | GND | Masse |
| SDA | GPIO22 | I²C Daten |
| SCL | GPIO23 | I²C Takt |
#Hinweise zur Verdrahtung
- I²C-Adresse: Der Sensor ist auf Adresse 0x76 konfiguriert
- Pull-up-Widerstände: Viele Breakout-Boards haben bereits 10kΩ Pull-ups integriert
#Funktionsweise
Der BME280 verwendet drei verschiedene Messprinzipien:
- Temperatur: Integrierter MEMS-Temperatursensor mit resistivem Messprinzip
- Luftfeuchtigkeit: Kapazitiver Feuchtesensor, der die Änderung der Dielektrizitätskonstante misst
- Luftdruck: Piezoresistiver Drucksensor mit einer Membran
Die Rohdaten werden intern über Kalibrierungskoeffizienten kompensiert, die im Sensor gespeichert sind. Diese Koeffizienten müssen beim Auslesen berücksichtigt werden.
#Beispielcode
#MicroPython
from machine import I2C, Pin
from time import sleep
class BME280:
def __init__(self, i2c, addr=0x76):
self.i2c = i2c
self.addr = addr
self._load_calibration()
# Konfiguration: Normal Mode, Oversampling x1
self.i2c.writeto_mem(self.addr, 0xF2, b'\x01') # ctrl_hum
self.i2c.writeto_mem(self.addr, 0xF4, b'\x27') # ctrl_meas
def _load_calibration(self):
cal1 = self.i2c.readfrom_mem(self.addr, 0x88, 26)
cal2 = self.i2c.readfrom_mem(self.addr, 0xE1, 7)
self.dig_T1 = cal1[0] | (cal1[1] << 8)
self.dig_T2 = self._signed(cal1[2] | (cal1[3] << 8))
self.dig_T3 = self._signed(cal1[4] | (cal1[5] << 8))
self.dig_P1 = cal1[6] | (cal1[7] << 8)
self.dig_P2 = self._signed(cal1[8] | (cal1[9] << 8))
self.dig_P3 = self._signed(cal1[10] | (cal1[11] << 8))
self.dig_P4 = self._signed(cal1[12] | (cal1[13] << 8))
self.dig_P5 = self._signed(cal1[14] | (cal1[15] << 8))
self.dig_P6 = self._signed(cal1[16] | (cal1[17] << 8))
self.dig_P7 = self._signed(cal1[18] | (cal1[19] << 8))
self.dig_P8 = self._signed(cal1[20] | (cal1[21] << 8))
self.dig_P9 = self._signed(cal1[22] | (cal1[23] << 8))
self.dig_H1 = cal1[25]
self.dig_H2 = self._signed(cal2[0] | (cal2[1] << 8))
self.dig_H3 = cal2[2]
self.dig_H4 = self._signed((cal2[3] << 4) | (cal2[4] & 0x0F))
self.dig_H5 = self._signed((cal2[5] << 4) | (cal2[4] >> 4))
self.dig_H6 = self._signed_byte(cal2[6])
def _signed(self, val):
return val - 65536 if val >= 32768 else val
def _signed_byte(self, val):
return val - 256 if val >= 128 else val
def read(self):
data = self.i2c.readfrom_mem(self.addr, 0xF7, 8)
raw_p = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
raw_t = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
raw_h = (data[6] << 8) | data[7]
# Temperaturkompensation
var1 = ((raw_t / 16384.0 - self.dig_T1 / 1024.0) * self.dig_T2)
var2 = ((raw_t / 131072.0 - self.dig_T1 / 8192.0) ** 2) * self.dig_T3
t_fine = var1 + var2
temp = t_fine / 5120.0
# Druckkompensation
var1 = t_fine / 2.0 - 64000.0
var2 = var1 * var1 * self.dig_P6 / 32768.0
var2 = var2 + var1 * self.dig_P5 * 2.0
var2 = var2 / 4.0 + self.dig_P4 * 65536.0
var1 = (self.dig_P3 * var1 * var1 / 524288.0 + self.dig_P2 * var1) / 524288.0
var1 = (1.0 + var1 / 32768.0) * self.dig_P1
press = 1048576.0 - raw_p
press = (press - var2 / 4096.0) * 6250.0 / var1
var1 = self.dig_P9 * press * press / 2147483648.0
var2 = press * self.dig_P8 / 32768.0
press = press + (var1 + var2 + self.dig_P7) / 16.0
# Luftfeuchtigkeitskompensation
h = t_fine - 76800.0
h = (raw_h - (self.dig_H4 * 64.0 + self.dig_H5 / 16384.0 * h)) * \
(self.dig_H2 / 65536.0 * (1.0 + self.dig_H6 / 67108864.0 * h * \
(1.0 + self.dig_H3 / 67108864.0 * h)))
h = h * (1.0 - self.dig_H1 * h / 524288.0)
hum = max(0.0, min(100.0, h))
return temp, press / 100.0, hum # °C, hPa, %
# Hauptprogramm
i2c = I2C(0, scl=Pin(23), sda=Pin(22), freq=400000)
# I²C-Scan zur Überprüfung
devices = i2c.scan()
print(f"Gefundene I²C-Geräte: {[hex(d) for d in devices]}")
# Sensor initialisieren
sensor = BME280(i2c)
# Messwerte ausgeben
while True:
temp, press, hum = sensor.read()
print(f"Temperatur: {temp:.1f} °C")
print(f"Luftdruck: {press:.1f} hPa")
print(f"Feuchte: {hum:.1f} %")
print("-" * 30)
sleep(2)
#C (Arduino Framework)
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// I²C-Pins für das Lernboard
#define I2C_SDA 22
#define I2C_SCL 23
// I²C-Adresse des Sensors
#define BME280_ADDR 0x76
Adafruit_BME280 bme;
void setup() {
Serial.begin(115200););
while (!Serial) delay(10););
// I²C mit den Board-spezifischen Pins initialisieren
Wire.begin(I2C_SDA, I2C_SCL);
Serial.println("BME280 Test - Lernboard");
// Sensor initialisieren
if (!bme.begin(BME280_ADDR)) {
Serial.println("BME280 nicht gefunden!");
Serial.println("Verkabelung prüfen.");
while (1) delay(10);) delay(10););
}
Serial.println("BME280 gefunden!");
Serial.println();
}
void loop() {
// Temperatur auslesen
float temperatur = bme.readTemperature();
Serial.print("Temperatur: ");
Serial.print(temperatur);
Serial.println(" °C");
// Luftdruck auslesen
float druck = bme.readPressure() / 100.0F;;
Serial.print("Luftdruck: ");
Serial.print(druck);
Serial.println(" hPa");
// Luftfeuchtigkeit auslesen
float feuchte = bme.readHumidity();
Serial.print("Feuchte: ");
Serial.print(feuchte);
Serial.println(" %");
// Ungefähre Höhe berechnen (Referenzdruck: 1013.25 hPa)
float hoehe = bme.readAltitude(1013.25););
Serial.print("Höhe: ");
Serial.print(hoehe);
Serial.println(" m");
Serial.println("------------------------------");
delay(2000););
}
#Tipps & häufige Fehler
-
Sensor wird nicht erkannt: Mit einem I²C-Scanner überprüfen, ob der Sensor auf Adresse 0x76 antwortet. Die Pins GPIO22 (SDA) und GPIO23 (SCL) müssen korrekt verbunden sein.
-
Unrealistische Werte: Die Kalibrierungsdaten müssen korrekt ausgelesen und angewendet werden. Bei Verwendung von Bibliotheken geschieht dies automatisch.
-
Eigenerwärmung: Der Sensor kann sich bei häufigen Messungen leicht erwärmen. Für genaue Temperaturmessungen längere Messintervalle wählen.
-
Verwechslung BMP280/BME280: Der BMP280 misst keine Luftfeuchtigkeit. Bei fehlenden Feuchtigkeitswerten prüfen, ob tatsächlich ein BME280 verbaut ist.
-
Höhenmessung ungenau: Die Höhenberechnung basiert auf dem Referenz-Luftdruck auf Meereshöhe (1013.25 hPa). Für genaue Messungen den aktuellen lokalen Luftdruck als Referenz verwenden.