Lüftgütemessung

Wemos D1mini, MH-Z19B, BME680, CCS811, WS2812, SH1106, DHT22 AM2301, tasmota und openHAB

Die Idee war schon lange da. Wie vermeide ich die Virenübertragung über die Luft? Wie messe ich die Virenbelastung in der Luft? Es gibt keinen Sensor, der die Virenbelastung misst, aber es ist klar, wenn die Luft ausgetauscht wird (lüften), dann nimmt die Virenkonzentration ab.

Aber wann soll man lüften?
Da schlechtes Raumklima direkt mit dem CO2 Gehalt in der Luft zusammen hängt, ist es sinnvoll den CO2 Gehalt zu messen und mit weiteren Daten, wie Temperatur, Luftfeuchtigkeit, etc. zu verarbeiten. Dazu gibt es genügend Literatur, ich finde diesen Bericht hier recht gut.

Die Idee war es also eine Luftgüte Messstation zu bauen und diese in die Home Automation Lösung zu integrieren.

Air Quality Station

Wemos D1 mini ESP8266

Das Herz der Lösung ist ein Wemos D1mini Wifi mit einem ESP8266 Modul.

Dieses kleine board gibt es bereits um € 5.- z.B. bei Semaf zu kaufen. Es kommt mit verschiedenen Stiftleisten, die man selbst anlöten muss. Zum Programmieren gibt es die Möglichkeit über die Arduino IDE oder man flashed sich tasmota drauf. Dazu einfach das board mit einem USB Kabel am PC anstecken und dann mit einer Flash Software die aktuelle tasmota Version raufspielen.

Da ich im Folgenden mit verschiedenen Sensoren arbeiten werde, habe ich am Anfang einmal die tasmota-sensors.bin firmware Version verwendet, denn da ist die Unterstützung für viele Sensoren schon dabei.

Übrigens: Es ist nicht nötig mit dem USB2Serial Adapter zu arbeiten, sondern einfach mit dem angeschlossenen USB Kabel. Das hat mich wieder Stunden gekostet. Manchmal denkt man einfach zu kompliziert.

Für das Flashen verwende ich das Programm ESP8266Flasher von Dietrich Kindermann.

Nach dem üblichen Einrichten von lokalen WiFi und MQTT gehört noch der Module Type Generic (18) ausgewählt, denn dann kann man jeden GPIO Pin einzeln konfigurieren.

DHT22 AM2301

Erster Sensor, der an den D1 angeschlossen wurde ist der DHT22 AM2302 als Shield für das D1 Mini Board. Das Shield einfach aufstecken und in der tasmota Oberfläche bei den Module Einstellungen den richtigen Anschluss auswählen.

D4 GPIO2 --- AM2301 

Nach dem reboot des D1 (power off-on) hat man Temperatur, Luftfeuchtigkeit und Taupunkt.

Diesen Sensor habe ich später wieder entfern, da die gewonnenen Messwerte auch von einem anderen Sensor geliefert werden.

MH-Z19B CO2-Sensor

Nächster Sensor ist einer für die Messung der CO2 Konzentration in der Luft. Da gibt es ein paar wenige z.B.: SCD30 von Sensirion oder von Winson den MHZ19B. Letzteren habe ich verwendet, er ist etwas billiger.

Die Verbindung erfolgt über den 5V Ausgang vom D1mini, Ground und den Rx/Tx Anschlüssen, die ausgekreuzt mit den Tx/Rx Pins vom MHZ19B verbunden werden. Standardmäßig sind am D1 die GPIO 1 und 3 hardwaremäßig für die serielle Kommunikation vorgesehen, das sind die Anschlüsse TX und RX. Man kann das auch umkonfigurieren, aber ist nicht notwendig.
Im tasmota Config Menü stellt man folgendes ein:

TX GPIO1 Serial Out --- MHZ TX
RX GPIO3 Serial In  --- MHZ RX

Das Ergebnis nach einem erneuten reboot sind CO2 Wert in ppm
(Der CO2-Gehalt in der Luft wird in parts per million = Anteile pro Million gemessen) und die Temperatur.

