TVOC und eCO2 Sensoren

Über den Beitrag

Bei den CO2 Sensoren zur Überwachung der Raumluftqualität gibt es zwei vorherrschende Technologien. In meinem letzten Beitrag hatte ich über die relativ teuren, aber nach meiner Erfahrung auch zuverlässigen NDIR CO2 Sensoren berichtet. Hier möchte ich nun die günstigeren, Metalloxid-basierten TVOC und eCO2 Sensoren behandeln.

Die TVOC und eCO2 Sensoren reagieren auf die Anwesenheit bestimmter organischer Stoffe in der Luft (VOCs) und berechnen daraus die Gesamtkonzentration an flüchtigen organischen Stoffen (Total Volatile Organic Compounds). Aus dem TVOC und ggf. weiteren Messwerten schätzen die Sensoren über proprietäre Algorithmen eine CO2 Äquivalentkonzentration (eCO2) ab.

Ich will nicht verhehlen, dass sich meine Begeisterung für diese Art Sensoren in Grenzen hält. Aber da ich nun einige Zeit investiert habe und der eine oder andere sich vielleicht fragt, was diese Teile können (oder nicht können!), möchte ich meine Erfahrungen teilen.

Ich betrachte in diesem Beitrag zwei Vertreter dieser Sensorenklasse, nämlich den CCS811 und den SGP30. Dabei widme ich mich den folgenden Themen:

  • Messprinzip der MOX TVOC und eCO2 Sensoren
  • Technische Eigenschaften der CCS811 und SGP30 Module
  • Baselines
  • Ansteuerung der Module mittels Bibliotheken
  • Zuverlässigkeit (Vergleich mit NDIR)
TVOC und eCO2 Sensoren, Links / Mitte: CCS811 Module, Rechts: SGP-30 Modul
TVOC und eCO2 Sensoren, Links / Mitte: CCS811 Module, Rechts: SGP-30 Modul

Messprinzip der TVOC und eCO2 Sensoren

Was sind VOCs?

VOCs können sehr unterschiedliche chemische Substanzen sein. Darunter fallen unter anderem Alkohole, Aldehyde, Ketone oder Kohlenwasserstoffe. Das klingt sehr chemisch-künstlich, aber diese Stoffe sind auch natürliche Stoffwechselprodukte, die wir ausatmen oder über die Haut abgeben.

Das „T“ in TVOC besagt lediglich, dass die Sensoren eine Gesamtkonzentration an VOCs ermitteln, ohne diese weiter nach Stoffklassen aufzuschlüsseln.

Wie funktioniert der eigentliche Sensor?

Das Herzstück der TVOC und eCO2 Sensoren ist eine dünne Metalloxidschicht. Deswegen werden die Sensoren auch als MOX Sensoren oder kurz als MOS bezeichnet. Bei dem Metalloxid handelt es sich meistens um Zinndioxid.

Die Metalloxidschicht besitzt durch Sauerstofffehlstellen eine gewisse Leitfähigkeit. In sauberer Umgebungsluft absorbiert die Metalloxidschicht Sauerstoff, der begierig Elektronen bindet. Dadurch sinkt die Konzentration an freien Ladungsträgern und damit auch die Leitfähigkeit. In belasteter Luft absorbiert das Metalloxid auch vermehrt VOCs. Die VOCs wiederum reagieren mit dem auf dem Metalloxid vorhandenen Sauerstoff. Die Reaktionsprodukte verlassen die Metalloxidschicht. Infolgedessen nimmt die Leitfähigkeit wieder zu. Damit das Ganze funktioniert, muss die Metalloxidschicht erhitzt werden. Das Metalloxid wirkt dabei nicht nur als Sensor, sondern auch als Katalysator.

Der Kehrwert der Leitfähigkeit ist der Widerstand und der lässt sich gut messen. Je schmutziger die Luft, desto geringer also der Widerstand. Eine nette Animation habe ich hier gefunden.

Aber wie ermitteln die Sensoren den CO2 Gehalt?

Wenn man zugrunde legt, dass jeder Mensch über die Zeit eine gewisse Menge an VOCs abgibt, lässt sich darüber eine CO2 Konzentration abschätzen. Da es sich dabei um eine berechnete CO2 Konzentration handelt, spricht man von einer Äquivalentkonzentration (eCO2 = equivalent CO2). Auf CO2 selbst reagieren die Sensoren nicht!

Wie zuverlässig sind die Sensoren?

