MH-Z19 - CO2 Sensor funktioniert nicht wunschgemäß

Hallo Programmierfreunde,

ich wollte meine kleine Wetterstation mit einem CO2 Sensor erweitern. Ich habe mit diesem Sensor schon mal gearbeitet und habe auch einen Code gehabt.
Jetzt habe ich den Sensor angeschlossen und den Code auf meine Bedürfnisse angepasst, aber er hält sich im Code irgendwo auf und zeigt mir nicht die Werte an.

Ich habe den Sensor folgend angeschlossen:

V+ → 5V
V- → Gnd
PWM → Pin 9
Txd → A0
Rxd → A1

Mein Sketch sieht so aus:

#include <SoftwareSerial.h>           //Einbindung der Bibliotheken für Serielle Kommunikation (UART), 
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>            //Für das "°" Zeichen

#define pwmPin 9                       //definiere Pin 9 als Pin für PWM-Signal

// Set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);
SoftwareSerial mySerial(A0, A1);      //Schnittstellen für UART-Kommunikation festlegen (Rx auf A1, Tx auf A0!) Für CO2

//Notwendig für den CO2 Sensor
byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; //CO2-Sensor ansprechen
unsigned char response[9];            //Antwort des CO2 Sensors
unsigned long th, tl, ppm, ppm2, ppm3 = 0;

//Definitionen für die LEDs
int ledR = 6; //deklariere LED rot Pin 6
int ledG = 5; //deklariere LED grün Pin 5
int ledB = 3; //deklariere LED blau Pin 3

void setup()
{
  Serial.begin(9600);         //Initialisiere die Serielle Verbindung
  mySerial.begin(9600);       //Start serielle Kommunikation ("UART") mit CO2-Sensor
  pinMode(pwmPin, INPUT);     //"pwmPin" als digitalen Eingang für PWM-Signal definieren
  pinMode(ledR, OUTPUT);      //ledR = 6 --> Pin 6 ist digitaler Ausgang für rote LED
  pinMode(ledG, OUTPUT);      //ledG = 5 --> Pin 5 ist digitaler Ausgang für grüne LED
  pinMode(ledB, OUTPUT);      //ledB = 3 --> Pin 3 ist digitaler Ausgang für blaue LED
  lcd.init();           //Im Setup wird der LCD gestartet 
  lcd.backlight();      //Hintergrundbeleuchtung einschalten
  lcd.setCursor(0,0);   //Cursor auf Poition 0,0 setzen
  Serial.print("Start");
  lcd.print("Start");   //Schreib Start auf das Display
  analogWrite(ledR,0);analogWrite(ledG,0);analogWrite(ledB,255);//Blaue LED an
}

void loop()
{
  
  //Auswertung des UART-Signals der CO2-Konz.
  mySerial.write(cmd, 9);
  mySerial.readBytes(response, 9);
  unsigned int responseHigh = (unsigned int) response[2];
  unsigned int responseLow = (unsigned int) response[3];
  ppm = (256 * responseHigh) + responseLow;

  //Auswertung des PWM-Signals der CO2-Konz.
  do
  {
    th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
    tl = 1004 - th;
    ppm2 = 2000 * (th - 2) / (th + tl - 4);
    ppm3 = 5000 * (th - 2) / (th + tl - 4);
  }
  while (th == 0);
  
  //LCD-Anzeige des PWM-Signals der CO2-Konz.
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CO2 ist ");
  lcd.print(ppm3);
  lcd.print(" ppm");
  Serial.println(ppm3);
/*****************************************************************/

  //Überprüfung der rel. Luftfeuchtigkeit und CO2-Konz. im Innenraum und Anzeige des Ergebnisses an der LED
  
  //Luftfeuchte und CO2 im grünen Bereich
  if((ppm3 <= 800))
  { 
    analogWrite(ledR, 0); analogWrite(ledG, 255); analogWrite(ledB, 0);
  }
   //Luftfeuchte im gelben Bereich zu niedrig oder zu hoch oder CO2-Konz. zu hoch
  if((ppm3 > 800) and (ppm3 < 1000))
  { 
  analogWrite(ledR, 255); analogWrite(ledG, 255); analogWrite(ledB, 0);
  }
  //Luftfeuchte im roten Bereich zu niedrig oder zu hoch oder CO2-Konz. zu hoch
  if((ppm3 >= 1000))
  { 
  analogWrite(ledR, 255); analogWrite(ledG, 0); analogWrite(ledB, 0);
  }
  delay(5000);     //Warte 5 Sek.
}

