Luftdruck-/Luftfeuchtesensor BME280

Fast kompatibel zum Luftdrucksensor BMP280 der Firma Bosch (siehe hier), gibt der BME280 neben dem gemessenen Luftdruck und der Umgebungstemperatur auch die Luftfeuchtigkeit als Rohwert aus, wobei die Ausgabe wahlweise über I2C- oder über SPI-Schnittstelle erfolgen kann. Mit Hilfe von 18 im Sensor gespeicherten Kompensationsparametern kann dann aus den Rohwerten der Luftdruck am Standort (Stationsniveauluftdruck), die Luftfeuchte und die Umgebungstemperatur ermittelt werden.

BME280-Breakout Boards sind in verschiedenen Ausführungen erhältlich, z.B. mit oder ohne Pegelwandler für die Versorgungs- und Logikspannung oder mit ausgeführter I2C- und SPI-Schnittstelle oder nur mit I2C-Schnittstelle. Da der Sensor selbst, sowohl was die Versorgungspannung, als auch die Logikspannung betrifft, laut Datenblatt für maximal 4,25 V ausgelegt ist, sind bei Verwendung von Mikrocontroller mit 5 V - Versorgungs- und Logikspannung (wie z.B. beim Arduino Uno, Nano oder Mega) unbedingt Pegelwandler einzusetzen.

 

                       

Bild 1: Luftdrucksensor BME280 auf einem Mini Breakout Board (Abmessg. ca. 10 x 13 mm), mit Pegelwandler für Versorgungs- und Logik-spannung von 5 V.


           

Bild 2: Luftdrucksensor BME280 auf einem Breakout Board mit I2C- und SPI-Schnittstelle, aber ohne Pegelwandler für Versorgungs- und Logikspannung von 5 V.


Testaufbau mit I2C-Schnittstelle:

Hier verwende ich das im Bild 1 dargestellte Mini-Breakout-Board. Es hat sowohl die Pegelwandler für Versorgungs- und Signalspannung von 5 V integriert, als auch die Pullup-Widerstände für die I2C-Schnittstelle, hat aber keine SPI-Schnittstelle auf die Stiftleiste herausgeführt.


I2C-Adresse:

Die Standard-I2C-Adresse des in Bild 1 abgebildeten Moduls ist 0x76 und kann mit einer Lötbrücke am Modul auf 0x77 geändert werden. Das habe ich aber nicht ausprobiert! Laut Bosch-Datenblatt ist der SDO-Pin am Sensor das Adressbit 0 der I2C-Adresse, der entweder auf GND oder auf VDD gelegt werden muss.


Verwendete Bauteile:

  • 1 Arduino Nano
  • 1 BME280-Luftdrucksensor Mini Breakout Board (siehe Bild 1)

Optional:

  • 2 Widerstände 10 kOhm (I2C-Pullup-Widerstände, falls diese nicht am BMPE280 Breakout Board vorhanden sind)


Testaufbau mit SPI-Schnittstelle:

Hier verwende ich das im Bild 2 dargestellte Breakout-Board. Es hat die Anschlüsse für I2C- und SPI-Schnittstelle auf die Stiftleiste herausgeführt, hat aber keine Pegelwandler für Versorgungs- und Signalspannung von 5 V integriert. Laut Bosch-Datenblatt ist die absolute maximale Versorgungs- und Logikspannung beim BME280 zwar deutlich höher als 3,3 V aber eben nicht 5 V. Daher ist der Versorgung des Bausteins mit 3,3 V und der Einsatz eines Logic-Level-Converters (5 V / 3,3 V bidirektional) für die Signalleitungen unbedingt zu empfehlen.


Verwendete Bauteile:

  • 1 Arduino Nano
  • 1 BME280 Luftdrucksensor (siehe Bild 2)
  • 1 Logic-Level-Converter, bidirektional, 4-fach


Anschluss des Sensors an Arduino Uno/Nano und Mega:

       Arduino                     Sensor (SPI)

Uno/Nano   Mega

  5V             5V         ->      VDD

  GND          GND      ->      GND

  D13           D52      ->       SCL  (CLK)

  D12           D51      ->       SDO (MISO)

  D11           D50      ->       SDA  (MOSI)

  Dx             Dx        ->       CSB    (SS)

Dx: Während die Pins für CLK, MISO und MOSI am Arduino fix vorgegeben sind (Hardware-SPI), kann der SS-Pin (Chipselect CS) softwaremäßig frei vergeben werden. Im nachfolgenden Beispiel wird für Dx der Pin D10 verwendet.

