CO₂-Ampel mit dem Arduino selbst bauen

FunduinoZuletzt aktualisiert am

Luftqualität messen und als Ampelfarbe sichtbar machen

Wie gut ist die Luft in einem Raum? Der CO₂-Anteil gibt darauf eine brauchbare Antwort: Je mehr ausgeatmete Luft sich ansammelt, desto höher steigt er – und desto nötiger wird das Lüften. In Schulen wurde außerdem festgestellt, dass die Konzentrationsfähigkeit mit steigendem CO₂-Anteil nachlässt.

Eine CO₂-Ampel macht diesen Wert sichtbar. In dieser Anleitung baust du eine solche Ampel mit dem Arduino: Zuerst liest du den Sensor aus und zeigst die Werte im seriellen Monitor an, danach steuerst du damit drei LEDs in Ampelfarben.

Arduino UNO mit MH-Z19B-Sensor und drei LEDs auf einem Steckbrett
Der Aufbau mit CO₂-Sensor und LED-Ampel

Welche CO₂-Werte sind kritisch?

In einer Bekanntmachung des Umweltbundesamtes aus dem Jahr 2008 mit dem Titel Gesundheitliche Bewertung von Kohlendioxid in der Innenraumluft findest du wissenschaftliche Hinweise darauf, welche CO₂-Werte normal und welche kritisch sind. Ein Wert von 400 ppm (parts per million) gilt als ganz natürlicher CO₂-Anteil der Außenluft. Für Schulen wurde festgestellt, dass die Konzentrationsfähigkeit mit steigendem CO₂-Anteil abnimmt.

Die Norm DIN EN 13779 teilt die Raumluftqualität in vier Kategorien ein:

  • IDA 1 – hohe Raumluftqualität: unter 400 ppm über der Außenluft, absolut unter 800 ppm
  • IDA 2 – mittlere Raumluftqualität: 400 bis 600 ppm über der Außenluft, absolut 800 bis 1000 ppm
  • IDA 3 – mäßige Raumluftqualität: 600 bis 1000 ppm über der Außenluft, absolut 1000 bis 1400 ppm
  • IDA 4 – niedrige Raumluftqualität: über 1000 ppm über der Außenluft, absolut über 1400 ppm

Eine CO₂-Ampel misst den CO₂-Anteil der Umgebungsluft und macht ihn als Ampelfarbe sichtbar: Von Grün wechselt sie über Gelb zu Rot, sobald bedenkliche Mengen erreicht sind. So sieht man auf einen Blick, wann gelüftet werden sollte.

Dafür brauchst du nur wenige Bauteile: einen Arduino UNO, einen CO₂-Sensor MH-Z19B, eine LED-Ampel sowie ein Steckbrett mit ein paar Kabeln.

Aufbau und Verkabelung

Im ersten Versuch zeigst du die Messwerte des Sensors nur im seriellen Monitor an. Die Ampel kommt danach dazu.

Der MH-Z19B liefert seinen Messwert als PWM-Signal. Diesen Ausgang verbindest du mit Pin 5 des Arduino. Dazu kommen die Stromversorgung des Sensors und die gemeinsame Masse.

Arduino UNO mit MH-Z19B-Sensor und drei LEDs auf einem Steckbrett
Der Aufbau mit CO₂-Sensor und LED-Ampel
CO2-Sensor MH-Z19B mit angeschlossenen Steckkabeln
Der MH-Z19B aus der Nähe
1 / 2

Messwerte auslesen

Der Sketch misst mit pulseIn(), wie lange das PWM-Signal des Sensors auf HIGH bleibt, und rechnet daraus den ppm-Wert aus.

Öffne nach dem Hochladen den seriellen Monitor bei 9600 Baud. Im Beispiel liegen die Werte unter 800 ppm – das entspricht Raumluft-Kategorie IDA 1, also hoher Raumluftqualität.

Serieller Monitor mit sekundenweise ausgegebenen CO2-Werten in ppm
Die Messwerte im seriellen Monitor
CO₂-Wert auslesen und anzeigen
// Funduino - CO2-Messung mit dem Sensor MH-Z19B
// Die Messwerte werden über das PWM-Signal des Sensors ermittelt.

// Der PWM-Pin des Sensors kommt an Pin 5 des Mikrocontrollers. Bei anderen
// Boards muss dieser Pin PWM-fähig sein.
int SensorPin = 5;

// Der voreingestellte Messbereich (0 bis 5000 ppm). Der MH-Z19B kann auch auf
// einen Höchstwert von 2000 ppm vorkonfiguriert sein.
int Messbereich = 5000;

unsigned long ZeitMikrosekunden;  // Dauer des PWM-Signalpegels in Mikrosekunden
unsigned long ZeitMillisekunden;  // Dauer des PWM-Signalpegels in Millisekunden

int PPM = 0;        // CO2-Messwert in ppm (parts per million, Anteile pro Million)
float Prozent = 0;  // prozentuale Länge des PWM-Signals

void setup()
{
  pinMode(SensorPin, INPUT);  // Pin 5 wird als Eingang definiert.
  Serial.begin(9600);         // Serielle Verbindung für den seriellen Monitor
}

