Stinkt das hier? – Teil 1 mit dem Bosch BME680

Mich, und die mich umgebende Welt, in Zahlen zu erfassen, um sie so besser verstehen zu können, treibt mich schon lange dazu, ab und an in entsprechende Geräte zu investieren. Vor ein paar Monaten kaufte ich mir just for fun ein fertiges Feinstaub-Messgerät (PM1.0 PM2.5 PM10 Detector von Banggood). Also ein Gerät zur Einschätzung der Luftqualität. Bei Recherchen zu diesem Thema wurde mir schnell klar, das es nicht nur der Feinstaub ist, der diese bestimmt und ich sah nach, was man denn noch alles messen könnte. So bin ich auf AQI und CO2 gestoßen und passende Sensoren dazu. Diesmal wollte ich aber kein fertiges Gerät kaufen, sondern meine Erfahrung mit dem ESP32 dazu nutzen, die Sensor-Daten selbst zu verarbeiten und sinnvoll anzuzeigen.

Zu diesem Artikel gibt es ein Video:

Bei Banggood bestellte ich mir darum einen BME680 von Bosch und einen MH-Z19B von Winsen Electronics. Die beiden Sensoren sind grundsätzlich unterschiedlich und arbeiten auf verschiedene Weise. Der BME680 kann flüchtige organische Verbindungen (Volatile Organic Compounds, kutz VOC) entdecken, wie Ethanol, Alkohol und Kohlenmonoxid. Er kann wirklich gut und unmittelbar Alkohol registrieren, wie ich durch Anhauchen nach einem Schluck Glühwein, festgestellt habe. 🙂 Der MH-Z19B kann hingegen nur Kohlenstoffdioxid registrieren.

Der BME680 basiert auf einem Metalloxid (MOX) -Gassensorelement, welches auf der Leitwertsänderung einer gassensitiven MOX-Halbleiterschicht in Folge der Einwirkung von Gasen, beruht. Dabei verursachen reduzierende Gase eine Verringerung des Widerstands und oxidierende Gase eine Widerstandserhöhung.

Der MH-Z19B funktioniert völlig anders: Hier gibt es eine von der Umgebungsluft durchströmte Röhre, in der am einen Ende eine Infrarot-Lichtquelle und am anderen ein Infrarotdetektor und ein Filter platziert ist. Der Filter lässt nur die Frequenzanteile des Infrarotlichtes durch, die von den Molekülen des Kohlenstoffdioxid am ehesten absorbiert werden. Dadurch ist es für den Infrarot-Detektor um so dunkler, um so mehr Kohlenstoffdioxid vorhanden ist.

Bei der Recherche fand ich es sehr interessant, dass der BME680 überhaupt kein Kohlendioxid erkennen kann, auch nicht teilweise! Ich wusste, das der BME680 kein Sensor ist, um ausschließlich Kohlendioxid nachzuweisen. Ich wusste aber auch, dass er einen bestimmten Typ von Gasen detektieren kann und ich nahm an, dass dazu auch Kohlendioxid gehört. Meine Schlussfolgerung war, dass, wenn er in einer Umgebung anspricht, in der Menschen sind, es eine gewisse Wahrscheinlichkeit gibt, dass es das ausgeatmete  Kohlendioxid dieser Menschen ist, auf das der Sensor reagiert. Bei einem genaueren Blick in das Datenblatt des Sensors, kann man aber an keiner Stelle lesen, dass er auch auf Kohlendioxid anspricht! Die beiden Gase entstehen aber durch verschiedene Prozesse und ich kann erst einmal nicht erkennen, wie man aus Kohlenmonoxid den Kohlendioxidanteil in der Atemluft erkennen kann. Woraufhin ich nach Informationen gesucht habe und auf diesen Artikel gestoßen bin.

Soweit ich das verstanden habe, besitzen beide Sensoren ihre ganz eigenen Mikrocontroller. Hier wird also nicht einfach ein Fotowiderstand über einen Spannungsteiler an einen analogen Eingang eines Arduino gelötet und dann der per Analog-Digital Wandler die Spannung abgefragt. Stattdessen kommuniziert man über Anschlussleitungen mit einem Mikrocontroller, der sozusagen, als Vermittler zwischen unserem ESP32 und dem eigentlichen Sensor steht.

