CO2 meter met MH-Z19 sensor en ventilatie beinvloeding

Toon hier Uw afgeronde projecten aan anderen.
Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

CO2 meter met MH-Z19 sensor en ventilatie beinvloeding

Berichtdoor wim2584 » 12 Nov 2020, 21:27

Code: Alles selecteren
/* CO2 meting en aansturing centrale afzuiging,

    meet de CO2 met MH-Z19 via PWM, display op 16 x 2 LCD , drie staus lampjes bovenop kastje, en centrale afzuiging aanpassen speed 1,2,3 (ITHO unit met draadloze RF unit).
    tevens een drukknop, bij kort indrukken, gaat backlight LCD uit, en blijven status ledjes aan, bij lang indrukken (> 3 sec) gaat zowel backlight en statusledjes uit, deze functie
    zit erin om geen hinderlijk light in de kamer te hebben.

    verder zit er een SD card in, waar alle waarden  (ppm CO2 / fanstatus / datum en tijd) op wordt weggeschreven, later kan er dan mbv EXCEL een grafiek van worden gemaakt

    alles werkt prima, echter de code zal zeker eenvoudiger en beter kunnen, bij mij is het zo "gegroeid"en even geen zin in optimalisering.
    bij mij staat eea nu paar weken aan, "normaal" fan 1 <900ppm, echter bij avondeten koeken en twee mensen +hond in de kamer looopt CO2 op boven de 900ppm en gaat fan naar stand 2
    stand 3 echter alleen bij meer mensen langere tijd in de kamer


    indicatieledjes en indicatie:

     < 600 ppm (instellen regel 266)groen + erg goed
     < 900 ppm (instellen regel 280)groen + goed
     > 900 <1200 ppm (instellen regel 293)oranje + acceptabel
     > 1200 <1500 ppm (instellen regel 306)oranje +rood +slecht
     > 1500 <=2000 ppm (instellen regel 319)rood + erg slecht

     centrale afzuiging:
     < 750 ppm (instellen regel 335) fan 1
     >900 < 1400 (instellen regel 344) fan 2
     >1500 (instellen regel 354) fan 3
     inschakelijd fan 1,2, 3 met delay (instellen regel 355/364/374)

     algemeen:

     version number (V1.5) (instellen regel 118)
      sampletijd (3000) (instellen regel (366)
      wegschrijven interval naar SDcard (instellen regel (408)
      aftellen opwarmtijd (120-0 sec) (instellen regel (186)

  Wim Lemson november 2020

*/

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
const int ledred = 4;
const int ledyellow = 3;
const int ledgreen = 2;
unsigned long Timer0;
unsigned long Timer1;
unsigned long Timer2;


// fan aansturing
const int fan_1 = A2;
const int fan_2 = 9;
const int fan_3 = 5;


// on off backlicht en led bovenop
int button = 8;

long buttonTimer = 0;
long longPressTime = 2000;
boolean buttonActive = false;
boolean longPressActive = false;
int state = HIGH;
int state1 = HIGH;


int fanstate;

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

#define pwmPin A1
unsigned long th, tl, ppm;


RTC_DS1307 RTC; // define the Real Time Clock object

const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);

  while (1);
}

void setup(void)
{
  //pinMode(inPin, INPUT_PULLUP);
  // pinMode(outPin, OUTPUT);
  pinMode(button, INPUT_PULLUP);


  lcd.init();                      // initialize the lcd
  lcd.backlight();

  Serial.begin(9600);

  Serial.println();

  // initialize the SD card
  Serial.print(F("Initializing SD card..."));
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    lcd.setCursor(0, 1);
    lcd.print("SD CARD : FOUT      ");
    lcd.setCursor(0, 0);
    error("Card failed, or not present");
  }
  Serial.println(F("card initialized."));
  lcd.setCursor(0, 1);
  lcd.print("SD CARD:ok ");
  lcd.setCursor(11, 1);
  lcd.print("V1.5");
  lcd.setCursor(0, 0);

  DateTime now = RTC.now();
  lcd.setCursor(0, 0);
  lcd.print(now.day(), DEC);
  lcd.print("/");
  lcd.print(now.month(), DEC);
  lcd.print("/");
  lcd.print(now.year(), DEC);
  lcd.print(" ");
  lcd.setCursor (11, 0);
  lcd.print(now.hour(), DEC);
  lcd.print((":"));
  lcd.print(now.minute(), DEC);

  delay(5000);
  lcd.setCursor(0, 0);
  lcd.print("                                       ");
  lcd.setCursor(0, 1);
  lcd.print("                              ");

  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i / 10 + '0';
    filename[7] = i % 10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break;  // leave the loop!
    }
  }

  if (! logfile) {

    lcd.setCursor(0, 1);
    lcd.print("SD CARD : FOUT ");
    lcd.setCursor(0, 0);
    error("couldnt create file");
  }

  Serial.print(F("Logging to: "));
  Serial.println(filename);

  // connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
    Serial.println(F("RTC failed"));
  }
  logfile.println(F("Date,Time,CO2ppm,fanstatus"));

  Serial.println(F("Date,Time,CO2ppm,fanstatus"));

  lcd.setCursor(3, 0);
  lcd.print("CO2 MONITOR");

  lcd.setCursor(2, 1);
  lcd.print("Opwarmen:   ");
  lcd.setCursor(14, 1);
  lcd.print("s");

  for (int i = 2 ; i >= 0; i--) {  // opwarmtijd in seconden
    lcd.setCursor(11, 1);
    lcd.print("   ");
    lcd.setCursor(11, 1);
    lcd.print(i);

    delay(1000);
  }

  lcd.setCursor(0, 0);
  lcd.print("                             ");
  lcd.setCursor(0, 1);
  lcd.print("                              ");

  pinMode(pwmPin, INPUT);
  digitalWrite(ledyellow, LOW);
  digitalWrite(ledred, LOW);
  digitalWrite(ledgreen, LOW);
  lcd.noBacklight();
  Timer0 = millis();
  Timer1 = millis();
  Timer2 = millis();




  //CO2 via pwm
  do {
    th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
    tl = 1004 - th;
    ppm = 2000 * (th - 2) / (th + tl - 4);
  } while (th == 0);
  lcd.setCursor(1, 0);
  lcd.print("CO2: ");
  lcd.setCursor(11, 0 );
  lcd.print("ppm");
  lcd.setCursor(6, 0 );
  lcd.print("    ");
  lcd.setCursor(6, 0 );
  lcd.print(ppm);
  lcd.setCursor(0, 1);
  lcd.print("Fan:");
  lcd.setCursor(4, 1 );
  lcd.print(fanstate);
  digitalWrite(fan_1, LOW);
  digitalWrite(fan_2, LOW);
  digitalWrite(fan_3, LOW);

}


