miguel5612 / MQSensorsLib

We present a unified library for MQ sensors, this library allows to read MQ signals easily from Arduino, Genuino, ESP8266, ESP-32 boards whose references are MQ2, MQ3, MQ4, MQ5, MQ6, MQ7, MQ8, MQ9, MQ131, MQ135, MQ136, MQ303A, MQ309A.
MIT License
169 stars 64 forks source link

Sensor won't finish the Calibration process if done in clean air. #67

Open LloydAlbin opened 1 year ago

LloydAlbin commented 1 year ago

Describe the bug When using the sample code for ESP32 and updating it for the MQ135 per the MQ135-all sample code, I run into the "Warning: Conection issue, R0 is infinite (Open circuit detected) please check your wiring and supply" unless I use a cigarette lighter's gas in front of the sensor during the calibration process.

Code

#include "Arduino.h"
#include <WiFi.h>

const char* ssid = ""; // Wifi SSID
const char* password = ""; // Wifi Password

//Include the library
#include <MQUnifiedsensor.h>
/************************Hardware Related Macros************************************/
#define         Board                   ("ESP-32") // Wemos ESP-32 or other board, whatever have ESP32 core.

//https://www.amazon.com/HiLetgo-ESP-WROOM-32-Development-Microcontroller-Integrated/dp/B0718T232Z (Although Amazon shows ESP-WROOM-32 ESP32 ESP-32S, the board is the ESP-WROOM-32D)
#define         Pin                     (32) //check the esp32-wroom-32d.jpg image on ESP32 folder 

/***********************Software Related Macros************************************/
#define         Type                    ("MQ-135") //MQ2 or other MQ Sensor, if change this verify your a and b values.
#define         Voltage_Resolution      (3.3) // 3V3 <- IMPORTANT. Source: https://randomnerdtutorials.com/esp32-adc-analog-read-arduino-ide/
#define         ADC_Bit_Resolution      (12) // ESP-32 bit resolution. Source: https://randomnerdtutorials.com/esp32-adc-analog-read-arduino-ide/
#define         RatioMQ135CleanAir      (3.6) //RS / R0 = 9.83 ppm
/*****************************Globals***********************************************/
MQUnifiedsensor MQ135(Board, Voltage_Resolution, ADC_Bit_Resolution, Pin, Type);
/*****************************Globals***********************************************/

void setup()
{

  //Init the serial port communication - to debug the library
  Serial.begin(9600); //Init serial port
  delay(10);

  //Set math model to calculate the PPM concentration and the value of constants
  MQ135.setRegressionMethod(1); //_PPM =  a*ratio^b

  /*****************************  MQ Init ********************************************/ 
  //Remarks: Configure the pin of arduino as input.
  /************************************************************************************/ 
  MQ135.init(); 
  /* 
    //If the RL value is different from 10K please assign your RL value with the following method:
    MQ135.setRL(10);
  */
  /*****************************  MQ CAlibration ********************************************/ 
  // Explanation: 
  // In this routine the sensor will measure the resistance of the sensor supposedly before being pre-heated
  // and on clean air (Calibration conditions), setting up R0 value.
  // We recomend executing this routine only on setup in laboratory conditions.
  // This routine does not need to be executed on each restart, you can load your R0 value from eeprom.
  // Acknowledgements: https://jayconsystems.com/blog/understanding-a-gas-sensor
  Serial.print("Calibrating please wait.");
  float calcR0 = 0;
  for(int i = 1; i<=10; i ++)
  {
    MQ135.update(); // Update data, the arduino will read the voltage from the analog pin
    calcR0 += MQ135.calibrate(RatioMQ135CleanAir);
    Serial.print(".");
  }
  MQ135.setR0(calcR0/10);
  Serial.println("  done!.");

  if(isinf(calcR0)) {Serial.println("Warning: Conection issue, R0 is infinite (Open circuit detected) please check your wiring and supply"); while(1);}
  if(calcR0 == 0){Serial.println("Warning: Conection issue found, R0 is zero (Analog pin shorts to ground) please check your wiring and supply"); while(1);}
  /*****************************  MQ CAlibration ********************************************/ 
  Serial.println("** Values from MQ-135 ****");
  Serial.println("|    CO   |  Alcohol |   CO2  |  Toluen  |  NH4  |  Aceton  |");  
}

