ESP8266 + CCS811 = Co2 Messgerät / Luftqualitätsmesser

Ich habe einen ESP8266 mit einem CCS811 verbunden, ein bißchen Code und schon hat man ein Co2 Messgerät / Luftqualitätsmesser :wink:

Hier mein Code für Arduino (hingeschmiert):

#include <ESP8266WiFi.h>
#include <AsyncMqttClient.h>
#define aktordebug 1
#define serialout 1



#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs;

float temp;
int co2;
int tvoc;
  float temp2;
  int co22;
  int tvoc2;
unsigned long timestamp;
bool go=false;

AsyncMqttClient mqttClient;
#include <ArduinoJson.h>
IPAddress mqttserver( 192, 168, 0, 3 );
//IPAddress mqttserver = { 192, 168, 0, 5 };
String mqttvalue;
String hbmqttvalue;
String hbmqttvalue2;
String mqttvalueold;
long mqttontimer = 0;
int mqttstatus [] = {0, 0, 0, 0};
const char* clientname;
const char*  mqttpublishvalue;
String mqttpublishabo = "/device/co2/status/";
String mqttsubscribeabo = "/arduino/co2-Labor/remote/";
String hbmqttsubscribeabo = "homebridge/from/set";
String mqttusername = "lol";
String mqttpassword = "lol";
String devicename = "Co2-Sensor";

void onMqttConnect(bool sessionPresent) {
  const char* mqttsubscribeabo2 = mqttsubscribeabo.c_str();

  Serial.println("** Connected to the broker **");
  Serial.print("Session present: ");
  Serial.println(sessionPresent);
  /*
    uint16_t packetIdSub = mqttClient.subscribe(mqttsubscribeabo2, 0);
    Serial.print("Subscribing at QoS 1, packetId: ");
    Serial.println(packetIdSub);
    uint16_t packetIdSub2 = mqttClient.subscribe("homebridge/from/set", 0);
    Serial.print("Subscribing2 at QoS 1, packetId: ");
    Serial.println(packetIdSub2);
  */
}


void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  Serial.println("** Disconnected from the broker **");
  Serial.println("Reconnecting to MQTT...");
  mqttClient.connect();
}

void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
  // Serial.println("** Subscribe acknowledged **");
  //Serial.print("  packetId: ");
  //Serial.println(packetId);
  //Serial.print("  qos: ");
  //Serial.println(qos);
}

void onMqttUnsubscribe(uint16_t packetId) {
  Serial.println("** Unsubscribe acknowledged **");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
  Serial.println("** Publish received **");
  Serial.print("  topic: ");
  Serial.println(topic);
  /*
    Serial.print("  qos: ");
    Serial.println(properties.qos);
    Serial.print("  dup: ");
    Serial.println(properties.dup);
    Serial.print("  retain: ");
    Serial.println(properties.retain);
    Serial.print("  len: ");
    Serial.println(len);
    Serial.print("  index: ");
    Serial.println(index);
    Serial.print("  total: ");
    Serial.println(total);
  */
  Serial.print("  payload: ");
  Serial.println(payload);

  //   Serial.print("  abo: ");
  //Serial.println(mqttsubscribeabo.c_str());



  if (strcmp (topic, mqttsubscribeabo.c_str()) == 0 )
  {
    mqttvalue = payload;
    if (serialout == 1 or aktordebug == 1) Serial.println("mqttvalue: " + mqttvalue);

  }

  if (strcmp(topic, "homebridge/from/set") == 0)
  {
    DynamicJsonBuffer  jsonBuffer;
    const char* json = payload;
    JsonObject& input = jsonBuffer.parseObject(json);


    String hbname =  input["name"];
    String characteristic =  input["characteristic"];
    String hbvalue = input["value"];

    if (serialout == 1 or aktordebug == 1) Serial.println("characteristic: " + characteristic);


    if (characteristic != "On")
    {
      if (serialout == 1 or aktordebug == 1) Serial.println("mqttvalue: " + mqttvalue);
      hbmqttvalue = payload;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-characteristic: " + characteristic);

    }

    if (characteristic == "On")
    {
      hbmqttvalue2 = payload;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-mqttvalue2: " + hbmqttvalue2);
      mqttontimer = millis() + 1000;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-Timer: " + mqttontimer);

    }


  }

}




void onMqttPublish(uint16_t packetId) {
  //Serial.println("** Publish acknowledged **");
  //Serial.print("  packetId: ");
  //Serial.println(packetId);
}


