CO₂-Messung: Der „Müdigkeits-Faktor“ im Büro aufdecken
Benötigte Bauteile
| Andium Anduino WiFi Shield | Für Arduino Due/Zero – WLAN & MQTT | 1 |
| Arduino Due | 3,3 V Logik, mehrere UARTs | 1 |
| NDIR CO₂-Sensor (z. B. Cozir) | UART, 3,3 V, <1,5 mA Mittelstrom | 1 |
| Jumper-Kabel | Für Sensor-Verkabelung (4 Drähte) | 1 Set |
Software & Dienste
- Arduino IDE
- Adafruit IO (MQTT-Broker & Dashboards)
Projektbeschreibung
Motivation
Kennen Sie das? Nachmittags im Meeting kaum wach bleiben, ständig gähnen, in 3-Stunden-Vorlesungen einschlafen? Nicht immer ist Schlafmangel schuld – schlechte Belüftung und hohe CO₂-Konzentration machen müde! Mit einem NDIR-CO₂-Sensor lässt sich die „Schläfrigkeits-Konzentration“ präzise messen und per UART auslesen.
Frühere CO₂-Sensoren brauchten viel Strom und lange Aufwärmphasen (Glühlampe). Moderne NDIR-Sensoren (z. B. Cozir) nutzen eine LED und Infrarot-Detektor: optische Dispersion misst CO₂ bei 3,3 V und <1,5 mA Mittelstrom. Details im Cozir-Datenblatt.
Los geht’s
Verkabelung (4 Drähte):
- Sensor 3,3 V → Arduino Due 3,3 V
- Sensor GND → GND
- Sensor Rx → Arduino Due Tx (D18, Serial1)
- Sensor Tx → Arduino Due Rx (D19, Serial1)
Wichtig: UART-Kreuzen (Rx↔Tx)! Nicht Serial (D0/D1) nutzen, sonst kein Serial Monitor. Sensor ist 3,3 V TTL – bei 5 V Boards Logik-Level-Shifter nötig.
Direkt-Test per Terminal: Putty/Serial Terminal, 9600 Baud, 8N1, CR+LF senden. Befehle: „Z“ (CO₂ lesen), „G“ (Frischluft-Kalibrierung), „K 1“ (Polling-Modus).
Kalibrierung
Zwei Methoden:
- Stickstoff (N₂): Sensor in CO₂-freiem Gas sättigen → echter Nullpunkt.
- Frischluft (einfacher): Sensor nach draußen bringen, Sketch mit
calibrateFreshAir()imsetup()laufen lassen. Sendet „G“ an Sensor → kalibriert auf ca. 450 ppm (globaler Mittelwert). Genau genug für Innenraum-Schwellenwerte (1000+ ppm).
Beispiel-Sketch (Kalibrierung & Auslesen)
char buffer[20] = {0};
int c = 0;
void setup() {
Serial.begin(9600); while(!Serial);
Serial1.begin(9600); while(!Serial1);
Serial.println("CO2-Messung startet");
// setOperatingMode(CZR_POLLING);
// calibrateFreshAir(); // einmalig im Freien ausführen
}
void loop() {
delay(10000);
c = Request("Z");
Serial.print("CO2: "); Serial.println(c); Serial.println();
}
int Request(char* s) {
buffer[0] = '\0'; int idx = 0;
Command(s); delay(250);
while(Serial1.available()) buffer[idx++] = Serial1.read();
buffer[idx] = '\0';
uint16_t rv = 0;
switch(buffer[1]) {
case 'T': rv = atoi(&buffer[5]); if (buffer[4] == 1) rv += 1000; break;
default: rv = atoi(&buffer[2]); break;
}
return rv;
}
void Command(char* s) { Serial1.print(s); Serial1.print("\r\n"); }
uint16_t calibrateFreshAir() { return Request("G"); }
void setOperatingMode(uint8_t mode) { sprintf(buffer, "K %u", mode); Command(buffer); }
Daten an Adafruit IO senden (MQTT)
Voraussetzung: Anduino WiFi mit Adafruit IO verbunden (siehe verlinktes Tutorial). Sketch sendet CO₂-Wert jede Minute per MQTT an Feed „co2“. Auf dem Anduino-LCD wird der Wert groß angezeigt (Vorheriger Wert schwarz überschreiben, neuer Wert weiß).
#include <WiFi101.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "AnduinoLCD.h"
#define WLAN_SSID "DEIN_SSID"
#define WLAN_PASS "DEIN_PASSWORT"
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "DEIN_USER"
#define AIO_KEY "DEIN_AIO_KEY"
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish carbonDioxide = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/co2");
AnduinoLCD LCD = AnduinoLCD(ST7735_CS_PIN, ST7735_DC_PIN, 13);
static int co2 = 0, co2Prev = 0;
#define CZR_STREAMING 0x01
#define CZR_POLLING 0x02
char buffer[20] = {0};
void setup() {
Serial.begin(115200); delay(3000);
Serial1.begin(9600);
connectToWiFi(); connectToAdafruit();
LCD.begin(); LCDinit();
// setOperatingMode(CZR_POLLING); calibrateFreshAir();
}
void loop() {
if(!mqtt.ping(3)) { if(!mqtt.connected()) connect(); }
co2 = Request("Z");
char b[20]; String str = String(co2);
for(int i=0; i<str.length(); i++) b[i]=str.charAt(i);
b[str.length()] = 0;
if(!carbonDioxide.publish((char*)b)) Serial.println("Publish fehlgeschlagen");
else { Serial.print("CO2 published: "); Serial.println(co2); displayCo2(co2, co2Prev); }
Serial.print("CO2: "); Serial.println(co2);
co2Prev = co2;
delay(60000);
}
// ... WiFi/MQTT/LCD-Hilfsfunktionen (connect, displayCo2, Request, Command, calibrateFreshAir, setOperatingMode) wie im Original ...
Ergebnis & Ausblick
Der Sensor ist extrem empfindlich – man kann quasi die Raumbelegung an der CO₂-Kurve ablesen (selbst in gut belüfteten Räumen). Beweisen Sie Ihrem Professor: Nicht die Differentialgleichung macht müde, sondern die schlechte Luft! Nächstes Mal: Vorlesung an den Strand verlegen.
Code-Bibliothek
Anduino Library (GitHub: andium/Anduino) – wandelt Arduino + Shield in AndiumNode um.
Herstellungsprozess
- Sensirion bringt SCD40: Ultra-miniaturisierter CO₂ und RH/T Sensor
- Sensordaten in Raspberry Pi integrieren: GPS & MPU-9150 Hands-On Guide
- Benutzerdefinierte Objektsensoren für LEGO Mindstorms EV3 bauen: DIY Licht-basierte „Augen“
- Lego Mindstorms NXT Ultraschallsensor direkt an Raspberry Pi anschließen
- HC-SR04 Ultraschallsensor an Raspberry Pi anschließen – Praktischer Leitfaden
- Acconeer A111 Pulsradar mit Raspberry Pi integrieren: Praktischer Leitfaden
- Kundenservice am Regal steigern: Fortgeschrittene Strategien für Transparenz und Effizienz
- RF-Funkstrom treibt universelle Sensornetzwerk-Adoption voran
- RapidPlex-Sensor: 5 wesentliche Fragen zum SARS-CoV-2-Heimtest
- Industrielle Instandhaltung: Die 5 wesentlichen Ebenen erklärt