Ich nehme mal mein Fazit vorweg: Die TVOC und eCO2 Sensoren liefern keine quantitativ zuverlässigen Ergebnisse. Das gilt vor allem für die eCO2 Werte. In ihrer Dimension zeigen die Werte allerdings eine gewisse Reproduzierbarkeit. Zumindest gilt das, wenn man sich an die empfohlenen Prozeduren hält. Positiv bewerte ich die hohe Empfindlichkeit der Sensoren und ihre und die schnelle Reaktion.

Der CCS811

Technische Eigenschaften

Ein CCS811 Modul

Hier die wichtigsten technischen Daten:

  • eCO2 Range: 400 – 32768 ppm
  • TVOC Range: 0 – 29206 ppb
  • Versorgungsspannung:
    • Für den blanken Sensor: 1.8 – 3.3 Volt
    • Für das Modul: es kommt auf euer Modul an, einige Module haben Spannungsregler, andere nicht!
  • Stromverbrauch: im Dauerbetrieb an 5 Volt habe ich 18 mA gemessen
    • Pulse- und Sleep-Modes können den Verbrauch auf ein Minimum reduzieren
  • Kommunikation: I2C (100 kHz / 400 kHz)
    • Adresse 0x5A / 0x5B (einstellbar, wenn Adresspin vorhanden)
    • Ob Pull-Ups nötig sind, hängt vom Modul ab

Weitere Angaben findet ihr im Datenblatt. Dazu gibt es noch ein halbes Dutzend Application Notes, die ihr hier auf den Seiten des Herstellers Sciosense findet.

Pinout

Nicht jedes Modul hat alle Anschlüsse des CCS811 als Pin ausgeführt.

TVOC und eCO2 Sensoren - Pinout der CCS811 Module
Pinout der CCS811 Module

Anschluss an den Microcontroller

Ein CCS811 Modul am Arduino Nano

Betrieb – das Baseline-Konzept

Der CCS811 TVOC und eCO2 Sensor berechnet die Ausgabewerte, wie schon beschrieben, über den Widerstand einer Metalloxidschicht. Die genaue Korrelation variiert von Sensor zu Sensor und ändert sich über die Betriebsdauer. Insbesondere gilt das für das die ersten Tage.

Für die Berechnung der TVOC und eCO2 Werte vergleicht der CCS811 die aktuellen Messwerte mit der sogenannten Baseline. Die Baseline repräsentiert die Messwerte für saubere Luft, d.h. einer CO2 Konzentration von 400 ppm und einer TVOC Konzentration von 0 ppb. Die Baseline wird im Hintergrund fortlaufend aktualisiert. In der Voreinstellung wird jeweils über ein 24 Stunden Fenster der höchste Widerstand als Baseline genommen. Daraus folgt, dass der Sensor in einem Raum stehen muss, der täglich gelüftet wird. Falls nicht, verschiebt sich die Baseline.

Wenn ihr den CCS811 vom Strom trennt, vergisst er seine Baseline. Die gute Nachricht ist, dass ihr die Baseline auslesen könnt. Wenn ihr sie zum Beispiel im EEPROM regelmäßig speichert, könnt ihr sie von dort wieder auslesen. Dadurch erhaltet sinnvolle Messwerte, ohne dass ihr erst wieder warten und lüften müsst, bis sich eine verlässliche Baseline eingestellt hat.

Laut Hersteller sollte man die Baseline in der ersten Woche täglich speichern, später alle 1 – 28 Tage. Falls ungeplante Stromunterbrechungen auftreten können, sollte man sicherheitshalber öfter speichern.

Versucht nicht den Baselinewert zu interpretieren. Er ist mehr als ein einfacher Widerstandswert und beinhaltet auch Informationen über die Luftfeuchte und Temperatur, denn auch diese beeinflussen die Messwerte.  

Ansteuerung des CCS811 mit der Adafruit-Bibliothek

Ich hatte zunächst die Bibliothek von Keyestudio, dem Hersteller eines meiner Module, ausprobiert. Die Dokumentation findet ihr hier. Ich war aber nicht besonders davon angetan. Es wird wenig erklärt und der Beispielsketch ist etwas merkwürdig, da im Sekundentakt eine konstante Baseline auf den CCS811 geschrieben wird.