void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();
  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  Serial.print("Connecting to Wi-Fi");
  WiFi.begin("lol", "lol");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println(" OK");

  //************************************************** MQTT Subscribe Abo  ************************************
  if (mqttsubscribeabo != "")
  {
    const char* mqttusername2 = mqttusername.c_str();
    const char* mqttpassword2 = mqttpassword.c_str();
    const char* mqttpublishabo2 = mqttpublishabo.c_str();
    const char* deviceid = devicename.c_str();

    mqttClient.onConnect(onMqttConnect);
    mqttClient.onDisconnect(onMqttDisconnect);
    //mqttClient.onSubscribe(onMqttSubscribe);
    //mqttClient.onUnsubscribe(onMqttUnsubscribe);
    //mqttClient.onMessage(onMqttMessage);
    mqttClient.onPublish(onMqttPublish);
    mqttClient.setServer(IPAddress(192, 168, 0, 5), 1883);
    mqttClient.setKeepAlive(5).setCleanSession(false).setWill("topic/online", 2, true, "no").setCredentials(mqttusername2, mqttpassword2).setClientId(deviceid);
    Serial.println("Connecting to MQTT...");
    mqttClient.connect();

    Serial.println("CCS811 test");

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

    //calibrate temperature sensor
    while (!ccs.available());
    temp = ccs.calculateTemperature();
    ccs.setTempOffset(temp - 25.0);

 if (ccs.available())
      {
       temp2 = float(ccs.calculateTemperature());
      }
if (!ccs.readData())
      {
        co22 = int(ccs.geteCO2());
        Serial.println("CO2: ");
        Serial.println(co22);
        delay(10);
        tvoc2 =int (ccs.getTVOC());
      }
  
  }
go=true;


}

void loop()
{

  if (millis() - timestamp >= 60000  or go==true)
  {
  go=false;
    for  (int i = 1; i < 7; i++)
    {
          Serial.println("For Schleife Durchgang: ");
          Serial.println(i);
      if (ccs.available())
      {
        temp2 = ccs.calculateTemperature();

        while (temp2 == 0) 
        {
          temp2 = ccs.calculateTemperature();
          Serial.println("Temp2: ");
          Serial.println(temp2);
          delay(1000);
        }
        temp=temp2 + temp;
      
      if (!ccs.readData())
      {
        co22 = int(ccs.geteCO2());
        while (co22 == 0)
        {
          co22 = int(ccs.geteCO2());
          Serial.println("CO2: ");
          Serial.println(co22);
          delay(1000);
        }
        co2 = co22 + co2;

        tvoc2 =int (ccs.getTVOC());
        while (tvoc2 == 0)
        {
          tvoc2 =int (ccs.getTVOC());
          Serial.println("TVOC2: ");
          Serial.println(tvoc2);
          delay(1000);
        }
        tvoc = tvoc2 + tvoc;
       
      }
      else Serial.println("ERROR: Kann nicht messen !");
    }
    delay(10000);
    }
    co2 = co2 / 7;
    tvoc = tvoc / 7;
    temp = temp / 7;

    clientname = devicename.c_str();
    const char* mqttusername2 = mqttusername.c_str();
    const char* mqttpassword2 = mqttpassword.c_str();
    const char* mqttpublishabo2 = mqttpublishabo.c_str();

    DynamicJsonBuffer jsonBuffer;
    JsonObject& mqttsenden = jsonBuffer.createObject();
    mqttsenden["devicename"] = devicename.c_str();
    mqttsenden["model"] = "co2";
    mqttsenden["room"] = "Wohnzimmer";
    mqttsenden["infoart"] = "co2";
    mqttsenden["value"] = String (co2);



    String  mqttpublishvaluetest;
    mqttsenden.printTo(mqttpublishvaluetest);
    mqttpublishvalue = mqttpublishvaluetest.c_str();

    uint16_t packetIdPub1 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
    if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
    if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest.c_str());


    JsonObject& mqttsenden2 = jsonBuffer.createObject();
    mqttsenden2["devicename"] = devicename.c_str();
    mqttsenden2["model"] = "Temperature";
    mqttsenden2["room"] = "Wohnzimmer";
    mqttsenden2["infoart"] = "tvoc";
    mqttsenden2["value"] = String (tvoc);

    String  mqttpublishvaluetest2;

    mqttsenden2.printTo(mqttpublishvaluetest2);
    mqttpublishvalue = mqttpublishvaluetest2.c_str();

    uint16_t packetIdPub2 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
    if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
    if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest2.c_str());



    JsonObject& mqttsenden3 = jsonBuffer.createObject();
    mqttsenden3["devicename"] = devicename.c_str();
    mqttsenden3["model"] = "Temperature";
    mqttsenden3["room"] = "Wohnzimmer";
    mqttsenden3["infoart"] = "Temperature";
    mqttsenden3["value"] = String(temp);

    String  mqttpublishvaluetest3;
    mqttsenden3.printTo(mqttpublishvaluetest3);
    mqttpublishvalue = mqttpublishvaluetest3.c_str();

    uint16_t packetIdPub3 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
    if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
    if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest3.c_str());

    timestamp = millis();
  }
}

Ich mache jede Minute eine Messung, jede Messung wird 6 x innerhalb eine Minute gemacht und dann den Mittelwert ausgerechnet…