void loop(void)
{
  pinMode(ledred, OUTPUT);
  pinMode(ledyellow, OUTPUT);
  pinMode(ledgreen, OUTPUT);
  pinMode(fan_1, OUTPUT);
  pinMode(fan_2, OUTPUT);
  pinMode(fan_3, OUTPUT);


  // backlight aan uit en ledjes bovenop

  if (digitalRead(button) == LOW) {

    if (buttonActive == false) {

      buttonActive = true;
      buttonTimer = millis();
    }

    if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
      longPressActive = true;
      Serial.println ("LONG");
      if  (state == HIGH)  {
        state = LOW;
        state1 = LOW;
      }  else {
        state = HIGH;
        state1 = HIGH;
      }
    }

  } else {

    if (buttonActive == true) {
      if (longPressActive == true) {
        longPressActive = false;
      } else {
        Serial.println ("SHORT");
        Serial.println (state);
        if  (state == HIGH)  {
          state = LOW;
          state1 = HIGH;
        }  else {
          state = HIGH;
          state1 = HIGH;
        }
      }
      buttonActive = false;
    }
  }
  if (state == HIGH ) {
    lcd.backlight();
  }
  else {
    lcd.noBacklight();
  }


  // status ledjes

  if (ppm < 600) {
    if (state1 == HIGH) {
      digitalWrite(ledyellow, LOW);
      digitalWrite(ledred, LOW);
      digitalWrite(ledgreen, HIGH);
    } else {
      digitalWrite(ledyellow, LOW);
      digitalWrite(ledred, LOW);
      digitalWrite(ledgreen, LOW);

    }
    lcd.setCursor(6, 1);
    lcd.print("Erg Goed     ");
  }
  else if (ppm < 900) {
    if (state1 == HIGH) {
      digitalWrite(ledyellow, LOW                         );
      digitalWrite(ledred, LOW);
      digitalWrite(ledgreen, HIGH);
    } else {
      digitalWrite(ledyellow, LOW);
      digitalWrite(ledred, LOW);
      digitalWrite(ledgreen, LOW);
    }
    lcd.setCursor(6, 1);
    lcd.print("Goed         ");
  }
  else if (ppm > 900 && ppm < 1200) {
    if (state1 == HIGH) {
      digitalWrite(ledyellow, HIGH);
      digitalWrite(ledred, LOW);
      digitalWrite(ledgreen, LOW);
    } else {
      digitalWrite(ledyellow, LOW);
      digitalWrite(ledred, LOW);
      digitalWrite(ledgreen, LOW);
    }
    lcd.setCursor(6, 1);
    lcd.print("Acceptabel     ");
  }
  else if (ppm > 1200 && ppm < 1500 ) {
    if (state1 == HIGH) {
      digitalWrite(ledyellow, HIGH);
      digitalWrite(ledred, HIGH);
      digitalWrite(ledgreen, LOW);
    } else {
      digitalWrite(ledyellow, LOW);
      digitalWrite(ledred, LOW);
      digitalWrite(ledgreen, LOW);
    }
    lcd.setCursor(6, 1);
    lcd.print("Slecht      ");
  }
  else if (ppm > 1500 && ppm <= 2000) {
    if (state1 == HIGH) {
      digitalWrite(ledyellow, LOW);
      digitalWrite(ledred, HIGH);
      digitalWrite(ledgreen, LOW);
    } else {
      digitalWrite(ledyellow, LOW);
      digitalWrite(ledred, LOW);
      digitalWrite(ledgreen, LOW);
    }
    lcd.setCursor(6, 1);
    lcd.print("Erg Slecht     ");
  }

  // ventilatie meer minder schakelen

  if (ppm < 750 && fanstate != 1 ) {
    fanstate = 1;
    digitalWrite(fan_1, HIGH);
    Serial.println("fan speed 1 on");
    delay(700);
    Serial.println("fan speed 1 off");
    digitalWrite(fan_1, LOW);

  }
  else if  (ppm > 900 && ppm < 1400  && fanstate != 2 ) {
    fanstate = 2;
    digitalWrite(fan_2, HIGH);
    Serial.println("fan speed 2 on");
    delay(700);
    Serial.println("fan speed 2 off");
    digitalWrite(fan_2, LOW);


  }
  else if (ppm > 1500  && fanstate != 3 ) {
    fanstate = 3;
    digitalWrite(fan_3, HIGH);
    Serial.println("fan speed 3 on");
    delay(700);
    Serial.println("fan speed 3 off");
    digitalWrite(fan_3, LOW);

  }

  //sample tijd

  if (millis() - Timer1 >= 30000 ) { // tijd tussen de samples in msec
    Timer1 = millis();

    //CO2 via pwm
    do {
      th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
      tl = 1004 - th;
      ppm = 2000 * (th - 2) / (th + tl - 4);
    } while (th == 0);

    DateTime now;
    now = RTC.now();

    Serial.print(now.year(), DEC);
    Serial.print(F("/"));
    Serial.print(now.month(), DEC);
    Serial.print(F("/"));
    Serial.print(now.day(), DEC);
    Serial.print(F(" "));
    Serial.print(now.hour(), DEC);
    Serial.print(F(":"));
    Serial.print (now.minute(), DEC);
    Serial.print(F(" "));
    Serial.print(F(","));
    Serial.print(ppm);
    Serial.print(F(","));
    Serial.println(fanstate);

    lcd.setCursor(1, 0);
    lcd.print("CO2: ");
    lcd.setCursor(11, 0 );
    lcd.print("ppm");
    lcd.setCursor(6, 0 );
    lcd.print("    ");
    lcd.setCursor(6, 0 );
    lcd.print(ppm);
    lcd.setCursor(0, 1);
    lcd.print("Fan:");
    lcd.setCursor(4, 1);
    lcd.print(fanstate);

  }
  if (millis() - Timer2 >= 360000 ) { // tijd wegschrijven naar SD kaart in msec
    DateTime now;
    now = RTC.now();
    logfile.print(now.year(), DEC);
    logfile.print(F("/"));
    logfile.print(now.month(), DEC);
    logfile.print(F("/"));
    logfile.print(now.day(), DEC);
    logfile.print(F(" "));
    logfile.print(F(","));
    logfile.print(now.hour(), DEC);
    logfile.print(F(":"));
    logfile.print(now.minute(), DEC);
    logfile.print(F(" "));
    logfile.print(F(","));
    logfile.print(ppm);
    logfile.print(F(","));
    logfile.print(fanstate);
    logfile.println();

    logfile.flush();

    Timer2 = millis();
  }
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: CO2 meter met MH-Z19 sensor en ventilatie beinvloeding