Was ich rausgefunden habe ist, dass die do-Schleife, in der das CO2 Signal ausgewertet wird nur ein mal durchlaufen wird. Weiter läuft das Programm dann nicht.

Sieht jemand meinen Fehler? Ich weiß nicht weiter.

Hallo,

ich kenn das Ding nicht , aber schau mal hier link

Heinz

Danke, das ist eine sehr gute Seite.

Ich habe den oberen Sketch auf meinen Arduino Uno geladen.
Ich habe den CO2 Sensor so verkabelt:

Rxd -> Pin3
Txd -> Pin2
V+ -> 5V
V- -> Gnd
PWM -> Pin6

Meinen Sketch stelle ich noch rein, damit ihr nicht lange suchen müsst:

/**
 * CO2-Messung mit Sensor Typ MHZ19B
 * Messwerterfassung durch PWM-Signal
 */

// Der Sensor hängt an Pin 6

const int pwmpin = 6;

// Der eingestellte Messbereich (0-5000ppm)

const int range = 5000;

// Die setup()-Funktion

void setup() {

  // PWM-Pin auf Eingang setzen
  
  pinMode(pwmpin, INPUT);

  // Serielle Übertragung über USB initialisieren

  Serial.begin(9600);
  
}

// Die loop()-Funktion
 
void loop() {
  
  // Messung der PWM-Länge mittels einer eigenen Funktion
  
  int ppm_pwm = readCO2PWM();

  // Ausgabe der Werte über die serielle USB-Verbindung
  
  Serial.print("PPM PWM: ");
  Serial.println(ppm_pwm);

  // Messungen alle 3 Sekundn
  
  delay(3000);
  
}

// Die Messung der PWM-Länge erfolgt in einer eigenen
// Funktion readCO2PWM(), was die loop()-Schleife etwas "aufgeräumter"
// erscheinen lässt. Die Funktion gibt eine Ganzzahl zurück (int).

int readCO2PWM() {

  // Es werden die für die Umrechnung der Zeitdauer auf
  // die PPM-Werte benötigten Variablen definiert.
  // Da es sich bei th um große Werte handeln kann - die verwendete
  // Arduino-Funktion gibt Mikrosekunden zurück - wird diese Variable
  // als vorzeichenlose (unsigned) große Ganzzahl (long) definiert.
  
  unsigned long th;
  int ppm_pwm = 0;
  float pulsepercent;

  // Alles, was in der do ... while-Schleife steht, wird
  // solange ausgeführt, bis der Ausdruck nach while, hier
  // th == 0 als zutreffend (wahr) erkannt wird.
  // Da die Arduino-Funktion pulseIn() 0 zurückgibt, solange
  // sie am Messen ist, dient die Schleife dazu, auf den
  // Messwert zu warten.
  
  do {

    // pulseIn gibt die Dauer des am Pin (pwmpin) anliegenden
    // Signals in Mikrosekunden an. Da die maximale Signallänge
    // 1004ms ist, wird als timeoutwert 1004000µs angegeben.
    // Die Ausgabe der pulseIn()-Funktion wird durch 1000 geteilt
    // und ergibt so für th die Signallänge in Millisekunden (ms).
    
    th = pulseIn(pwmpin, HIGH, 1004000) / 1000;

    // Pulslänge in Prozent (%)

    float pulsepercent = th / 1004.0;

    // PPM-Werte bei gegebenem Range
    
    ppm_pwm = range * pulsepercent;
    
  } while (th == 0);
  
  // Der gemessene Wert wird an die loop()-Funktion zurückgegeben,
  // wo er dann ausgegeben wird.
  
  return ppm_pwm; 
}

Ich verstehe die serielle Ausgabe nicht:

Die sieht so aus, was sind das für Zahlen??