MQTT Befehle für den MH-Z19B

# Automatic Baseline Correction for MH-Z19B CO2 sensor
cmnd/d1mini/Sensor15	
0 = disabled
1 = enabled (default)
2 = start manual calibration from 400 ppm of CO2
9 = reset sensor to factory defaults
1000 = sets measurement range to 1000ppm CO2
2000 = sets measurement range to 2000ppm CO2
3000 = sets measurement range to 3000ppm CO2
5000 = sets measurement range to 5000ppm CO2
10000 = sets measurement range to 10000ppm CO2

BME680

Mit dem hochmodernen BME680-Breakout kann man Temperatur, Druck, Luftfeuchtigkeit und Raumluftqualität messen. Die Gaswiderstandswerte reagieren auf Änderungen flüchtiger organischer Verbindungen und können mit den Feuchtigkeitswerten kombiniert werden, um ein Maß für die Raumluftqualität zu erhalten.

image

Der BME680 von Bosch wird über den I2C Bus angesprochen. Wobei ich die Anschlüsse D2 für die Datenleitung SDA (Serial Data) und D1 für den Takt SCL (Serial Clock) verwendet habe. Dieses Breakout Board ersetzt das DHT22 AM2301 shield.

D2 GPIO4 --- I2C SDA
D1 GPIO5 --- I2C SCL

CCS811 Gas Sensor

Der CCS811 ist eine digitale Gas-Sensorlösung, die einen Metraloxid (MOX)-Gassensor für die Überwachung der Luftqualität in Innenräumen (IAQ) integriert, der eine breite Palette an flüchtigen organischen Verbindungen (VOCs) mit einer Mikrocontroller-Einheit (MCU), einem Analog-zu-(ADC) und einer I2C-Schnittstelle umfasst.

Nachdem ein richtiger CO2 Sensor doch etwas teurer ist, wollte ich schauen, ob man mit einem billigeren Gassensor auch die gleichen Ergebnisse erzielen kann. Dafür benötigt man aber einen längeren Zeitraum, derzeit kann ich noch keine Aussage machen.

Auch der CCS811 wird über den I2C Bus betrieben. Also einfach parallel dazu hängen, reboot und Werte ablesen.

WS2812 8Bit LED 8 Neopixel Stick

8 Neopixel auf einem Stick, die über eine Datenleitung einzeln angesteuert werden können. Es sind keine Anschluss Stifte dabei und das Anlöten ist ein wenig tricky.

Die Datenleitung habe ich auf D5 (GPIO14) gelegt und die Versorgung an 5V.

D5 GPIO14 --- WS2812

Per MQTT Befehle können die einzelnen LEDs angesteuert werden. Wenn man allerdings die Helligkeit regeln möchte und dafür den Dimmer Befehl verwendet, dann werden immer alle LEDs auf die gleiche Farbe gestellt. Ich habe das so gelöst, dass ich einfach über die RGB Farben einen niedrigeren Wert verwende.

cmnd/d1mini/Color 00FF00 // alle LEDs grün
cmnd/d1mini/LED1 0,10,0  // LED1 auf hellgrün
cmnd/d1mini/Dimmer 0     // alle LEDs aus

In OpenHAB existiert eine Regel, die bei Änderung des CO2 Wertes die entsprechend LEDs von grün auf rot setzt. Je mehr rot, desto schlechter die Luft.

SH1106 OLED 1.3″ I2C Display

Das 1.3″OLED display hat 128×64 individuell beschreibbare OLED pixels.
Es kommuniziert ebenfalls mit dem microcontroller über den I2C Bus .

Der letzte Teil der Luftgüte Mess-Station ist ein Display, auf dem die wichtigsten Messwerte angezeigt werden sollen. Prinzipiell ist der Anschluss keine Hexerei, da ja der I2C Bus verwendet wird. Leider werden die Displays aber standardmäßig nicht von der tasmota firmware unterstützt, auch nicht von der tasmota-sensors.bin, daher muss man sich seine eigene firmware erstellen und auf den ESP8266 flashen.

