In diesem Beitrag möchte ich dir den Umweltsensor BME680 vorstellen. Mit diesem Umweltsensor kannst du die relative Luftfeuchtigkeit, den Luftdruck sowie die Luftqualität messen.
Bezug
Den Sensor BME680 habe ich im Online Shop von Watterott für 13,65 € zzgl. Versandkosten bestellt.
Du findest diesen Sensor aber auch auf ebay.de* zu einem ähnlichen Preis.
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
Lieferumfang
Zum Lieferumfang des Sensors gehört neben der Platine eine 8fach Stiftleiste im Rastermaß 2,54 mm.
Technische Daten des Umweltsensors BME680
- Betriebsspannung 3,3V … 5V
- I2C Adresse
- 0x76 wenn SDO auf 0 gesetzt ist, oder
- 0x77 wenn SDO auf 1 gesetzt ist
rel. Luftfeuchtigkeitssensor
- Antwortzeit (t63%) 8 Sekunden
- Toleranz ± 3 %
- Hysteresis 1,5 % rel. Luftfeuchtigkeit
Luftdrucksensor
- Messbereich 300…1100 hPa
- rel. Toleranz ± 0.12 hPa (950…1050hPa bei 25°C)
- absolute Toleranz ± 1 hPa (bei 0… +40°C)
Temperatursensor
- Messbereich -40°C … +85°C
- volle Genauigkeit 0°C … +65°C
Luftqualitätssensor
- Antwortzeit (t33-63%) 1 Sekunde
- “Indoor Air Quality (IAQ) Index”
Anschluss vom Umweltsensor BME680 an den Arduino
Den Sensor BME680 kann man entweder auf ein Breadboard stecken und mit Breadboardkabel an den Arduino anschließen oder aber direkt mit dem Breadboardkabel. Jedoch bevorzuge ich den Anschluss über ein Breadboard, denn dann “fliegt” die Platine nicht auf dem Schreibtisch umher.
Auf dem Sensor sind folgende Pins angeschlossen, welche mit dem Arduino UNO R3 wie folgt verbunden werden:
Sensor | Arduino UNO R3 |
---|---|
GND | GND |
NC | |
VCC | 3,3V |
SCL / SCK | analoger Pin A5 |
SDA / SDI | analoger Pin A4 |
SDO | |
CS |
In diesem Beitrag möchte ich den Sensor über I2C betreiben d.h. ich werde die beiden Pins SCL & SDA verwenden.
Programmieren
Zum Programmieren des Sensors über I2C benötigst du neben einer zusätzlichen Bibliothek auch die Adresse des Sensors. Diese I2C Adresse kannst du zbsp. mit dem I2C Scanner Sketch abfragen. Du findest dieses sehr nützliche Programm unter https://playground.arduino.cc/Main/I2cScanner/.
Bibliothek zum betreiben des Sensors in der Arduino IDE
Für das Auslesen der Werte des Sensors verwende ich die Bibliothek von Adafruit welche recht einfach über den Bibliotheksverwalter installiert werden kann.
Dazu musst du zuerst nach dem Begriff “bme680” (1) suchen, und dann wählst du die Schaltfläche “Installieren” im Eintrag “Adafruit BME680 Library” aus. Nachdem diese aus dem Internet geladen und installiert wurde, kannst du dieses Fenster über die Schaltfläche “Schließen” (3) verlassen.
Dieser Bibliothek liegen 3 Beispiele bei, welche sofort lauffähig sind. Das Beispiel mit der Bezeichnung “bme680test” liefert auf der seriellen Schnittstelle folgende Ausgabe:
Ausgeben der Daten vom Umweltsensor BME680 auf einem Display
In dem Beispiel aus der Adafruit Bibliothek zum Sensor BME680 werden die Daten bereits auf der seriellen Schnittstelle ausgegeben, einzig soll nun die Luftqualität, welche in kOhm angezeigt werden, in einem anderen Format auf einem 0,96″ OLED Display angezeigt werden.
Aufbau der Schaltung
Das Pinout des Sensors habe ich bereits gezeigt, in diesem Abschnitt kommt lediglich ein zusätzliches 0,91″ OLED Display hinzu, welches ebenfalls über I2C angeschlossen wird.
Dieses 0,91″ OLED Display habe ich im Beitrag Arduino Lektion 76: 0,91 Zoll OLED Display ausführlich vorgestellt.
einrichten der zusätzlichen Bibliothek für das OLED Display
Für das OLED Display benötigen wir zusätzlich eine Bibliothek, welche ebenfalls von Adafruit kommt und über den Bibliotheksverwalter installiert wird.
Im Bibliotheksverwalter der Arduino IDE suchen wir nach dem Begriff “adafruit ssd1306” (1) und wählen der Liste den Eintrag “Adafruit SSD1306” (2) aus, nachdem die Installation abgeschlossen ist kann der Dialog über die Schaltfläche “Schließen” geschlossen werden.
Quellcode zum Programmieren vom Umweltsensor BME680
Für die Berechnung der Luftqualität habe ich auf dem GitHub Repository / BME680-Example ein Beispiel gefunden, welches diesen recht zuverlässig berechnet und als Text ausgibt.
#include <Wire.h> #include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Adafruit_Sensor.h> #include "Adafruit_BME680.h" #define BME_SCK 13 #define BME_MISO 12 #define BME_MOSI 11 #define BME_CS 10 #define SEALEVELPRESSURE_HPA (1013.25) Adafruit_BME680 bme; // I2C #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); float hum_score, gas_score; float gas_reference = 250000; float hum_reference = 40; int getgasreference_count = 0; void setup() { Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.display(); delay(1000); display.clearDisplay(); if (!bme.begin()) { Serial.println("Der Sensor BME680 konnte nicht gefunden werden!"); while (1); } bme.setTemperatureOversampling(BME680_OS_8X); bme.setHumidityOversampling(BME680_OS_2X); bme.setPressureOversampling(BME680_OS_4X); bme.setIIRFilterSize(BME680_FILTER_SIZE_3); bme.setGasHeater(320, 150); // 320*C for 150 ms } void loop() { if (! bme.performReading()) { Serial.println("Failed to perform reading :("); return; } delay(1000); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); String temp = "Temp.: "; temp += String(bme.temperature, 2); temp += "C"; display.println(temp); display.setCursor(0, 8); String hum = "Hum.: "; hum += String(bme.humidity, 2); hum += "%"; display.println(hum); String gas = "Gas: "; gas += String(bme.gas_resistance / 1000.0, 2); gas += " KOhms"; display.setCursor(0, 16); display.println(gas); String airQuality = getAirQuality(); display.setCursor(0, 24); display.println(airQuality); display.display(); display.clearDisplay(); } String getAirQuality() { float current_humidity = bme.readHumidity(); if (current_humidity >= 38 && current_humidity <= 42) hum_score = 0.25*100; // Humidity +/-5% around optimum else { //sub-optimal if (current_humidity < 38) hum_score = 0.25/hum_reference*current_humidity*100; else { hum_score = ((-0.25/(100-hum_reference)*current_humidity)+0.416666)*100; } } //Calculate gas contribution to IAQ index float gas_lower_limit = 5000; // Bad air quality limit float gas_upper_limit = 50000; // Good air quality limit if (gas_reference > gas_upper_limit) gas_reference = gas_upper_limit; if (gas_reference < gas_lower_limit) gas_reference = gas_lower_limit; gas_score = (0.75/(gas_upper_limit-gas_lower_limit)*gas_reference -(gas_lower_limit*(0.75/(gas_upper_limit-gas_lower_limit))))*100; float air_quality_score = hum_score + gas_score; if ((getgasreference_count++)%10==0) GetGasReference(); return CalculateIAQ(air_quality_score); } void GetGasReference(){ int readings = 10; for (int i = 1; i <= readings; i++){ gas_reference += bme.readGas(); } gas_reference = gas_reference / readings; } String CalculateIAQ(float score) { String IAQ_text = "Air quality is "; score = (100 - score) * 5; if (score >= 301) IAQ_text += "Hazardous"; else if (score >= 201 && score <= 300 ) IAQ_text += "Very Unhealthy"; else if (score >= 176 && score <= 200 ) IAQ_text += "Unhealthy"; else if (score >= 151 && score <= 175 ) IAQ_text += "Unhealthy for Sensitive Groups"; else if (score >= 51 && score <= 150 ) IAQ_text += "Moderate"; else if (score >= 00 && score <= 50 ) IAQ_text += "Good"; return IAQ_text; }
Vergleich der Sensordaten vom BME680 mit einem Aranet4
Wenn man die Sensordaten vom BME680 mit einem Aranet4 vergleicht, sieht man das die Werte für die Temperatur, rel. Luftfeuchtigkeit relativ dicht beieinander liegen. Einzig die Luftqualität ist deutlich anders, denn der Aranet4 misst deutlich genauer und liefert den Wert in “ppm”. Der BME680 jedoch misst den Wert in IAQ und diesen Wert müsste man zunächst umrechnen.
Wenn du einen zuverlässigen Wert für die Luftqualität benötigst so empfehle ich dir die Bibliothek von Bosch welche du auf dem GitHub Repository https://github.com/BoschSensortec/BME680_driver findest.
Hallo 🙂
Ich habe heute einfach dieses Projekt mit dem LCD nachgebaut und deinen Code kopiert. Wieso gibst du Gas in kOhm aus statt bspw. den Luftdruck auszugeben?
Was müsste man dann im Code genau ändern?
Ich bin absoluter Anfänger und versuche das nachzuvollziehen.
Viele Grüße!
Hallo Felix,
vielen Dank für deinen Kommentar.
Die Ausgabe des Wertes für GAS ist in “kOhm” (KiloOhm) da der Sensor für einen Aussagekräftigen Wert für ein Gasgemisch zu ungenau ist.
Man müsste diesen zuvor immer justieren / kalibrieren, wie es die teuren Sensoren machen.
Gruß
Stefan