Skip to main content

Umweltsensor

#BME280 – Temperatur, Luftfeuchtigkeit & Luftdruck

Kombinierter Umweltsensor für präzise Messungen von Temperatur, relativer Luftfeuchtigkeit und barometrischem Druck.


#Ü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.


#Weiterführende Links