MQ-2. Détecteur de gaz et de fumées. Exemple de code Arduino

Partager sur facebook
Partager sur twitter
Partager sur linkedin
Partager sur pinterest
Partager sur email
Partager sur telegram

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) se qui empêche d’utiliser une breadbord. Dans ce cas, pas le choix, il faudra utiliser des Jumpers Dupont M/F.

Connectez les quatre broches du capteur à l’Arduino ou l’ESP que vous utilisez 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

arduino mq2 circuit wiring analog input

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 https://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 calibrer un MQ-2 pour détecter différents gaz

Le code ci-dessus permet simplement de lire la valeur analogique renvoyée par le détecteur. Si vous souhaitez connaitre plus précisément la valeur du niveau d’emission du gaz, nous allons devoir procéder à une calibration. Le fabricant a publié deux courbes dans la documentation technique pour nous permettre de réaliser la calibration.

mq2 mq-2 sensibilite capteur pour gpl co alcool propane fumées hydrogene

La seconde courbe permet d’ajuster la calibration en fonction de la température et de l’humidité.

mq2 mq-2 correction sensibilite fonction humidite temperature

Pour réaliser la calibration, 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. Ce programme réalise la calibration de la résistance R0 seul. Pour cela, assurez vous que le capteur soit placé dans un air propre lorsque vous démarrez le programme.

/*******************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 interal(in milisecond) between each samples in the
                                                     //cablibration 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 interal(in milisecond) 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.

A LIRE AUSSI :
Les capteurs MQ, détecter des gaz, polluants et fumées (MQ2, MQ4, MQ5, MQ6, MQ9, MQ135)

Voir plus de kits

Avez-vous aimé cet article ?
[Total: 0 Moyenne: 0]
Partager sur facebook
Partager sur twitter
Partager sur linkedin
Partager sur pinterest
Partager sur email
Partager sur telegram

Vous avez aimé ce projet ? Ne manquez plus aucun projet en vous abonnant à notre lettre d’information hebdomadaire!

quel modèle esp8266 choisir
Quel modèle d'ESP8266EX choisir en 2020 ?
guide choix esp32 development board
Quel ESP32 choisir en 2020 ?

Vous rencontrez un problème avec ce sujet ?

Peut-être que quelqu’un a déjà trouvé la solution, visitez le forum avant de poser votre question

18 Commentaires
  1. Bonjour,
    cette information reste encore une inconnue pour moi 🙂
    Il n’y a aucune spécification qui précise clairement la tension minimum fourni par le MQ-2 dans un environnement non pollué.
    Il y a bien quelques tutos qui expliquent que la tension varie en fonction de la concentration : “plus la concentration est faible plus la tension est petite”. Mais petite de combien ?…
    En tout cas, dans mon cas, lorsque je fait une lecture à la sortie du convertisseur analogique-numérique, j’ai quelque fois 0.
    Peut-être que la précision du CAN (ADS1115) est trop faible pour de petites tensions.

    • Bonjour Julien. Oui effectivement le problème vient peut être du CAN. Sur une carte Arduino et un ESP8266, je n’ai jamais rencontré ce problème.

  2. Merci pour votre réponse !
    Je pense que tout est correcte au niveau des branchements et du capteur car, effectivement, un test avec un briquet me retourne bien des valeurs plus grandes.
    Si j’ai bien compris, le calibrage doit se faire dans un air sans polluant. Or, dans ces conditions, une valeur à 0 peut être retournée par le CAN. Du coup je ne comprend pas comment réaliser ce calibrage, j’aurais à un moment une division par 0…

    Merci

    • Bonjour Julien, effectivement le calibrage doit se faire dans l’air sans polluant mais le MQ-2 ne retourne jamais 0 donc aucune chance d’avoir une division par 0

  3. Bonjour,
    je ne trouve pas l’implémentation de la fonction analogRead().
    Elle est incluse dans quelle package, comment est-elle importée dans le code ?
    Que fais cette fonction ? Apparemment elle ne retourne jamais 0 puisque son résultat est utilisé dans la fonction MQResistanceCalculation() dans laquelle il y a une division par cette valeur…

    Toutes ces questions car j’essaye de faire une alarme incendie pour un projet personnel, et j’essaye de savoir comment utiliser ce capteur.
    Dans mon cas j’utilise un Raspberry et un CAN. En présence d’aucun gaz, la valeur lue est quelque fois à 0, donc je ne comprend pas bien comment je peux faire la division, et donc le calibrage.

    Merci pour tout renseignement.

    • Bonjour Julien. La fonction analogRead() est une fonction de base, il n’y a rien à installer. Le lit la valeur du convertisseur Analogique/numérique. Par exemple la tension de sortie du MQ2 varie entre 0 et 5V (0V s’il n’y a aucun polluant…jusqu’à 5V si le détecteur se trouve dans une atmosphère saturée). Si la valeur est nulle, il y a plusieurs raisons :
      – il n’y a pas de polluant dans la pièce
      – le branchement est incorrect (5V, GND, sortie analogique sur A0)
      – le capteur est HS
      Pour vérifier, vous pouvez prendre un peu d’alcool ménager sur un coton ou ouvrir un briquet quelques secondes à proximité du MQ-2.
      Dernière recommandation, n’utilisez jamais un détecteur de la série MQxx pour développer un système d’alarme DIY. La précision de mesure est aléatoire est peu fiable. C’est un détecteur destiné à l’apprentissage avant tout. Achetez un appareil certifié pour protéger votre habitation et vos proches.

  4. Bonjour,

    peut on utiliser la sortie digital et analog en même temps ?

  5. Bonjour ,
    j’ai pas compris pourquoi vous avez initialisé R0=10 K ohms?

    • Bonjour Basma. La résistance du capteur varie en fonction de la présence d’un polluant dans l’atmosphère. Par défaut, la résistance du capteur est de 10 kohms en l’absence de polluant. Pour étalonner le capteur, on mesure la résistance en fonction d’une concentration connue en polluant. Les courbes d’étalonnages sont faites en laboratoire. Ensuite c’est de la fabrication de série. Après, en fonction de la qualité de la production, la mesure serra plus ou moins fiable. Il faut refaire la même chose pour chaque gaz. C’est assez approximatif…mais pas chère. Pour mesurer la teneur en CO2, je vous conseille d’utiliser un MH-Z19 auto-calibré https://projetsdiy.fr/projet-micropython-publier-taux-co2-capteur-mhz19-domoticz-2/

  6. Bonjour,
    Je ne comprend pas très bien comment sont déterminés les coordonnées en Y des points choisis pour donner une approximation de la courbe original. Pourrais-je avoir une explication de cela ?

    Merci d’avance pour votre réponse

    • Bonjour Bruce. La résistivité électrique du capteur change lorsqu’elle est en présence d’une molécule pour laquelle le capteur est sensible. Ces courbes ont été établie en laboratoire. R0 correspond à la résistance à vide (sans polluant). RS, la résistance pour une concentration en polluant donné… sous certaines conditions de température et d’humidité.

      • Désolé mais je me rends compte que c’est ma question qui n’était pas claire, je pensais aux coordonnées dans le programme. J’ai compris comme sont trouvées les valeurs de x et de la pente (slope) mais je n’arrive pas à retrouver les coordonnées en Y qui sont affichées ici dans le programme (et ce pour tous les points).
        Encore désolé pour ma mauvaise formulation sur ma question précédente.

        • Oups désolé. J’ai travaillé dessus l’année dernière, faut que je me remette dedans ;-). Il fait une interpolation entre deux points de la courbe tirées de la doc technique du fabricant. C’est un peu plus compliqué qu’une interpolation car l’échelle et semi logarithmique. Je ne suis pas prof de math et c’est un peu loin pour moi maintenant. Par contre Google est notre ami ! https://openclassrooms.com/forum/sujet/equation-de-droite-sur-graphique-log. A très bientôt.

        • Merci beaucoup pour ton aide c’est ce qu’il me fallait ! Bonne continuation à toi et merci de m’avoir répondu ! 🙂

  7. Hello

    Petit problème dans le code …

    A la ligne 101 et 125, s’est glissé une petite erreur … (i suivi du symbole <> suivi de lt pose problème …)
    Pour 101, il faut mettre for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) { et pour 125, il faut mettre for (i=0;i<READ_SAMPLE_TIMES;i++) {

    Je ne sais pas pourquoi, mais l'outil de chat me rajoute des =" partout dans mon texte :-/

    Peux-tu corriger ton code 😉 ?

    Manu

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

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