Berichtdoor Koepel » 13 Nov 2020, 15:39

Bedankt voor het plaatsen van je project.

Wat zijn je ervaringen met de MH-Z19 ? Waarom koos je voor PWM ? Waar heb je de sensor gekocht ?

Berichten: 88
Geregistreerd: 16 Jul 2015, 21:02

Re: CO2 meter met MH-Z19 sensor en ventilatie beinvloeding

Berichtdoor wim2584 » 13 Nov 2020, 22:33

sensor heb ik gekocht op Alieexpress (15 euro), hij werkt prima met de library MH-Z19, (hier staan ook calibratie en andere "handige"tools in), eerst had ik via RX-TX, maar aangezien ik ook serial wilde gebruiken.... eerst geprobeerd met een softserial, maar op de een of andere manier gaf dat conflicten met andere libraries.
paar testjes gedaan met rx-tx en vergeleken met PWM, resultaten waren gelijk, dus overgestap naar PWM... (had inmiddels genoeg tijd eraan besteed :P

nu paar weken in gebruik, werkt leuk, zeker met het ingrijpen in de ventilatie, hiervoor heb ik de standaard remote control van ITHO gebruikt en hardware matig (draadjes geslodeerd aan de knopjes), verbonden met de CO2 meter, op de uitgang van de arduino heb ik kleine reedrelais gezet.

groet

Berichten: 1
Geregistreerd: 09 Jan 2021, 23:26

Re: CO2 meter met MH-Z19 sensor en ventilatie beinvloeding

Berichtdoor lbot » 10 Jan 2021, 12:51

Klopt het dat de hardware bestaat uit: Ic2 2x16 LCD display, RTC , MH-z19, 3-tal Leds, relais (en Arduino)?

Terug naar Afgeronde projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 3 gasten