Capteur de CO2

De Les Fabriques du Ponant
Révision datée du 19 janvier 2022 à 16:21 par Antonydbzh (discussion | contributions) (quel capteur choisir ?)
Aller à : navigation, rechercher

En temps de covid, mesurer le taux de CO2 dans l'air d'une pièce peut-être un bon indicateur de la nécessité d'aération.

BoitierCapteurCO2.jpg PagewebCapteurCO2.jpg

de quoi s'agit-il ?

Avant toute chose

Il faut saluer et remercier le travail effectué par les personnes qui ont réalisé le site Nousaerons.fr (cliquez sur l'image pour y aller !).

CopieEcranNousAerons2021.png

D'une manière générale nous citons toutes les sources mobilisées pour réaliser cette page.

Taux de CO2 et qualité de l'air intérieur

Texte tiré de https://projetco2.fr/pourquoi-mesurer-co2

Le lien entre la qualité de l'air d'une pièce et la concentration en CO2 est donnée par les valeurs caractéristiques suivantes :

  • < 800 ppm : correspond à une qualité d'air excellente selon la norme NF EN 13779 et c'est une recommandation du Haut Conseil de la Santé publique. Cela constitue donc une valeur "cible" à atteindre.
  • entre 800 et 1000 ppm : correspond à une qualité d'air moyenne selon la norme NF EN 13779
  • entre 1000 et 1500 ppm : correspond à une qualité d'air modérée selon la norme NF EN 13779. Cela correspond à des valeurs trop élevées en contexte Covid-19.
  • > 1500 ppm : correspond à une qualité d'air basse selon la norme NF EN 13779. Cela correspond à des valeurs beaucoup trop élevées en contexte Covid-19.

Dans un lieu confiné, il n'est pas rare de dépasser le premier seuil au bout de quelques minutes. C'est le cas dans certaines salles de réunions ou salles de classes mal ventilées.

Attention, il existe des situations spécifiques pour lesquelles les seuils donnés ci-dessus ne sont pas pertinents :

  • Ces seuils ne sont pas pertinents dans les salles dans lesquels un recyclage partiel de l'air est assuré par un dispositif de filtration de type HEPA. Cette solution de purification de l'air en milieu clos par filtration doit faire l'objet d'une étude spécifique
  • Ces seuils sont donnés pour un taux en "plein air" d'environ 400 à 420 ppm qui sert de référence. Ce taux peut monter dans les grandes métropoles jusqu'à 500 ppm voire 600 ppm lors des pics de pollution. Ces valeurs élevées sont usuellement mesurées le matin. Il convient alors d'ajuster les seuils à surveiller à l'augmentation constatée du taux "plein air". Par exemple, si le taux de CO2 mesuré en plein air est de 500 ppm, il faut ajouter 100 ppm à tous les seuils proposés ci-dessus.

Hors contexte covid-19, la mesure du CO2 et la vérification de la qualité de l'air reste importante. Une bonne aération diminue les risques de maladie respiratoire. D'autre part, une concentration en CO2 supérieure à 1 000 ppm entraîne une diminution (réversible) des facultés cognitives.

Ainsi les recommandation pour notre capteur :

  • rouge si CO2 >1000 ppm. au dessus de 1000 ppm c'est trop
  • orange si 1000 ppm > CO2 > 800 ppm. Entre 800 ppm et 1000 ppm de CO2, il faut aérer.
  • vert si CO2 < 800 ppm. Sous les 800 ppm la qualité de l'air est excellente (avec un masques)

Pour info : le taux de CO2 atmosphérique était de 400 ppm en 2013, il a passé les 415 ppm en 2019, il était de 283 ppm en 1839.

quel capteur choisir ?

Le SenseAir S8 LP

le capteur SenseAir S8 existe en plusieurs versions :

  • la classique : S8 LP - préférer celui-ci !!
  • la moins cher S8-4B (attention le capteur n'effectue une mesure que toutes les 20 secondes).

Pourquoi ?

C'est une technologie fiable : analyse de l'air par lumière infra-rouge (NDIR - Non dispersive InfraRed)

  • deux faisceaux de lumière
  • un qui n'est pas absorbé par les gaz de l'air sert de référence.
  • un qui n'est absorbé que par le CO2

la différence permet de calculer la concentration en CO2 en ppm (partie par million de volume).

  • 10 000 ppm = 1%
  • la concentration normale en CO2 est de 415 ppm soient environ 0,04%

C'est un capteur qui est recommandé par l'ANSES.

calibration

Nécessaire de temps en temps si on constate une dérive (pour cela placer son capteur à l'extérieur pendant 15 minutes, si il ne donne pas 400 à 415 ppm, il faudra procéder à la calibration).

Comment faire ?

Avant de commencer l'étalonnage manuel, le capteur doit être à environ 400 ppm pendant quelques minutes (un minimum de 15 minutes) pour que le capteur se stabilise.

La procédure est très simple :

  1. Laissez le capteur fonctionner à l'extérieur pendant au moins 15 minutes.
  2. Connectez la broche bCAL_in à GND pendant plus de 4 secondes et moins de 8 secondes.
  3. Laissez le capteur à l'extérieur pendant environ 5 minutes pour qu'il termine son étalonnage et se stabilise.
  4. C'est fait. Le capteur va considérer que la concentration actuelle est de 400 ppm.
  5. laissez 5 minutes à l'extérieur pour contrôler les mesures.

Il est important de ne pas laisser la broche bCAL_in connectée à GND pendant plus de 8 secondes, car si les 13 secondes sont dépassées, le capteur démarre un mode de calibration différent, qui n'est pas celui qui nous intéresse (c'est un mode de calibration avec une concentration de 0 ppm de CO2, pour lequel il faut immerger le capteur dans l'azote, par exemple).


Source : https://emariete.com/en/meter-co2-esp8266-nodemcu-sensor-senseair-s8/

un boitier

Un boitier qui signale s'il faut aérer avec des led.

BoitierCapteurCO2.jpg

Accès précis à la mesure

Le boitier émet un réseau wifi ouvert permettant de s'y connecter et de rejoindre un site web local qui indique le taux de CO2 mesuré.

Un QRcode peut être utilisé pour rejoindre le site web à l'adresse 192.168.4.1

CapteurCO2QRCode.jpg

le QRCode

QrCodeCapteurCO2.png

Affichage sur un smartphone

PagewebCapteurCO2.jpg

Montage électronique Schéma Fritzing

Matériel :

  • un D1 mini (esp8266).
  • un shield batterie
  • une batterie 18650
  • un capteur SenseAir S8
  • 3 led (rouge, orange, verte) de 10mm de diamètre (des grosses).
  • 3 résistances de 220 ohms (rouge-rouge-marron).
  • 1 interrupteur
  • du fil électrique

MontageBoitiercapteurCO2.jpg

FritzingCapteurCO2.png

STL du Boitier

Ce stl est "grand" pour pouvoir être imprimé avec une imprimante 3D bas de gamme (qui bave un peu, quoi).

téléchargez le stl du boitier

téléchargez le zip du fichier Fusion 360 du boitier

CapteurCO23DFusion360.png

Fichier:CapteurCO2-FaceArriere.stl

Fichier:CapteurCO2-FaceAvant.stl

montage avec Arduino

D1mini SenseAir bb.png

Programme pour allumer des leds en fonction de la qualité de l'air

BUG POSSIBLES

des utilisateur ont constaté un problèe d'attribtion de broche. Solution :

  • soit modifier la bibliothèque,
  • soit dans le setup attribuer les GPIO au capteur et pas les numéros de broche monCapteur.CO2_Init(2,0) à la place de monCapteur.CO2_Init(D4,D3)(voir le schéma du D1 mini).

ATTENTION AUX BIBLIOTHEQUES ARDUINO

N'oubliez pas d'installer la bibliothèque "Airgradient", ainsi que "ESPAsyncWebServer" à partir du gestionnaire de bibliothèque.

ArduinoajouterBib.png

ArduinoImportbibAirgradient.png

Toutes les info sur les bibliothèques :

pour l'ESP8266 (le D1 mini) il faut aussi la bibliothèque [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP)

le code

////////////////////
// Capteur de CO2 //
////////////////////
/*
 * Proposé dans le cadre de PAPIFAB, un atelier mensuel à l'initiative de la ville Brest animé par les petits débrouillards.
 * 
 *                                   D1 mini
                                     BROCHAGE                            
                                _________________                        
                               /     D1 mini     \                       
                              |[ ]RST        TX[ ]|                   
                              |[ ]A0  -GPIO  RX[ ]|                    
                              |[ ]D0-16    5-D1[ ]|                     
                              |[ ]D5-14    4-D2[ ]|                     
                    Led Rouge |[X]D6-12    0-D3[X]| -> UART_RxD             
                   Led Orange |[X]D7-13    2-D4[X]| -> UART_TxD       
                    Led Verte |[X]D8-15     GND[X]| -> G0              
                              |[ ]3V3 .      5V[X]| -> G+       
                              |       +---+       |                     
                              |_______|USB|_______|     

                             ________________________
                            |   |° ° ° ° ° °|    |   |
                  +5V <- G+ |[X]| ° ° ° ° °/     |[ ]| DVCC_out
                  GND <- G0 |[X]|° ° ° ° °/      |[X]| UART_RxD -> D3
                   Alarm_OC |[ ]|_°_°_°_°|       |[X]| UART_TxD -> D4
                   PWM 1Khz |[ ]|                |[ ]| UART_R/T
                            |   |  SenseAir® S8  |[ ]| bCAL_in/CAL
                            |___|________________|___|
Matériel :
- des fils dupont.
- un capteur SenseAir® S8
- Un D1 mini
- ...

   ___
 / ___ \
|_|   | |
     /_/ 
     _   ___   _ 
    |_| |___|_| |_
         ___|_   _|
        |___| |_|
Les petits Débrouillards 2021- CC-By-Sa http://creativecommons.org/licenses/by-nc-sa/3.0/

Ce code est inspiré du code pour le "AirGradient DIY Air Quality Sensor" avec un Microcontroller ESP8266.
Pour plus d'infos, visitez https://www.airgradient.com/diy/
MIT License

Ce projet se nourrit également du travail de Nous aérons : https://nousaerons.fr/makersco2/
*/

#include <AirGradient.h> //appel de la bibliothèque "AirGradient.h" qui gère le capteur
AirGradient monCapteur = AirGradient(); // création de "monCapteur"

int CO2 = 400; // 400ppm c'est la valeur du CO2 dans l'air extérieur
int ledR = 12; // broche D6 sur le GPIO 12
int ledO = 13; // broche D7 sur le GPIO 13
int ledV = 15; // broche D8 sur le GPIO 15
long temps;    // cette variable sert à compter le temps
int brillance = 0;
int pas = 10;

void mesure () { // Cette fonction appelle le capteur et lui demande une mesure
  CO2 = monCapteur.getCO2_Raw();
  Serial.print("Taux de C02 : ");
  Serial.print(CO2); 
  Serial.print(" ppm - ");
}

void affichage (){ // Cette fonction allume les leds en fonction du taux de CO2 mesuré
  /* Seuil recommandés dans un contexte ou l'air n'est pas filtré : 
   * ROUGE si CO2 > 1000ppm. Au dessus de 1000ppm c'est trop, il est est urgent d'aérer !
   * ORANGE si 1000ppm > CO2 > 800ppm. Entre 800ppm et 1000ppm de CO2, il faut commencer à aérer.
   * VERT si CO2 < 800ppm. Sous les 800ppm, la qualité de l'air est excellente (avec un masques)
   * dans tous les cas, respectez les gestes barrières.
   * Source : Haut Conseil pour la Santé Publique, avis du 22 novembre 2020.
   */
  if (CO2 < 800){ // La qualité de l'air est excellente (avec un masques)
    digitalWrite(ledV,HIGH);
    digitalWrite(ledO,LOW);
    digitalWrite(ledR,LOW);
    Serial.println("La qualité de l'air est excellente");
    }
  else if (CO2 > 800 && CO2 < 1000){ // Il faut commencer à aérer.
    digitalWrite(ledV,LOW); 
    digitalWrite(ledO,HIGH); 
    digitalWrite(ledR,LOW);
    Serial.println("Il faut commencer à aérer.");
    }
  else if (CO2 > 1000){ // C'est trop, il est est urgent d'aérer !
    digitalWrite(ledV,LOW);
    digitalWrite(ledO,LOW); 
    digitalWrite(ledR,HIGH); 
    Serial.println("C'est trop ! il est est urgent d'aérer !");
    }
}

void demarrage (){ // Procédure de test des leds (juste pour le fun, c'est pas indispensable)
  for (int i=0; i<3; i++) { // boucle qui les allumes les unes après les autres
    digitalWrite(ledV,LOW);
    digitalWrite(ledO,LOW); 
    digitalWrite(ledR,HIGH);
    delay(100);
    digitalWrite(ledV,LOW);
    digitalWrite(ledO,HIGH); 
    digitalWrite(ledR,LOW);
    delay(100);
    digitalWrite(ledV,HIGH);
    digitalWrite(ledO,LOW); 
    digitalWrite(ledR,LOW);
    delay(100);
    }

  for (int i=0; i<3; i++) { // Boucle qui les allume toutes en un fondu enchainé.
    for (int j=0; j<30; j++){
    analogWrite(ledV,brillance);
    analogWrite(ledO,brillance); 
    analogWrite(ledR,brillance);
    brillance = brillance + pas ;
    if (brillance <= 0 || brillance >= 130) {
      pas = -pas;
      }
    delay(30);
    }
  }
  digitalWrite(ledV,LOW); // on éteint tout
  digitalWrite(ledO,LOW); 
  digitalWrite(ledR,LOW);
}

void setup(){
  Serial.begin(9600);    // ouverture du port série
  monCapteur.CO2_Init(); // initialisation de "monCapteur"
  
  pinMode(ledR, OUTPUT); // broches configurée en sorties
  pinMode(ledO, OUTPUT); 
  pinMode(ledV, OUTPUT);

  temps = millis();      // on enregistre le temps

  demarrage();           // procédure de test des leds au démarrage
}

void loop(){
  if((millis() - temps) > 5000){ // au bout de 5 secondes :
    mesure ();                   // on mesure le taux de CO2
    affichage ();                // on affiche le résultat
    temps = millis();            // on remet le compteur à zero.
    }
}

Programme qui allume les led et diffuse un réseau wifi avec la mesure

//////////////////////
//  Capteur de CO2  //
// avec affiche web //
//////////////////////
/*
 * Proposé dans le cadre de PAPIFAB, un atelier mensuel à l'initiative de la ville Brest animé par les petits débrouillards.
 * 
 *                                   D1 mini
                                     BROCHAGE                            
                                _________________                        
                               /     D1 mini     \                       
                              |[ ]RST        TX[ ]|                   
                              |[ ]A0  -GPIO  RX[ ]|                    
                              |[ ]D0-16    5-D1[ ]|                     
                              |[ ]D5-14    4-D2[ ]|                     
                    Led Rouge |[X]D6-12    0-D3[X]| -> UART_RxD             
                   Led Orange |[X]D7-13    2-D4[X]| -> UART_TxD       
                    Led Verte |[X]D8-15     GND[X]| -> G0              
                              |[ ]3V3 .      5V[X]| -> G+       
                              |       +---+       |                     
                              |_______|USB|_______|     

                             ________________________
                            |   |° ° ° ° ° °|    |   |
                  +5V <- G+ |[X]| ° ° ° ° °/     |[ ]| DVCC_out
                  GND <- G0 |[X]|° ° ° ° °/      |[X]| UART_RxD -> D3
                   Alarm_OC |[ ]|_°_°_°_°|       |[X]| UART_TxD -> D4
                   PWM 1Khz |[ ]|                |[ ]| UART_R/T
                            |   |  SenseAir® S8  |[ ]| bCAL_in/CAL
                            |___|________________|___|
  Matériel :
  - des fils dupont.
  - un capteur SenseAir® S8
  - Un D1 mini
  - ...

     ___
   / ___ \
  |_|   | |
       /_/ 
       _   ___   _ 
      |_| |___|_| |_
           ___|_   _|
          |___| |_|
  Les petits Débrouillards 13 août 2021- CC-By-Sa http://creativecommons.org/licenses/by-nc-sa/3.0/

  Ce code est inspiré du code pour le "AirGradient DIY Air Quality Sensor" avec un Microcontroller ESP8266.
  Pour plus d'infos, visitez https://www.airgradient.com/diy/
  MIT License

  Ce projet se nourrit également du travail de Nous aérons : https://nousaerons.fr/makersco2/
*/
// Appel des bibliothèques
#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AirGradient.h> //appel de la bibliothèque "AirGradient.h" qui gère le capteur
AirGradient monCapteur = AirGradient(); // création de "monCapteur"

const char* ssid     = "Taux de CO2";
const char* password = "";

// Creation du serveur AsyncWebServer sur le port 80
AsyncWebServer serveurCO2(80);

int CO2 = 400; // 400ppm c'est la valeur du CO2 dans l'air extérieur
int ledV = 15; // broche D8 sur le GPIO 15
int ledO = 13; // broche D7 sur le GPIO 13
int ledR = 12; // broche D6 sur le GPIO 12

long temps;    // cette variable sert à compter le temps
int brillance = 0;
int pas = 10;

// page web "index.html"
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    html {
     font-family: Arial;
     display: inline-block;
     margin: 0px auto;
     text-align: center;
    }
    h2 { font-size: 3.0rem; }
    p { font-size: 3.0rem; }
  </style>
</head>
<body>
  <h2>Taux de CO2 mesuré</h2>
  <p>
    <span>L'air ambiant contient</span> 
    <span>%TAUXCO2%</span>
    <span>ppm de CO2</span>
  </p>
</body>
<script>
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("TauxDeCO2").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/TauxDeCO2", true);
  xhttp.send();
}, 10000 ) ;

</script>
</html>)rawliteral";