18:11:58.828 -> PPM PWM: 39
18:12:01.828 -> PPM PWM: 39
18:12:04.828 -> PPM PWM: 39
18:12:07.875 -> PPM PWM: 44
18:12:10.874 -> PPM PWM: 39
18:12:13.921 -> PPM PWM: 44
18:12:16.921 -> PPM PWM: 39
18:12:19.968 -> PPM PWM: 39
18:12:22.968 -> PPM PWM: 39
18:12:25.968 -> PPM PWM: 44
18:12:29.015 -> PPM PWM: 44
18:12:32.014 -> PPM PWM: 39
18:12:35.061 -> PPM PWM: 39
18:12:38.061 -> PPM PWM: 44
18:12:41.092 -> PPM PWM: 39
18:12:44.139 -> PPM PWM: 44
18:12:47.139 -> PPM PWM: 44
18:12:50.139 -> PPM PWM: 44
18:12:53.186 -> PPM PWM: 44
18:12:56.186 -> PPM PWM: 44
18:12:59.232 -> PPM PWM: 44
18:13:02.232 -> PPM PWM: 44

Ich freue mich für jede Hilfe. Hat niemand eine Idee, wie man das lösen kann?

Hallo Programmierer,

hat keiner mit so einem Ding programmiert?
Ich hoffe, dass es noch jemanden gibt, der mir helfen kann.
Der Sensor gibt laut Datenblatt Zahlenwerte von 400 ppm bis 2000 oder 5000 ppm aus, aber meiner schreibt auf das Display und auf dem seriellen Monitor Zahlen von 10 bis 40.

Ich komme da nicht weiter. Aber sicherlich gibt es schlaue Köpfe, die da weiter wissen :slight_smile:

Ich habe eine zweite Variante getestet.

Aus dem Internet habe ich einen einfachen Sketch für den CO2-Sensor gefunden:

#include <SoftwareSerial.h>;

SoftwareSerial mySerial(A0, A1); // connect also co2sensor-ardunoUno17 with  Tx-A0,Rx-A1,Vin-5v,GND-GND  ,Old bootloader in my case

byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
unsigned char response[9];

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

void loop()
{
  mySerial.write(cmd, 9);
  memset(response, 0, 9);
  mySerial.readBytes(response, 9);
  int i;
  byte crc = 0;
  for (i = 1; i < 8; i++) crc+=response[i];
  crc = 255 - crc;
  crc++;

   if ( !(response[0] == 0xFF && response[1] == 0x86 && response[8] == crc) ) {
    Serial.println("CRC error: " + String(crc) + " / "+ String(response[8]));
  } else {
    unsigned int responseHigh = (unsigned int) response[2];
    unsigned int responseLow = (unsigned int) response[3];
    unsigned int ppm = (256*responseHigh) + responseLow;
    Serial.println(ppm);
  }
  delay(10000);
}

Als Ausgabe auf dem seriellen Monitor bekomme ich nur diese Fehlermeldung:

22:53:31.718 -> CRC error: 0 / 0

Ich habe den MH-Z19b so verkabelt:
Tx → A0
Rxd → A1
V+ → 5V
V- → Gnd
PWM → Pin9

Ich freue mich, wenn mir da jemand weiterhelfen kann.

Ich habe einen fertigen Luftmonitor mit CO2 Anzeige, zum Sensor kann ich nur sagen, was im Datenblatt steht.

Erst einmal muß der Sensor mindestens 3 Minuten warmlaufen, bevor er brauchbare Werte bringt. Vermutlich hängt Dein erster Sketch, weil der Sensor noch keine Impulse ausgibt. Die Fehler in den anderen Sketchen könnten (teilweise) auch davon kommen.

Die Ausgabe mit PWM ist im Datenblatt veranschaulicht. Die minimale Pulsbreite (pulseIn) ist 2ms, quasi ein Startbit. Der Rest des Impulses (pulseIn-2) von 0-1000 gibt die PPM CO2 an, wobei 1000 dem vollen Messbereich entspricht, d.h. 2000 oder 5000, je nach Voreinstellung.

Deshalb verstehe ich die Rechnung mit pulsepercent auch nicht, sie entspricht nicht der Angabe im Datenblatt. Auch die andere Rechnung ist Murks, entweder wird tl tatsächlich gemessen oder auf eine Korrektur der Zeitbasis verzichtet.
Ich würde es so machen:

 unsigned long th, ppm;
 th=pulseIn(...)/1000; //high in ms
 ppm=(th-2)*range; //range hier 2 oder 5

