CO₂-Sensor-Kit

Wie es dazu kam oder die Anforderungen

@heinz hat beim letzten BOb-Online-Treffen einige CO₂-Messreihen bei Bienenvölkern vorgestellt, die mit kommerziellen Messgeräten erhoben wurden. Der Sensor wurden im Bienenstock ganz unten, unter den Rähmchen platziert. Da “fertige” Geräte recht teuer und unflexibel einsetzbar sind, kam die Idee auf etwas DIY zu basteln, das

  • flexibler ist und z.B. nicht nur an einem Punkt, sondern mit mehreren Sensoren CO₂ messen auch unterschiedlichen Punkten parallel messen kann
  • die Daten nicht lokal speichert, wo man sie “abholen” muss, sondern sie gleich online in eine Datenbank schreibt, und na klar
  • gleich z.B. mit Grafana visualisiert
  • dabei günstiger ist als die “fertigen” Geräte

CO₂ im Bienenstock

CO₂ könnte im Bienenvolk im Sommer als Indikator für Stoffwechsel dienen. Im Winter ist es komplizierter: Es gibt da Theorien, die besagen, dass durch erhöhten CO₂-Gehalt eine Stoffwechsel-Reduktion in der Wintertraube eintritt. Teilweise wird von exorbitant hohen CO₂-Konzentrationen von 6 % CO₂, das wären 60.000 ppm (!), und auch mehr berichtet.

Ein schöner Artikel ist auch dieser hier, der Messwerte im Winter publiziert und dabei “unseren” CO₂-Sensor, den Sensirion SCD41 (s.u.), verwendet hat:

Hardware

Die verwendete Hardware ist recht übersichtlich:

  • CO₂-Sensor SCD41 (3x), kompaktes breakout bei Amazon, 3er-Pack
    Den SCD41 gibt in unterschiedlichen breakout-Varianten. Der oben verlinkte ist von der Bauform für uns mit dem minimalen footprint ganz gut geeignet, da er in einen Lockenwickler oder Königinnenversandkäfig passt und so vor Wachs und Propolis geschütz werden kann.
    Die Varianten von DFRobot, Adafruit oder Sparkfun sind dann doch zu groß – und teurer!

  • Soldered I2C-Multiplexer TCA9548A
    Da wir mehr als einen I2C-Sensor anschließen wollen, brauchen wir einen Multiplexer, der SCD41 hat selbst leider keine Möglichkeit die I2C-Adresse einzustellen. Mit dem Multiplexer können wir bis zu 8 Sensoren anschließen.
    Ursprünglich – und oben auf dem Foto ist er noch verbaut – hatte ich den Gravity I2C-Multiplexer besorgt. Leider frisst der aber in deep sleep 2,5 mA Strom, das verwendete Board verursacht nur 12 µA. Da ist vermutlich auch nix zu machen, da auf dem DFRobot-Board ein level switcher verlötet ist. Daher in der nächsten Ausbaustufe der Multiplexer von Soldered. Schön finde ich an beide die Möglichkeit direkt per kompletter 4er-Stifteleiste (8x je SDAx, SCLx, Vcc, GND) einen Sensor anzuschließen. Andere break outs haben das nicht!

  • DFRobot Firebeetle 2 / ESP32-E
    Mit sehr gutem deep sleep-Stromverbrauch (12 µA), daher auch ein Option für batteriebetriebene Projekte. Mal schauen, ob wir das wirklich brauchen und nicht der Stromverbrauch der Sensoren im Betrieb schon so hoch ist, dass das egal wäre.

Für einen optimalen Batteriebetrieb im deep sleep muss der solder jumper auf dem Firebeetle 2 durchtrennt werden, dann funktioniert nur noch die einfarbig grüne onboard LED bei Batteriebetrieb, nicht mehr die hübsche RGB-LED, was debug-Infos etwas schwieriger macht. Wenn die Stromversorgung über USB läuft funktioniert auch immer noch die RGB-LED!

SCD41 CO₂-Sensor

Hier hat jemand das (“do not remove”) mal trotzdem gemacht: :-) https://wolles-elektronikkiste.de/en/scd4x-co₂-sensors und einen “sacrified”, was uns den Blick in einen geöffneten SCD41 ermöglicht.

Wiring

SCD41 Sensor Firebeetle 2 / ESP32 Pin
GND GND
VDD 3V3
SCL SCL / GPIO 22
SDA SDA / GPIO 21

Bibliotheken und I2C-Adresse

SCD41

