CO2-Messung mit CS811 - seltsames Verhalten

Hallo!

Ich habe ein Projekt, bei dem u.a. der CO2-Wert in einem mehr oder weniger abgedichteten Raum gemessen und bei Erreichen eines Schwellwerts ein Lüfter für ein festgelegtes Intervall gestartet wird. Die Messung erfolgt mit einem I2C CS811-Gassensor. Das Projekt hat noch einen Datenlogger mit RTC, einen DHT11, einen DS18B20, ein paar Aktoren und ein Display.

Folgendes Verhalten habe ich festgestellt: Nachdem das System bei sich wenig ändernden Außenbedingungen etwa einen Tag lang ungefähr alle zwei Stunden den Lüfter aktiviert hat wird nun seit zwei Tagen in Folge (ab einer ähnlicher Uhrzeit!?) der Lüfter während der Nacht nahezu pausenlos eingeschaltet. Der verantwortliche CO2-Wert steigt laut logfile in unrealistisch kurzer Zeit weit über den Schwellwert. So lange der Lüfter läuft, sinkt der Wert zu Beginn noch unter den Wert, im Laufe der Nacht dann auch nicht mal mehr das.

Wenn ich einen simplen Sketch zur Sensorabfrage aufspiele bekomme ich plausible Werte.

Ich habe schon angefangen, diverse andere Funktionen auszuschalten um zu sehen, ob eine davon dieses Verhalten erzeugt. Leider ist mein Programm derart gewachsen, dass das Vorgehen nicht einfach ist, zumal der Fehler (bis jetzt) nur Nachts festzustellen ist. Hat hier jemand eine Idee oder hat sogar etwas ähnliches schon an anderer Stelle beobachtet? Die RTC-Funktion, die ich auf Grund der scheinbaren Zeitabhängigkeit als erstes in Verdacht hatte und die u.a. ebenfalls am I2C hängt, ist es schon mal nicht.

Suchst Du Hellseher oder gibst Du uns auch Code (in Codetags) und Schaltung?

Gruß Tommy

Tommy56: Suchst Du Hellseher oder gibst Du uns auch Code (in Codetags) und Schaltung?

Gruß Tommy

Nein natürlich erwarte ich nicht, dass mir jemand etwas zu meinem speziellen Code sagt ohne dass ich ihn hier rein stelle. Meine Frage war ja zunächst, ob das beschriebene Verhalten des driftenden Werts dieses speziellen Sensors jemandem schon mal so oder so ähnlich aufgefallen ist. So lange das nicht der Fall ist arbeite ich weiter daran, den Code etwas vorzeigbarer zu gestalten und stelle ihn dann natürlich zur Verfügung.

Ich habe jetzt den Übeltäter gefunden:

Das Projekt beinhaltet einen Ultraschallzerstäuber (Betriebsfrequenz: 105 ± 5 kHz • Chip: ETA1617 NE555), der - wenn die Luftfeuchtigkeit zu gering ist - in Intervallen von 10 s eingeschaltet wird.
Das angehängte Bild zeigt das Verhalten. Beim Ein- bzw. Ausschalten erscheint ein positiver oder negativer Peak in der CO2-Messung. Ich habe die Länge der Impulse variiert, von 3 s bis 20 s - aber es hat nichts am grundlegenden Verhalten geändert.

Als Lösung fällt mir spontan nur ein das Programm so umzubauen, dass die CO2-Messung nicht in der Nähe eines Impulses vorgenommen wird. Oder habe ich einen anderen Fehler im Programm, der Ursache sein könnte?

/*******************************************************
 * L i b r a r i e s
*******************************************************/
#include <Adafruit_CCS811.h>


/*******************************************************
 * S e n s o r e n
*******************************************************/
// C S 8 1 1
//-- e C O 2

Adafruit_CCS811 ccs;

uint16_t CO2_val;


void CS811(){
  if(ccs.available()){
    if(!ccs.readData()){
      CO2_val = ccs.geteCO2();
    }
  }else{
      Serial.println("ERROR reading CS811!");
      while(1);
  }
}



/*******************************************************
 * A K T O R E N
*******************************************************/

// U l t r a s c h a l l v e r n e b l e r
/* Wird in loop() aufgerufen;
 * wenn RLF zu niedrig startet für 10 s die Zerstäubung,
 */

#define humid_pin 9

bool humid_state;
const uint32_t interval_humid= 10000;
uint32_t previousMillis_humid = 0;