Im nachfolgenden Text geht es um den BME680 und in einem zweiten Artikel werde ich über meine Erfahrungen mit dem MH-Z19B berichten.

Bosch BME680

Der eigentliche Sensor von Bosch ist mit einer Fläche von 3 x 3 mm sehr klein und lässt sich darum von Hand nicht verlöten. Er ist für die Montage mit einem SMD-Roboter vorgesehen, wo er direkt auf eine mit Lötpaste versehene Platine gesetzt wird, die anschließend in einem Ofen so weit erhitzt wird, dass das in der Paste enthaltene Lötzinn schmilzt und nach dem Abkühlen eine leitfähigen Verbindung der Sensorkontakte mit der Platine entsteht. Für uns Bastler oder für die Entwickler in großen Firmen, die so einen Sensor in Prototypen ausprobieren wollen, gibt es aber kleine Platinen, sogenannte Entwickler-Boards, die es erlauben den Sensor von Hand zu verdrahten und in eigenen Schaltungen einzusetzen. Bei diesen Boards handelt es sich um kleine Platinen, auf denen der Sensor, wie gerade beschrieben, zusammen mit anderen Bauteilen, aufgelötet ist und die für alle Anschlüsse Lötaugen besitzen.

Der Sensor kann nicht nur Gase messen, sondern auch Temperatur, Luftfeuchtigkeit und Luftdruck:

  • Temperatur von 40 – 85°C
  • Luftfeuchtigkeit von 0 – 100 %RH
  • Luftdruck von 300 – 1100 hPa
  • Detektierbares Gas in Ohm

Der Sensor besitzt einen I2C-Bus, über den mit ihm kommuniziert werden kann. Dazu verbindet man das TTGO T-Display folgendermaßen mit dem Entwicklerboard:

  • Einen der beiden 3.3 Volt Pins mit VCC
  • Ein GND Pin mit GND vom Entwicklerboard
  • Pin 21 -> SDA
  • Pin 22 -> SCL

Meinen ersten Versuch unternahm ich dann mit dem Beispielcode von Adafruit. Dazu muss die BME680 Bibliothek von Adafruit installiert werden! Anschließend kann das Beispiel aus der Arduino IDE gewählt werden. Dabei viel mir sofort auf, dass die vom Sensor zurück gelieferte Temperatur mit mehr als 28 Grad bei weitem zu hoch war. Ich nahm an, dass dies möglicherweise an einer im Sensor eingebauten Heizung für den MOX-Sensor liegen könnte und verwarf den Gedanken, den BME680 auch für Wetterstationen verwenden zu können. Da für mich der Hauptsinn des BME680 aber im Detektieren der Atemluftqualität AQI liegt, nahm ich weiterhin an, dass die anderen Sensordaten im wesentlichen dazu da sind, die  Einflüsse von Temperatur, Luftfeuchtigkeit und Luftdruck auf den MOX-Sensor zu korrigieren.

BSEC Arduino Library

Weitere Recherchen ergaben, dass es wohl nicht so einfach ist, einen sinnvollen Wert für den AQI zu bekommen. Und das weiß auch die Firma Bosch und hat darum eine aufwendige Bibliothek entwickelt, die einem die ganze Arbeit abnimmt und fertige Werte für den AQI berechnet! Ich habe die ‘BSEC Arduino Library’ hier gefunden. Beim Versuch das zugehörige Beispielprogramm ‘basic.ino’ zu kompilieren, gab es allerdings einen Fehler, da die Arduino IDE scheinbar nicht damit zurecht kommt, wenn eine Bibliothek ohne Quellcode verwendet wird. Ich bekam in etwa diese Fehlermeldung:

Library BSEC-Arduino-library has been declared precompiled:
Using precompiled library in C:\Users\Thomas\Documents\Arduino\libraries\BSEC-Arduino-library\src\esp32
The plaform does not support 'compiler.libraries.ldflags' for precompiled libraries.

Eine Recherche ergab schnell Lösungsmöglichkeiten. Sogar direkt auf der GitHub Seite der Bibliothek von Bosch, was ich wohl im Eifer des Gefechtes erst einmal überlesen hatte. Trotzdem kam ich nicht weiter. Dort stand etwas von der Modifikation eine Datei namens ‘platform.txt’, ohne aber genau zu schreiben, wo sich die eigentlich befindet. Das muss ich wohl als Arduino Entwickler einfach so wissen. Ich suchte und fand eine Datei mit passendem Inhalt im Verzeichnis:

