Project tutorial

Wooden Chest Air Quality Monitor © GPL3+

A compact air quality, temperature and humidity monitor enclosed in a small wooden chest, with a four-row LCD display.

  • 748 views
  • 2 comments
  • 7 respects

Components and supplies

Apps and online services

About this project

prototype

A project completed to measure the air condition in a diesel polluted building. Then the final design enclosed in a wooden box to demonstrate its function to apprentices for inspiration for their projects.

testing sensitivity to fumes using a permanent marker pen

Finished

Code

Final codeArduino
reads values from CCS811 and DHT11 sensors and outputs to a 4 row LCD and serial monitor
//***************************************************************************
//  This is a library for the CCS811 air 

//  This sketch reads the sensor

//  Designed specifically to work with the Adafruit CCS811 breakout
//  ----> http://www.adafruit.com/products/3566

 // These sensors use I2C to communicate. The device's I2C address is 0x5A 

#include <SD.h>            // sd card
#include <Wire.h>
#include "RTClib.h"      // real time clock
#include <DHT.h>                                                   // load lib dht11
#include "Adafruit_CCS811.h"
#include "Arduino.h"
#include "LiquidCrystal_PCF8574.h"

#define LCD_ADDRESS 0x27                                       // Define LCD characteristics
#define LCD_ROWS 4
#define LCD_COLUMNS 20
#define SCROLL_DELAY 150
#define BACKLIGHT 255                                         // object initialization
#define dht_apin 2
#define dht_type DHT11

int n = 1;
int val;                                                   // A simple data logger for the Arduino analog pins  

#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)

                                                      // how many milliseconds before writing the logged data permanently to disk
                                                      // set it to the LOG_INTERVAL to write each time (safest)
                                                      // set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to 
                                                      // the last 10 reads if power is lost but it uses less power and is much faster!

#define SYNC_INTERVAL 10000 // mills between calls to flush() - to write data to the card 600000 = 10 minutes
uint32_t syncTime = 0; // time of last sync()


RTC_DS1307 RTC;                                         // define the Real Time Clock object


const int chipSelect = 10;                             // for the data logging shield, we use digital pin 10 for the SD cs line


DHT dht(dht_apin, dht_type);                          // sensor pin S to pin11

LiquidCrystal_PCF8574 lcdI2C;
Adafruit_CCS811 ccs;


File logfile;

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


void setup() {

 Serial.begin(9600);

  // 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)) {
    error("Card failed, or not present");
  }
  Serial.println(F("card initialized."));
  
  // 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) {
    error("couldnt create file");
  }
  
  Serial.print(F("Logging to: "));
  Serial.println(filename);

  // connect to RTC
  Wire.begin();  
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println(F("RTC failed"));
#endif  //ECHO_TO_SERIAL
  }
  

  logfile.println("datetime,co2  ,tvoc  ,Humidity  ,Temperature ");    
//#if ECHO_TO_SERIAL
//  Serial.println("..........,......,datetime,.....,......,......");
//#endif //ECHO_TO_SERIAL
 
  // If you want to set the aref to something other than 5v
  analogReference(EXTERNAL);
  lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, BACKLIGHT); 
  Serial.println(F("CCS811 test"));
  lcdI2C.print("     CCS811 test" );
  lcdI2C.setCursor (0,1); 
  lcdI2C.print("     warming up" );
  lcdI2C.setCursor (0,2);
  lcdI2C.print("data logger file No." );
  lcdI2C.setCursor (0,3);
  lcdI2C.println(filename);
  if(!ccs.begin()){
  Serial.println(F("Failed to start sensor! Please check your wiring."));
  while(1);
  }
  //calibrate temperature sensor
  while(!ccs.available());
  float temp = ccs.calculateTemperature();
  ccs.setTempOffset(temp - 25.0);

 delay(10000);                       // wait for 10 seconds
   lcdI2C.clear();                          // Clear LCD screen.
  
}