Wenn tl oder die Zykluszeit gemessen wird, kann man ppm so berechnen

 unsigned tcy=th+tl; //oder gemessene Zykluszeit
 ppm =range*(th-2)/(tcy-4); //range hier 2000UL oder 5000UL

Vorsicht mit Überläufen bei der Rechnung, am besten alle Variablen unsigned long.

Teil 2: seriell
Ein- und Ausgabe sind mit einem CRC Prüfcode abgesichert. Die CRC Berechnung im Datenblatt verwendet char, vermutlich unsigned sonst würde 0xFF keinen Sinn machen, also dürfte byte statt char auch in Ordnung sein.

Vor einer Messung sollte einmal der Meßbereich gesetzt werden (in setup), vermutlich wird dann schon (nach der Aufwärmzeit?) das PWM Signal ausgegeben.

Dann kann das Kommando zur seriellen Übertragung gegeben werden, siehe "Read CO2 concentration" im Datenblatt. Das zu sendende Kommando ist komplett angegeben, man kann damit die eigene Berechnung des CRC überprüfen.

Das Testprogramm prüft nicht nur den CRC der Antwort, wenn irgendwas nicht stimmt wird nur die CRC Fehlermeldung ausgegeben. Ich würde trotzdem mal alles ausgeben lassen, was der Sensor geschickt hat.

Mich würde noch interessieren was rauskommt, wenn man einen anderen Sensor als #1 abfragt. Vielleicht Temperatur und Luftfeuchtigkeit? Vielleicht kommt da auch nur was bei der nächsten Sensor Version?

Hallo Dieter,

Ok zunächst ein mal kann ich dir nur empfehlen, deine Variablen gescheit zu nennen. Kein Plan was "th" ist und tut. Wenn du deine variable "gegesseneDönerInDerWoche" nennst, weiß jeder was da drin gespeichert ist.

Als nächstes, ich rate jeden davon ab, do while schleifen zu benutzen, denn die widersprechen den menschlichen arbeitsstrukturs. Das ist auch so wie es aussieht bei dir der Fall. Es wird ein mal in die do reingegangen, th wird ausgerechnet und da kommt. Kein 0 raus. Dann wird diese Schleife für immer ignoriert.

Ich empfehle es dir, diese Schleife in einer if Abfrage und darauf folgende while / for Schleife umzubauen (falls du da überhaupt eine Schleife benötigst)

Viele Grüße

Die Benennung von th und tl folgt dem Datenblatt, somit weiß jeder, der sich mit der Materie auskennt, was gemeint ist.

Die Kritik an der while Schleife ist hier auch völlig unangebracht. Die Messung soll so lange wiederholt werden, bis ein sinnvoller Wert (!=0) ermittelt wurde. In Pascal hieße das Repeat ... Until ..., was ich für leichter verständlich halte als die C Syntax.

Danke für die Hilfe,

ich habe meinen Sketch angepasst. Der sieht jetzt so aus:

/**
 * CO2-Messung mit Sensor Typ MHZ19B
 * Messwerterfassung durch PWM-Signal
 */

// Der Sensor hängt an Pin 6

const int pwmpin = 6;

// Der eingestellte Messbereich (0-5000ppm)

const int range = 5000;

// Die setup()-Funktion

void setup() {

  // PWM-Pin auf Eingang setzen
  
  pinMode(pwmpin, INPUT);

  // Serielle Übertragung über USB initialisieren

  Serial.begin(9600);
  
}

// Die loop()-Funktion
 
void loop() {
  
  // Messung der PWM-Länge mittels einer eigenen Funktion
  
  int ppm_pwm = readCO2PWM();

  // Ausgabe der Werte über die serielle USB-Verbindung
  
  Serial.print("PPM PWM: ");
  Serial.println(ppm_pwm);

  // Messungen alle 3 Sekundn
  
  delay(3000);
  
}

// Die Messung der PWM-Länge erfolgt in einer eigenen
// Funktion readCO2PWM(), was die loop()-Schleife etwas "aufgeräumter"
// erscheinen lässt. Die Funktion gibt eine Ganzzahl zurück (int).

