Der Gassensor BME680 von Bosch ist eine kostengünstige Sensor und mit etwas Geschick steht er den teuren Fertiglösung in Nichts nach. Für mich steht dabei eine quantitative Bestimmung der Luftqualität in Innenräumen im Vordergrund. In diesem Beitrag habe ich den BME680 mit der Netatmo Wetterstation verglichen. Die Netatmo Wetterstation ist laut Hersteller als CO2-Sensor ausgeführt, wohingegen der BME680 flüchtige organische Verbindungen (engl. VOC – volatile organic compounds) detektieren kann. Die Definition von VOC ist laut wikipedia von Land zu Land unterschiedlich und so ist in den USA CO2 nicht als VOC zu sehen.
Der BME680 gibt grundsätzlich einen Index für die Luftqualität aus und ist in der Lage ein Äquivalent für den CO2-Wert zu berechnen. Dieser Index für die Luftqualität, kurz IAQ, korreliert sehr gut mit dem CO2-Wert der Netatmo Wetterstation, wie in diesem Beitrag zu sehen ist.
Da es mir rein um eine Indikation der Luftqualität in Innenräumen geht, ist es für mich auch in Ordnung, dass der IAQ-Index einer von Bosch generierten einheitenloser Wert ist. Die Größe des Wertes ist ein Maß für die Qualität der Umgebungsluft und wird für das Setzen von Aktion herangezogen.
Um den Sensor an einem beliebigen Ort zu betreiben, verwende ich den Mikrocontroller ESP8266 und greife auf dessen Wifi-Schnittstelle zu. Über die I2C Schnittstelle kommunizieren BME680 und ESP8266 miteinander.
Pinning – BME680 und ESP8266 verkabeln
In meinem Beispiel verwende ich einen NodeMCU, welcher mit dem BME680 verkabelt wird. Den BME680 gibt es in verschiedenen Ausführung. Grundsätzlich ist das Pinning jedoch wie folgt:
- Vin -> 3.3V
- GND -> GND
- SCL/CLK -> D1
- SDA/SDI -> D2
Eventuell muss der Pin CS auf High, also 3.3V gezogen werden, ansonsten ist die I2C Schnittstelle nicht aktiv und das SPI ist stattdessen aktiv (siehe Datenblatt Kapitel 6. Digital Interfaces). Vielfach ist aber schon ein Pull Up Widerstand verbaut und somit muss der CS Pin nicht angeschlossen werden. Kommt es aber zu Verbindungsproblemen, kann trotzdem eine Verbindung zwischen CS und 3.3V helfen. Ist SPI einmal aktiv, kann erst ein Power Cycle diesen Zustand aufheben.
Bosch Library – BSEC
Um den Sensor BME680 meiner Meinung nach sinnvoll betreiben zu können, benötigt man die Bosch Library. Diese steht auf github zum Download zur Verfügung.
Unter Code > Download ZIP können die benötigten Files heruntergeladen werden. Weiter unten befindet sich eine Anleitung auf Englisch, die den Upload der Software auf den ESP8266 mittels Arduino IDE erklärt. Da dies beim ersten Anlauf etwas knifflig sein könnte, zeige ich euch Schritt für Schritt wie es funktioniert.
Die Installation über Arduino und dessen Library Manager ist auch möglich. Unter Tools > Library Manager mit dem Stichwort BSEC wurde ich fündig:
Da es einfacher geht, installiere ich die Library mittels Library Manager. Stand 11.03.2021 ist die Version 1.6.1480 verfügbar und wird in diesem Tutorial verwendet.
Zwischenschritt, ESP8266 unter Arduino einrichten
Falls das Board NodeMCU noch nicht unter Arduino installiert wurde, muss dieser Zwischenschritt noch erfolgen. Dafür möchte ich auf diesen Beitrag verweisen.
In meinem Fall wähle ich folgendes Board aus: NodeMCU 1.0 (ESP-12E Module)
Falls der ESP8266 unter Port nicht erkannt wird, kann es sein, dass der CH340 USB Driver noch nicht installiert wurde. Der Geräte Manager unter Windows gibt Aufschluss darüber, ob der Driver vorhanden ist. Für die Installation des Drivers möchte ich auf einen weiteren externen Beitrag verweisen.
BSEC Software > Example basic
Um den Gassensor auswerten zu können, greife ich auf das Beispiel basic von Bosch zurück.
Bevor mit dem Upload begonnen werden kann, ist vorab noch eine Modifikation der Datei plaform.txt durchzuführen. Die Datei befindet sich in folgendem Verzeichnis:
C:\Users\YOURUSERNAME\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4
Von Zeile 82 bis 89 ist folgender Abschnitt:
# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
compiler.S.extra_flags=
compiler.cpp.extra_flags=
compiler.ar.extra_flags=
compiler.objcopy.eep.extra_flags=
compiler.elf2hex.extra_flags=
Durch nachfolgende Zeilen zu ersetzen:
# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
#compiler.c.elf.extra_flags=-v
compiler.cpp.extra_flags=
compiler.S.extra_flags=
compiler.ar.extra_flags=
compiler.elf2hex.extra_flags=
compiler.libraries.ldflags=
Weiters ist in Zeile 112 folgender Abschnitt:
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {build.exception_flags} -Wl,-Map "-Wl,{build.path}/{build.project_name}.map" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{archive_file_path}" {compiler.c.elf.libs} -Wl,--end-group "-L{build.path}"
durch diese Zeilen zu ersetzen:
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {build.exception_flags} -Wl,-Map "-Wl,{build.path}/{build.project_name}.map" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{archive_file_path}" {compiler.c.elf.libs} {compiler.libraries.ldflags} -Wl,--end-group "-L{build.path}"
Dieser Schritt ist auch unter dem Kapitel 3 – Modify the platform.txt file des Tutorials von Bosch auf github nachzulesen.
Bevor mit dem Flashen begonnen werden kann, muss eventuell die I2C-Adresse angepasst werden. Den Sensor den ich verwende, hat die Adresse 0x77. Ein Blick in die Datei bme680_defs.h offenbart, dass sich hierbei um die Secondary Address handelt. Seid ihr euch nicht sicher, welche Adresse euer Gerät hat, kann man dies mit dem I2cScanner herausfinden.
Daher habe ich folgende Zeil in der basic.ino
iaqSensor.begin(BME680_I2C_ADDR_PRIMARY, Wire);
durch nachfolgende Zeile ersetzt:
iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire);
Nach dem Speichern des Projekts, kann mit dem Upload begonnen werden. Nach einem erfolgreichen Upload sollte der Log in Arduino ungefähr so aussehen:
Der Serial Monitor sollte auch schon Daten ausgeben. Viele Daten, wie etwa IAQ oder CO2 äquivalent sind anfänglich noch nicht plausibel. Nach ca. 30 Minuten kalibrieren sollten die Werte jedoch belastbar sein. In diesem Zusammenhang ist mir aufgefallen, dass die Temperatur etwas höher ist, als die tatsächliche Umgebungstemperatur. Dies liegt wahrscheinlich daran, dass der Sensor im inneren ein Heizelement hat, welches für den Gassensor benötigt wird. Auch eine kurzzeitige Erwärmung beeinflusst die Temperaturmessung. Somit werde ich diesen Sensor als reinen Gassensor verwenden und auf die anderen Messwert verzichten.
Static IAQ, IAQ – Was ist das?
Wie am Anfang dieses Beitrags angesprochen, gibt der Sensor einen Index for Air Quality (IAQ) aus. Diesen Wert nutze ich für das Setzen von Aktion, wie etwa Push Nachrichten oder Text-to-Speech Nachrichten über Alexa. Ein IAQ-Wert über 150 bedeutet für mich Fenster auf und Lüften.
Der BME680 ist auch in der Lage einen zum IAQ äquivalenten CO2-Wert zu errechnen. Dieser Wert ist nur errechnet, da dieser nicht direkt gemessen werden kann. Für mich nicht weiter von Interesse.
Dieser Sensor stellt einen Static IAQ-Wert und einen IAQ-Wert zur Verfügung. Laut Datenblatt ist sollte der Static IAQ-Wert für „stationary devices“, also stationäre Geräte verwendet werden – also genau das was ich suche. Offenbar läuft im Hintergrund ein spezieller Algorithmus. Im Umkehrschluss ist der „normale“ IAQ-Wert für mobile Geräte anzuwenden (siehe Bosch BME680 Datenblatt, Seite 25)
Daten an den FHEM Server übermitteln- Webserver
Der schnellste und einfachste Weg war für mich das Beispiel basic um die Webserver Funktionalität zu erweitern. Mittels dem Modul HTTPMOD wird auf die generierte Website zugreifen und benötigten Daten werden extrahiert.
Wie ein Webserver im Detail erstellt wird, möchte in diesem Zusammenhang nicht näher erklären und stattdessen auf die vielen Tutorials im Netz verweisen (z.B.: LINK)
Mein Code steht hier zum Download bereit. In Zeile 8 und Zeile 9 sind SSID und Passwort des eigenen Netzwerk einzugeben.
Nach einem erfolgreichen Upload ist unter der vergebenen IP-Adresse die Seite power aufzurufen. In meinem Fall sieht es wie folgt aus:
Die vergebene IP-Adresse kann über das Webinterface des Routers entnommen werden. In meinem Fall hat der Router die Adresse 192.168.1.1. Hier kann auch gleich diesem Gerät eine fixe IP-Adresse zugeordnet werden, da das Modul HTTPMOD auf diese IP-Adresse zugreifen wird.
Ab in das Webinterface des FHEM Servers… Nachfolgende Zeilen werden der fhem.cfg hinzugefügt. Die Abtastrate wird in meinem Fall auf 120 Sekunden gesetzt. Ich werte die Parameter CO2_equivalent, temperature, relative_humidity, IAQ, Static_IAQ, breath_VOC_equivalent und gas_resistance aus.
define bme680_webserver_test_1 HTTPMOD http://192.168.1.136/power 120
attr bme680_webserver_test_1 userattr reading1Name reading1Regex reading2Name reading2Regex reading3Name reading3Regex reading4Name reading4Regex reading5Name reading5Regex reading6Name reading6Regex reading7Name reading7Regex
attr bme680_webserver_test_1 enableControlSet 1
attr bme680_webserver_test_1 enableCookies 1
attr bme680_webserver_test_1 enforceGoodReadingNames 1
attr bme680_webserver_test_1 reading1Name C02equivalent
attr bme680_webserver_test_1 reading1Regex CO2_equivalent:([\d.]+)
attr bme680_webserver_test_1 reading2Name Temperature
attr bme680_webserver_test_1 reading2Regex temperature:([\d.]+)
attr bme680_webserver_test_1 reading3Name Humidity
attr bme680_webserver_test_1 reading3Regex relative_humidity:([\d.]+)
attr bme680_webserver_test_1 reading4Name IAQ
attr bme680_webserver_test_1 reading4Regex IAQ:([\d.]+)
attr bme680_webserver_test_1 reading5Name Static_IAQ
attr bme680_webserver_test_1 reading5Regex Static_IAQ:([\d.]+)
attr bme680_webserver_test_1 reading6Name breath_VOC_equivalent
attr bme680_webserver_test_1 reading6Regex breath_VOC_equivalent:([\d.]+)
attr bme680_webserver_test_1 reading7Name gas_resistance
attr bme680_webserver_test_1 reading7Regex gas:([\d.]+)
attr bme680_webserver_test_1 room BME680
Für eine schöne Darstellung ändere ich das Attribute stateFormat wie folgt ab:
attr bme680_webserver_test_1 stateFormat {sprintf("Static-IAQ: %.2f , Temperature: %.2f °C", ReadingsVal($name,"Static_IAQ",0),ReadingsVal($name,"Temperature",0) )}
Dabei erhalte ich folgendes Resultat:
Ein Logging füge ich in diesem Zusammenhang auch gleich hinzu:
define LOG_bme680_webserver_test_1 FileLog ./log/bme680_webserver_test_1-%Y-%m.log bme680_webserver_test_1
3D Daten – Alles schön verpackt
Zum Abschluss verpackte ich NodeMCU und BME680 noch in einem Gehäuse, damit alles sauber aufgestellt werden kann. Daten stehen hier zum Download bereit:
Zusammenfassung
In nur wenigen Schritten kann ein kostengünstiger Gassensor für unter 10 Euro gebaut werden. Unter der Voraussetzung man kauft die Komponenten direkt aus dem asiatischen Raum zu.
Leider sind die Preise für den BME680 in letzter Zeit etwas gestiegen. Vielleicht hängt dies mit dem weltweiten Engpass von diversen Elektronikkomponenten zusammen. So kostete der BME680 im August 2020 nur 6 Dollar und mit Stand heute, März 2021 liegt der Preis beim doppelten.
In Zeiten wie diesen, mit viel Homeoffice, find ich so ein Gadget besonders interessant und wichtig. So kann bei schlechter Luftqualität eine Benachrichtigung an die Personen im Haushalt erfolgen. Regelmäßiges Lüften beugt auch der Schimmelbildung vor.