// Renvooe les données du capteur de CO2
String processor(const String& var){
  if(var == "TAUXCO2"){
    return String(CO2);
  }
  return String();
}

void mesure () { // Cette fonction appelle le capteur et lui demande une mesure
  CO2 = monCapteur.getCO2_Raw();
  Serial.print("Taux de C02 : ");
  Serial.print(CO2); 
  Serial.print(" ppm - ");
}

void affichage (){ // Cette fonction allume les leds en fonction du taux de CO2 mesuré
  /* Seuil recommandés dans un contexte ou l'air n'est pas filtré : 
   * ROUGE si CO2 > 1000ppm. Au dessus de 1000ppm c'est trop, il est est urgent d'aérer !
   * ORANGE si 1000ppm > CO2 > 800ppm. Entre 800ppm et 1000ppm de CO2, il faut commencer à aérer.
   * VERT si CO2 < 800ppm. Sous les 800ppm, la qualité de l'air est excellente (avec un masques)
   * dans tous les cas, respectez les gestes barrières.
   * Source : Haut Conseil pour la Santé Publique, avis du 22 novembre 2020.
   */
  if (CO2 < 800){ // La qualité de l'air est excellente (avec un masques)
    digitalWrite(ledV,HIGH);
    digitalWrite(ledO,LOW);
    digitalWrite(ledR,LOW);
    Serial.println("La qualité de l'air est excellente");
    }
  else if (CO2 > 800 && CO2 < 1000){ // Il faut commencer à aérer.
    digitalWrite(ledV,LOW); 
    digitalWrite(ledO,HIGH); 
    digitalWrite(ledR,LOW);
    Serial.println("Il faut commencer à aérer.");
    }
  else if (CO2 > 1000){ // C'est trop, il est est urgent d'aérer !
    digitalWrite(ledV,LOW);
    digitalWrite(ledO,LOW); 
    digitalWrite(ledR,HIGH); 
    Serial.println("C'est trop ! il est est urgent d'aérer !");
    }
}