int readCO2PWM() {

  // Es werden die für die Umrechnung der Zeitdauer auf
  // die PPM-Werte benötigten Variablen definiert.
  // Da es sich bei th um große Werte handeln kann - die verwendete
  // Arduino-Funktion gibt Mikrosekunden zurück - wird diese Variable
  // als vorzeichenlose (unsigned) große Ganzzahl (long) definiert.
  
  unsigned long th, ppm, tl;
  unsigned tcy=th+tl; //oder gemessene Zykluszeit
  int ppm_pwm = 0;
  float pulsepercent;

  // Alles, was in der do ... while-Schleife steht, wird
  // solange ausgeführt, bis der Ausdruck nach while, hier
  // th == 0 als zutreffend (wahr) erkannt wird.
  // Da die Arduino-Funktion pulseIn() 0 zurückgibt, solange
  // sie am Messen ist, dient die Schleife dazu, auf den
  // Messwert zu warten.
  
  do {

    // pulseIn gibt die Dauer des am Pin (pwmpin) anliegenden
    // Signals in Mikrosekunden an. Da die maximale Signallänge
    // 1004ms ist, wird als timeoutwert 1004000µs angegeben.
    // Die Ausgabe der pulseIn()-Funktion wird durch 1000 geteilt
    // und ergibt so für th die Signallänge in Millisekunden (ms).
    
    th = pulseIn(pwmpin, HIGH, 1004000) / 1000;  //high in ms

    ppm =range*(th-2)/(tcy-4); //range hier 2000UL oder 5000UL

    // Pulslänge in Prozent (%)

    float pulsepercent = th / 1004.0;

    // PPM-Werte bei gegebenem Range
    ppm = (th-2) * range;  //Range hier 2 oder 5
    ppm_pwm = range * pulsepercent;
    Serial.println(ppm);
    
  } while (th == 0);
  
  // Der gemessene Wert wird an die loop()-Funktion zurückgegeben,
  // wo er dann ausgegeben wird.
  
  return ppm_pwm;
}

Als Antwort auf dem seriellen Monitor bekomme ich immer die gleiche Zahl:

09:58:29.873 -> 4294957296
09:58:30.576 -> 4294957296
09:58:31.279 -> 4294957296
09:58:31.935 -> 4294957296
09:58:32.638 -> 4294957296
09:58:33.342 -> 4294957296
09:58:34.045 -> 4294957296
09:58:34.748 -> 4294957296
09:58:35.451 -> 4294957296
09:58:36.107 -> 4294957296
09:58:36.810 -> 4294957296
09:58:37.513 -> 4294957296

DrDiettrich:
Vor einer Messung sollte einmal der Meßbereich gesetzt werden (in setup), vermutlich wird dann schon (nach der Aufwärmzeit?) das PWM Signal ausgegeben.

Dann kann das Kommando zur seriellen Übertragung gegeben werden, siehe "Read CO2 concentration" im Datenblatt. Das zu sendende Kommando ist komplett angegeben, man kann damit die eigene Berechnung des CRC überprüfen.

Mich würde noch interessieren was rauskommt, wenn man einen anderen Sensor als #1 abfragt. Vielleicht Temperatur und Luftfeuchtigkeit? Vielleicht kommt da auch nur was bei der nächsten Sensor Version?

Dietrich, ich konnte deiner Erklärung nicht ganz folgen. Ich freue mich, wenn du noch etwas kleinschrittiger Erklären könntest, was du meinst. Ich bin noch ein Anfänger in diesem Bereich.

Du solltest th und tl nur verwenden, wenn Du beide vorher gemessen hast. Ansonsten reicht erst mal tcy=1004ms. Ohne Messung kommt halt immer der gleiche Murks raus. Zudem wenn pulsepercent unsinnig berechnet wird - schmeiß das einfach ganz raus.

Versuche einfach mal, den verwendeten Code zu verstehen. Z.B. behauptet der Kommentar vor der while Schleife genau das Gegenteil von dem, was so eine Schleife macht. Wenn Du in fremdem Code nicht einmal so grobe Fehler erkennen kannst, dann solltest Du anfangen, Deine Programme selbst zu schreiben, bis Du die Grundbegriffe des Programmierens verstanden hast.