Am Schnellsten geht das mit einem Online Compiler namens tasmocompiler. Dieser wird in einem docker container gestartet und ist fertig wenn man die Meldung sieht:
Server started on port 3000
Danach kann man ein Browserfenster starten und die paar Schritte durchgehen. Ich finde es gut, dass man hier auch eine statische IP Adresse vergeben kann, denn mit meinem A1 Hybridmodem (ist eine Krücke, man kann z.B. nicht den DHCP-Server ausschalten) kann ich nur 32 Geräte für eine IP reservieren und das ist zu wenig.

Im Schritt 3 nur die Teile auswählen, die man wirklich benötigt und vor allem die Displays nicht vergessen.

Im Schritt 4 kann man noch zusätzliche Einstellung vornehmen. Ich habe festgestellt, dass der BME680 nicht standarmäßig dabei ist, daher dort folgenden Eintrag hinzufügen.

#ifndef USE_BME680
#define USE_BME680    // Enable BME680 sensor 
#endif

Danach erzeugt der Compiler deine individuelle firmware, die man zuerst runterlädt und dann auf den d1mini flashed.

Wenn alle I2C Sensoren funktionieren, dann müsste man das auch beim Scan sehen

cmnd/d1mini/I2Cscan ->
{"I2CScan":"Device(s) found at 0x3c 0x5a 0x77"}
0x3c ... SH1106 Display
9x5a ... CCS811
0x77 ... BME680

Der Temperatur Wert des BME680 stimmt meistens nicht und muss kalibriert werden. Am besten einen Referenzwert nehmen und dann anpassen. Auch für die Luftfeuchtigkeit.

cmnd/d1mini/TempOffset Wert # -12.6 bis 12.6
cmnd/d1mini/HumOffset Wert  # -10.0 bis 10.0 

Um etwas auf das Display zu zaubern, muss man einmal ein paar Einstellungen vornehmen. Genaue Beschreibung hier:

cmnd/d1mini/DisplayModel 7
cmnd/d1mini/DisplayCols 20
cmnd/d1mini/DisplayRows 8
cmnd/d1mini/DisplayMode 0
cmnd/d1mini/DisplayText textstring

In der OpenHAB rule wird dann der entsprechende String zusammengebaut und per MQTT geschickt. Für so eine Ausgabe baut man folgenden string. Genaue Beschreibung hier.

var text="[zx0y0r128:64x2y2r124:60f1c2l2s2] CO2: "
 + d1miniMHZ19BCO2.state.toString +" ppm" 
d1mini2SH1106DisplayText.sendCommand(text)
text="[f0s1c2l4] Temp: " 
+ d1mini2BME680Temp.state.toString +" C" 
d1mini2SH1106DisplayText.sendCommand(text)
text="[f0s1c2l5] Hum : " 
+ d1mini2BME680Hum.state.toString +" %" 
d1mini2SH1106DisplayText.sendCommand(text)
text="[f0s1c2l6] Pres: " 
+ d1mini2BME680Pressure.state.toString +" hPa" 
d1mini2SH1106DisplayText.sendCommand(text)
text="[f0s1c2l7] Gas : " 
+ d1mini2BME680Gas.state.toString +" kOhm" 
d1mini2SH1106DisplayText.sendCommand(text)

Einkaufsliste

Wemos d1mini ESP8266 kompatibel€ 5.-
DHT22 AM2301 (optional)€ 6.-
MH-Z19B CO2-Sensor€ 43.-
BME680€ 15.-
CCS811 Gas Sensor€ 15.-
WS2812 8Bit LED 8 Neopixel Stick€ 4.-
SH1106 OLED 1.3″ I2C Display€ 12.-
Arbeitszeitunbezahlbar

Fazit

Sobald man die Werte sieht, merkt man wie schnell, vor allem in kleinen Räumen, die Luft schlechter wird. Jetzt heiß es noch die Feinjustierung vorzunehmen und dann lassen wir alles einmal über einen längeren Zeitraum laufen.

Eines ist jedenfalls sicher, es wird öfters gelüftet unser Raumklima ist besser geworden.

Wertebereiche