I2C-Mulitplexer

Der I2C-Multiplexer von DFRobot kann über ein 4-adriges Kabel mit PH2.0-Stecker oder über Stifteleiste angeschlossen werden.

Code

Features

Konfiguration über Variablen im Arduino-Sketch (ganz oben im Code)

  • Erststart: Wenn der FireBeetle das allererste Mal mit der Open-Hive-Software bespielt wird, ist der interne Speicher (NVS-Flash) noch leer. Der ESP lädt dann automatisch die Standardwerte aus dem Arduino-Code und speichert sie dauerhaft im NVS-Flash. Ab diesem Moment können sie flexibel über das Webportal geändert werden.
  • Im laufenden Betrieb: Sobald Konfigurationsdaten im Speicher vorhanden sind, werden die Werte im Arduino-Code bei allen weiteren Kaltstarts (Power Cycles / Hard-Resets) komplett ignoriert. Das System lädt stattdessen ausschließlich die gespeicherten und ggf über das Webportal geänderten Einstellungen.
  • Erzwingen von Code-Updates / Werkstatt-Reset: Will man die Einstellungen dennoch einmalig hart mit denen im Arduino-Code überschreiben, muss man vor dem Flashen die Variable bool forceUpdateDefaults = true; setzen.
    Wichtig Unmittelbar nach diesem Upload muss die Variable im Code zwingend wieder auf false zurückgestellt werden und der Sketch ein zweites mal hochgeladen werden! Bleibt das Flag fälschlicherweise auf true stehen, überschreibt der ESP32 bei jedem Kaltstart ggf. eingegebenen WLAN-Zugangsdaten, die Sensoranzahl usw. und löscht die per Webinterface gemachten Änderungen somit ungewollt wieder!

Konfigurations-Webseite auf dem Gerät

Direkt nach einem hard reset – Strom unterbrechen oder reset-Taster am Firebeetle drücken – versucht das Gerät mit den aktuell hinterlegen WLAN-Zugangsdaten ins Netz zu kommen. Dabei blinkt die RGB-LED blau.

  • Über AccessPoint des Geräts: Wenn keine oder keine funktionierenden WLAN-Zugangsdaten hinterlegt sind oder das System nach ca. 15 Sekunden keine Verbindung hergestellt hat, richtet es einen eigenen WLAN Access Point ein, die RGB LED blinkt dann für ca. 2 Minuten lila. Verbinde dich z.B. mit dem Mobilephone mit dem WLAN beehive-co2-sensor (Name kann per Konfiguration geändert werden) und dem Passwort openhive. Anschließend den Browser öffnen und die Konfigurationsseite über die IP-Adresse http://192.168.4.1 abrufen.
  • Über das lokale Netz (wenn funktionierende WLAN-Daten hinterlegt sind): Wenn das Gerät im selben lokalen Netz wie dein PC oder Mobilephone eingeloggt ist, kann die Konfigurationsseite bequem über den Hostnamen http://beehive-co2-sensor.local (alternativ auch ohne .local) bzw. über die IP-Adresse aufgerufen werden.
  • Hinweis: Sollte der Name nicht aufgelöst werden (insbesondere bei vielen Android-Devices), muss stattdessen die vom Router vergebene IP-Adresse eingegeben werden.
  • Erreichbarkeit / Zeitfenster: Die Konfigurations-Webseite und der drahtlose OTA-Upload sind nach einem Hard-Reset für 2 Minuten erreichbar. Danach überspringt das Gerät das Konfigurationsfenster automatisch, startet die normale Messung und geht anschließend in den deep sleep. Falls man nicht so lange warten möchte – z.B. beim debuggen – kann man im Seriellen Monitor c für cancel senden oder am Firebeetle den user button drücken, dann wird die Konfigurationsmöglichkeit nach einem hard reset übersprungen.

Konfigurations-Optionen

Auf der website können diese Parameter konfiguriert werden:

Network Connection Settings

  • WiFi SSID Name
  • WiFi Password
  • Server URL (Endpoint)

Core Sensor and Timing Allocations

  • Connected Sensors (1-8)
  • Interval (Minutes)
  • Sensor Altitude (Meters)

System Diagnostic Flags

  • Serial Debug
  • RGB LED Debug

Device Identification & Security Keys

  • Device Name (WLAN SSID / Hostname)
  • Device Security Key (AP / OTA Password)

Weiter kann die Kalibrierung (s.u.) der Sensoren hier getriggert werden.

