Devices & Components
16x2 LCD display with I²C interface
MQ-131 LOW Gas Sensor
MQ136 Gas Sensor
MQ137 Gas Sensor
Gravity: Analog Propane Gas Sensor (MQ6) For Arduino
MQ4 Gas sensor
MQ-9 Gas Sensor
(MQ307A) Gas Sensor
MQ7 Gas sensor
MQ214
MQ135 Gas sensor
MQ-5 Gas Sensor
MQ-6 Gas Sensor
MQ303B Gas Sensır
MQ-31 HIGH Gas Sensor
MQ8 Gas sensor
MQ216 Gas Sensor
MQ138 Gas Sensor
20K Potantiometer
MQ2 gas sensor
MQ3 Gas sensor
MQ4 Gas sensor
MQ306A Gas Sensor
(MQ309A) Gas Sensor
Software & Tools
PlatformIO IDE
Arduino IDE
Project description
Code
Adjustable Air Quality Monitoring & Analysis Platform with Plug-UnPlug System
cpp
1#include <AirQuality.h> 2#include <Correction.h> 3#include <GasSensor.h> 4#include <SensorDefinitions.h> 5 6#include <LiquidCrystal_I2C.h> 7 8#define ADC_BIT_RESU (12) // for ESP32 9#define pin (35) // D35 (ADC1) 10#define pot (34) // D35 (ADC1) 11 12int Air, ppm; 13float sensorVal, temp, rh, correction; 14String selectedModel, mode; 15 16GasSensor sensor(ADC_BIT_RESU, pin); 17SensorModel* sensorModel = nullptr; 18 19String mqList1[] = { "MQ135", "MQ2", "MQ3", "MQ4", "MQ5", "MQ6", "MQ7", "MQ8", "MQ9", "MQ136", "MQ137", "MQ138", "MQ214", "MQ216" }; 20String mqList2[] = { "MQ303A", "MQ303B", "MQ306A", "MQ307A", "MQ309A" }; 21String mqList3[] = { "MQ131", "MQ131_LOW" }; 22 23int lcdColumns = 16; 24int lcdRows = 2; 25 26LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows); 27 28void setup() { 29 Serial.begin(115200); // for ESP32 30 sensor.begin(); 31 lcd.init(); 32 lcd.backlight(); 33 // WARNING: Please run the code after connecting the appropriate resistance specified 34 // in the Required_MQ_LoadResistor.ino file to the sensor mode you selected, 35 // otherwise the results will not reflect the reality. 36} 37 38void loop() { 39 int val = map(analogRead(pot), 0, (1 << ADC_BIT_RESU) - 1, 1, 21); 40 41 if (val >= 1 && val <= 14) selectedModel = mqList1[val - 1]; 42 else if (val >= 15 && val <= 19) selectedModel = mqList2[val - 15]; 43 else if (val >= 20 && val <= 21) selectedModel = mqList3[val - 20]; 44 45 sensorModel = getSensorModel(selectedModel); 46 if (!sensorModel) { 47 Serial.println("Sensor model not found."); 48 while (true); 49 } 50 Serial.print("Selected sensor: "); 51 Serial.println(sensorModel->model); 52 mode = sensorModel->model; 53 54 temp = 20.0; // DHT22 is recommended °C (Celsius) 55 rh = 33.0; // DHT22 is recommended % (Relative Humidity) 56 57 /* NOTE: The temperature and humidity of the environment do not have a direct effect on the ppm value of the environment. 58 On the other hand, the temperature and humidity of the environment will cause the sensor to detect ppm more or less than normal. 59 The amount of deviation of the erroneous measurement caused by environmental conditions is modeled by the data graphs of each sensor. 60 In this case, this error margin calculated with the Correction Coefficient, known as Correction.h, is necessary to correct the incorrect ppm value. 61 62 At 20°C, 33% RH, correction = 1.0 is the environmental condition where the sensor accuracy rate is highest. 63 If the correction coefficient is greater than 1.0, the sensor will measure values lower than the true value, and if it is less than 1.0, 64 it will measure values higher than the true value. Temperature and humidity are inversely proportional to the correction coefficient. */ 65 66 sensorVal = sensor.read(); 67 correction = sensorModel->useCorrection ? calculateCorrection(temp, rh, selectedModel) : 1.0; 68 69 Air = sensorVal > 0 && mode != "MQ307A" ? airConcentration(mode, sensorVal) * correction : 0; 70 71 if (mode == "MQ3") Air *= 50.0; // mg/L --> ppm 72 if (mode == "MQ131_LOW") Air *= 0.02; // ppb --> ppm 73 74 lcd.setCursor(0, 0); 75 lcd.print("Air: " + String(Air)); 76 77 lcd.setCursor(16 - mode.length(), 0); 78 lcd.print(mode); 79 80 lcd.setCursor(0, 1); // Correction --> CR 81 lcd.print("CR: x" + String(correction, 4)); 82 83 lcd.setCursor(13, 1); 84 lcd.print("ppm"); 85 86 delay(3000); 87 lcd.clear(); 88 89 for (byte i = 0; i < sensorModel->gasCount; i++) { 90 const GasModel& gasType = sensorModel->gasList[i]; 91 92 if (isMQSensor(mode, mqList1, sizeof(mqList1) / sizeof(mqList1[0]))) { 93 float RsRocalValue = sensor.calculateCalValue1(gasType.a, gasType.b, sensorModel->calibrateAir, gasType.minPpm, gasType.maxPpm); 94 ppm = sensor.calculateRsRoPPM(sensorVal, correction, gasType.a, gasType.b, RsRocalValue, sensorModel->air, sensorModel->rlcal, gasType.maxPpm); 95 if (mode == "MQ3") ppm *= 50.0; 96 } 97 98 else if (isMQSensor(mode, mqList2, sizeof(mqList2) / sizeof(mqList2[0]))) { 99 float RsRscalValue = sensor.calculateCalValue2(gasType.a, gasType.b, sensorModel->calibrateAir, gasType.minPpm, gasType.maxPpm); 100 if (mode == "MQ306A" && i == 0) RsRscalValue = 0.873876; 101 if (mode == "MQ307A" && i == 1) RsRscalValue = 0.999619; 102 if (mode == "MQ309A" && i >= 2) RsRscalValue = 0.83393; 103 ppm = sensor.calculateRsRsPPM(sensorVal, gasType.a, gasType.b, RsRscalValue, sensorModel->rlcal, gasType.maxPpm); 104 } 105 106 else if (isMQSensor(mode, mqList3, sizeof(mqList3) / sizeof(mqList3[0]))) { 107 float RoRscalValue = sensor.calculateCalValue1(gasType.a, gasType.b, sensorModel->calibrateAir, gasType.minPpm, gasType.maxPpm); 108 ppm = sensor.calculateRoRsPPM(sensorVal, correction, gasType.a, gasType.b, RoRscalValue, sensorModel->air, sensorModel->rlcal, gasType.maxPpm); 109 if (mode == "MQ131_LOW") ppm *= 0.02; 110 } 111 112 lcd.setCursor(0, 0); 113 lcd.print("Air: " + String(Air)); 114 115 lcd.setCursor(16 - mode.length(), 0); 116 lcd.print(mode); 117 118 lcd.setCursor(0, 1); 119 lcd.print(String(gasType.gasName) + ": " + String(ppm)); 120 121 lcd.setCursor(13, 1); 122 lcd.print("ppm"); 123 124 delay(1500); 125 lcd.clear(); 126 } 127 128 Serial.println("----------"); 129 delay(5000); 130}
Documentation
ESP32 Circut Diagram
esp32circut.png

Figure-1 Required Voltages and Resistors for MQ Sensors
fig1.png

Comments
Only logged in users can leave comments