Hier einmal eine Liste von Werten, die für ein angenehmes Raumklima verantwortlich sind und wie ich es auf den LEDs anzeige.

IDA … Indoor Air Raumluft Kategorie – Raumluftqualität

CO2 Belastung (400 ppm ist Außenluft)
< 460 ppm  - Hohe Raumluftqualität   IDA1 - 8x grün
< 550 ppm  - Hohe Raumluftqualität   IDA1 - 1x rot - 7x grün
< 640 ppm  - Hohe Raumluftqualität   IDA1 - 2x rot - 6x grün
< 730 ppm  - Hohe Raumluftqualität   IDA1 - 3x rot - 5x grün
< 820 ppm  - Mittlere Raumluftqual.  IDA2 - 4x rot - 4x grün
< 910 ppm  - Mittlere Raumluftqual.  IDA2 - 5x rot - 3x grün
< 1000 ppm - Mittlere Raumluftqual.  IDA2 - 6x rot - 2x grün
< 1100 ppm - Mäßige Raumluftqual.    IDA3 - 7x rot - 1x grün
< 1400 ppm - Mäßige Raumluftqual.    IDA3 - 8x rot - 7x grün
> 1400 ppm - Niedrige Raumluftqual.  IDA4  -8x grelles rot 

Temperatur 
20 °C Minimal bei sitzender Tätigkeit
21 °C bis 23 °C - Empfehlung Wohnraum
26 °C Maximaltemperatur in Arbeitsräumen

Luftfeuchtigkeit
< 23%     - unbehaglich 
30% - 40% - zu niedrig
40% - 60% - ideal
> 60 %    - Neigung zur Schimmelbildung
> 70 %    - zu hoch
> 95 %    - unbehaglich 

Grenzwert Taupunkt
 9° C - allgemeine Empfehlung Mindestwert
15 °C - allgemeine Empfehlung Höchstwert

TVOC (Total Volatile Organic Compounds) 
in ppb (parts per billion)
Flüchtige Organische Verbindungen
150 bis 400 ppb - hygienisch unbedenklich
bis 1300 ppb    - hygienisch auffällig
> 1500 ppb      - hygienisch inakzeptabel

Tipps & Tricks

Wenn man eine LED mit einer bestimmten Farbe per MQTT schaltet, dann möchte man ja auch den Farbwert zurückbekommen.
Schickt man z.B. das commandTopic
cmnd/d1mini/LED1 „00FF00“ dann bekommt man folgendes zurück
stat/d1mini/RESULT {„Led1″:“00FF00“}

Das Ergebnis steht also im topic RESULT. Aber auch die Ergebnisse aller anderen LEDs, etc. kommen über das topic RESULT zurück. Wenn man dann das transformationPattern=“JSONPATH:$.Led1″ verwendet und das natürlich angepasst auch bei allen anderen LEDs, etc., dann bekommt man eine Menge Warnings in der openHAB.log Datei.

Invalid path '$.Led2' in '{"Led1":"00FF00"}'
Invalid path '$.Led3' in '{"Led1":"00FF00"}'
.....
Invalid path '$.DisplayText' in '{"Led1":"00FF00"}'

Es funktioniert alles bestens, aber das log file wird vollgemüllt.
Folgende Verbesserung im transformationPattern löst das Problem. Das muss natürlich bei jedem channel, bei dem das Ergebnis über das RESULT topic kommt, geändert werden

Type string : d1miniLED1 "LED1 Farbe"
[stateTopic="stat/d1mini/RESULT", 
transformationPattern="REGEX:(.*Led1.*)∩JSONPATH:$.Led1",
commandTopic="cmnd/d1mini/LED1"] 
CategoriesIoT
    1. peter says:

      Hab ich mir auch schon überlegt, aber eigentlich ist die Luft nur schlechter, wenn man im Raum ist und dann kann man einfach das Fenster aufmachen. Interessant ist es natürlich in der Nacht, wir werden sehen.

  1. Pingback:Luftgütemessung 2.0 » IoT-Antoni

Schreibe einen Kommentar

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

Begin typing your search above and press return to search. Press Esc to cancel.