void humidifier(){
      
          
              if (millis() - previousMillis_humid >= interval_humid) {
                previousMillis_humid = millis();

                if (humid_state == LOW) {
                  humid_state = HIGH;
                } else {
                  humid_state = LOW;
                }
                digitalWrite(humid_pin, humid_state);
                
              }
          
}



// messen

void meas(){
    CS811();
}

// loggen

String logg() {
  String data = ("");
  data += millis()/1000;data += ("\t");
  data += ("|");   data += (humid_state);data += ("|");data += (" ");
  data += (CO2_val);data += (" ppm");data+= ('\t');
  data += ("\t");

  return data;
}


void setup() {
  Serial.begin(9600);
    
    pinMode(humid_pin, OUTPUT);
    digitalWrite(humid_pin, LOW);

// Initialisiere CS811
    if(!ccs.begin()){
      Serial.println("Failed to start CS811! Please check your wiring.");
      while(1);
    }else{
      Serial.println("CS811: \t Sensor initialized.");
    }
    while(!ccs.available());

delay(300);

}


/*******************************************************
 * M A I N
*******************************************************/
uint32_t previousMillis_main = 0;
const uint32_t interval_main = 1000;
uint32_t currentMillis_main;
String dataString;

void loop() {

  
  currentMillis_main = millis();
    if(currentMillis_main - previousMillis_main >= interval_main){
          previousMillis_main=currentMillis_main;
          
          meas();
          humidifier();
          dataString=logg();
          Serial.println(dataString);
    }
}

Hayley_Hay: Als Lösung fällt mir spontan nur ein das Programm so umzubauen, dass die CO2-Messung nicht in der Nähe eines Impulses vorgenommen wird. Oder habe ich einen anderen Fehler im Programm, der Ursache sein könnte?

Leider scheint auch dieser Ansatz das Problem nicht zu lösen: Wenn der Zerstäuber ein Mal im Programmablauf aktiviert wurde, ist der Messwert für die gesamte (für mich bisher erkennbare) Laufzeit nicht mehr in Ordnung. Gibt es vielleicht irgend eine mögliche schaltungstechnische Lösung? Den Ultraschallzerstäuber irgendwie zu entstören oder den Sensor abzuschirmen?

Hi

Wenn der Sensor nicht tut, wenn der Aktor vor sich hin röchelt - was spricht dagegen, den Aktor für die Zeit der Messung abzuschalten?

MfG

postmaster-ino:
Hi

Wenn der Sensor nicht tut, wenn der Aktor vor sich hin röchelt - was spricht dagegen, den Aktor für die Zeit der Messung abzuschalten?

MfG

Hi!
Das war mein erster Gedanke, ja. Leider ist die Messung komplett hinüber, sobald der Aktor ein Mal angesprungen ist - egal wie lange ich warte, der Sensorwert bleibt zu hoch.
Gerade habe ich den Zerstäuber an einem externen Netzteil. Das scheint bisher am besten zu funktionieren, es treten keine Peaks auf und der Wert steigt nur langsam und realistisch an. Ich würde es gerne anders lösen, aber dafür fehlt mir das elektrotechnische know-how (s.o.).

Hilft es, den Sensor in Reset oder Sleep zu schicken, solange der Nebler läuft?

(deleted)

Ich würde den Datentyp String verbannen und durch char[] ersetzen. Die Speicherverwaltung bekommt auf kleinen Prozessoren mit String irgendwann Probleme.

Ist Dein Sensor CS811 oder CCS811?

Der Sensor CCS811 mißt kein CO2 sondern “Total Volatile Organic Compound (TVOC)” und gibt als Meßwert entweder TVOC oder CO2 Equivalent aus.

Also wie gesagt Du mißt kein CO2.
lauthttps://revspace.nl/CJMCU-811
reagiert der Sensor auf:

Very roughly from experimentation (and memory):

Alklanet (contains 2-butoxyethanol), very sensitive to this stuff, we use it everywhere in the space to clean working surfaces
permanent marker: very sensitive to it
toluene: very sensitive
acetone: very sensitive
butanol: sensitive
butylacetate: sensitive
butane, it is detected but not impressively so
chloroform, almost no response!
dichloro-methane: insensitive
acetaldehyde: not very sensitive to it

So können unvorhergesehene Messung erklährt werden weil der Sensor nicht einen nicht vorhandenen CO2 Anstieg mißt sondern ein Ausgasen von gasförmigen Stoffen.

Grüße Uwe