Domotique et objets connectés à faire soi-même

MQ-2. Débuter avec le détecteur de gaz et fumées avec du code Arduino. Calibration, concentration en ppm

Le MQ-2 est un capteur qui permet de détecteur du gaz ou de fumée à des concentrations de 300 ppm à 10000 ppm. Après calibration, le MQ-2 peut détecter différents gaz comme le GPL (LPG), l’i-butane, le propane, le méthane, l’alcool, l’hydrogène ainsi que les fumées. Il est conçu pour un usage intérieur à température ambiante.

 

Le MQ2 doit être alimenté en 5V pour le capteur physico-chimique puisse atteindre sa température de fonctionnement. Il dispose d’une sortie analogique et d’un réglage de la sensibilité par potentiomètre. Vous pourrez aussi le trouver avec une interface Grove, notamment chez le fabricant SeeedStudio pour vos projets Intel Edisson. Vous pouvez vous procurer le MQ2 à partir de 2,70€

Attention, n’utilisez pas ce détecteur pour réaliser des applications pouvant mettre en danger la sécurité des personnes (applications médicales, industrielles…)
Attention. Le capteur chauffe après quelques minutes d’utilisation. C’est normal, c’est le principe même de fonctionnement de tous les capteurs physicochimiques. Tenez en compte dans la conception de votre projet.

Matériel nécessaire pour tester le MQ-2 sur un Arduino

Pour ce tutoriel vous aurez besoin du matériel suivant

Circuit

Vous risquer de rencontrer des problèmes pour installer votre MQ-2 sur un breadboard. En effet, les fabricants soudent assez souvent les connecteurs coudés un peu trop loin du bord (pour laisser apparaitre les repérages), ce qui empêche d’utiliser une breadboard. Dans ce cas, il est préférable d’utiliser des Jumpers Dupont M/F.

Connectez les 3 broches du capteur à l’Arduino (ou ESP32 / ESP8266) en suivant le schéma de câblage suivant

Reliez les Pins Vcc et GND du capteur au 5V et au GND de l’Arduino

Reliez le Pin D0 du capteur à l’entrée analogique A0 de l’Arduino

Code de base

Voici le code vous permettant de tester votre MQ-2. Par défaut, la sortie analogique du MQ-2 est branchée sur l’entrée analogique A0 de l’Arduino.

/*
  Programme de test des détecteurs de gaz de la série MQx
  Plus d'info sur http://www.projetsdiy.fr
*/

const int mqxPin = A0;  // La sortie analogique du détecteur MQx est reliée au Pin analogique A0 de l'Arduino

void setup()
{
    Serial.begin(9600); // Initialise le port série à 9600 bps // 
}

void loop()
{
    Serial.println(analogRead(mqxPin));
    delay(1000);        // Imprime une mesure chaque seconde
}

Comment déterminer la concentration en polluant avec un MQ-2

Pour détecter la présence d’un polluant (gaz ou fumée), on calcul le ratio entre la résistance initiale (R0) et la résistance (le signal analogique lu par l’Arduino) que le MQ2 renvoie à tout moment (Rs).

Connaissant ce ratio, on utilise la courbe théorique ci-dessous pour déterminer la quantité de chaque polluant.

Ici par exemple, le ratio Rs/R0 = 2, on lit une concentration en fumées de 800ppm sur la courbe rouge.

Il est préférable de déterminer Le R0 à chaque fois qu’on allume le capteur. En effet, la résistance des capteurs MQxx peut évoluer avec le temps car la surface active du capteur peut changer (présence de poussière, stabilisation de la céramique…).

En mesurant la température et le taux d’humidité, on peut corriger le ratio Rs/R0 ce qui permet d’améliorer la précision de détection.

Dans la pratique, le MQ2 envoie un signal analogique à l’Arduino. Ce signal sera la valeur de Rs

Exemple de code Arduino pour détecter la présence de GPL, CO et fumées avec un MQ2