Die Messwerte gefallen mir aber überhaupt nicht, ich empfinde Sie viel zu Hoch:

Habt Ihr noch eine Idee ?

Hallo drapple,

schön dass sich noch mehr mit dem CCS811 beschäftigen. Um etwas genaueres zu deinem Diagramm sagen zu können, bräuchte man noch eine Maßangabe/Skalierung über die Zeit und in CO2-ppm oder TVOC-ppb.

Vor 3 Wochen habe ich auch ein wenig mit iAQ, CCS811 und BME680 (GeCoS) herum gespielt. Die Daten vom CCS811 habe ich über die Adafruit-python-lib in einen PI3 eingelesen. Leider kann der PI kein Clock Streching (der ESP kann das), so dass das Loggen nach max. 2-3 Tagen immer abrupt stoppte. Aber für Messkurvenaufnahmen hat es schon gereicht.

Im unten stehenden Diagramm, kann man schön sehen, dass zwischen ~09:00-12:00 der unterste Wert mit 450 CO2 ppm ermittelt wurde. Das passt auch, da waren in dem Raum alle Fenster geöffnet. Die zwei Spitzen über 3000 kommen mir seltsam vor, beim iAQ waren die weniger ausgeprägt.

Na ja, wer misst, misst manchmal auch Mist.

Gruss
Bernd

Hi ich messe mal so 3n Tage und dann schauen wir uns die Werte nochmal an…

Aber stimmt mein Code soweit ? Oder übertreibe ich das ?

Wi machst du es ?

Hi drapple,

das mit der Mittelung würde ich erst mal weg lassen, kann man später immer noch machen, wenn man sich im klaren ist, wie der Sensor tickt.

Ich würde erst die Rohdaten über einen längeren Zeitraum loggen und dann entscheiden, wie man besser mittelt oder Ausreiser eliminiert (z.B. über einfache Mittelwertbildung oder Median).

Mein Diagramm ist 1:1 aus den Rohdaten entstanden, wie sie mir die Adafruit-Lib geliefert hat. Dar waren noch keine Filter dran.

Gruss
Bernd

Kannst du mal deinen Code posten ?

Bei original code springen die Werte extrem…

Wie oft liest du einen Wert und machst wie lange pause ?

Klar, ist nichts weltbewegendes, habe nur die Timer und den Output des Adafruit-Examples etwas modifiziert.

#this example reads and prints CO2 equiv. measurement, TVOC measurement, and temp every 60 seconds

import time

from time import sleep
from Adafruit_CCS811 import Adafruit_CCS811

ccs =  Adafruit_CCS811()

while not ccs.available():
        pass
temp = ccs.calculateTemperature()
ccs.tempOffset = temp - 25.0

while(1):
        if ccs.available():
            temp = ccs.calculateTemperature()
            if not ccs.readData():
               print "Time: ",time.strftime("%d.%m.%Y, %H:%M:%S,"), 
                      "CO2: ", ccs.geteCO2(), 
                      "ppm, TVOC: ", ccs.getTVOC(), 
                      ", temp: ", temp
            else:
              print "ERROR!"
              while(1):
                pass
        sleep(60)

Der Output schaut dann so aus (Temperaturschwankungen gefallen mir nicht):

pi@PI2:~/Adafruit_CCS811_python/examples $ sudo python test.py
Time:  06.05.2018, 19:38:36, CO2:  1754 ppm, TVOC:  206 , temp:  25.0
Time:  06.05.2018, 19:39:36, CO2:  417 ppm, TVOC:  2 , temp:  38.7329333563
Time:  06.05.2018, 19:40:36, CO2:  400 ppm, TVOC:  0 , temp:  19.9668962201
Time:  06.05.2018, 19:41:36, CO2:  1065 ppm, TVOC:  101 , temp:  40.3296483251
Time:  06.05.2018, 19:42:37, CO2:  1259 ppm, TVOC:  130 , temp:  12.6505182656
Time:  06.05.2018, 19:43:37, CO2:  1291 ppm, TVOC:  135 , temp:  12.4761153412
Time:  06.05.2018, 19:44:37, CO2:  1153 ppm, TVOC:  114 , temp:  39.3602511265
Time:  06.05.2018, 19:45:37, CO2:  702 ppm, TVOC:  46 , temp:  42.3801041265
Time:  06.05.2018, 19:46:37, CO2:  1128 ppm, TVOC:  110 , temp:  12.8260326275
Time:  06.05.2018, 19:47:37, CO2:  1231 ppm, TVOC:  126 , temp:  13.0026739041

Gruss
Bernd

Danke, du machst es mit Pi ich mache es mit dem ESP jetzt…

ich glaube ich bin auf dem richtigen weg:

Am Anfang sieht man gut, das kein Mensch im Raum war, und wann der Raum wieder betreten wurde :cool:

#include <ESP8266WiFi.h>
#include <AsyncMqttClient.h>
#define aktordebug 1
#define serialout 1



#include "Adafruit_CCS811.h"

Adafruit_CCS811 ccs;

unsigned long temp;
unsigned long co2;
unsigned long tvoc;
unsigned long temp2;
unsigned long co22;
unsigned long tvoc2;

unsigned long temp3;

unsigned long temp4;
unsigned long co23;
unsigned long co24;
unsigned long tvoc22;
unsigned long tvoc23;


unsigned long timestamp;
bool go=false;

AsyncMqttClient mqttClient;
#include <ArduinoJson.h>
IPAddress mqttserver( 192, 168, 0, 3 );
//IPAddress mqttserver = { 192, 168, 0, 5 };
String mqttvalue;
String hbmqttvalue;
String hbmqttvalue2;
String mqttvalueold;
long mqttontimer = 0;
int mqttstatus [] = {0, 0, 0, 0};
const char* clientname;
const char*  mqttpublishvalue;
String mqttserverurl = "drapple.no-ip.org";
String mqttpublishabo = "/device/co2/status/";
String mqttsubscribeabo = "/arduino/co2-Labor/remote/";
String hbmqttsubscribeabo = "homebridge/from/set";
String mqttusername = "lol";
String mqttpassword = "lol";
String devicename = "Co2-Sensor";

void onMqttConnect(bool sessionPresent) {
  const char* mqttsubscribeabo2 = mqttsubscribeabo.c_str();

  Serial.println("** Connected to the broker **");
  Serial.print("Session present: ");
  Serial.println(sessionPresent);
  /*
    uint16_t packetIdSub = mqttClient.subscribe(mqttsubscribeabo2, 0);
    Serial.print("Subscribing at QoS 1, packetId: ");
    Serial.println(packetIdSub);
    uint16_t packetIdSub2 = mqttClient.subscribe("homebridge/from/set", 0);
    Serial.print("Subscribing2 at QoS 1, packetId: ");
    Serial.println(packetIdSub2);
  */
}


void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  Serial.println("** Disconnected from the broker **");
  Serial.println("Reconnecting to MQTT...");
  mqttClient.connect();
}

void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
  // Serial.println("** Subscribe acknowledged **");
  //Serial.print("  packetId: ");
  //Serial.println(packetId);
  //Serial.print("  qos: ");
  //Serial.println(qos);
}

void onMqttUnsubscribe(uint16_t packetId) {
  Serial.println("** Unsubscribe acknowledged **");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
  Serial.println("** Publish received **");
  Serial.print("  topic: ");
  Serial.println(topic);
  /*
    Serial.print("  qos: ");
    Serial.println(properties.qos);
    Serial.print("  dup: ");
    Serial.println(properties.dup);
    Serial.print("  retain: ");
    Serial.println(properties.retain);
    Serial.print("  len: ");
    Serial.println(len);
    Serial.print("  index: ");
    Serial.println(index);
    Serial.print("  total: ");
    Serial.println(total);
  */
  Serial.print("  payload: ");
  Serial.println(payload);

  //   Serial.print("  abo: ");
  //Serial.println(mqttsubscribeabo.c_str());



  if (strcmp (topic, mqttsubscribeabo.c_str()) == 0 )
  {
    mqttvalue = payload;
    if (serialout == 1 or aktordebug == 1) Serial.println("mqttvalue: " + mqttvalue);

  }

  if (strcmp(topic, "homebridge/from/set") == 0)
  {
    DynamicJsonBuffer  jsonBuffer;
    const char* json = payload;
    JsonObject& input = jsonBuffer.parseObject(json);


    String hbname =  input["name"];
    String characteristic =  input["characteristic"];
    String hbvalue = input["value"];

    if (serialout == 1 or aktordebug == 1) Serial.println("characteristic: " + characteristic);


    if (characteristic != "On")
    {
      if (serialout == 1 or aktordebug == 1) Serial.println("mqttvalue: " + mqttvalue);
      hbmqttvalue = payload;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-characteristic: " + characteristic);

    }

    if (characteristic == "On")
    {
      hbmqttvalue2 = payload;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-mqttvalue2: " + hbmqttvalue2);
      mqttontimer = millis() + 1000;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-Timer: " + mqttontimer);

    }


  }

}




void onMqttPublish(uint16_t packetId) {
  //Serial.println("** Publish acknowledged **");
  //Serial.print("  packetId: ");
  //Serial.println(packetId);
}