Library MyBME280 für Arduino und Attiny85:

Für Arduino und Attiny85 (Attiny45 hat zu wenig Flash-Speicher) habe ich für diesen Sensor eine Library mit folgenden Funktionen geschrieben:


  • Verwendung der I2C- oder SPI-Schnittstelle (SPI-Schnittstelle nicht für Attiny)
  • Abfrage, ob der Baustein ansprechbar ist (Auslesen der Chip-Identifikationsnummer, welche 0x60 ist)
  • Setzen von einzelnen Parameter, wenn andere Parameter als die Voreingestellten erforderlich sind  1)
  • Setzen von definierten Parametersätzen  2)
  • Initialisieren der Parameter und Einlesen der Kalibrierungskoeffizienten
  • Ermittlung der Umgebungstemperatur
  • Ermittlung des Luftdrucks am Standort (Stationsluftdruck)
  • Ermittlung des reduzierten Luftdrucks bezogen auf Meereshöhe (Reduzierter Luftdruck)


1)  Die in der Library voreingestellten Parameter sind:

  • NORMAL_MODE
  • P_OVERSAMPLING_x8
  • T_OVERSAMPLING_x2
  • H_OVERSAMPLING_x8
  • STANDBY_TIME_1000
  • FILTER_COEFF_4

Die einzelnen Parameter werden im Control-, Config- und Humidity-Controlregister des BME280 gespeichert (siehe Register). Was die einzelnen Parameter bedeuten und welche Änderungsmöglichkeiten es gibt, habe ich nachfolgend zusammengefasst:

Setzen des Modus

Beim BME280 gibt es drei Betriebsmoden:

  • SLEEP_MODE: Im Sleep-Modus erfolgen keine Messungen
  • NORMAL_MODE: Im Normal-Modus erfolgen die Messungen zyklisch. Die Zykluszeit ist abhängig von der "Standby Time" und den Oversampling-Einstellungen.
  • FORCED_MODE: Wenn der Forced-Modus gesetzt wird, führt der Sensor genau eine Messung durch und wechselt anschließend in den Sleep-Modus, solange bis der Forced-Modus für eine nächste Messung erneut gesetzt wird.

Setzen von Temperatur-Oversampling:

Info: In der digitalen Signalverarbeitung spricht man von Oversampling (Überabtastung), wenn ein Signal mit einer höheren Abtastrate bearbeitet wird, als es für die Darstellung der Signalbandbreite benötigt wird, was z.B. bei Analog/Digitalwandler Vorteile bringen kann -> siehe z.B. de.wikipedia.org/wiki/%C3%9Cberabtastung

Mit dem Parameter kann die Temperaturmessung entweder ausgeschaltet werden oder es wird die Auflösung der Temperaturmessung vorgegeben. Eine ausgeschaltete Temperaturmessung kann nützlich sein, um extrem schnelle Druckmessungen durchzuführen.

  • T_OVERSAMPLING_x0:   Keine Temperaturmessung
  • T_OVERSAMPLING_x1:   Auflösung 16 Bit
  • T_OVERSAMPLING_x2:   Auflösung 17 Bit
  • T_OVERSAMPLING_x4:   Auflösung 18 Bit
  • T_OVERSAMPLING_x8:   Auflösung 19 Bit
  • T_OVERSAMPLING_x16: Auflösung 20 Bit

Jeder Erhöhungsschritt reduziert das Rauschen und - wenn das Filter ausgeschaltet ist - erhöht sich die Auflösung um 1 Bit. Bei eingeschaltetem Filter ist die Auflösung immer 20 Bit! Die gemessene Temperatur ist auch für die Genauigkeit der Berechnung des Drucks aus den Rohwerten erforderlich.

Setzen von Druck-Oversampling:

Mit dem Parameter kann die Druckmessung entweder ausgeschaltet werden oder es wird die Auflösung der Druckmessung vorgegeben:

  • P_OVERSAMPLING_x0:   Keine Druckmessung
  • P_OVERSAMPLING_x1:   Auflösung 16 Bit
  • P_OVERSAMPLING_x2:   Auflösung 17 Bit
  • P_OVERSAMPLING_x4:   Auflösung 18 Bit
  • P_OVERSAMPLING_x8:   Auflösung 19 Bit
  • P_OVERSAMPLING_x16: Auflösung 20 Bit

Jeder Erhöhungsschritt reduziert das Rauschen und - wenn das Filter ausgeschaltet ist - erhöht sich die Auflösung um 1 Bit. Bei eingeschaltetem Filter ist die Auflösung immer 20 Bit!