firmware update

  • klassisches update über die Arduino IDE mit USB-Kabel ;-)
  • daneben auch OTA in den ersten 2 Minuten (konfigurierbar) nach einem hard reset, OTA-Passwort ist im code definiert und default “openhive” (kann per Konfiguration geändert werden)

Bis zu 8 CO2-Sensoren

  • Da die SCD41 im peak relativ viel strom brauchen und wir nicht ausschließen können, dass dann alle 8 gleichzeitig den Maximalstrom des Firebeetle überschreiten, erfolg softwareseitig eine Aufteilung in zwei Gruppen mit max. 4 SCD41 die nacheinander angesteuert werden. Daher finden die Messungen aber auch die Kalibrierung ab 5 Sensoren zeitversetzt statt: Bei der Messung zuerst Sensor 1-4 dann etwa 10 Sekunden später die zweite Messung, bei der Kalibierung ist das delay länger, nämlich 3 Minuten, da die Sensoren diese Aufwärmzeit brauchen.

Hier sieht man die Messung in Gruppen mit 4 Sensoren. Mit den peaks die alle unter 600 mA liegen halten wir die spec vom Firebeetle board ein? Interessant ist, dass die peakts auch bei 3 Sensoren max 440 mA zeigen und selbst mit einem Sensor noch 400 mA peaks da sind.

Telemetrie

Aktuell nur WLAN, da Bienenvölker häufig keinen AccessPoint haben überlege ich Hardware und code mit Mobilfunk zu erweitern.

Debug RGB-LED

Die RGB-LED auf dem Firebeetle 2 leuchtet nicht wenn sie (a) in der Konfiguration deaktiviert wurde oder (b) die solder bridge auf dem Firebeetle 2 zu Stromsparzwecken durchtrennt wurde und das System über den LiPo-Anschluss mit Strom versorgt wird (dann gibt es nur rudimäntäre Infos über die grüne onboard LED – wenn sie schnell blinkt ist OTA oder Webkonfiguration ready).

  • blau blinkend – WLAN Verbindung wird aufgebaut
  • lila blinkend – OTA oder Webkonfiguration ready
  • lila kontinuierlich – Kalibrierung läuft
  • orange – Messung wird durchgeführt
  • blau (ohne blinken) – Daten werden übertragen
  • grün – Übertragung erfolgreich
  • rot – keine Übertragung / Fehler bei der Übertragung

Visualisierung

Das ganze Dashboard mit den Temperatur- und Feuchtigkeitswerten samt LiPo-Spannung gibt es unter https://swarm.hiveeyes.org/grafana/d/dzuuIz5vz/co2-test-kit

Rohdaten kann man sich auch anschauen und zwar hier:
https://swarm.hiveeyes.org/api/hiveeyes/testdrive/openhive/test-co2-a/data.txt (die letzen 24 Stunden)

Kalibrierung

Wenn man oben die Sensorwerte ohne Kalibrierung anschaut fällt schon auf, dass die drei CO₂-Sensoren sehr variieren. Für die Temperatur sieht man auch deutlich zu geringe Werte!

Default / Werkseinstellung ist bei den Temperaturen ein delta von 4 °C (Abzug!) eingestellt, da sie normalerweise in continuous mode betrieben werden. D.h. sie sind immer an und sie heizen sich somit auf. Da wir Strom sparen wollen und nicht so häufig messen liefert die Werkseinstellung falsche, d.h. zu niedrige Werte. Daher setzen wir das delta über den Kalibrierungs-Sketch bei uns auf 0. Mit der punktuellen Messung ohne kontinuierlichen Betrieb passen die Temperaturen dann!


Kalibrierung outdoor mit etwas Windschutz.

Die Kalibrierung der CO2-Werte erfolgt durch die Exposition im Freien. Der Sensor geht dann davon aus, dass hier 400 ppm herrschen und schreibt das mit der Kalibrierungs-Routine fest. Die Sensorkalibrierung heizt den SCD41 ca. 3 Miunten auf daher dem Sketch Zeit lassen. Bei mehr als 4 Sensoren macht das der Sketch in 2 Gruppen, damit der Maximalstrom des Firebeetle nicht überschritten wird, es dauert also nochmal 3 Minuten!

Die Kalibrierung kann über das Webportal initialisiert werden:

Der Sensor hat auch eine automatische Selbstkalibrierung (ASC), die grob so funktioniert: Der niedrigste Wert innerhalb von 7 Tagen wird mit 400 ppm angenommen und darauf kalibriert. Das mag in normalen Räumen, die ab und an auch menschenleer sind so sein, für unseren Answendungsfall können wir das aber nicht voraussetzen. Daher deaktiviert der Kalibrierungssketch die ASC!