void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();
  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  Serial.print("Connecting to Wi-Fi");
  WiFi.begin("", "");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println(" OK");

  //************************************************** MQTT Subscribe Abo  ************************************
  if (mqttsubscribeabo != "")
  {
    const char* mqttusername2 = mqttusername.c_str();
    const char* mqttpassword2 = mqttpassword.c_str();
    const char* mqttpublishabo2 = mqttpublishabo.c_str();
    const char* deviceid = devicename.c_str();

    mqttClient.onConnect(onMqttConnect);
    mqttClient.onDisconnect(onMqttDisconnect);
    //mqttClient.onSubscribe(onMqttSubscribe);
    //mqttClient.onUnsubscribe(onMqttUnsubscribe);
    //mqttClient.onMessage(onMqttMessage);
    mqttClient.onPublish(onMqttPublish);
    mqttClient.setServer(IPAddress(192, 168, 0, 5), 1883);
    mqttClient.setKeepAlive(5).setCleanSession(false).setWill("topic/online", 2, true, "no").setCredentials(mqttusername2, mqttpassword2).setClientId("co2");
    Serial.println("Connecting to MQTT...");
    mqttClient.connect();

    Serial.println("CCS811 test");

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

    //calibrate temperature sensor
    while (!ccs.available());
    temp = ccs.calculateTemperature();
    ccs.setTempOffset(temp - 25.0);

 if (ccs.available())
      {
       temp2 = float(ccs.calculateTemperature());
      }
if (!ccs.readData())
      {
        co22 = int(ccs.geteCO2());
        Serial.println("CO2: ");
        Serial.println(co22);
        delay(10);
        tvoc2 =int (ccs.getTVOC());
      }
      
  
  
  
  }
//go=true;


}

void loop()
{

  if (millis() - timestamp >= 60000  or go==true)
  {
  go=false;
    for  (int i = 1; i < 7; i++)
    {
          Serial.println("For Schleife Durchgang: ");
          Serial.println(i);
      if (ccs.available())
      {
        temp2 = ccs.calculateTemperature();
        delay(10);
        temp3 = ccs.calculateTemperature();
        delay(10);
        temp4 = ccs.calculateTemperature();

        temp2=temp2+temp3+temp4;
        temp2=temp2/3;
         Serial.println("Temp2: ");
          Serial.println(temp2);
        if (temp2 == 0) ESP.reset();
       
        temp=temp2 + temp;
      
      if (!ccs.readData())
      {
        co22 = int(ccs.geteCO2());
        delay(10);
        co23 = int(ccs.geteCO2());
        delay(10);
        co24 = int(ccs.geteCO2());

        co22=co22+co23+co24;
        co22=co22/3;
          Serial.println("CO2: ");
          Serial.println(co22);
        if (co22 == 0) ESP.reset();
        co2 = co22 + co2;
        
        tvoc2 =int (ccs.getTVOC());
        delay(10);
        tvoc22 =int (ccs.getTVOC());
        delay(10);
        tvoc23 =int (ccs.getTVOC());

        tvoc2=tvoc2+tvoc22+tvoc23;
        tvoc2=tvoc2/3;
      
         Serial.println("TVOC2: ");
          Serial.println(tvoc2);
        if (tvoc2 == 0) ESP.reset();
        tvoc = tvoc2 + tvoc;
       
      }
      else Serial.println("ERROR: Kann nicht messen !");
    }
    delay(10000);
    }
    co2 = co2 / 6;
    tvoc = tvoc / 6;
    temp = temp / 6;

    clientname = devicename.c_str();
    const char* mqttusername2 = mqttusername.c_str();
    const char* mqttpassword2 = mqttpassword.c_str();
    const char* mqttpublishabo2 = mqttpublishabo.c_str();

    DynamicJsonBuffer jsonBuffer;
    JsonObject& mqttsenden = jsonBuffer.createObject();
    mqttsenden["devicename"] = devicename.c_str();
    mqttsenden["model"] = "co2";
    mqttsenden["room"] = "Wohnzimmer";
    mqttsenden["infoart"] = "co2";
    mqttsenden["value"] = String (co2);



    String  mqttpublishvaluetest;
    mqttsenden.printTo(mqttpublishvaluetest);
    mqttpublishvalue = mqttpublishvaluetest.c_str();

    uint16_t packetIdPub1 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
    if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
    if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest.c_str());


    JsonObject& mqttsenden2 = jsonBuffer.createObject();
    mqttsenden2["devicename"] = devicename.c_str();
    mqttsenden2["model"] = "Temperature";
    mqttsenden2["room"] = "Wohnzimmer";
    mqttsenden2["infoart"] = "tvoc";
    mqttsenden2["value"] = String (tvoc);

    String  mqttpublishvaluetest2;

    mqttsenden2.printTo(mqttpublishvaluetest2);
    mqttpublishvalue = mqttpublishvaluetest2.c_str();

    uint16_t packetIdPub2 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
    if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
    if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest2.c_str());



    JsonObject& mqttsenden3 = jsonBuffer.createObject();
    mqttsenden3["devicename"] = devicename.c_str();
    mqttsenden3["model"] = "Temperature";
    mqttsenden3["room"] = "Wohnzimmer";
    mqttsenden3["infoart"] = "Temperature";
    mqttsenden3["value"] = String(temp);

    String  mqttpublishvaluetest3;
    mqttsenden3.printTo(mqttpublishvaluetest3);
    mqttpublishvalue = mqttpublishvaluetest3.c_str();

    uint16_t packetIdPub3 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
    if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
    if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest3.c_str());

    timestamp = millis();

    co2=0;
    tvoc=0;
    temp=0;
  }




}