Setzen von Feuchte-Oversampling:

Mit dem Parameter kann die Feuchtemessung entweder ausgeschaltet werden oder es wird die Auflösung der Feuchtemessung vorgegeben.

  • H_OVERSAMPLING_x0:   Keine Feuchtemessung
  • H_OVERSAMPLING_x1:   Auflösung 16 Bit
  • H_OVERSAMPLING_x2:   Auflösung 16 Bit
  • H_OVERSAMPLING_x4:   Auflösung 16 Bit
  • H_OVERSAMPLING_x8:   Auflösung 16 Bit
  • H_OVERSAMPLING_x16: Auflösung 16 Bit

Jeder Erhöhungsschritt reduziert das Rauschen. Die Auflösung beträgt immer 16 Bit.

Setzen der Standby-Zeit: Das ist jene Zeit, wo im Normal-Modus der Sensor nach einer Messung nicht aktiv ist, also keine Messungen durchführt werden:

  • STANDBY_TIME_0p5:   Standby Zeit = 0,5 ms
  • STANDBY_TIME_10:     Standby Zeit = 10 ms
  • STANDBY_TIME_20:     Standby Zeit = 20 ms
  • STANDBY_TIME_62p5: Standby Zeit = 62,5 ms
  • STANDBY_TIME_125:   Standby Zeit = 125 ms
  • STANDBY_TIME_250:   Standby Zeit = 250 ms
  • STANDBY_TIME_500:   Standby Zeit = 500 ms
  • STANDBY_TIME_1000: Standby Zeit = 1000 ms

Setzen des Filter-Koeffizienten:

Gibt an, wie viele Abtastungen (samples) erforderlich sind, bis - bei einer sprunghaften Änderung des Messwertes - die Datenausgabe mindestens 75 % der Änderung gefolgt ist:

  • FILTER_COEFF_0:    1 Abtastung (Filter ausgeschaltet)
  • FILTER_COEFF_2:    2 Abtastungen
  • FILTER_COEFF_4:    5 Abtastungen
  • FILTER_COEFF_8:   11 Abtastungen
  • FILTER_COEFF_16: 22 Abtastungen

Je höher die Filter-Koeffizient, desto langsamer nähert sich der Messwert dem tatsächlichen Druck an und umso geringer wird das Rauschen.

Achtung: Die Zusammenhänge der einzelnen Parameter in Bezug auf Stromverbrauch, Signalauflösung, Messzeiten, Signalrauschen, etc. kann im Datenblatt des Sensors ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME280_DS001-12.pdf nachgelesen werden!


2)  Für 4 Szenarien können die Parameter als Parametersätze gesetzt werden. Die Werte der Parametersätze entsprechen den vorgeschlagenen Werten des Bosch-Datenblattes des Sensors:

Weathermonitoring: Nur ganz geringe Messrate erforderlich, geringe Leistungsaufnahme, maximales Höhenrauschen möglich, Messrate: z.B. 1/60 Hz (1 mal pro Minute)

  • SLEEP_MODE (Aufruf des Forced_Modus im Anwenderprogramm mit der Funktion "startSingleMeas()", z.B. 1 mal pro Minute)
  • P_OVERSAMPLING_x1
  • T_OVERSAMPLING_x1
  • H_OVERSAMPLING_x1
  • FILTER_COEFF_0
  • STANDBY_TIME_xxxx (Standby time im Forced Mode ohne Bedeutung)

Humidity Sensing: Geringe Messrate erforderlich, Leistungsaufnahme ist gering, Messrate: z.B. 1 Hz

  • SLEEP_MODE (Aufruf des Forced_Modus im Anwenderprogramm mit der Funktion "startSingleMeas()", z.B. 1 mal pro Sekunde)
  • P_OVERSAMPLING_x0 (Luftdruckmessung ausgeschaltet)
  • T_OVERSAMPLING_x1
  • H_OVERSAMPLING_x1
  • FILTER_COEFF_0
  • STANDBY_TIME_xxxx (Standby time im Forced Mode ohne Bedeutung)

Indoor Navigation: Geringst mögliches Höhenrauschen, sehr geringe Filter-Bandbreite, erhöhte Leistungsaufnahme. Messrate: 25 Hz

  • NORMAL_MODE
  • P_OVERSAMPLING_x16
  • T_OVERSAMPLING_x2
  • H_OVERSAMPLING_x1
  • FILTER_COEFF_16
  • STANDBY_TIME_0p5