Pour utiliser le MQ2, inutile de réinventer la roue, nous allons utiliser le code mis à disposition par Sandbox Electronics qui permet de calibrer le capteur pour détecter la présence de GPL, de CO (Monoxide de carbone) ou de fumées dans l’atmosphère environnante.

Créez un projet Arduino et collez le code ci-dessous.

Le programme commence par mesurer la résistance sur CALIBARAION_SAMPLE_TIMES échantillons (mesures). On attend CALIBRATION_SAMPLE_INTERVAL entre chaque mesure. Par défaut, la calibration initiale de R0 dure 2,5 secondes (5 * 500 ms).

Durant la calibration de R0, assurez vous que le capteur soit placé dans un air “propre”, idéalement à l’extérieur.

On peut assimiler chaque courbe à une droite. Les variables LPGCurve COCurve et SmokeCurve permettent de déterminer la concentration en GPL, fumées et CO dans l’atmosphère connaissant le ratio Rs/R0.

La méthode MQGetGasPercentage() permet de connaître la concentration en polluant. On doit lui indiquer le ratio Rs/R0 ainsi que le polluant recherché GAS_LPG (GPL), GAS_CO (monoxyde de carbone) ou GAS_SMOKE (fumées).

Pour connaître la présence d’autres gaz, il suffira d’ajouter les courbes correspondantes dans votre code.

/*******************Demo for MQ-2 Gas Sensor Module V1.0*****************************
Support:  Tiequan Shao: support[at]sandboxelectronics.com

Lisence: Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)

Note:    This piece of source code is supposed to be used as a demostration ONLY. More
         sophisticated calibration is required for industrial field application. 

                                                    Sandbox Electronics    2011-04-25
************************************************************************************/

/************************Hardware Related Macros************************************/
#define         MQ_PIN                       (0)     //define which analog input channel you are going to use
#define         RL_VALUE                     (5)     //define the load resistance on the board, in kilo ohms
#define         RO_CLEAN_AIR_FACTOR          (9.83)  //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,
                                                     //which is derived from the chart in datasheet

/***********************Software Related Macros************************************/
#define         CALIBARAION_SAMPLE_TIMES     (50)    //define how many samples you are going to take in the calibration phase
#define         CALIBRATION_SAMPLE_INTERVAL  (500)   //define the time interval(in millisecond) between each samples in the
                                                     //calibration phase
#define         READ_SAMPLE_INTERVAL         (50)    //define how many samples you are going to take in normal operation
#define         READ_SAMPLE_TIMES            (5)     //define the time interval(in millisecond) between each samples in 
                                                     //normal operation

/**********************Application Related Macros**********************************/
#define         GAS_LPG                      (0)
#define         GAS_CO                       (1)
#define         GAS_SMOKE                    (2)

/*****************************Globals***********************************************/
float           LPGCurve[3]  =  {2.3,0.21,-0.47};   //two points are taken from the curve. 
                                                    //with these two points, a line is formed which is "approximately equivalent"
                                                    //to the original curve. 
                                                    //data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59) 
float           COCurve[3]  =  {2.3,0.72,-0.34};    //two points are taken from the curve. 
                                                    //with these two points, a line is formed which is "approximately equivalent" 
                                                    //to the original curve.
                                                    //data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000,  0.15) 
float           SmokeCurve[3] ={2.3,0.53,-0.44};    //two points are taken from the curve. 
                                                    //with these two points, a line is formed which is "approximately equivalent" 
                                                    //to the original curve.
                                                    //data format:{ x, y, slope}; point1: (lg200, 0.53), point2: (lg10000,  -0.22)                                                     
float           Ro           =  10;                 //Ro is initialized to 10 kilo ohms

void setup()
{
  Serial.begin(9600);                               //UART setup, baudrate = 9600bps
  Serial.print("Calibrating...\n");                
  Ro = MQCalibration(MQ_PIN);                       //Calibrating the sensor. Please make sure the sensor is in clean air 
                                                    //when you perform the calibration                    
  Serial.print("Calibration is done...\n"); 
  Serial.print("Ro=");
  Serial.print(Ro);
  Serial.print("kohm");
  Serial.print("\n");
}

void loop()
{
   Serial.print("LPG:"); 
   Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_LPG) );
   Serial.print( "ppm" );
   Serial.print("    ");   
   Serial.print("CO:"); 
   Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_CO) );
   Serial.print( "ppm" );
   Serial.print("    ");   
   Serial.print("SMOKE:"); 
   Serial.print(MQGetGasPercentage(MQRead(MQ_PIN)/Ro,GAS_SMOKE) );
   Serial.print( "ppm" );
   Serial.print("\n");
   delay(200);
}

/****************** MQResistanceCalculation ****************************************
Input:   raw_adc - raw value read from adc, which represents the voltage
Output:  the calculated sensor resistance
Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
         across the load resistor and its resistance, the resistance of the sensor
         could be derived.
************************************************************************************/ 
float MQResistanceCalculation(int raw_adc)
{
  return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}

/***************************** MQCalibration ****************************************
Input:   mq_pin - analog channel
Output:  Ro of the sensor
Remarks: This function assumes that the sensor is in clean air. It use  
         MQResistanceCalculation to calculates the sensor resistance in clean air 
         and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about 
         10, which differs slightly between different sensors.
************************************************************************************/ 
float MQCalibration(int mq_pin)
{
  int i;
  float val=0;

  for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) {            //take multiple samples
    val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  val = val/CALIBARAION_SAMPLE_TIMES;                   //calculate the average value

  val = val/RO_CLEAN_AIR_FACTOR;                        //divided by RO_CLEAN_AIR_FACTOR yields the Ro 
                                                        //according to the chart in the datasheet 

  return val; 
}
/*****************************  MQRead *********************************************
Input:   mq_pin - analog channel
Output:  Rs of the sensor
Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
         The Rs changes as the sensor is in the different consentration of the target
         gas. The sample times and the time interval between samples could be configured
         by changing the definition of the macros.
************************************************************************************/ 
float MQRead(int mq_pin)
{
  int i;
  float rs=0;

  for (i=0;i<READ_SAMPLE_TIMES;i++) {
    rs += MQResistanceCalculation(analogRead(mq_pin));
    delay(READ_SAMPLE_INTERVAL);
  }

  rs = rs/READ_SAMPLE_TIMES;

  return rs;  
}

/*****************************  MQGetGasPercentage **********************************
Input:   rs_ro_ratio - Rs divided by Ro
         gas_id      - target gas type
Output:  ppm of the target gas
Remarks: This function passes different curves to the MQGetPercentage function which 
         calculates the ppm (parts per million) of the target gas.
************************************************************************************/ 
int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
{
  if ( gas_id == GAS_LPG ) {
     return MQGetPercentage(rs_ro_ratio,LPGCurve);
  } else if ( gas_id == GAS_CO ) {
     return MQGetPercentage(rs_ro_ratio,COCurve);
  } else if ( gas_id == GAS_SMOKE ) {
     return MQGetPercentage(rs_ro_ratio,SmokeCurve);
  }    

  return 0;
}

/*****************************  MQGetPercentage **********************************
Input:   rs_ro_ratio - Rs divided by Ro
         pcurve      - pointer to the curve of the target gas
Output:  ppm of the target gas
Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm) 
         of the line could be derived if y(rs_ro_ratio) is provided. As it is a 
         logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 
         value.
************************************************************************************/ 
int  MQGetPercentage(float rs_ro_ratio, float *pcurve)
{
  return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}

Les autres détecteurs de la famille MQ-xx

Le MQ-2 appartient à une famille de capteurs dédiés à la détection des gaz. C’est le détecteur le plus polyvalent, les autres sont spécialisés dans une ou deux molécules. Vous pouvez vous les procurer séparément. On le trouve très souvent dans les kits de capteurs. Vous pouvez utiliser le même code que précédemment pour les tester, il faudra ajuster la calibration en fonction du capteur choisi.

Voir plus de kits

Avez-vous aimé cet article ?
[Total: 0 Moyenne: 0]
Exit mobile version