Die Bibliothek von Adafruit gefiel mir viel besser. Ihr findet sie hier auf GitHub oder ihr installiert sie direkt über die Arduino IDE. Sucht dort nach „CCS811“. Dazu gibt es auch noch ein Tutorial auf den Adafruit Seiten

Der Start

Ihr beginnt am besten, indem ihr den folgenden Sketch hochladet. Es handelt sich um einen Beispielsketch der Bibliothek, den ich um die regelmäßige Ausgabe der Baseline erweitert habe.  Ich empfehle in gut gelüfteter Umgebung zu starten, damit die Messwerte mehr Sinn ergeben.

/***************************************************************************
  Example sketch modified by Wolfgang Ewald. Original comments:
  
  This is a library for the CCS811 air

  This sketch reads the sensor

  Designed specifically to work with the Adafruit CCS811 breakout
  ----> http://www.adafruit.com/products/3566

  These sensors use I2C to communicate. The device's I2C address is 0x5A

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Dean Miller for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs;

void setup() {
  Serial.begin(9600);

  Serial.println("CCS811 test");

  if(!ccs.begin()){
    Serial.println("Failed to start sensor! Please check your wiring.");
    while(1);
  }

  // Wait for the sensor to be ready
  while(!ccs.available());
}

void loop() {
  static int counter = 0;
  static unsigned int baseline = ccs.getBaseline();
  if(ccs.available()){
    if(!ccs.readData()){
      Serial.print("CO2: ");
      Serial.print(ccs.geteCO2());
      Serial.print("ppm, TVOC: ");
      Serial.println(ccs.getTVOC());
    }
    else{
      Serial.println("ERROR!");
      while(1);
    }
  }
  counter++;
  if(counter==30){
    baseline = ccs.getBaseline();
    Serial.print("Baseline: ");
    Serial.println(baseline, HEX);
    counter=0;
  }
  delay(500);
}

 

Und so oder ähnlich sieht die Ausgabe aus:

TVOC und eCO2 Sensoren - Ausgabe von Adafruit_CCS811_mod.ino
Ausgabe von Adafruit_CCS811_mod.ino

Dauerbetrieb

Im Dauerbetrieb wollt ihr die Baseline wahrscheinlich regelmäßig speichern und sie im Falle eines Neustarts in den CCS811 zurückschreiben. Dazu könnt ihr den EEPROM Speicher eures Arduinos benutzen. Der folgende Sketch schreibt eine erste Baseline in den EEPROM. Nehmt die Baseline, die ihr selbst zuvor ermittelt habt und ändert den Sketch entsprechend ab.

#include <EEPROM.h>

void setup(){
  unsigned int baseline = 0x847B;
  int address = 0;  
  Serial.begin(9600);
  
  EEPROM.put(address, baseline); 
  baseline = 0;
  Serial.println(baseline);
  EEPROM.get(address, baseline);
  Serial.println(baseline,HEX);
}

void loop()
{
}

 

Für den Dauerbetrieb habe ich den Testsketch noch etwas erweitert. Zu Beginn wird die im EEPROM gespeicherte Baseline gelesen und in den CCS811 geschrieben. Mit der Funktion setDriveMode() könnt ihr den Messmodus ändern. In der Hauptschleife wird die Baseline alle drei Stunden ausgelesen und in den EEPROM geschrieben.

/***************************************************************************
  Example sketch, modified by Wolfgang Ewald. Original comments:
  
  This is a library for the CCS811 air

  This sketch reads the sensor

  Designed specifically to work with the Adafruit CCS811 breakout
  ----> http://www.adafruit.com/products/3566

  These sensors use I2C to communicate. The device's I2C address is 0x5A

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Dean Miller for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include <EEPROM.h>
#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs;

void setup() {
  Serial.begin(9600);

  Serial.println("CCS811 test");

  if(!ccs.begin()){
    Serial.println("Failed to start sensor! Please check your wiring.");
    while(1);
  }

  // Wait for the sensor to be ready
  while(!ccs.available());
  unsigned int restoredBaseline = 0;
  EEPROM.get(0, restoredBaseline);
  ccs.setBaseline(restoredBaseline);
  Serial.print("Restored baseline: ");
  Serial.println(restoredBaseline, HEX);
  /*You can set the following modes to set the measurement frequency: 
   * CCS811_DRIVE_MODE_IDLE
   * CCS811_DRIVE_MODE_1SEC   
   * CCS811_DRIVE_MODE_10SEC
   * CCS811_DRIVE_MODE_60SEC
   * CCS811_DRIVE_MODE_250MS
   * Mode 1 is default. Low frequncy saves power.
   */
   // ccs.setDriveMode(CCS811_DRIVE_MODE_1SEC);
}

