CO2 mērītājs

Slēguma shēma

Jau sen bija vēlme nomērīt ikdienas CO2 līmeni dzīvoklī. It īpaši tagad, kad 2 pieaugušie strādājam no mājām. Maksāt par Aranet4 baigi nebija vēlmes, bet ņemšanās ap elektroniku man vienmēr bijis labs brīvā laika pavadīšanas veids. Ņemot piemēru no šī raksta, uzbūvēju pats savu mērītāju.

Par pamatu ņēmu tajā  pašā rakstā minētās izejvielas – populāro un salīdzinoši lēto MH-Z19B sensoru, Arduino Pro Micro (ATmega32U4), OLED ekrānu, plastmasas korpusu, bateriju turētāju, slēdzi, divus 5.1k rezistorus un 47nF kondensatoru. Kopējās izmaksas ap 30 EUR.

Apvienojot savas “profesionālās” lodēšanas prasmes un LEGO likšanas tehniku galu galā sanāca ne pārāk estētisks, bet lietošanā ērts CO2 mērītājs.

Secinājumi un novērojumi pēc 2 nedēļu ilgas ikdienas lietošanas:

  • Arduino varēju ievietot korpusā tā, lai no ārpuses varētu pieslēgties Micro USB ligdzai, ja nu rodas vēlme turēt visu laiku ieslēgtu, vai arī uzlabot programmas kodu.
  • Lai sensors nokalibrētos, bija nepieciešams savienot Hd un GND pinus uz 10s un atstāt sensoru uz diennakti ieslēgtu.
  • Ja baterijas gandrīz izlādējušās, tad senors rādīs 400PPM visu laiku, jo pietrūkst jaudas. Sākumā domāju, ka jākalibrē pa jaunam.
  • 3 cilvēkiem brīvdienu vakaros izdevās CO2 līmenī dzīvojamā istabā uzcelt pat līdz 1400ppm, kā rezultātā izdomāju veidu, kā uzlabot gaisa kvalitāti – sakārtot ventilāciju. Noslēgtu ventilācijas difuzoru aizvietot ar vārstu, kas pie ieslēgta tvaika nosūcēja nobloķē tvaika ieplūšanu atpakaļ telpā. Kad tvaika nosūcēju izslēdz, tad vārsts atveras un nodrošina dabisku gaisa nosūci no telpas. Svaigā gaisa pieplūdi nodrošina aiz radiatoriem montēts āra gaisa pieplūdes risinājums.
  • Pēc ventilācijas uzlabošanas CO2 līmenis vairs neuzkāpj augstāk par 1000ppm.

Arduino programmas kods ņemts no sākumā minētā bloga. Iztulkoju tik pa savam.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

#define pwmPin 7
int preheatSec = 120;
int prevVal = LOW;
long th, tl, h, l, ppm = 0;

void PWM_ISR() {
  long tt = millis();
  int val = digitalRead(pwmPin);
  
  if (val == HIGH) {    
    if (val != prevVal) {
      h = tt;
      tl = h - l;
      prevVal = val;
    }
  }  else {    
    if (val != prevVal) {
      l = tt;
      th = l - h;
      prevVal = val;
      ppm = 2000 * (th - 2) / (th + tl - 4);      
    }
  }
}

void setup()   {     
  Serial.begin(115200);
  pinMode(pwmPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(pwmPin), PWM_ISR, CHANGE);  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x64)
  display.setTextColor(WHITE);
}

void displayPreheating(int secLeft) {
  display.setTextSize(2);    
  display.println("IESILDOS..");
  display.setTextSize(1);    
  display.println();    
  display.setTextSize(5);          
  display.print(" ");
  display.print(secLeft);  
  display.display();   
}

void displayPPM(long ppm) {
  display.setTextSize(2);    
  display.println("CO2    PPM");    
  display.setTextSize(1);    
  display.println();    
  display.setTextSize(4);    
  if (ppm < 1000) {
    display.print(" ");
  }
  display.print(ppm);  
  display.println();
  if (ppm < 1000) {
    display.setTextSize(1);    
    display.println("SUPER LABS GAISS");
  }
  if ((ppm > 1000) && (ppm < 1400)) {
    display.setTextSize(1);    
    display.println("PA VIDAM");
  }
  if (ppm > 1400) {
    display.setTextSize(1);    
    display.println("ATVER LOGU!");
  }
  display.display();
  Serial.println(ppm);
}

void loop() {    
    display.clearDisplay(); 
    display.setCursor(0,0); 
    if (preheatSec > 0) {
      displayPreheating(preheatSec);       
      preheatSec--;
    }
    else {      
      displayPPM(ppm);
    }
    delay(1000);  
}