Zum Debuggen würde ich vorschlagen, jeden Meßwert und die Zwischenergebnisse auszugeben, dann kann man den/die Fehler leichter eingrenzen.

Sketch gekürzt von mir:

adruinoboy:
ich habe meinen Sketch angepasst. Der sieht jetzt so aus:

void loop() {

Serial.print("PPM PWM: ");
  Serial.println(ppm_pwm);
  // Messungen alle 3 Sekundn
  delay(3000);
}




Als Antwort auf dem seriellen Monitor bekomme ich immer die gleiche Zahl:



09:58:29.873 -> 4294957296
09:58:30.576 -> 4294957296
09:58:31.279 -> 4294957296
09:58:31.935 -> 4294957296
09:58:32.638 -> 4294957296
09:58:33.342 -> 4294957296
09:58:34.045 -> 4294957296
09:58:34.748 -> 4294957296

Irgendwie passen die Ausgaben auf dem Monitor absolut nicht zum Sketch.

Wo in dem Sketch erfolgt eine Messung?

Gruß Tommy

Sorry Tommy, ich hatte den Sketch etwas gekürzt um zu zeigen, was meiner Meinung nach nicht zusammen passt.

Die Messung soll doch in readCO2PWM() erfolgen. Dort tut sich auch was, nur richtig ist der Code dort noch lange nicht.

Die Messung war im letzten zitierten Code von Moko nicht drin.
Deshalb meine Ansage.

Gruß Tommy

Hallo,

ich kann leider mit dem Datenblatt nicht viel anfangen. Es tut mir Leid, dass ich so ein Anfänger bin.
Ich habe mich jetzt wieder für meinen ersten Sketch entschieden, weil da am Anfang vor dem ‘void setup’ genau daklariert ist, was im Datenblatt steht (0xFF u.s.w.).

Also mein Sketch sieht jetzt so aus:

#include <SoftwareSerial.h>           //Einbindung der Bibliotheken für Serielle Kommunikation (UART), 
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>            //Für das "°" Zeichen

#define pwmPin 9                       //definiere Pin 9 als Pin für PWM-Signal

// Set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);
SoftwareSerial mySerial(A0, A1);      //Schnittstellen für UART-Kommunikation festlegen (Rx auf A1, Tx auf A0!) Für CO2

//Notwendig für den CO2 Sensor
byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; //CO2-Sensor ansprechen
unsigned char response[9];            //Antwort des CO2 Sensors
unsigned long th, tl, ppm, ppm2, ppm3 = 0;

//Definitionen für die LEDs
int ledR = 6; //deklariere LED rot Pin 6
int ledG = 5; //deklariere LED grün Pin 5
int ledB = 3; //deklariere LED blau Pin 3

void setup()
{
  Serial.begin(9600);         //Initialisiere die Serielle Verbindung
  mySerial.begin(9600);       //Start serielle Kommunikation ("UART") mit CO2-Sensor
  pinMode(pwmPin, INPUT);     //"pwmPin" als digitalen Eingang für PWM-Signal definieren
  pinMode(ledR, OUTPUT);      //ledR = 6 --> Pin 6 ist digitaler Ausgang für rote LED
  pinMode(ledG, OUTPUT);      //ledG = 5 --> Pin 5 ist digitaler Ausgang für grüne LED
  pinMode(ledB, OUTPUT);      //ledB = 3 --> Pin 3 ist digitaler Ausgang für blaue LED
  lcd.init();           //Im Setup wird der LCD gestartet 
  lcd.backlight();      //Hintergrundbeleuchtung einschalten
  lcd.setCursor(0,0);   //Cursor auf Poition 0,0 setzen
  Serial.print("Start");
  lcd.print("Start");
  analogWrite(ledR,0);
  analogWrite(ledG,0);
  analogWrite(ledB,255);
}