C:\Program Files (x86)\Arduino\hardware\arduino\avr

Und passte sie entsprechend an. Leider half das nichts. Ich kontrollierte meine Änderungen mehrmals, aber es kam immer wieder die gleiche Fehlermeldung! Da kamen bei mir erstmals Zweifel auf, ob das wirklich die richtige Datei war? Ich machte ein paar Änderungen, von denen ich annahm, dass der Compiler oder Linker sie auf keinen Fall verdauen kann und wieder passierte nichts, bzw. es kam immer nur die gleiche Fehlermeldung. Ich begab mich erneut auf die Suche nach der Datei und dabei blitzte es in meinem Kopf auf: ich habe doch für den ESP32 irgendwann einmal eine eigene Software-API installiert? Sollte da drin die richtige ‘platform.txt’ sein?

Und genau so war es, ich musste die ‘platform.txt’ aus diesem Verzeichnis bearbeiten:

C:\Users\Thomas\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4

Endlich war ich im Spiel! Jetzt waren alle Voraussetzungen erfüllt, um nach Belieben mit dem BME680 experimentieren zu können. Doch jetzt war es auch super einfach geworden. Die Bibliothek bietet eine Funktion an, mit der einfach der AQI ausgelesen werden kann! Ich musste gar nichts mehr berechnen. Darum verlagerte ich meinen Ehrgeiz mehr in eine ästhetische Richtung und überlegte, wie ich den AQI passend in Szene setzen konnte.

Screen Design

Da meine Tochter noch in die Schule geht und sie dort wegen Corona regelmäßig lüften müssen, es aber Winter ist und immer kälter wird, kommt es sehr darauf an, die Öffnungsdauer zu optimieren. Ich wollte ein Gerät bauen bzw. programmieren, welches mitteilte, wann ein Fenster zu öffnen und wann es wieder zu schließen ist. Und das mit möglichst minimalem Aufwand. Meinen TTGO T-Display Controller hatte ich für weniger als 5,13 Euro in einer Sonderaktion bekommen. Der BME680 war mit 14,47 Euro sogar wesentlich teurer! Einen passenden Akku hatte ich für ca. 4,- Euro noch herum liegen und um alles zu integrieren verwendete ich erst einmal mein für die Nerd-Anhänger konstruiertes Gehäuse. Allerdings ist das Display des TTGO T-Display mit 14.86  x 24.91 mm sehr klein, so das darauf angezeigte Informationen aus ein paar Meter Entfernung nicht erkannt werden können.

Zum Glück gibt es Menschen, die den AQI auf verschiedene Farben aufgeteilt haben, wobei jede Farbe einem bestimmten Luftzustand entspricht. Im Datenblatt zum BME680 von Bosch gibt es einen 7-teiligen Index, während ich sonst im Internet meistens eine 6-teiligen gefunden habe. Sucht einfach einmal nach AQI Index.

Ich habe folgende Aufteilung verwendet:

    0   50 Grün Gut
  51 100 Gelb Mäßig
101 150 Orange Ungesund für bestimmte Gruppen
151 200 Rot Ungesund
201 300 Magenta Sehr ungesund
301 500 Braun Gefährlich

In einem ersten Ansatz habe ich einfach den Hintergrund des Displays komplett in der passenden Farbe eingefärbt und in der Mitte den AQI Wert angezeigt. Bei den Recherchen zum AQI habe ich aber auch viele Grafiken mit Gesichtern gesehen, deren Gesichtsausdruck die aktuelle Luftqualität widerspiegelt. Das hat mir gut gefallen und ich habe mir entsprechende Icons gebastelt und diese in der passenden Farbe auf schwarzen Hintergrund dargestellt. In den dadurch entstandenen schwarzen Bereichen habe ich in einer kleinen Schriftart den Zahlenwert des AQI und die Äquivalenz-CO2 hingeschrieben.

So könnte das Gerät in der Schule auf den Lehrer Schreibtisch gestellt werden und die Schüler sollten zumindest die Farbe erkennen können. Wenn die Farbe auf Rot oder Orange wechselt, sollten die Fenster geöffnet und wenn die Farbe anschließend wieder auf Grün wechselt, die Fenster wieder geschlossen werden.