Der Sensor verhält sich noch komisch, er schaukelt sich sich immer hoch und kommt dann nicht mehr auf normale Werte :

Ab 9 Uhr waren die Fenster bis 23:30 Uhr geöffnet und keiner war daheim bis 23:30 Uhr…
Um 7 Uhr habe ich ihn für 5min vom Strom genommen, dann hat er wieder richtig gemessen…

Vielleicht wäre es gut ihn per GPIO ein und auszuschalten ?

Hallo drapple,

Ein/Ausschalten würde ich nicht machen. Der Sensor braucht ja sowieso 1-2 Tage, bis er richtig tickt. Lege ihn doch über Nacht ohne längere Zeit (mehrere Stunden) raus in die freie Luft. Da sollte er sauber auf CO2=450 ppm herunter kommen. Wiederhole das mehrmals. Dank kann man vergleichen, ob die Kurven passen.

Gruss
Bernd

So habe mein Script über den Haufen geschmissen und habe neu und sehr einfach aufgebaut, keine mehrfache Messung, keine Mittelung usw…

1 Messung pro Minute und fertig:

#include <ESP8266WiFi.h>
#include <AsyncMqttClient.h>
#include <ArduinoJson.h>
#define aktordebug 1
#define serialout 1
#include "Adafruit_CCS811.h"
Adafruit_CCS811 ccs;
//********************************** WLAN Einstellungen ******************************

#define ssid  "lol"
#define wlanpassword "lol"


unsigned long temp;
unsigned long co2;
unsigned long tvoc;



unsigned long timestamp;
bool go = false;


//********************************** MQTTT ******************************
AsyncMqttClient mqttClient;
IPAddress mqttserver( 192, 168, 0, 5 );
//IPAddress mqttserver = { 192, 168, 0, 5 };
String mqttvalue;
String hbmqttvalue;
String hbmqttvalue2;
String mqttvalueold;
long mqttontimer = 0;
int mqttstatus [] = {0, 0, 0, 0};
const char* clientname;
const char*  mqttpublishvalue;
String mqttserverurl = "drapple.no-ip.org";
String mqttpublishabo = "/device/co2/status/";
String mqttsubscribeabo = "/arduino/co2-Labor/remote/";
String hbmqttsubscribeabo = "homebridge/from/set";
String mqttusername = "lol";
String mqttpassword = "lol";
String devicename = "Co2-Sensor";


//********************************** MQTTT Function ******************************
void onMqttConnect(bool sessionPresent) {
  const char* mqttsubscribeabo2 = mqttsubscribeabo.c_str();

  Serial.println("** Connected to the broker **");
  Serial.print("Session present: ");
  Serial.println(sessionPresent);
  /*
    uint16_t packetIdSub = mqttClient.subscribe(mqttsubscribeabo2, 0);
    Serial.print("Subscribing at QoS 1, packetId: ");
    Serial.println(packetIdSub);
    uint16_t packetIdSub2 = mqttClient.subscribe("homebridge/from/set", 0);
    Serial.print("Subscribing2 at QoS 1, packetId: ");
    Serial.println(packetIdSub2);
  */
}


void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
  Serial.println("** Disconnected from the broker **");
  Serial.println("Reconnecting to MQTT...");
  mqttClient.connect();
}

void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
  // Serial.println("** Subscribe acknowledged **");
  //Serial.print("  packetId: ");
  //Serial.println(packetId);
  //Serial.print("  qos: ");
  //Serial.println(qos);
}

void onMqttUnsubscribe(uint16_t packetId) {
  Serial.println("** Unsubscribe acknowledged **");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
  Serial.println("** Publish received **");
  Serial.print("  topic: ");
  Serial.println(topic);
  /*
    Serial.print("  qos: ");
    Serial.println(properties.qos);
    Serial.print("  dup: ");
    Serial.println(properties.dup);
    Serial.print("  retain: ");
    Serial.println(properties.retain);
    Serial.print("  len: ");
    Serial.println(len);
    Serial.print("  index: ");
    Serial.println(index);
    Serial.print("  total: ");
    Serial.println(total);
  */
  Serial.print("  payload: ");
  Serial.println(payload);

  //   Serial.print("  abo: ");
  //Serial.println(mqttsubscribeabo.c_str());



  if (strcmp (topic, mqttsubscribeabo.c_str()) == 0 )
  {
    mqttvalue = payload;
    if (serialout == 1 or aktordebug == 1) Serial.println("mqttvalue: " + mqttvalue);

  }

  if (strcmp(topic, "homebridge/from/set") == 0)
  {
    DynamicJsonBuffer  jsonBuffer;
    const char* json = payload;
    JsonObject& input = jsonBuffer.parseObject(json);


    String hbname =  input["name"];
    String characteristic =  input["characteristic"];
    String hbvalue = input["value"];

    if (serialout == 1 or aktordebug == 1) Serial.println("characteristic: " + characteristic);


    if (characteristic != "On")
    {
      if (serialout == 1 or aktordebug == 1) Serial.println("mqttvalue: " + mqttvalue);
      hbmqttvalue = payload;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-characteristic: " + characteristic);

    }

    if (characteristic == "On")
    {
      hbmqttvalue2 = payload;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-mqttvalue2: " + hbmqttvalue2);
      mqttontimer = millis() + 1000;
      if (serialout == 1 or aktordebug == 1) Serial.println("hb-Timer: " + mqttontimer);

    }
  }
}