void loop()
{
  
  //Auswertung des UART-Signals der CO2-Konz.
  mySerial.write(cmd, 9);
  mySerial.readBytes(response, 9);
  unsigned int responseHigh = (unsigned int) response[2];
  unsigned int responseLow = (unsigned int) response[3];
  ppm = (256 * responseHigh) + responseLow;

  //Auswertung des PWM-Signals der CO2-Konz.
  do
  {
    analogWrite(ledB, 255);
    th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
    tl = 1004 - th;
    ppm2 = 2000 * (th - 2) / (th + tl - 4);
    ppm3 = 5000 * (th - 2) / (th + tl - 4);
  }
  while (th == 0);
  
  //LCD-Anzeige des PWM-Signals der CO2-Konz.
  analogWrite(ledR, 255);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CO2 ist ");
  lcd.print(ppm3);
  lcd.print(" ppm");
  Serial.println(ppm3);
/*****************************************************************/

  //Überprüfung der rel. Luftfeuchtigkeit und CO2-Konz. im Innenraum und Anzeige des Ergebnisses an der LED
  
  //Luftfeuchte und CO2 im grünen Bereich
  if((ppm3 <= 800))
  { 
    analogWrite(ledR, 0);
    analogWrite(ledG, 255);
    analogWrite(ledB, 0);
  }
   //Luftfeuchte im gelben Bereich zu niedrig oder zu hoch oder CO2-Konz. zu hoch
  if((ppm3 > 800) and (ppm3 < 1000))
  { 
  analogWrite(ledR, 255);
  analogWrite(ledG, 255);
  analogWrite(ledB, 0);
  }
  //Luftfeuchte im roten Bereich zu niedrig oder zu hoch oder CO2-Konz. zu hoch
  if((ppm3 >= 1000))
  { 
  analogWrite(ledR, 255);
  analogWrite(ledG, 0);
  analogWrite(ledB, 0);
  }
  delay(5000);     //Warte 5 Sek.
}

Meine Ausgabe im seriellen Monitor ist für mich nicht nachvollziehbar.

14:01:43.339 -> Start40
14:01:50.449 -> 40
14:01:56.503 -> 40
14:02:02.532 -> 40
14:02:08.575 -> 40
14:02:14.626 -> 35
14:02:20.666 -> 40
14:02:26.720 -> 40
14:02:32.778 -> 40
14:02:38.841 -> 40
14:02:44.863 -> 40
14:02:50.940 -> 40
14:02:57.024 -> 40
14:03:03.035 -> 40

Du hast recht, die Werte sehen nicht gut aus.

Interessant wäre zum Debuggen auch noch ppm, th und die tatsächliche Zykluszeit.

Hi

adruinoboy:
ich kann leider mit dem Datenblatt nicht viel anfangen. Es tut mir Leid, dass ich so ein Anfänger bin.

Also DAS muß Dir nun wirklich nicht leid tun - denke, wir Alle waren (oder sind) Anfänger.
Das größte Problem dabei: Nur Du kannst Das ändern (also Jeder nur für sich).

Mir sagt im Großteil der Datenblätter ebenfalls ein Großteil der enthaltenen Daten auch nicht wirklich viel - aber wenn ich aus dem Datenblatt eine gewisse Eigenschaft des Delinquenten herausfinden will/muß, sollte Das mit Google & Co durchaus lösbar sein.

Durch 'Ich kann Das nicht, weil ich neu bin' (mach Du Das für mich ...) wird hier nur selten 'durch gehen'.

MfG

Hallo,

ich freue mich über die schnellen Antworten und über die ermutigenden Worte.

Ich habe jetzt meinen Sketch erweitert, damit alle Werte auf dem seriellen Monitor ausgegeben werden.
Hier der leicht veränderte Sketch:

#include <SoftwareSerial.h>           //Einbindung der Bibliotheken für Serielle Kommunikation (UART), 
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>            //Für das "°" Zeichen

#define pwmPin 9                       //definiere Pin 9 als Pin für PWM-Signal

// Set the LCD address to 0x27 for a 20 chars and 4 line display
LiquidCrystal_I2C lcd(0x27, 20, 4);
SoftwareSerial mySerial(A0, A1);      //Schnittstellen für UART-Kommunikation festlegen (Rx auf A1, Tx auf A0!) Für CO2

//Notwendig für den CO2 Sensor
byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; //CO2-Sensor anspreche
unsigned char response[9];            //Antwort des CO2 Sensors
unsigned long th, tl, ppm, ppm2, ppm3 = 0;

//Definitionen für die LEDs
int ledR = 6; //deklariere LED rot Pin 6
int ledG = 5; //deklariere LED grün Pin 5
int ledB = 3; //deklariere LED blau Pin 3