void loop() {
  static int counter = 0;
  static unsigned int baseline = ccs.getBaseline();
  static unsigned long lastBaselineSaving = millis();
  const unsigned long baselineSavePeriod = 10800000; // 3h - modify according to your needs
  if(ccs.available()){
    if(!ccs.readData()){
      Serial.print("CO2: ");
      Serial.print(ccs.geteCO2());
      Serial.print("ppm, TVOC: ");
      Serial.println(ccs.getTVOC());
    }
    else{
      Serial.println("ERROR!");
      while(1);
    }
  }
  counter++;
  if(counter==30){
    baseline = ccs.getBaseline();
    Serial.print("Baseline: ");
    Serial.println(baseline, HEX);
    counter=0;
  }
  if((millis()-lastBaselineSaving)>baselineSavePeriod){
    baseline = ccs.getBaseline();
    EEPROM.put(0, baseline); 
    lastBaselineSaving = millis();
  }
  delay(500);
}

 

Der SGP30

Der SGP30 ist dem CCS811 vom Prinzip her ähnlich, im Detail unterscheidet er sich aber deutlich. Der Sensor besitzt eine besondere Sensitivität für Wasserstoff und Ethanol. Daraus berechnet er Äquivalentkonzentrationen für TVOC und CO2 und benutzt dazu zwei Baselines.

Technische Eigenschaften

Ein SGP30 Modul
Ein SGP30

Hier die wichtigsten technischen Eigenschaften:

  • eCO2 Range: 400 – 60000 ppm.
  • TVOC Range: 0 – 60000 ppb.
  • Messfrequenz: 1 Hz (nicht einstellbar).
  • Versorgungsspannung:
    • Sensor: 1.62 – 1.98 Volt.
    • Für das Modul: es kommt darauf an, ob und welche Spannungsregler euer Modul hat. Mein CJMCU-30 Modul (rechts) kann mit 3 – 5 Volt betrieben werden.
  • Stromverbrauch: Im Dauerbetrieb bei 5 Volt habe ich 47 mA gemessen.
  • Kommunikation: I2C (100 kHz / 400 kHz).
    • Adresse: 0x58, nicht veränderbar.
    • Ob Pull-Ups und / oder Level Shifter nötig sind, hängt vom Modul ab.

Weitere Angaben findet ihr im Datenblatt.

Die Verkabelung mit dem Microcontroller ist bei der geringen Anzahl an Pins wohl selbsterklärend.

Betrieb – Baselines

Auch der SGP30 führt dynamische Baseline Anpassungen durch. Das bedeutet, dass er, genau wie der CCS811, in einer Umgebung stehen sollte, die regelmäßig gelüftet wird. Ebenso besitzt der SGP30 keinen internen permanenten Speicher, sodass die Baselines extern gespeichert werden müssen. 

Sofern ihr noch keine Baselines ermittelt habt, sollte der Sensor 12 Stunden in Betrieb gewesen sein bevor ihr die Baselines speichert und bei zukünftigen Starts zurückschreibt. Schreibt ihr keine Baseline zurück, dann wird der SGP30 neue Baselines ermitteln. Steht der Sensor dabei in einem Raum mit belasteter Luft, werden die Baselines entsprechend falsch sein. 

Ansteuerung des SGP30 mit der Adafruit-Bibliothek

Start

Ihr findet die Adafruit SGP-30 Bibliothek hier auf GitHub oder ihr installiert sie über die Bibliotheksverwaltung der Arduino IDE.

Startet am besten mit dem unveränderten Beispielsketch SGP30test.ino. Er liefert die Rohdaten für Wasserstoff und Ethanol und die daraus berechneten eCO2 und TVOC Werte. Nach jeweils dreißig Messungen liest er die Baselines und gibt sie aus. Lasst den SGP30 am besten für zwölf Stunden laufen und notiert euch dann die Baseline Werte.

TVOC und eCO2 Sensoren - Ausgabe von SGP30test.ino
Ausgabe von SGP30test.ino

Dauerbetrieb

Wenn ihr nicht jedes Mal nach einem Neustart zwölf Stunden auf gültige Baselines warten wollt, dann müsst ihr die Baselines speichern und zurückschreiben. Mit dem folgenden Sketch könnt ihr einen Startwert im EEPROM speichern.