void loop()
{
  // pulseIn misst, wie lange das Signal am Pin auf HIGH bleibt. Ohne den dritten
  // Wert endet die Messung nach 1.000.000 Mikrosekunden, also nach einer Sekunde.
  // Das Signal des Sensors kann aber bis zu 1004 ms lang sein - deshalb setzen
  // wir diesen "Timeout" höher.
  ZeitMikrosekunden = pulseIn(SensorPin, HIGH, 2000000);

  // Umrechnen von Mikrosekunden in Millisekunden
  ZeitMillisekunden = ZeitMikrosekunden / 1000;

  // Laut Datenblatt ist das PWM-Signal des MH-Z19B höchstens 1004 ms lang. Wir
  // teilen die gemessene Dauer durch diesen Höchstwert und bekommen so den Anteil
  // des aktiven Pegels am Gesamtsignal.
  Prozent = ZeitMillisekunden / 1004.0;

  // Aus diesem Anteil und dem Messbereich ergibt sich der ppm-Wert.
  PPM = Messbereich * Prozent;

  Serial.print("CO2 Anteil in der Luft in PPM: ");
  Serial.println(PPM);

  delay(1000);  // Eine Sekunde bis zur nächsten Messung
}

Die Ampel ergänzen

Jetzt nutzt du die Messwerte, um eine Ampel anzusteuern. Schließe zusätzlich drei LEDs in Ampelfarben an die digitalen Pins 6, 7 und 8 an – oder ein fertiges LED-Ampel-Modul. Später könnten dort statt der LEDs auch Relais hängen, um eine echte Ampelanlage zu schalten.

Die drei LEDs stellen die vier Raumluft-Kategorien dar:

  • IDA 1 – grüne LED
  • IDA 2 – grüne und gelbe LED
  • IDA 3 – gelbe LED
  • IDA 4 – rote LED

Die Rechnung im Sketch ist bewusst einfach gehalten: Sie teilt die gemessene Signaldauer durch den Höchstwert von 1004 Millisekunden. Für eine Ampel, die Grün, Gelb und Rot unterscheiden soll, reicht das gut aus. Wer es genauer braucht, findet im Datenblatt des MH-Z19B eine ausführlichere Formel, die auch die Pausenzeit des Signals berücksichtigt.

CO₂-Ampel: Messwert als Ampelfarbe anzeigen
// Funduino - CO2-Ampel mit dem Sensor MH-Z19B

int ROT  = 6;  // Rote LED an Pin 6
int GELB = 7;  // Gelbe LED an Pin 7
int GRUN = 8;  // Grüne LED an Pin 8

// Der PWM-Pin des Sensors kommt an Pin 5 des Mikrocontrollers.
int SensorPin = 5;

// Der voreingestellte Messbereich (0 bis 5000 ppm).
int Messbereich = 5000;

unsigned long ZeitMikrosekunden;  // Dauer des PWM-Signalpegels in Mikrosekunden
unsigned long ZeitMillisekunden;  // Dauer des PWM-Signalpegels in Millisekunden

int PPM = 0;        // CO2-Messwert in ppm
float Prozent = 0;  // prozentuale Länge des PWM-Signals

void setup()
{
  pinMode(SensorPin, INPUT);  // Pin 5 wird als Eingang definiert.
  Serial.begin(9600);

  pinMode(ROT, OUTPUT);   // Pin 6 ist ein Ausgang.
  pinMode(GELB, OUTPUT);  // Pin 7 ist ein Ausgang.
  pinMode(GRUN, OUTPUT);  // Pin 8 ist ein Ausgang.
}

void loop()
{
  ZeitMikrosekunden = pulseIn(SensorPin, HIGH, 2000000);
  ZeitMillisekunden = ZeitMikrosekunden / 1000;
  Prozent = ZeitMillisekunden / 1004.0;
  PPM = Messbereich * Prozent;

  Serial.print("CO2 Anteil in der Luft in PPM: ");
  Serial.println(PPM);

  // Ab hier wird die Ampel angesteuert.
  if (PPM < 800)  // Messwert kleiner als 800: hohe Raumluftqualitaet
  {
    digitalWrite(GRUN, HIGH);  // gruene LED an
    digitalWrite(GELB, LOW);
    digitalWrite(ROT, LOW);
  }
  if (PPM >= 800 && PPM <= 1000)  // 800 bis 1000: mittlere Raumluftqualitaet
  {
    digitalWrite(GRUN, HIGH);  // gruene und gelbe LED an
    digitalWrite(GELB, HIGH);
    digitalWrite(ROT, LOW);
  }
  if (PPM > 1000 && PPM <= 1400)  // 1000 bis 1400: maessige Raumluftqualitaet
  {
    digitalWrite(GRUN, LOW);
    digitalWrite(GELB, HIGH);  // nur die gelbe LED an
    digitalWrite(ROT, LOW);
  }
  if (PPM > 1400)  // ueber 1400: niedrige Raumluftqualitaet
  {
    digitalWrite(GRUN, LOW);
    digitalWrite(GELB, LOW);
    digitalWrite(ROT, HIGH);  // rote LED an
  }

  delay(1000);  // Eine Sekunde bis zur nächsten Messung
}
Anleitung bewerten

Kommentare

Frage stellen oder Erfahrung teilen

Schreib uns, wenn etwas nicht funktioniert. Nenne dabei dein Board und die Fehlermeldung.

Wir prüfen jeden Kommentar vor der Veröffentlichung. Deine E-Mail-Adresse bleibt bei uns.