Capteur MG811, fonctionnement et code

Bonjour,

Je suis à la recherche de quelques explications sur le fonctionnement et le code d’exemples du capteur MG811 :
Datasheet + code : MG-811 CO2 Sensor Module | Sandbox Electronics

Fonctionnement :
Si j’ai bien compris, le signal de sortie est une tension comprise entre 100 et 600mV qui dépend du pourcentage de C02. Ainsi pour 400ppm de CO2 on aura une certaine tension, qui diminuera ensuite lorsque le taux de CO2 augmentera.

Il est marqué qu’un circuit amplificateur du signal est requis pour amplifier la faible amplitude du signal.
Ce circuit est directement intégré dans le capteur pas besoin de le réaliser non ?

Je n’ai pas bien compris le fonctionnement de la sortie BOOL : il semble induire une tension seuil à comparer avec la tension de sortie. Mais je ne comprends pas dans quel cas (Vout supérieur ou inferieur à la tension seuil) BOOL vaut TRUE or FALSE (HIGH or LOW)

Code :

/*******************Demo for MG-811 Gas Sensor Module V1.1*****************************
Author:  Tiequan Shao: tiequan.shao@sandboxelectronics.com
         Peng Wei:     peng.wei@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    2012-05-31
************************************************************************************/
 
/************************Hardware Related Macros************************************/
#define         MG_PIN                       (0)     //define which analog input channel you are going to use
#define         BOOL_PIN                     (2)
#define         DC_GAIN                      (8.5)   //define the DC gain of amplifier
 
/***********************Software Related Macros************************************/
#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 milisecond) between each samples in 
                                                     //normal operation
 
/**********************Application Related Macros**********************************/
//These two values differ from sensor to sensor. user should derermine this value.
#define         ZERO_POINT_VOLTAGE           (0.220) //define the output of the sensor in volts when the concentration of CO2 is 400PPM
#define         REACTION_VOLTGAE             (0.020) //define the voltage drop of the sensor when move the sensor from air into 1000ppm CO2
 
/*****************************Globals***********************************************/
float           CO2Curve[3]  =  {2.602,ZERO_POINT_VOLTAGE,(REACTION_VOLTGAE/(2.602-3))};   
                                                     //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: (lg400, 0.324), point2: (lg4000, 0.280) 
                                                     //slope = ( reaction voltage ) / (log400 –log1000) 
 
void setup()
{
    Serial.begin(9600);                              //UART setup, baudrate = 9600bps
    pinMode(BOOL_PIN, INPUT);                        //set pin to input
    digitalWrite(BOOL_PIN, HIGH);                    //turn on pullup resistors
 
   Serial.print("MG-811 Demostration\n");                
}
 
void loop()
{
    int percentage;
    float volts;
 
    volts = MGRead(MG_PIN);
    Serial.print( "SEN-00007:" );
    Serial.print(volts); 
    Serial.print( "V           " );
 
    percentage = MGGetPercentage(volts,CO2Curve);
    Serial.print("CO2:");
    if (percentage == -1) {
        Serial.print( "<400" );
    } else {
        Serial.print(percentage);
    }
 
    Serial.print( "ppm" );  
    Serial.print("\n");
 
    if (digitalRead(BOOL_PIN) ){
        Serial.print( "=====BOOL is HIGH======" );
    } else {
        Serial.print( "=====BOOL is LOW======" );
    }
 
    Serial.print("\n");
 
    delay(200);
}
 
/*****************************  MGRead *********************************************
Input:   mg_pin - analog channel
Output:  output of SEN-000007
Remarks: This function reads the output of SEN-000007
************************************************************************************/ 
float MGRead(int mg_pin)
{
    int i;
    float v=0;
 
    for (i=0;i<READ_SAMPLE_TIMES;i++) {
        v += analogRead(mg_pin);
        delay(READ_SAMPLE_INTERVAL);
    }
    v = (v/READ_SAMPLE_TIMES) *5/1024 ;
    return v;  
}
 
/*****************************  MQGetPercentage **********************************
Input:   volts   - SEN-000007 output measured in volts
         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(MG-811 output) is provided. As it is a 
         logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic 
         value.
************************************************************************************/ 
int  MGGetPercentage(float volts, float *pcurve)
{
   if ((volts/DC_GAIN )>=ZERO_POINT_VOLTAGE) {
      return -1;
   } else { 
      return pow(10, ((volts/DC_GAIN)-pcurve[1])/pcurve[2]+pcurve[0]);
   }
}
  • Quel est la différence entre l’utilisation de #define et const ?

  • Il est marqué qu’il faut définir soit même les valeurs : ZERO_POINT_VOLTAGE et REACTION_VOLTGAE Mais je ne vois pas comment faire cela ? Ne peut-on pas conserver les valeurs données (c’est ce que j’ai trouvé dans les tutoriels que j’ai pu consulter jusqu’à maintenant) ?

  • Quel est l’intérêt de déclarer des variables dans la boucle loop (percentage et volts) ? Parce qu’a chaque tour on rajoute 2 opérations (déclaration de variables) alors que si on faisait ces déclarations en dehors on n’éviterait ce phénomène non ?

  • La encore je ne comprends pas bien la partie concernant le booléen BOOL si quelqu’un peut me l’expliquer brièvement ?

Désolé pour toutes ces questions, j’espère avoir des éclaircissements de votre part. Merci :slight_smile:

Salut,

Il y a un comparateur sur la carte qui permet de définir un seuil. En fonction de ce seuil bool est à l'état haut ou à l'état bas. Ca permet de se passer d'un µC dans certain cas, par exemple si tu veux allumer un gyrophare si le CO2 est trop haut.

Visiblement il y a un amplificateur donc un ampli externe n'est pas necessaire.

const => la variable existe (et prend donc de la place dans la RAM) mais est en lecture seul
#define => directive pré-processeur. Dans les fait il va remplacer dans le code ce que tu définis, donc aucune variable n'est créer, ça va simplement remplacer de que tu définis dans le code avant de le compiler. A privilégier donc car ça ne prend pas de place en RAM

les variables dans la loop() seront locales. D'une manière générale il faut les privilégier : plus rapide d'accès, évite les confusions et étant détruite à la fin ça permet de gagner de la RAM temporairement pour autre chose. Leur création ne prenant qu'un cycle c'est pas cher payé ...

Merci pour ces réponses !
Reste cette question (avis aux amateurs :slight_smile: ): Il est marqué qu'il faut définir soit même les valeurs : ZERO_POINT_VOLTAGE et REACTION_VOLTGAE Mais je ne vois pas comment faire cela ? Ne peut-on pas conserver les valeurs données (c'est ce que j'ai trouvé dans les tutoriels que j'ai pu consulter jusqu'à maintenant) ?

Et aussi peut-on connaitre le contenu des librairies téléchargées ? Par exemple savoir ce que fait telle fonction ... ?