Die Icons habe ich mit Inkscape bearbeitet und anschließend als 100 x 100 Pixel große PNG-Grafiken gerendert und gespeichert. Mit dem lcd-image-converter habe ich sie anschließend in eine Quellcode-Datei für mein Projekt umgewandelt.

Verbesserung 1

Nachdem das Gerät soweit fertig war, habe ich es einige Tage getestet und nur noch kleine Änderungen und Verbesserungen vorgenommen. Um die angezeigten Werte besser verstehen zu können, habe ich ein bisschen im Datenblatt geschmökert und mich im Bosch Forum herum getrieben. Dabei hat sich für mich heraus kristallisiert, dass der Sensor sich jedes Mal nach dem Einschalten erst einmal mit einer Art Selbstkalibrierung beschäftigt und das einige Zeit (ca. 5 Minuten) dauern kann. Während des Kalibrierungsvorgangs liefert er einen Status, an dem man erkennen kann, wie weit er schon ist:

  • IAQ-Accuracy = 0 könnte entweder bedeuten: Die BSEC wurde gerade gestartet, und der Sensor stabilisiert sich (dies dauert normalerweise 5 min im LP-Modus oder 20min im ULP-Modus),
    es gab eine Zeitverletzung (d.h. die BSEC wurde zu früh oder zu spät gerufen), die durch eine Warnung/Fehlerflagge der BSEC angezeigt werden sollte,
  • IAQ-Accuracy = 1 bedeutet, dass die Hintergrundgeschichte der BSEC unsicher ist. Dies bedeutet in der Regel, dass die Gassensordaten zu stabil waren, als dass die BSEC ihre Referenzen klar definieren konnte,
  • IAQ Accuracy = 2 bedeutet, dass die BSEC neue Kalibrierdaten gefunden hat und derzeit kalibriert,
  • IAQ-Accuracy = 3 bedeutet, dass die BSEC erfolgreich kalibriert wurde.

Ich habe diesen Wert genommen und auf dem Display einen farbigen Status-Kreis mit unterschiedlicher Farbe, je nach Status gezeichnet. Wenn der Kreis hellgrün ist, sind die Werte in Ordnung.

Verbesserung 2

In der Startphase des Sensors kann es sein, dass eine Zeit lang keine Datenänderungen erfolgen. Dies lässt sich verbessern, indem man die schon gewonnenen Kalibrierungsdaten in einem nichtflüchtigen Speicher sichert und beim nächsten Start gleich am Anfang lädt. Das bei der Bibliothek mitgelieferte Beispiel ‘basic_config_state.ino’ zeigt exemplarisch, wie sich das lösen lässt. Ich habe nur die für mich relevanten Teile heraus kopiert und mein bisheriges Programm so modifiziert, dass ich auf Knopfdruck des TTGO T-Display die Kalibrierungsdaten sichere und bei jedem Neustart wieder lade.

Das händische Sichern der Kalibrierungsdaten sollte nur erfolgen, wenn der Status-Kreis hellgrün ist und damit den Wert 3 signalisiert. Das Sichern macht auch nur Sinn, wenn der Sensor in der immer gleichen Umgebung verwendet wird. Bei häufigem Umgebungswechsel spielen die Kalibrierungsdaten keine Rolle mehr. Der Sensor fängt dann die Kalibrierung von Neuem an.

Sonstiges

Der Sensor sammelt im Laufe der Zeit verschiedene Daten, die er von Zeit zu Zeit zur Selbstkalibrierung verwendet. Je nachdem wie er eingestellt ist, verwendet er dazu die Daten der letzten 4 oder der letzten 28 Tage. Die Einstellung nimmt man im Code durch Auswahl einer bestimmten Datei der Bibliothek vor, wie hier beispielhaft gezeigt:

const uint8_t bsec_config_iaq[] = {
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
};

Stellt der Sensor für ihn unschlüssige Messwerte fest, so setzt er die IAQ-Accuracy auf 2 und beginnt die Kalibrierung von neuem. Nach erfolgter Kalibrierung wartet der Sensor-Mikrocontroller 4 oder 28 Tage auf das Eintreffen von für ihn sinnvollen Messwerten. Sollten keine eintreffen, setzt er die IAQ-Accuracy auf 1 und benötigt eine künstliche Gas Stimulation – wie auch immer die aussehen mag. Möglicherweise ein Tropfen Isopropylalkohol …