#include <EEPROM.h>

void setup(){
  unsigned int eCO2Baseline = 0x9233;
  unsigned int TVOCBaseline = 0x93AA;
  int address = 0;  
  Serial.begin(9600);
  
  EEPROM.put(address, eCO2Baseline); 
  address += sizeof(unsigned int);
  EEPROM.put(address, TVOCBaseline); 
  
  address = 0;
  EEPROM.get(address, eCO2Baseline);
  address += sizeof(unsigned int);
  EEPROM.get(address, TVOCBaseline); 
  Serial.println(eCO2Baseline,HEX);
  Serial.println(TVOCBaseline, HEX);
}

void loop()
{
}

 

Für den Dauerbetrieb habe ich SGP30test.ino modifiziert. Zu Beginn liest der Sketch die Baselines aus dem EEPROM und schreibt sie in den SGP30. Alle drei Stunden wird die aktuelle Baseline gelesen und im EEPROM gespeichert.

#include <Wire.h>
#include "Adafruit_SGP30.h"
#include <EEPROM.h>

Adafruit_SGP30 sgp;

/* return absolute humidity [mg/m^3] with approximation formula
* @param temperature [°C]
* @param humidity [%RH]
*/
uint32_t getAbsoluteHumidity(float temperature, float humidity) {
    // approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
    const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature)); // [g/m^3]
    const uint32_t absoluteHumidityScaled = static_cast<uint32_t>(1000.0f * absoluteHumidity); // [mg/m^3]
    return absoluteHumidityScaled;
}

void setup() {
  unsigned int restoredECO2Baseline = 0;
  unsigned int restoredTVOCBaseline = 0;
  int address = 0;  
  Serial.begin(9600);
  while (!Serial) { delay(10); } // Wait for serial console to open!
  
  EEPROM.get(address, restoredECO2Baseline);
  address += sizeof(unsigned int);
  EEPROM.get(address, restoredTVOCBaseline); 
  Serial.print("Restored eCO2 baseline: ");
  Serial.println(restoredECO2Baseline,HEX);
  Serial.print("Restored TVOC baseline: ");
  Serial.println(restoredTVOCBaseline, HEX);

  Serial.println("SGP30 test");

  if (! sgp.begin()){
    Serial.println("Sensor not found :(");
    while (1);
  }
  Serial.print("Found SGP30 serial #");
  Serial.print(sgp.serialnumber[0], HEX);
  Serial.print(sgp.serialnumber[1], HEX);
  Serial.println(sgp.serialnumber[2], HEX);
  
  sgp.setIAQBaseline(restoredECO2Baseline, restoredTVOCBaseline);  
}

int counter = 0;
void loop() {
  static unsigned int eCO2Baseline;
  static unsigned int TVOCBaseline;
  static unsigned long lastBaselineSaving = millis();
  unsigned long baselineSavePeriod = 10800000; // 3h
  // If you have a temperature / humidity sensor, you can set the absolute humidity to enable the humditiy compensation for the air quality signals
  //float temperature = 22.1; // [°C]
  //float humidity = 45.2; // [%RH]
  //sgp.setHumidity(getAbsoluteHumidity(temperature, humidity));

  if (! sgp.IAQmeasure()) {
    Serial.println("Measurement failed");
    return;
  }
  Serial.print("TVOC "); Serial.print(sgp.TVOC); Serial.print(" ppb\t");
  Serial.print("eCO2 "); Serial.print(sgp.eCO2); Serial.println(" ppm");

  if (! sgp.IAQmeasureRaw()) {
    Serial.println("Raw Measurement failed");
    return;
  }
  Serial.print("Raw H2 "); Serial.print(sgp.rawH2); Serial.print(" \t");
  Serial.print("Raw Ethanol "); Serial.print(sgp.rawEthanol); Serial.println("");
 
  delay(1000);

  counter++;
  if (counter == 30) {
    counter = 0;

    if (! sgp.getIAQBaseline(&eCO2Baseline, &TVOCBaseline)) {
      Serial.println("Failed to get baseline readings");
      return;
    }
    Serial.print("****Baseline values: eCO2: 0x"); Serial.print(eCO2Baseline, HEX);
    Serial.print(" & TVOC: 0x"); Serial.println(TVOCBaseline, HEX);
  }
  if((millis()-lastBaselineSaving)>baselineSavePeriod){
    int address = 0;
    sgp.getIAQBaseline(&eCO2Baseline, &TVOCBaseline);
    EEPROM.put(address, eCO2Baseline); 
    address += sizeof(unsigned int);
    EEPROM.put(address, TVOCBaseline);
    lastBaselineSaving = millis();
  }
}

 