void loop() {
    float h = dht.readHumidity();
    float f = dht.readTemperature();
    if(ccs.available()){
    float temp = ccs.calculateTemperature();
    if(!ccs.readData()){
     
DateTime now;
 
  delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));   // delay for the amount of time we want between readings
   
  now = RTC.now();  // fetch the time

 int H = now.hour(); // Get the hours right now and store them in an integer called h
 int M = now.minute(); // Get the minutes right now and store them in an integer called m
 int S = now.second(); // Get the seconds right now and store them in an integer called s
  
  logfile.print(now.year(), DEC);
  logfile.print("/");
  logfile.print(now.month(), DEC);
  logfile.print("/");
  logfile.print(now.day(), DEC);
  logfile.print(" ");
  if (H<10){   // Add a zero, if necessary, as above
  logfile.print(0);
 }
  logfile.print(now.hour(), DEC);
  logfile.print(":");
  if (M<10){   // Add a zero, if necessary, as above
  logfile.print(0);
 }
  logfile.print(now.minute(), DEC);
  logfile.print(":");
  if (S<10){   // Add a zero, if necessary, as above
  logfile.print(0);
 }
  logfile.print(now.second(), DEC);
  logfile.print('"');
  Serial.print('"');
  Serial.print(now.year(), DEC);
  Serial.print("/");
  Serial.print(now.month(), DEC);
  Serial.print("/");
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  if (H<10){   // Add a zero, if necessary, as above
  Serial.print(0);
 }
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  if (M<10){   // Add a zero, if necessary, as above
  Serial.print(0);
 }
  Serial.print(now.minute(), DEC);
  Serial.print(F(":"));
  if (S<10){   // Add a zero, if necessary, as above
  Serial.print(0);
 }
  Serial.print(now.second(), DEC);
  Serial.print(F("    "));
  Serial.print(F("CO2: "));
  Serial.print(ccs.geteCO2());
  Serial.print(F("ppm, TVOC: "));
  Serial.print(ccs.getTVOC());
  Serial.print(F("ppb   Temp:"));
  Serial.println(f);                          // temp from dht11
    
    
    lcdI2C.setCursor (0,0);  
    lcdI2C.print ("CO2  ");  
    lcdI2C.setCursor (5,0);  
    lcdI2C.print ("       ");
    lcdI2C.setCursor (5,0); 
    lcdI2C.print(ccs.geteCO2());              // Print print String to LCD on first line
    lcdI2C.setCursor (0,1);                    // Set cursor at the begining of line 2
    lcdI2C.print ("tVOC ");
    lcdI2C.print(ccs.getTVOC());          // Print print String to LCD on second line
    lcdI2C.print ("     ");
    lcdI2C.setCursor (12,1); 
    if (H<10){   // Add a zero, if necessary, as above
    lcdI2C.print(0);
    }
    lcdI2C.print(now.hour(), DEC);
    lcdI2C.print (":");
    if (M<10){   // Add a zero, if necessary, as above
    lcdI2C.print(0);
 }
    lcdI2C.print(now.minute(), DEC);
    lcdI2C.print (":");
    if (S<10){   // Add a zero, if necessary, as above
    lcdI2C.print(0);
 }
   lcdI2C.print(now.second(), DEC); 
   lcdI2C.setCursor (0,2);  
   lcdI2C.print ("Humidity    ="); // print on the lcd Humidity = 
   lcdI2C.print(h); // to print the humidity
   lcdI2C.print("% "); //print "percentage" symbol
   lcdI2C.setCursor (0,3); 
   lcdI2C.print("Temperature ="); // print on the lcd temp = 
   lcdI2C.print (f); // print on the lcd temperture
   lcdI2C.print((char)223); // print "degrees" symbol 
   lcdI2C.print("C"); // print "C" with spaces after to fill 20 character line

  
  logfile.print(", ");    
  logfile.print(ccs.geteCO2());
  logfile.print(",");    
  logfile.print(ccs.getTVOC());
  logfile.print(",");
  logfile.print(h);
  logfile.print(",");
  logfile.print(f);
  logfile.println();


  
  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();
  
  // blink LED to show we are syncing data to the card & updating FAT!
 
  logfile.flush();


    
    }
    else{
      Serial.println(F("ERROR!"));
      while(1);
    }
  }
 
}

Schematics

Schematic off Fritzing
Schematic off Fritzing showing data logger and sensors fitted to an arduino uno
Capture off fritzing yxwkogotqw
fritzing file
Fritzing is an open-source hardware initiative that makes electronics accessible as a creative material for anyone
complete_ccs811_dht11_lcd_logger_dXV4NpgvHR.fzz

Comments

Similar projects you might like

Arduino Bluetooth Basic Tutorial

by Mayoogh Girish

  • 455,615 views
  • 42 comments
  • 240 respects

Home Automation Using Raspberry Pi 2 And Windows 10 IoT

Project tutorial by Anurag S. Vasanwala

  • 288,865 views
  • 96 comments
  • 676 respects

Security Access Using RFID Reader

by Aritro Mukherjee

  • 231,168 views
  • 38 comments
  • 241 respects

OpenCat

Project in progress by Team Petoi

  • 199,014 views
  • 155 comments
  • 1,384 respects
Add projectSign up / Login