Bleibt die Frage, was hier mit schlüssigen Daten gemeint ist? Ich vermute, dass der Sensor-Mikrocontroller nach einigermaßen regelmäßigen Messwertveränderungen sucht, die außerdem einen gewissen Wertebereich überdecken müssen. Sollte er diese im Verlauf des eingestellten Intervalls (4 oder 28 Tage) nicht finden, geht er von Problemen aus und wünscht einen Beweis dafür, dass die Erde außerhalb seines Gehäuses noch lebt. 🙂

Ob ich eher 4 Tage oder 28 Tage zur Selbstkalibrierung verwende, hängt davon ab, wie ich den Sensor einsetzen möchte. Bei mobilem Einsatz ist es besser 4 Tage zu verwenden und wenn das Gerät stationär eingesetzt werden soll, sind 28 Tage von Vorteil.

Fazit

Diese Selbstkalibrierungen sind mir etwas suspekt. Ich kann nicht nachvollziehen, was da eigentlich wirklich passiert. Möglicherweise steht das im Datenblatt, aber das habe ich nur überflogen und nach den ersten mathematischen Formeln erst einmal beiseite gelegt. Vielleicht sehe ich es mir bei Gelegenheit noch einmal genauer an. Zur Zeit lasse ich die beiden Sensoren nebeneinander, jeder mit seinem eigenen TTGO T-Display, in einem Zimmer liegen. Manchmal erscheinen mir die Werte schlüssig, manchmal ist der eCO2 Wert des BME680 fast identisch mit dem CO2 Wert des MH-Z19B. Aber dann weichen sie wieder ein ganz Stück voneinander ab. Was ja auch durchaus sein kann, schließlich misst der MH-Z19B tatsächlich nur das CO2 in der Luft und der BME680 noch alles möglich andere. Theoretisch sollten die Messwerte im Lauf der Zeit besser werden. Aber manchmal nehme ich die Geräte mit in einen anderen Raum oder betreibe sie mobil. Ich bin mal gespannt. Aber momentan würde ich nicht sagen, dass man mit diesen Sensoren kurz nach dem Kauf und dem erstem Ausprobieren präzise Werte geliefert bekommt.

5 Kommentare

  1. Hi, danke für den Super Artikel. Habe mit dem BME680 ähliche Erfahrungen gemacht und bin schlussendlich der Meinung das dieser Sensor Mist ist. Schon die riesige Temp. Abweichung obwohl er eigentlich +/- 1°C genau sein soll. Die bleibt bestehen selbst wenn man die Heizung für den Gassensor abschaltet. Der MH-19 Z komniniert mit einem SHT31 für die Temp. und Feuchte ist was ich jetzt einsetze.

  2. Hallo!

    wirklich ein schönes Projekt. Würdest Du auch den Arduino-Code zur Verfügung stellen oder habe ich einen entsprechenden Link übersehen?

    Danke & Gruß,

    Oliver

  3. Hi,

    das gefällt mir gut. Ich nutze aktuell den BME680 mit Raspberry Pi/Balena, aber die Version mit TT-GO wäre schlanker und standalone nutzbar.

    Ist der Code frei verfügbar?

    Danke
    Andreas

  4. Hallo Andreas,

    vielen Dank für Dein Interesse! An für sich veröffentliche ich nur wenig von meinem Programmcode, da ich auch immer noch darauf achten muss, mit meiner Arbeit vielleicht irgendwie Geld verdienen zu können. Dann ist es ja so, dass ich, wollte ich meinen Code auf GitHub, oder so, zur Verfügung stellen, der ja sauber gemacht und schick sein soll, so dass die Entwickler, die ihn studieren, vor Ehrfurcht vor meinem Code blass werden. 🙂 Da müsste ich dann wahrscheinlich noch einmal an den Code ran.

    Aber bei diesem Projekt ist auch noch das Problem, dass ich die verwendeten Bilder zwar mit Inkscape selbst gebastelt habe, dazu aber Vorlagen Screenshots von einem kommerziellen Produkt verwendet habe. ich fürchte, ich werde dann bei Veröffentlichung Ärger bekommen.

    Thomas

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.