SGP30 und CCS811 vs. NDIR Sensor

Ich habe die beiden TVOC und eCO2 Sensoren SGP30 und CCS811 zwei Wochen im Dauertest gehabt und die eCO2 Werte mit den Messwerten meines Technoline WL 1030 verglichen. In meinem letzten Beitrag hatte ich gezeigt, dass man den Messwerten des Technoline Gerätes Glauben schenken darf.

Nach vollständiger Lüftung haben alle Sensoren Werte in der Nähe von 400 ppm angezeigt. Mit zunehmender Belastung hingegen enteilten die eCO2 Ergebnisse für den CCS811 und den SGP30. Der CCS811 lieferte ggü. dem Technoline WL 1030 bis zu vierfach höhere Werte. Beim SGP30 waren die Werte „nur“ bis zu zweifach überhöht.

Vergesst also die absoluten Werte! Die TVOC und eCO2 Sensoren geben Tendenzen wieder, nicht mehr. Wenn ihr wirklich den CO2 Gehalt der Raumluft überwachen wollt, dann greift lieber auf die etwas teureren NDIR CO2 Sensoren zurück.

SGP40

Mittlerweile gibt es ein Nachfolgemodell des SGP30, nämlich den SGP40. Dieser liefert anstelle von TVOC und eCO2 Werten einen dimensionslosen Index zwischen 0 und 500. Für mich erscheint das ein guter Ansatz, da ein eCO2 Wert doch suggeriert, man könne damit zumindest halbwegs verlässlich CO2 Konzentrationen abschätzen. Bestellt ist das Teil, ausprobiert habe ich es nicht. Vielleicht berichte ich darüber in einem späteren Beitrag. 

Danksagung

Der Rauch auf dem Beitragsbild, in den ich das CCS811 Modul hineingepixelt habe, stammt von goranmx auf Pixabay

Adafruit danke ich für ihre Bibliotheken und die Fritzing Bauteile. 