Gaming: Geringes Höhenrauschen, sehr geringe Filter-Bandbreite, erhöhte Leistungsaufnahme. Messrate: 83 Hz

  • NORMAL_MODE
  • P_OVERSAMPLING_x4
  • T_OVERSAMPLING_x1
  • H_OVERSAMPLING_x0 (Luftfeuchtemessung ausgeschaltet)
  • FILTER_COEFF_16
  • STANDBY_TIME_0p5


Die Library kann hier heruntergeladen werden:

Sollte die Library jemand verwenden oder testen, würde ich mich über eine Rückmeldung sehr freuen!


Version 2.1

MyBME280.cpp.txt 

MyBME280.h.txt 

keywords.txt 

Leider kann ich hier keine "cpp"- oder "h"-Files hochladen, daher zum Verwenden der Libraries ".txt" aus den Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MyBME280" dort speichern, wo eure anderen Libraries gespeichert sind.


Zur Auflistung der Funktionen der Library geht es hier: Funktionen

Programmbeispiele MyBME280 mit I2C- oder SPI-Schnittstelle:

Beispiel 1 für Arduino:

Im Beispiel 1 (mit I2C-Schnittstelle) werden die Parameter des Sensors auf "Weather Monitoring" gesetzt und mit der Funktion startSingleMeas() wird alle 60 Sekunden eine neue Messung gestartet und die Messergebnisse angezeigt. Zur Verwendung der SPI-Schnittstelle müssen die entsprechenden Zeilen am Beginn des Sketches auskommentiert bzw. mit Kommentarzeichen versehen.


//Testprogramm 1 für Luftdrucksensor BME280
//Code fuer Arduino
//Author Retian
//Version 1.1


//Prototypen:
void leseMesswerte(void);
void ausgabeMesswerte(void);


#include <MyBME280.h>


//Hier auswählen zwischen I2C- und SPI-Schnittstelle

//Mit I2C-Schnittstelle:

#define BME280_I2cAdd 0x76 //I2C-Adresse
MyBME280 BME(BME280_I2cAdd);

//Mit SPI-Schnittstelle:

//#define cs 10 //CS-Pin für SPI-Schnittstelle
//MyBME280 BME(cs, BME280_SPI);


unsigned long zeit;

float luftTemp, luftDruck, redLuftDruck, luftFeuchte;
int hoehe = 460; //Messort 460 m ueber dem Meer


void setup() {
  Serial.begin(115200);
  if (BME.isReady())
  {
    Serial.println("BME280 ok");
    BME.setWeatherMonitoring(); //Setze Parameter für Wetterueberwachung
    BME.init();
    //Beim Initialisieren des Parametersatzes für Wetterueberwachung (Forced-Mode)
    //wird bereits eine Messung vom Sensor durchgeführt und als Rohwerte gespeichert
    leseMesswerte();
    ausgabeMesswerte();
  }
  else
  {
    Serial.println("BME280 Fehler");
    while (1); //hier geht es im Fehlerfall nicht weiter
  }
  zeit = millis();
}


void loop() {
  if (millis() > zeit + 60000) //Messung alle 60 Sekunden
  {
    BME.startSingleMeas();
    leseMesswerte();
    ausgabeMesswerte();
    zeit = millis();
  }
}


void leseMesswerte()
{
  luftTemp = BME.readTemp();
  luftDruck = BME.readPress();
  redLuftDruck = BME.readReducedPress(hoehe);
  luftFeuchte = BME.readHumidity();
}


void ausgabeMesswerte()
{
  Serial.print("Lufttemperatur  : ");
  Serial.print(luftTemp);
  Serial.println(" Grad C");
  Serial.print("LuftDruck       : ");
  Serial.print(luftDruck);
  Serial.println(" hPa");
  Serial.print("Red. LuftDruck  : ");
  Serial.print(redLuftDruck);
  Serial.println(" hPa");
  Serial.print("Luftfeuchtigkeit: ");
  Serial.print(luftFeuchte);
  Serial.println(" %");
  Serial.println();
}


Beispiel 2 für Attiny85 (nur mit I2C-Schnittstelle):

Zum Testen eines BME280 mit einem Attiny85 (Attiny45 hat zu wenig Flash-Speicher) kann - mit entsprechenden Anpassungen bei Stiftbelegung und I2C-Adresse sowie der verwendeten Library - die Verdrahtung und das Programmbeispiel für den BMP280 verwendet werden -> siehe BMP280 mit Attiny85

Da die SPI-Schnittstelle 4 von 5 verfügbaren Pins beim Attiny85 belegen würde, habe ich die SPI-Schnittstelle für Attiny nicht realisiert.