void onMqttPublish(uint16_t packetId) {
  //Serial.println("** Publish acknowledged **");
  //Serial.print("  packetId: ");
  //Serial.println(packetId);
}

//********************************** Void Setup ******************************
void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();
  WiFi.persistent(false);
  WiFi.mode(WIFI_STA);
  Serial.print("Connecting to Wi-Fi");
  WiFi.begin(ssid, wlanpassword);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println(" OK");

  //************************************************** MQTT Subscribe Abo  ************************************
  if (mqttsubscribeabo != "")
  {
    const char* mqttusername2 = mqttusername.c_str();
    const char* mqttpassword2 = mqttpassword.c_str();
    const char* mqttpublishabo2 = mqttpublishabo.c_str();
    const char* deviceid = devicename.c_str();

    mqttClient.onConnect(onMqttConnect);
    mqttClient.onDisconnect(onMqttDisconnect);
    //mqttClient.onSubscribe(onMqttSubscribe);
    //mqttClient.onUnsubscribe(onMqttUnsubscribe);
    //mqttClient.onMessage(onMqttMessage);
    mqttClient.onPublish(onMqttPublish);
    mqttClient.setServer(mqttserver, 1883);
    mqttClient.setKeepAlive(5).setCleanSession(false).setWill("topic/online", 2, true, "no").setCredentials(mqttusername2, mqttpassword2).setClientId("co2");
    Serial.println("Connecting to MQTT...");
    mqttClient.connect();

    Serial.println("CCS811 test");

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

    //calibrate temperature sensor
    while (!ccs.available());
    temp = ccs.calculateTemperature();
    ccs.setTempOffset(temp - 25.0);

    if (ccs.available())
    {
      Serial.print("
");
      temp = float(ccs.calculateTemperature());
      Serial.print("Temperatur: ");
      Serial.print(temp);
      Serial.print("	");

    }
    if (!ccs.readData())
    {
      co2 = int(ccs.geteCO2());
      Serial.print("CO2: ");
      Serial.print(co2);
      Serial.print("	");
      delay(10);
      tvoc = int (ccs.getTVOC());
      Serial.print("TVOC: ");
      Serial.print(tvoc);
      Serial.print("
");
    }
  }
  go = true;
}
//********************************** Void Loop ******************************
void loop() {
  if (millis() - timestamp >= 60000  or go == true)
  {
    go = false;

    if (ccs.available())
    {
      Serial.print("
");
      temp = float(ccs.calculateTemperature());
      Serial.print("Temperatur: ");
      Serial.print(temp);
      Serial.print("	");
    }
    if (!ccs.readData())
    {
      co2 = int(ccs.geteCO2());
      Serial.print("CO2: ");
      Serial.print(co2);
      Serial.print("	");
      delay(10);
      tvoc = int (ccs.getTVOC());
      Serial.print("TVOC: ");
      Serial.print(tvoc);
      Serial.print("
");
    }

    if (temp == 0 or co2 == 0 or tvoc == 0)
    {
      if (ccs.available())
      {
        Serial.print("
");
        temp = float(ccs.calculateTemperature());
        Serial.print("Temperatur: ");
        Serial.print(temp);
        Serial.print("	");
      }
      if (!ccs.readData())
      {
        co2 = int(ccs.geteCO2());
        Serial.print("CO2: ");
        Serial.print(co2);
        Serial.print("	");
        delay(10);
        tvoc = int (ccs.getTVOC());
        Serial.print("TVOC: ");
        Serial.print(tvoc);
        Serial.print("
");
      }
    }
    
    if (temp != 0 and co2 != 0 and tvoc != 0)
    {
      clientname = devicename.c_str();
      const char* mqttusername2 = mqttusername.c_str();
      const char* mqttpassword2 = mqttpassword.c_str();
      const char* mqttpublishabo2 = mqttpublishabo.c_str();
//********************************** CO2 senden  ******************************   
      DynamicJsonBuffer jsonBuffer;
      JsonObject& mqttsenden = jsonBuffer.createObject();
      mqttsenden["devicename"] = devicename.c_str();
      mqttsenden["model"] = "co2";
      mqttsenden["room"] = "Wohnzimmer";
      mqttsenden["infoart"] = "co2";
      mqttsenden["value"] = String (co2);
      String  mqttpublishvaluetest;
      mqttsenden.printTo(mqttpublishvaluetest);
      mqttpublishvalue = mqttpublishvaluetest.c_str();

      uint16_t packetIdPub1 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
      Serial.print("
");
      if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
      if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest.c_str());

//********************************** TVOC senden  ******************************   
      JsonObject& mqttsenden2 = jsonBuffer.createObject();
      mqttsenden2["devicename"] = devicename.c_str();
      mqttsenden2["model"] = "Temperature";
      mqttsenden2["room"] = "Wohnzimmer";
      mqttsenden2["infoart"] = "tvoc";
      mqttsenden2["value"] = String (tvoc);
      
      String  mqttpublishvaluetest2;

      mqttsenden2.printTo(mqttpublishvaluetest2);
      mqttpublishvalue = mqttpublishvaluetest2.c_str();

      uint16_t packetIdPub2 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
      Serial.print("
");
      if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
      if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest2.c_str());
//********************************** Temperatur senden  ******************************      
      JsonObject& mqttsenden3 = jsonBuffer.createObject();
      mqttsenden3["devicename"] = devicename.c_str();
      mqttsenden3["model"] = "Temperature";
      mqttsenden3["room"] = "Wohnzimmer";
      mqttsenden3["infoart"] = "Temperature";
      mqttsenden3["value"] = String(temp);

      String  mqttpublishvaluetest3;
      mqttsenden3.printTo(mqttpublishvaluetest3);
      mqttpublishvalue = mqttpublishvaluetest3.c_str();

      uint16_t packetIdPub3 = mqttClient.publish(mqttpublishabo2, 1, false, mqttpublishvalue);
      Serial.print("
");
      if (serialout == 1 or aktordebug == 1)  Serial.println("MQTT mit ATH Senden....");
      if (serialout == 1 or aktordebug == 1)  Serial.print(mqttpublishvaluetest3.c_str());
      Serial.print("
");
      timestamp = millis();

      co2 = 0;
      tvoc = 0;
      temp = 0;
    }
  }

}

Es sieht schonmal nach einer Stunde messen viel besser aus, ich poste morgen mal ein Chart…

Kurze Erkenntnis:

Ich hatte den Sensor auf einem Sideboard das mit Klarlack überzogen ist gelegt, auf dem spinnen die Messwerte, wie man im Chart sehen kann.

Ich habe es nun auf einen normalen Holztisch gelegt und die Werte sind absolut ok unter 800ppm und das seit 3 Stunden…

Also muss ja irgendwas am Klarlack sein das die Messwerte so verfälscht…

Hänge den Sensor mal lieber in die „Luft“, und dann mal sehen.:slight_smile:

Das passt, der VOC-Sensor reagiert auf ausgasende Lösungsmittel.

Hallo Leute,

ich würde hier nicht wild spekulieren, sondern zielorientiert vorgehen.

drapple, ich würde den Sensor auf eine Metall- oder Keramikplatte legen und dies mal längere Zeit indoor und outdoor aufzeichnen.

Gruss
Bernd

Da siehst du mal, wie gut dein Sensor ist.

Hallo Leute,

wie ist so die erfahrung mit dem CCS811 Sensor?

Suche eine „günstige“ lösung die Luftqualität zu messen.

Gruß

Hi kurzer Bericht:

ich habe den Sensor mit der Lib nicht stabil zum laufen bekommen !

Aber dafür habe ich es hinbekommen, das der Programmierer von Tasmota (Sonoff alternative Firmware) den Chip in seine Firmware integriert hat, seit dem läuft es ohne Probleme !!!

GitHub - arendst/Sonoff-Tasmota: Provide ESP8266 based itead Sonoff with Web, MQTT and OTA firmware using Arduino IDE or PlatformIO

Hi @drapple,

mache meine ersten Versuche mit Tasmota, wie bekomme ich darüber an den CCS811 ran?
Hab die Firmware darauf und läuft … FInde den Sensor in der Auswahl aber nicht.

Gruß
hardlog

Hi du musst es mit der Arduino IDE selber kompilieren und vorher den Sensor auskommentieren

Hi,

ok, soweit bin ich dann doch noch nicht in der Materie drin… ein Sketch mit Arduino IDE zu erstellen bekomme ich hin. Zum Sensor finde ich natürlich auch entsprechende Codes, die ich manuell per Arduino IDE auf den Arduino bekomme. Nur wie geht es mit/in Verbindung mit Tasmota? Du hättest nicht ein kleines code-Beispiel für mich?

Gruß
hardlog