From 68b77f660d8b622569a1ebb17932866afc3aa837 Mon Sep 17 00:00:00 2001 From: MaxQ22 <104859462+MaxQ22@users.noreply.github.com> Date: Sun, 15 May 2022 16:38:59 +0200 Subject: [PATCH] Adjustments to use the library with the ESP32 The original Arduino library for the MQ135 cannot be used with the ESP32 for several reasons. This fork is changed, to work with the ESP32. --- .gitignore | 4 + MQ135.cpp | 7 +- MQ135.h | 3 +- MQ135_Simulation.asc | 64 ++++++++++++ README.md | 76 +++++++++++--- Schematic.PNG | Bin 0 -> 4697 bytes examples/MQ135/MQ135.cpp | 139 ++++++++++++++++++++++++++ examples/MQ135/MQ135.h | 58 +++++++++++ examples/MQ135/MQ135.ino | 13 ++- examples/MQ135_DHTxx/MQ135_BME280.ino | 92 +++++++++++++++++ examples/MQ135_DHTxx/MQ135_DHTxx.ino | 57 ----------- 11 files changed, 434 insertions(+), 79 deletions(-) create mode 100644 .gitignore create mode 100644 MQ135_Simulation.asc create mode 100644 Schematic.PNG create mode 100644 examples/MQ135/MQ135.cpp create mode 100644 examples/MQ135/MQ135.h create mode 100644 examples/MQ135_DHTxx/MQ135_BME280.ino delete mode 100644 examples/MQ135_DHTxx/MQ135_DHTxx.ino diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..972181b --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +MQ135_Simulation.raw +MQ135_Simulation.net +MQ135_Simulation.log diff --git a/MQ135.cpp b/MQ135.cpp index 0de4d14..b59b74a 100755 --- a/MQ135.cpp +++ b/MQ135.cpp @@ -21,15 +21,17 @@ v1.0 - First release @brief Default constructor @param[in] pin The analog input pin for the readout of the sensor +@param[in] refvpin The analog input pin for the reference voltage measurement @param[in] rzero Calibration resistance at atmospheric CO2 level @param[in] rload The load resistance on the board in kOhm */ /**************************************************************************/ -MQ135::MQ135(uint8_t pin, float rzero, float rload) { +MQ135::MQ135(uint8_t pin, uint8_t refvpin, float rzero, float rload) { _pin = pin; _rzero = rzero; _rload = rload; + _refvpin = refvpin; } /**************************************************************************/ @@ -65,7 +67,8 @@ float MQ135::getCorrectionFactor(float t, float h) { /**************************************************************************/ float MQ135::getResistance() { int val = analogRead(_pin); - return ((1023./(float)val) - 1.)*_rload; + int refv = analogRead(_refvpin); + return _rload * ( refv * 0.00080586 * 2 - val * 0.00080586 ) / ( val * 0.00080586 ); } /**************************************************************************/ diff --git a/MQ135.h b/MQ135.h index 6a14f4f..ce1ce94 100755 --- a/MQ135.h +++ b/MQ135.h @@ -41,11 +41,12 @@ v1.0 - First release class MQ135 { private: uint8_t _pin; + uint8_t _refvpin; float _rload; // The load resistance on the board in kOhm float _rzero; // Calibration resistance at atmospheric CO2 level public: - MQ135(uint8_t pin, float rzero=76.63, float rload=10.0); + MQ135(uint8_t pin, uint8_t refvpin, float rzero=130.0, float rload=44.0); float getCorrectionFactor(float t, float h); float getResistance(); float getCorrectedResistance(float t, float h); diff --git a/MQ135_Simulation.asc b/MQ135_Simulation.asc new file mode 100644 index 0000000..ab4d5fc --- /dev/null +++ b/MQ135_Simulation.asc @@ -0,0 +1,64 @@ +Version 4 +SHEET 1 992 680 +WIRE 0 48 -32 48 +WIRE 96 48 80 48 +WIRE 224 48 96 48 +WIRE 432 48 224 48 +WIRE 352 80 64 80 +WIRE 96 112 96 48 +WIRE 224 112 224 48 +WIRE -32 128 -32 48 +WIRE 432 128 432 48 +WIRE 64 208 64 80 +WIRE 352 208 352 80 +WIRE 352 208 64 208 +WIRE 224 240 224 192 +WIRE 304 240 224 240 +WIRE 432 240 432 208 +WIRE 480 240 432 240 +WIRE 224 256 224 240 +WIRE 96 272 96 192 +WIRE 432 272 432 240 +WIRE 16 352 16 272 +WIRE 224 352 224 336 +FLAG -32 208 0 +FLAG 224 352 0 +FLAG 432 352 0 +FLAG 304 240 VSense +FLAG 480 240 VRef +FLAG 16 352 0 +SYMBOL voltage -32 112 R0 +SYMATTR InstName V1 +SYMATTR Value 5 +SYMBOL res 208 96 R0 +SYMATTR InstName RSense +SYMATTR Value {Rsense} +SYMBOL res 80 96 R0 +SYMATTR InstName RHeat +SYMATTR Value 33 +SYMBOL res 96 32 R90 +WINDOW 0 0 56 VBottom 2 +WINDOW 3 32 56 VTop 2 +SYMATTR InstName RPar+ +SYMATTR Value 0.5 +SYMBOL res 112 256 R90 +WINDOW 0 0 56 VBottom 2 +WINDOW 3 32 56 VTop 2 +SYMATTR InstName Rpar- +SYMATTR Value 0.5 +SYMBOL res 208 240 R0 +SYMATTR InstName RL +SYMATTR Value 44k +SYMBOL res 416 112 R0 +SYMATTR InstName R1 +SYMATTR Value 100k +SYMBOL res 416 256 R0 +SYMATTR InstName R2 +SYMATTR Value 100k +TEXT 584 56 Left 2 !.step param Rsense 24k 90k 1k +TEXT 582 96 Left 2 !.op +TEXT 136 96 Left 2 ;MQ135 +TEXT 104 232 Left 2 ;H +TEXT 104 64 Left 2 ;H +TEXT 232 64 Left 2 ;A +TEXT 232 224 Left 2 ;B diff --git a/README.md b/README.md index 65ca8d4..e037c1d 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,5 @@ -# MQ135 GAS SENSOR - -![arduino-library-badge](https://www.ardu-badge.com/badge/MQ135.svg?) ![latest version](https://img.shields.io/github/release/Phoenix1747/MQ135.svg?) ![issues](https://img.shields.io/github/issues/Phoenix1747/MQ135.svg?) ![open pr](https://img.shields.io/github/issues-pr-raw/phoenix1747/MQ135.svg?) - -Updated and improved Arduino library for the MQ135 gas/air quality sensor. - -This library is also available in the Arduino IDE, see [Arduino Library List](https://www.arduinolibraries.info/libraries/mq135). - -## Datasheet - -Can be found [here](https://www.olimex.com/Products/Components/Sensors/SNS-MQ135/resources/SNS-MQ135.pdf). +# MQ135 GAS SENSOR ESP32 Fork +This is a fork of the incredible Arduino Library for the MQ135 gas sensor by Phoenix1747, adopted for usage with the ESP32. Despite the inferior performance of the ADC (Analog to Digital Converter) of the ESP32 compared to the Atmel Chips on the Arduinos in terms of linearity and measurement accuracy, i wanted to use the MQ135 with the ESP32s ADC and transmit the values via WIFI. This needed two adjustments to the MQ135 library. First adjustment to be made is the change from a 10 bit ADC (as found on most Arduinos) to a 12 bit ADC, as present on the ESP32. The second adjustment to be made is the voltage level. The MQ135 sensor requires a 5V+-0.1V supply voltage. This means, the output signal needs to be adjusted, so that we get a 0 to 3.3V reading for the ESP32. The concept of this adjustment is to dimension the voltage divider in such a way, that the sense signal voltage swings between 0 and 3.3V. ## Application @@ -18,6 +9,8 @@ This type of sensor is used in air quality control equipments for buildings/offi This library has: - Corrections for temperature and humidity + - Compatibility with the ESP32 chip, using the Arduino Core + - Measurement of the Reference voltage to enable Kelvin-Sensing - Measurements: - getResistance - getCorrectedResistance @@ -26,7 +19,18 @@ This library has: - getRZero - getCorrectedRZero -## Calibration +## Library Usage + +## Installation +To install the library, just copy the MQ135.cpp and MQ135.h files to your .../arduino/libraries folder. + +Then include the MQ135.h file in your project + +```cpp +#include +``` + +### Calibration To get an accurate ppm reading it is important to calibrate the sensor. @@ -45,7 +49,51 @@ To finish the calibration process you now only need to pass your `RZERO` value t MQ135 gasSensor(PIN_MQ135, RZERO); ``` +### Sensing concept +The MQ135 sensor itself features 4 pins. Two pins are the 5V supply and ground for the heating element, the two are the connections to the variable resistance, that changes with gas concentration. One of those is connected to a 5V reference voltage and the other one is connected to a reference resistor, called RL in the datasheet. This is the actual measurement signal. The internal sense resistance of the sensor, that changes with gas concentration and the RL resistor form a voltage divider. Via backwards calculation of this voltage divider, the resistance of the sense resistor can be calculated. The MQ135 is wired in this application as shown in the following schematic: + + ![MQ135 Schematic](/Schematic.PNG) + +### Adjusting the sense signal to 3.3V +For usage with the ESP32 The RL reference resistor has to be determined, so that the measurement signal does not exceed 3.3V for the ESP32. As the minimal resistance of the sensor element is 30 kOhms, and the maximum allowed supply voltage is 5.1 V, we can determine the necessary value of the reference resistor. For this calculation, we have to take into account, that the 30 kOhms value is for 100 ppm NH3 gas concentration and it will go down to a factor of 0.8 of that value for higher gas concentrations. + +``` +RL = ( 3.3V * 30kOhm*0.8 ) / ( 5.1V - 3.3V ) = 44kOhm +``` + +While this value of reference resistor should be o.k. to be used with the ESP32, of course, to maximize sensitivity and resolution, it is best to measure each individual MQ135s R0 and calculate the corresponding RL. If the R0 of your particular sensor is at the maximum value given in the datasheet of 200 kOhm, the reference resisstor should be 293kOhm, to still get no output voltage above 3.3V and not waist a lot of the resoluation of the ESPs ADC. + +On the Arduino, the 5V supply voltage is also used as the reference voltage for the ADC converter. The original library uses this property, so that the reference voltage does not need to be measured. As the MQ135 needs to be supplied with 5V, according to the datasheet, this trick does not work anymore with the ESP32. So another voltage divider (R1 and R2 in the schematic above) is added, to divide the reference voltage by 2 and subsequently measure it with the ESP32 at Node Vref. + +This gives another possiblity to enhance the measurement. In the MQ135, the H+ and H- pins are used to supply the heating element, while the A and B pins are used to connect to the sense resistor, that changes with gas concentration. This principle is called a "Kelvin measurement" and prevents an influence of the high current draw of the heating element on the measurement. Unfortunatly, in most cheap MQ135 boards, the H+ and A pins are short circuited and connected via one pin only (VCC). This means, the huge current draw of the heating element (~140mA) leads to a voltage drop over the wires and the connectors. Those parasitic resistances are included in the schematic above as RPar+ and Rpar-. It is recommended to solder the R1/R2 divider directly to the A-pin of the actual MQ135 sensor on the break out board, as otherwise, this voltage drop of several millivolts leads to a measurement error. If the reference resistor is also populated on the break out board, it is recommended to unsolder this resistor, solder it only to the pad on the board, connecting to the B pin of the MQ135 and connect the other resistor terminal via a soldered jumper wire directly to GND of the ESP32. + +Using this schematic and measureing the VSense and VRef nodes with the ESP32s ADC, the sense resistor (Rsense) value can be calculated as follows: +``` +RSense = RL * ( VRef * 2 - VSense ) / VSense +``` + +### Adjusting for the 12-bit ADC +Adjusting the library to the 12-bit ADC of the ESP32 is trivial. In a 12bit-ADC of the ESP32, the measured voltage is calculated by the following formula: + +``` +V = 3.3 V/(4096-1) * Code +V = 0.00080586 * Code +``` + +So the sense resistance is calculated with: + +``` +RSense = RRef * ( VRefCode * 0.00080586 * 2 - VSenseCode * 0.00080586 ) / ( VSenseCode * 0.00080586 ) +``` + +This formula is implemented in the MQ135::getResistance() function. Additionally, a new parameter is added to the constructor of the MQ135 class, to pass the pin number, the VRef voltage is measured with. From there on, the original Arduino library is used unchanged, to calculate the actual gas concentration based on the measured sense resistance. + + +## Datasheet + +The datasheet of the MQ135 gas sennsor can be found [here](https://www.olimex.com/Products/Components/Sensors/SNS-MQ135/resources/SNS-MQ135.pdf). -## More Info +The example for the temperature and humidity copensation uses a BME280 to compensate for temperature and humidity effects. The datasheet of the BME280 can be found [here](https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf). To read out the values from the BME280, the Adafruit library is used in the example, which can be found [here](https://github.com/adafruit/Adafruit_BME280_Library). -https://hackaday.io/project/3475-sniffing-trinket/log/12363-mq135-arduino-library +For more information on the original Arduino library visit: +https://hackaday.io/project/3475-sniffing-trinket/log/12363-mq135-arduino-library \ No newline at end of file diff --git a/Schematic.PNG b/Schematic.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f5ecbd7fc405a198bb7726cc703e755b90576a4e GIT binary patch literal 4697 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 100 + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +/// Parameters for calculating ppm of CO2 from sensor resistance +#define PARA 116.6020682 +#define PARB 2.769034857 + +/// Parameters to model temperature and humidity dependence +#define CORA .00035 +#define CORB .02718 +#define CORC 1.39538 +#define CORD .0018 +#define CORE -.003333333 +#define CORF -.001923077 +#define CORG 1.130128205 + +/// Atmospheric CO2 level for calibration purposes +#define ATMOCO2 414.47 //Global CO2 Aug 2021 + +class MQ135 { + private: + uint8_t _pin; + uint8_t _refvpin; + float _rload; // The load resistance on the board in kOhm + float _rzero; // Calibration resistance at atmospheric CO2 level + + public: + MQ135(uint8_t pin, uint8_t refvpin, float rzero=117.0, float rload=44.0); + float getCorrectionFactor(float t, float h); + float getResistance(); + float getCorrectedResistance(float t, float h); + float getPPM(); + float getCorrectedPPM(float t, float h); + float getRZero(); + float getCorrectedRZero(float t, float h); +}; +#endif diff --git a/examples/MQ135/MQ135.ino b/examples/MQ135/MQ135.ino index 1a10497..6365208 100644 --- a/examples/MQ135/MQ135.ino +++ b/examples/MQ135/MQ135.ino @@ -6,15 +6,18 @@ Application They are used in air quality control equipments for buildings/offices, are suitable for detecting of NH3, NOx, alcohol, Benzene, smoke, CO2, etc - Original creator of this library: https://github.com/GeorgK/MQ135 + Original creator of this library: https://github.com/GeorgK/MQ135, example adapted by https://github.com/MaxQ22/MQ135 for the ESP32 */ -#define PIN_MQ135 A2 +//Define the pins, the MQ135 is connected to and the reference voltage is connected to +#define PIN_MQ135 35 +#define PIN_VREF 34 -MQ135 mq135_sensor(PIN_MQ135); +//Instance of the MQ135 sensor. The values for RL and RZero should be adjusted to the actual values of the used sensor and setup. My sensor happend to have a RZero of 130 kOhm and i used a 44 kOhm load resistor. +MQ135 mq135_sensor(PIN_MQ135, PIN_VREF, 130, 44); -float temperature = 21.0; // Assume current temperature. Recommended to measure with DHT22 -float humidity = 25.0; // Assume current humidity. Recommended to measure with DHT22 +float temperature = 21.0; // Assume current temperature. Recommended to measure with DHT22/BME280 or other temperture + humidity sensor +float humidity = 25.0; // Assume current humidity. Recommended to measure with DHT22/BME280 or other temperture + humidity sensor void setup() { Serial.begin(9600); diff --git a/examples/MQ135_DHTxx/MQ135_BME280.ino b/examples/MQ135_DHTxx/MQ135_BME280.ino new file mode 100644 index 0000000..8a96649 --- /dev/null +++ b/examples/MQ135_DHTxx/MQ135_BME280.ino @@ -0,0 +1,92 @@ +#include +#include + +/* MQ135 + DHT Temp Sensor + + Combination of the MQ135 air quality sensor and a Bosch BME280 sensor to accurately measure ppm values through the library correction. + Uses the Adafruit BME 280 library https://github.com/adafruit/Adafruit_BME280_Library + + Written by: https://github.com/MaxQ22/MQ135 based on the DHT11/22 example by https://github.com/Phoenix1747/MQ135 +*/ + +//Pin Definitions +#define SDA 23 +#define SCL 22 +#define PIN_MQ135 35 +#define PIN_VREF 34 + +//The Values for RZero and RL should be adjusted to the actual setup. My RZero was 130 kOhm and the used Load Resistor 44 kOhm +MQ135 mq135_sensor(PIN_MQ135, PIN_VREF, 130, 44); +//Instance of the BME280 +Adafruit_BME280 bme; + +float temperature, humidity, pressure; // Temp, Pres and Humid floats, will be measured by the BME280 + +void setup() { + Serial.begin(9600); + + //Initialize the I2C for the BME280 Sensor + pinMode(SDA, INPUT_PULLUP); + pinMode(SCL, INPUT_PULLUP); + Wire.begin(SDA, SCL); + + //Initialize the BME280 sensor. If it is not found, then display a error message + unsigned status; + status = bme.begin(0x76, &Wire); + + if (!status) + { + Serial.println(F("Could not find a valid BMP280 sensor, check wiring or " + "try a different address!")); + Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16); + Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n"); + Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n"); + Serial.print(" ID of 0x60 represents a BME 280.\n"); + Serial.print(" ID of 0x61 represents a BME 680.\n"); + } +} + +void loop() +{ + //Read temperature and humidity for the compensation and pressure just out of interest + humidity = bme.readHumidity(); + temperature = bme.readTemperature(); + pressure = bme.readPressure(); + + // Check if any reads failed and exit early (to try again). + if (isnan(humidity) || isnan(temperature) || isnan(pressure)) + { + Serial.println(F("Failed to read from BME280 sensor!")); + return; + } + + float rzero = mq135_sensor.getRZero(); + float correctedRZero = mq135_sensor.getCorrectedRZero(temperature, humidity); + float resistance = mq135_sensor.getResistance(); + float ppm = mq135_sensor.getPPM(); + float correctedPPM = mq135_sensor.getCorrectedPPM(temperature, humidity); + + Serial.print("MQ135 RZero: "); + Serial.print(rzero); + Serial.print("\t Corrected RZero: "); + Serial.print(correctedRZero); + Serial.print("\t Resistance: "); + Serial.print(resistance); + Serial.print("\t PPM: "); + Serial.print(ppm); + Serial.print("ppm"); + Serial.print("\t Corrected PPM: "); + Serial.print(correctedPPM); + Serial.print("ppm"); + Serial.print("\t Temperature: "); + Serial.print(temperature); + Serial.print("°C"); + Serial.print("\t Humidity: "); + Serial.print(humidity); + Serial.println("%"); + Serial.print("\t Pressure: "); + Serial.print(pressure); + Serial.println("Pa"); + + delay(300); +} diff --git a/examples/MQ135_DHTxx/MQ135_DHTxx.ino b/examples/MQ135_DHTxx/MQ135_DHTxx.ino deleted file mode 100644 index f54eed0..0000000 --- a/examples/MQ135_DHTxx/MQ135_DHTxx.ino +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include - -/* MQ135 + DHT Temp Sensor - - Combination of the MQ135 air quality sensor and a DHT11/22 temperature sensor to accurately measure ppm values through the library correction. - Uses the Adafruit DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library - - Written by: https://github.com/Phoenix1747/MQ135 -*/ - -#define PIN_MQ135 A2 // MQ135 Analog Input Pin -#define DHTPIN 2 // DHT Digital Input Pin -#define DHTTYPE DHT11 // DHT11 or DHT22, depends on your sensor - -MQ135 mq135_sensor(PIN_MQ135); -DHT dht(DHTPIN, DHTTYPE); - -float temperature, humidity; // Temp and Humid floats, will be measured by the DHT - -void setup() { - Serial.begin(9600); - - dht.begin(); -} - -void loop() { - humidity = dht.readHumidity(); - temperature = dht.readTemperature(); - - // Check if any reads failed and exit early (to try again). - if (isnan(humidity) || isnan(temperature)) { - Serial.println(F("Failed to read from DHT sensor!")); - return; - } - - float rzero = mq135_sensor.getRZero(); - float correctedRZero = mq135_sensor.getCorrectedRZero(temperature, humidity); - float resistance = mq135_sensor.getResistance(); - float ppm = mq135_sensor.getPPM(); - float correctedPPM = mq135_sensor.getCorrectedPPM(temperature, humidity); - - Serial.print("MQ135 RZero: "); - Serial.print(rzero); - Serial.print("\t Corrected RZero: "); - Serial.print(correctedRZero); - Serial.print("\t Resistance: "); - Serial.print(resistance); - Serial.print("\t PPM: "); - Serial.print(ppm); - Serial.print("ppm"); - Serial.print("\t Corrected PPM: "); - Serial.print(correctedPPM); - Serial.println("ppm"); - - delay(300); -}