void setup()
{
  Serial.begin(9600);         //Initialisiere die Serielle Verbindung
  mySerial.begin(9600);       //Start serielle Kommunikation ("UART") mit CO2-Sensor
  pinMode(pwmPin, INPUT);     //"pwmPin" als digitalen Eingang für PWM-Signal definieren
  pinMode(ledR, OUTPUT);      //ledR = 6 --> Pin 6 ist digitaler Ausgang für rote LED
  pinMode(ledG, OUTPUT);      //ledG = 5 --> Pin 5 ist digitaler Ausgang für grüne LED
  pinMode(ledB, OUTPUT);      //ledB = 3 --> Pin 3 ist digitaler Ausgang für blaue LED
  lcd.init();                 //Im Setup wird der LCD gestartet 
  lcd.backlight();            //Hintergrundbeleuchtung einschalten
  lcd.setCursor(0,0);         //Cursor auf Poition 0,0 setzen
  Serial.println("Start");
  lcd.print("Start");
  analogWrite(ledR,0);
  analogWrite(ledG,0);
  analogWrite(ledB,255);
}

void loop()
{
  
  //Auswertung des UART-Signals der CO2-Konz.
  mySerial.write(cmd, 9);
  mySerial.readBytes(response, 9);
  unsigned int responseHigh = (unsigned int) response[2];
  unsigned int responseLow = (unsigned int) response[3];
  ppm = (256 * responseHigh) + responseLow;

  //Auswertung des PWM-Signals der CO2-Konz.
  do
  {
    analogWrite(ledB, 255);
    th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
    tl = 1004 - th;
    ppm2 = 2000 * (th - 2) / (th + tl - 4);
    ppm3 = 5000 * (th - 2) / (th + tl - 4);
  }
  while (th == 0);
  
  //LCD-Anzeige des PWM-Signals der CO2-Konz.
  analogWrite(ledR, 255);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("CO2 ist ");
  lcd.print(ppm3);
  lcd.print(" ppm");
  Serial.print("ppm: ");
  Serial.println(ppm);
  Serial.print("th: ");
  Serial.println(th);
  Serial.print("tl: ");
  Serial.println(tl);
  Serial.print("ppm2: ");
  Serial.println(ppm2);
  Serial.print("ppm3: ");
  Serial.println(ppm3);
/*****************************************************************/

  //Überprüfung der rel. Luftfeuchtigkeit und CO2-Konz. im Innenraum und Anzeige des Ergebnisses an der LED
  
  //Luftfeuchte und CO2 im grünen Bereich
  if((ppm3 <= 800))
  { 
    analogWrite(ledR, 0);
    analogWrite(ledG, 255);
    analogWrite(ledB, 0);
  }
   //Luftfeuchte im gelben Bereich zu niedrig oder zu hoch oder CO2-Konz. zu hoch
  if((ppm3 > 800) and (ppm3 < 1000))
  { 
  analogWrite(ledR, 255);
  analogWrite(ledG, 255);
  analogWrite(ledB, 0);
  }
  //Luftfeuchte im roten Bereich zu niedrig oder zu hoch oder CO2-Konz. zu hoch
  if((ppm3 >= 1000))
  { 
  analogWrite(ledR, 255);
  analogWrite(ledG, 0);
  analogWrite(ledB, 0);
  }
  delay(5000);     //Warte 5 Sek.
}

Und hier die Ausgabe des seriellen Monitors:

12:49:56.521 -> Start
12:49:57.599 -> ppm: 0
12:49:57.599 -> th: 10
12:49:57.599 -> tl: 994
12:49:57.599 -> ppm2: 16
12:49:57.646 -> ppm3: 40
12:50:03.693 -> ppm: 0
12:50:03.693 -> th: 10
12:50:03.693 -> tl: 994
12:50:03.693 -> ppm2: 16
12:50:03.693 -> ppm3: 40
12:50:09.740 -> ppm: 0
12:50:09.740 -> th: 10
12:50:09.740 -> tl: 994
12:50:09.740 -> ppm2: 16
12:50:09.740 -> ppm3: 40

Ich hoffe ihr könnt mir jetzt weiter helfen.