Now that it is very important to know the saturation levels of the environment for example in the workplace, I started to search the Internet if there would be any sensor that could be used with Arduino to know the levels of CO2, luckily there was a sensor that measures the air quality, the sensor in question is the MQ-135, as you can see in its data sheet, this sensor can measure certain substances, such as NH3, alcohol, benzene, smoke, CO2, etc., that's how I found this sensor, now it was a matter of finding out how you could use this sensor with Arduino.
Knowing that there was the opportunity to use it with our Arduino, the first thing I looked for was, the safety limits in parts per million (ppm) of CO2 for homes, rooms and buildings, according to different studies these levels can range between 400 and 800 ppm. Knowing the correct sensor and the safety levels, it was time to design how this could be implemented in a useful project, that would show us this information and thinking, that would also inform us of the temperature and humidity.
So the mission of this project will be the following, it should measure the concentration in parts per million of CO2, show it on a screen and warn us sonorously in case it reaches a dangerous concentration, also inform us of the temperature and humidity, wanting to extend the life of the screen, I thought it would be a good idea to put three LEDs of different colors to have a quick visual information of the level of CO2 concentration without the need to see the data. With all this we get down to work.
The materials needed for this project are:
- Arduino NANO
- Air quality sensor MQ-135
- Temperature and humidity sensor DHT-11
- MT3608 DC-DC adapter
- 1 red LED
- 1 yellow LED
- 1 green LED
- Two-color OLED I2C 128x64 pixel display 1.3 inches
- 2 1K resistors
- 1 resistor of 220 ohms
- 1 buzzer
The required software is:
- Arduino IDE
- MQ135_calibration sketch
- CO2_monitor sketch
- MQ135 library
- DHT-11 library
- Wire library
- Adafruit_GFX and Adafruit_SSD1306 library
Description of the circuit operation
The operation of this circuit is very simple, the MQ-135 sensor measures the concentration in parts per million of CO2, the DHT-11 sensor measures both the temperature and the existing humidity, these three data are sent to a bicolor OLED screen of 0.96 inches to show us each value for 3 seconds at intervals of 1 minute and the screen remains off that time, these time values can be configured. While the screen remains off the three LEDs visually inform us of the existing CO2 levels, the green LED remains on if the concentration is equal to or less than 550, the yellow LED will remain on if the concentration is between 551 and 799 parts per million of CO2 and the red LED will turn on along with a buzzer sound when the concentration exceeds 799 parts per million, we can also configure these three levels.
Preparation and adjustment of the atmospheric CO2 level reference of the RZERO resistor
The first thing to do is to prepare the MQ-135 sensor to read the correct values that we will use in the next step, to do this, we must leave for about 2 hours the sensor powered with 5 volts when the sensor is new, to remove impurities that have been generated during its manufacture, once this is done the ideal is to make the reference adjustment of the RZERO resistor in the final circuit, as it will be done with the supply and working voltages that normally have and the resulting measurement will be optimal.
The purpose of this calibration is to adjust the resistance of the atmospheric CO2 level until the MQ-135 sensor reads a concentration between 300 and 450 ppm, this is the normal concentration of this gas in the environment. It is very important to supply 5 VDC independently to the sensor, since it consumes 850 mW.
When we have everything connected, we run the Arduino IDE, load and run the scketch "MQ135_calibration.ino", previously we had to load the MQ135 library. We open the Serial Monitor and observe the ppm reading value; we must modify and save the RZERO value in the MQ135.h file in the Arduino IDE libraries folder until the ppm reading is the one we want to leave as the working reference of the circuit. The value to be modified is the one colored in green (22500 value).
/// Calibration resistance at atmospheric CO2 level /// Modify this value until ppm value is 450 #define RZERO 22500
To make the adjustment, we must change the value of RZERO, save the modifications of the MQ135.h file of the library in its folder of the Arduino IDE and reload the calibration sketch, check the new value of the CO2 concentration in the Serial Monitor and repeat the process again to adjust the RZERO with the value with which we want to leave as a reference of the CO2 concentration in the air for the warning limits in the sketch of our project.
MQ135_calibration.ino sketch
#include "MQ135.h" #define RZERO 1 MQ135 gasSensor = MQ135(A0); int val; int sensorPin = A0; int sensorValue = 0; void setup() { Serial.begin(115200); pinMode(sensorPin, INPUT); } void loop() { val = analogRead(A0); Serial.print ("raw = "); Serial.println (val); float zero = gasSensor.getRZero(); Serial.print ("rzero: "); Serial.println (zero); float ppm = gasSensor.getPPM(); Serial.print ("ppm: "); Serial.println (ppm); delay(2000); }
C02_monitor.ino sketch
/*** Spain_mtg 31_10_2021 ***/ /************* Necessary libraries for the project **************************/ #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <DHT.h> #include "pitches.h" /************* Screen parameters ********************************************/ #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); /****** Humidity and temperature sensor DHT-11 paramters and variables *****/ #define DHTPIN 2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); float t, h; /****************** MQ-135 sensor parameteres and variables ****************/ #define RZERO 1 #include "MQ135.h" MQ135 gasSensor = MQ135(A0); int val; int sensorPin = A0; int sensorValue = 0; float ppm, zero; /***************** LEDs ****************************************************/ #define led_verde 3 #define led_amarillo 4 #define led_rojo 5 unsigned long tiempo_anterior; // Time counter /*********************** SETUP BLOCK ***************************************/ void setup( ) { Serial.begin(115200); dht.begin(); // DHT-11 initialization if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Checking display present Serial.println(F("SSD1306 allocation failed")); for(;;); } delay(2000); display.clearDisplay(); // Initialization screen and display.setTextColor(WHITE); // config text color pinMode(sensorPin, INPUT); // MQ-135 pin data pinMode(led_verde, OUTPUT); pinMode(led_amarillo, OUTPUT); pinMode(led_rojo, OUTPUT); digitalWrite(led_verde, LOW); digitalWrite(led_amarillo, LOW); digitalWrite(led_rojo, LOW); } /*********************** LOOP BLOCK *************************************/ void loop( ) { t = dht.readTemperature(); // Read temperature h = dht.readHumidity(); // Read Humidity if (isnan(h) || isnan(t)) { // If there aren't temperature and Serial.println("Fallo de lectura del sensor DHT !!!"); // humidity read, show message to inform } val = analogRead(A0); // CO2 read zero = gasSensor.getRZero(); // Calibration value for the MQ-135 sensor ppm = gasSensor.getPPM(); // Formula in the library for obtaín the ppm of CO2 chequeo_led (); // Go and run to LEDs check method Serial.print( "T = " ); // Show values by the Serial Port Serial.print(t); Serial.print(" ºC, H = "); Serial.print(h); Serial.print( "%, " ); Serial.print ("raw = "); Serial.print (val); Serial.print (", rzero: "); Serial.print (zero); Serial.print (", ppm: "); Serial.println (ppm); delay (1000); if ( millis()-tiempo_anterior >= 60000) { // If the time past is most or equal than 60 sg encendido_pantalla(); // Execute the turn on screen method. tiempo_anterior = millis(); // Save the actual time. } } void chequeo_led() { if (ppm >= 800) { // If the CO2 concentration is equal o most than 800 digitalWrite(led_rojo, HIGH); // Turn on de red LED tone(8, NOTE_C5, 5000); // Buzzer sound display.clearDisplay(); // Set the screen parameters to show the PPM value display.setTextSize(2); display.setCursor(7,0); display.print("CO2 (PPM):"); display.setTextSize(3); display.setCursor(40,35); display.print(ppm,0); display.display(); delay(10000); } else { digitalWrite(led_rojo, LOW); display.clearDisplay(); display.display(); } if (ppm >= 551 && ppm <= 799) { digitalWrite(led_amarillo, HIGH); // The yellow LED turno on if the CO2 concentration } else { digitalWrite(led_amarillo, LOW); } // is between 551 and 799 if (ppm <= 550) { digitalWrite(led_verde, HIGH); // The green LED turn on only when the CO2 } else { digitalWrite(led_verde, LOW); } // concentration is most low than 551 } void encendido_pantalla() { // Turn on screen method display.clearDisplay(); // Set the screen parameters and show the PPM value display.setTextSize(2); display.setCursor(7,0); display.print("CO2 (PPM):"); display.setTextSize(3); display.setCursor(40,35); display.print(ppm,0); display.display(); delay(3000); display.clearDisplay(); // Set the display parameters and show the Humidity value display.setTextSize(2); display.setCursor(20,0); display.print("HUMEDAD:"); display.setTextSize(3); display.setCursor(20,35); display.print(h,1); display.setCursor(90,35); display.print("%"); display.display(); delay(3000); display.clearDisplay(); // Set the display parameters and show the Temperature value display.setTextSize(2); display.setCursor(40,0); display.print("TEMP:"); display.setTextSize(3); display.setCursor(5,35); display.print(t,1); display.setCursor(85,35); display.cp437(true); display.write(167); display.setCursor(107,35); display.print("C"); display.display(); delay(3000); display.clearDisplay(); display.display(); }
Project images