void loop() {
  MQ135.update(); // Update data, the arduino will read the voltage from the analog pin

  MQ135.setA(605.18); MQ135.setB(-3.937); // Configure the equation to calculate CO concentration value
  float CO = MQ135.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ135.setA(77.255); MQ135.setB(-3.18); //Configure the equation to calculate Alcohol concentration value
  float Alcohol = MQ135.readSensor(); // SSensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ135.setA(110.47); MQ135.setB(-2.862); // Configure the equation to calculate CO2 concentration value
  float CO2 = MQ135.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ135.setA(44.947); MQ135.setB(-3.445); // Configure the equation to calculate Toluen concentration value
  float Toluen = MQ135.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ135.setA(102.2 ); MQ135.setB(-2.473); // Configure the equation to calculate NH4 concentration value
  float NH4 = MQ135.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup

  MQ135.setA(34.668); MQ135.setB(-3.369); // Configure the equation to calculate Aceton concentration value
  float Aceton = MQ135.readSensor(); // Sensor will read PPM concentration using the model, a and b values set previously or from the setup
  Serial.print("|   "); Serial.print(CO); 
  Serial.print("   |   "); Serial.print(Alcohol);
  // Note: 400 Offset for CO2 source: https://github.com/miguel5612/MQSensorsLib/issues/29
  /*
  Motivation:
  We have added 400 PPM because when the library is calibrated it assumes the current state of the
  air as 0 PPM, and it is considered today that the CO2 present in the atmosphere is around 400 PPM.
  https://www.lavanguardia.com/natural/20190514/462242832581/concentracion-dioxido-cabono-co2-atmosfera-bate-record-historia-humanidad.html
  */
  Serial.print("   |   "); Serial.print(CO2 + 400); 
  Serial.print("   |   "); Serial.print(Toluen); 
  Serial.print("   |   "); Serial.print(NH4); 
  Serial.print("   |   "); Serial.print(Aceton);
  Serial.println("   |"); 
  /*
    Exponential regression:
  GAS      | a      | b
  CO       | 605.18 | -3.937  
  Alcohol  | 77.255 | -3.18 
  CO2      | 110.47 | -2.862
  Toluen  | 44.947 | -3.445
  NH4      | 102.2  | -2.473
  Aceton  | 34.668 | -3.369
  */

  delay(500); //Sampling frequency
}

I also updated MQUinifiedsensor.cpp to give me some diagnostic information to help with debugging this issue.

...
float MQUnifiedsensor::calibrate(float ratioInCleanAir) {
  Serial.print("_sensor_volt = ");
  Serial.print(_sensor_volt);
  Serial.print(" | _RL = ");
  Serial.print(_RL);
  Serial.print(" | _VOLT_RESOLUTION = ");
  Serial.print(_VOLT_RESOLUTION);
  Serial.print(" | ratioInCleanAir = ");
  Serial.println(ratioInCleanAir);
...

To Reproduce Compile and run.

Calibrating please wait._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
.  done!.
Warning: Conection issue, R0 is infinite (Open circuit detected) please check your wiring and supply

Now re-run using a cigarette lighter's gas in front of the sensor. Note the zeros are after I turn off the gas.

Calibrating please wait._sensor_volt = 0.60 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.66 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.88 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 0.92 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 1.00 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 1.02 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 1.06 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 1.06 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 1.10 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
._sensor_volt = 1.11 | _RL = 10.00 | _VOLT_RESOLUTION = 3.30 | ratioInCleanAir = 3.60
.  done!.
** Values from MQ-135 ****
|    CO   |  Alcohol |   CO2  |  Toluen  |  NH4  |  Aceton  |
|   13.37   |   3.55   |   406.91   |   1.60   |   9.32   |   1.33   |
|   18.18   |   4.55   |   408.64   |   2.09   |   11.30   |   1.73   |
|   22.29   |   5.37   |   410.02   |   2.50   |   12.85   |   2.06   |
|   32.57   |   7.29   |   413.20   |   3.49   |   16.30   |   2.84   |
|   3.42   |   1.18   |   402.57   |   0.49   |   3.96   |   0.41   |
|   0.00   |   0.00   |   400.01   |   0.00   |   0.03   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |
|   0.00   |   0.00   |   400.00   |   0.00   |   0.00   |   0.00   |

Expected behavior I would expect this app to be able to calibrate properly in clean air. I have also tried putting in a delay(20000); after the MQ135.init(); to see if it just needed 20 seconds to warm up before the calibration process started. This did not help so I also tried 60,000 and it also did not help, _sensor_volt = 0.00 after either 20,000 and 60,000 wait.

Hardware:

miguel5612 commented 1 month ago

My friend, in these cases, we usually check the sensor manually, with a program, such as the example given by Jaycon Systems:

https://www.jaycon.com/understanding-a-gas-sensor/

Once all the setup works correctly and we understand each mathematical equation, we proceed to make the adjustment in the library (if required) and we load an example (if it is for a different board than the ones already saved) or update the example (if it is an existing board) in the library.

Finally with a pull request I can support you to make this setting available to the whole community.

I remain attentive to any new developments