13 thoughts on “TVOC und eCO2 Sensoren

  1. Wie immer ein informativer Beitrag !
    Da ich aktuell mit dem Thema „Luftqualität“ beschäftige, wollte ich einfach ‚mal nachfragen, ob Du schon mit dem SGP40 weitergekommen bist (der inzwischen auch schon wieder mit dem SGP41 einen Nachfolger hat).

    Grüße
    Alex

    1. Die Teile liegen hier noch. Ich hatte bisher noch keine Lust mich wieder and das Thema zu machen nach den durchwachsenen Erfahrungen. Es hat wohl auch seine Gründe, warum praktisch alle CO2 „Fertig-Messgeräte“ nicht auf Metalloxidsensoren, sondern auf NDIR-Technik basieren. Also ja, im Prinzip möchte ich mir die Teile noch anschauen, aber verspreche lieber nicht, wann ich mich daran mache.
      VG, Wolfgang

  2. Hallo,
    vielen Dank für den Hinweis.
    Jetzt bin ich mir fast sicher, dass das CCS811- Modul defekt ist.
    In dem entsprechenden Listing steht im Prinzip die gleiche Methode, wie ich sie auch anwende, um in den App-Mode zu kommen.
    Das Modul habe ich erstmal beiseite gelegt.
    Jetzt habe ich einen MH-Z19C. Das sieht vielversprechend aus.
    Nochmal Danke und Gruss, W. Staven

  3. Hallo,
    vielen Dank für die Antwort.
    Ja, den Software-Reset habe ich mit eingebaut.
    Hatte aber auch nichts gebracht.
    Der Hersteller hüllt sich in Schweigen.
    Ich programmiere Mikrocontroller schon seit über 30 Jahren.
    Und trotzdem bekomme ich es nicht hin.
    Es geht nur darum, die richtige Routine zum Umschalten von Bootmode auf Appmode hinzubekommen.
    Gruss, W. Staven

    1. Hallo,
      leider hab ich nicht die Zeit, dass im Detail nachzuvollziehen. Aber die beiden erwähnten Bibliotheken funktionieren. Als würde ich versuchen, den Code der Bibliotheken nachzubauen. Vielleicht lohnt es sich auch die Boliotheken auszuprobieren und so sicherzustellen, dass die Module keinen Defekt haben.
      VG, Wolfgang Ewald

  4. Hallo,
    Kompliment, Sie verstehen es wie kaum ein anderer, die Dinge um den CCS811 klar und deutlich zu erklären.
    Ich habe ein Problem mit den CCS811 Sensoren von Joy-It.
    Das Umschalten vom Boot-Mode in den App-Mode bekomme ich nicht hin.
    Dabei halte ich mich strikt an das Flussdiagramm im Programming Guide auf Seite23:
    Nach Power-Up befindet sich der CCS811 im Boot-Mode.
    Zuerst wird die HW ID geprüft.
    Ich lese 0x61 aus, also korrekt.
    Dann wird das Statusregister ausgelesen. Ich erhalte 0x10 = Firmware loaded, also auch ok.
    Dann soll, da sind die Angaben im Datenblatt wie auch im Programmimg Guide für mich nicht klar, ein Write-Zyklus mit der Mailbox ID 0xF4 durchgeführt werden, offenbar ohne anhängenden Daten.
    Das soll das Umschalten von Boot-Mode auf App-Mode bewirken.
    Danach soll das Statusregister ausgelesen werden. Ich erhalte aber nur 0x10 und nicht, wie im Programming Guide auf Seite 10 beschrieben, 0x90 = FW_Mode Bit ist zusätzlich gesetzt=CCS811 nun im App-Mode.
    Das habe ich so programmiert:
    …..
    I2c_start();
    I2c_write (0xB4); // CCS811 slave id
    I2c_write (0xF4); // mailbox id Boot-Mode auf App-Mode
    Delay_ms(1);
    Status=…… // Statusregister auslesen

    Normalerweise müsste noch am Ende
    I2c_stop();
    hinzugefügt werden. Aber dann hängt sich die I2C-Schnittstelle auf.
    Anschliessend bekomme ich nach Auslesen des Statusregisters immer nur die 0x10 und nicht 0x90.
    Was mache ich falsch ?

    Gruss, Wolfgang Staven

    1. Hallo,

      ich habe einfach nur ganz plump die vorgefertigten Bibliotheken eingesetzt und mich nicht damit beschäftigt, was im Hintergrund bei der Initialisierung passieren muss.

      Ich habe deswegen mal in die Bibliotheken von Adafruit und Keyestudio geschaut. Beide führen bei der Initialisierung vor dem Wechsel in den App Mode noch einen Software-Reset durch und senden dazu an das Software Reset Register die Sequenz: 0x11, 0xE5, 0x72, 0x8A. Ob das hilft weiß ich nicht, es fiel mir nur auf. Sie können ja mal versuchen, die Prozedur nachzuvollziehen. Hier Link zur keyestudio cpp-Bibliotheksdatei:

      https://www.dropbox.com/sh/or1jzflapzbdepd/AAAGrCZgyjPOtNyLYNcyzL90a/Libraries/CCS811?dl=0&preview=CCS811.cpp&subfolder_nav_tracking=1

      Ich kann mich da gerade nicht noch weiter hinein vertiefen. Aber vielleicht hilft das ja schon.

      VG, Wolfgang Ewald

  5. Danke für den guten und sehr informativen Beitrag.
    Ich möchte mir für meine Wohnung den CCS811 zur Überprüfung der Raumluft zulegen. Im Grunde gibt der Sensor einen Zahlenwert X aus. Aber woher weiß ich, ab welchem Wert X die Luft „schlecht“ ist und die Wohnung gelüftet werden soll?

    1. Wie ich im Beitrag schrieb, sind die Werte, die diese Teile ausspucken ziemlich unzuverlässig. Ich habe keine Tabelle mit Grenzwerten gefunden und ich denke das spricht auch für sich. Man kann die Werte wohl noch stabilisieren, wenn man noch einen Luftfeuchtesensor installiert und die Werte mit einrechnet (z.B. mit der Adafruit Bibliothek).

      Ich würde ein paar Euro mehr investieren und einen der MH-Zxx Sensoren (vorheriger Beitrag) nutzen.
      VG, Wolfgang

  6. Danke! Sehr interessant. Überlege den CCS811 kommeziell zu verbauen, da günstiger. Angezeigt werden soll nur eine Grün/gelb/rote LED die zum lüften anregen soll. Vllt reicht es ja für den Zweck.

Schreibe einen Kommentar

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