void demarrage (){ // Procédure de test des leds (juste pour le fun, c'est pas indispensable)
  for (int i=0; i<3; i++) { // boucle qui les allumes les unes après les autres
    digitalWrite(ledV,LOW);
    digitalWrite(ledO,LOW); 
    digitalWrite(ledR,HIGH);
    delay(100);
    digitalWrite(ledV,LOW);
    digitalWrite(ledO,HIGH); 
    digitalWrite(ledR,LOW);
    delay(100);
    digitalWrite(ledV,HIGH);
    digitalWrite(ledO,LOW); 
    digitalWrite(ledR,LOW);
    delay(100);
    }

  for (int i=0; i<3; i++) { // Boucle qui les allume toutes en un fondu enchainé.
    for (int j=0; j<30; j++){
    analogWrite(ledV,brillance);
    analogWrite(ledO,brillance); 
    analogWrite(ledR,brillance);
    brillance = brillance + pas ;
    if (brillance <= 0 || brillance >= 130) {
      pas = -pas;
      }
    delay(30);
    }
  }
  digitalWrite(ledV,LOW); // on éteint tout
  digitalWrite(ledO,LOW); 
  digitalWrite(ledR,LOW);
}

void setup(){
  Serial.begin(9600);    // ouverture de la communication série
  monCapteur.CO2_Init(); // initialisation de "monCapteur"
  
  pinMode(ledR, OUTPUT); // broches configurée en sorties
  pinMode(ledO, OUTPUT); 
  pinMode(ledV, OUTPUT);

  temps = millis();      // on enregistre le temps

  demarrage();           // procédure de test des leds au démarrage
  
  Serial.print("Réglage du point d'accès …");
  WiFi.softAP(ssid);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("addresse IP du point d'accès: ");
  Serial.println(IP);

  // Chemin vers le serveur web  
  serveurCO2.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });
  serveurCO2.on("/TauxDeCO2", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", String(CO2).c_str());
  });

  // démarrage du serveur
  serveurCO2.begin();
}

void loop(){
  if((millis() - temps) > 5000){  // au bout de 5 secondes : (ajuster le temps !!)
    mesure ();                    // on mesure le taux de CO2
    affichage ();                 // on affiche le résultat
    temps = millis();             // on remet le compteur à zero.
    }
}

Programme pour publier sur thingspeak

A faire !

Ressources et inspirations

voir : https://www.arduino.cc/reference/en/libraries/airgradient-air-quality-sensor/ Capteurs à disposition : Senseair S8

Rien a voir

il faut tester ça ! http://hebergement.universite-paris-saclay.fr/supraconductivite/projet/smartphone/

Ressources

voir aussi

Compte twitter : https://twitter.com/nousaerons

ressources sur CO2 et santé