Weitere techniche Details unter https://sensirion.com/media/documents/077BC86F/62BF01B9/CD_AN_SCD4x_Low_Power_Operation_D1.pdf oder auch https://wolles-elektronikkiste.de/scd4x-co₂-sensoren#calibration

Wenn wir schon dabei sind, können wir gleich die Meereshöhe für den Ort der Aufstellung konfigurieren, hat via geändertem Luftdruck Einfluss auf die Messung!

Temperatur und Feuchte vor der Kalibrierung

Da mir die gemessenen Werte nicht ganz koscher vorkamen habe ich ab 10.04. einen BME280 neben die SCD41-Sensoren gelegt, um Temperatur und Feuchte unabhängig mit “bekannt gutem” Sensor zu messen.

In der Grafana Tabelle habe ich die Mittelwerte mit ausgeben lassen, damit können wir ganz einfach das delta über 10 Tage (Einstellung für die Grafiken oben) berechnen:

Wert
SCD41
Wert
BME280
delta
Temp
Wert
SCD41
Wert
BME280
delta
Humid
SCD41 #1 16.05 20.87 +4.82 SCD41 #1 59.65 38.43 -21.22
SCD41 #2 16.14 20.87 +4.73 SCD41 #2 54.19 38.43 -15.76
SCD41 #3 16.18 20.87 +4.69 SCD41 #3 51.43 38.43 -13
Temperatur °C Feuchte %H

Damit wären wir eher 4,7 °C unter dem realen Wert, das offset kann man aber nicht negativ angeben, d.h die maximale Korrektur ist 4,0 °C / das sind 0 °C offset.

Einhausung

Nun habe ich mir den Design-in Guide des SCD41 genauer angeschaut: https://sensirion.com/media/documents/0D0C9129/623B1183/Sensirion_CO2_Sensors_SCD4x_design-in_guide.pdf .

Bisher habe ich die “nackten” Sensoren getestet. Der Design Guide empfiehlt aber den Sensor einzuhausen, mit nicht zu viel Raum außen herum aber doch so, dass direkte Luftströme angehalten werden.

Large dead volumes can increase the response time of the sensor significantly.

Steht da auch und vermutlich nicht nur die response time sondern auch die accuracy – vermute ich.

Das könnt bedeuten, dass auch meine Idee den Sensor einfach in einen Königinnenversandkäfig zu stecken – wie auf dem Bild – ggf. nicht ausreicht.

Physikalisch erkläre ich mir das so, dass der Sensor intern aufheizt und Luftströme dann kontraproduktiv sind, da sie kühlen. Muss ich mit aber auch noch genauer anschauen wie unser Sensor da arbeitet.

Fotos

Literatur zu CO2 im Bienenstock

Hinweis: Arduino-IDE und Firebeetle 2 ESP32-E

Die boards-Definition der IDE hat mit OTA ein Problem da in boards.txt die Regel für OTA schlicht fehlt, bitte ergänzen:

dfrobot_firebeetle2_esp32e.upload.tool.network=esp_ota
dfrobot_firebeetle2_esp32e.upload.maximum_size=1966080
dfrobot_firebeetle2_esp32e.build.partitions=min_spiffs

Dann funktioniert auch OTA mit dem Firebeetle 2 ESP32-E!

I2C-Multiplexer: Soldered TCA9548A vs. DFRobot Gravity

Den Soldered I2C-Multiplexer TCA9548A habe ich nun getestet und das Gesamtsystem ist mit 15 µA im deep sleep deutlich sparsamer als der DFRobot. Wenn man den deep sleep current des Firebeetles (12 µA) abzieht baucht das Multiplexer-board ca. 3 µA, ist dafür aber etwas mehr bulky:

Hallo Clemens, finde ich gut, dass Du den CO2-Sensor-Kit online gestellt hast. Zur Kalibrierung des SCD4x habe ich noch einen Link gefunden; vielleicht ist der für Dich hilfreich.

https://www.reddit.com/r/AirQuality/comments/12y0nwm/warning_about_the_sensirion_scd4041_co2_sensors/

Gruß Heinz

Danke @heinz für den Hinweis zur Auto-Kalibrierung. Wichtig, dass wir die ausschalten! Ich bin darauf schon gestoßen und habe die für unseren Anwendungsfall deaktiviert, siehe oben: