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€
Sommaire
Matériel nécessaire pour tester le MQ-2 sur un Arduino
Pour ce projet, vous aurez besoin du matériel suivant :
- 1x Arduino Uno (ou équivalent)
- 1x Breadboard (optionnel)
- 1x Détecteur de gaz MQ-2
- Quelques câbles Dupont M/M ou M/F si vous n’utilisez pas de breadboard
Réalisation du 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 breadboard. Dans ce cas, pas le choix, il faudra utiliser des Jumpers Dupont M/F.
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 A0 de l’Arduino.
/* Programme de test des déctecteurs 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 }
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.
La seconde courbe permet d’ajuster la calibration en fonction de la température et de l’humidité.
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. Pour en savoir plus sur la famille des capteurs MQ, lisez cet article.
- Programmer les cartes ESP32 avec l’IDE Arduino sur macOS, Windows 10, Linux ARM [MàJ]. Framework ESP-IDF
- Débuter avec l’Arduino et Node-RED. Enregistrer et afficher des mesures en JSON depuis le port série
- Débuter avec les objets connectés DIY (2). Communiquer, programmer, stocker, visualiser, fabriquer des circuits
- Comparaison HC-SR04 (ultrasons), Sharp GP2Y0A02YK0F (IR), VL53L0X (Laser), quelle solution choisir pour la mesure de distance avec Arduino ou Raspberry Pi
- Test et étalonnage du capteur de proximité A02YK0, clone asiatique du Sharp GP2Y0A02YK0F
- Capteur INA219, mesurer la puissance d’un panneau solaire ou une batterie avec un Arduino ou ESP8266
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… Lire la suite »
Merci pour votre réponse 🙂
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 ! 🙂
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
Bonjour Manu. Merci beaucoup, c’est corrigé.