ACTIVITE ARDUINO/PYTHON : Utilisation d’un capteur CO2 avec Arduino, tracé de graphe dans Python

Objectif : Mesurer la concentration CO2 en ppm dans une pièce à l’aide du capteur Gravity SEN0219

Remarque : Cet article s’inspire d’un TP proposé par Pierre Dieumegard sur le site sciencexp.

Le lien se trouve à cette adresse : http://sciencexp.free.fr/index.php?perma=capteurCO2GravitySEN0219

Cet article propose le même code Arduino adapté ici au shield LCD 2×16 DFR0009.

Ce montage permet de mesurer la concentration en CO2 dans une pièce et d’alerter sur l’aération :

  • Concentration inférieure à 800 ppm : pas de danger -> LED verte éclairée et smiley « content »
  • Concentration comprise entre 800 et 1600 ppm : aération requise-> LED orange éclairée et smiley « moyen content »
  • Concentration supérieure à 1600 ppm : aération impérative -> LED rouge éclairée et smiley « pas content »

Voici le code Arduino :

/* 
 Infrared CO2 Sensor0-5000ppm   
 
 This example The sensors detect CO2 
 @author lg.gang(lg.gang@qq.com) 
 @version  V1.0 
 @date  2016-7-6 
 GNU Lesser General Public License. 
 See http://www.gnu.org/licenses/ for details. 
 All above must be included in any redistribution 
 **/ 
 // intégration des capteurs d'humidité DHT11 et de CO2 par
 // Pierre Dieumegard, 4 décembre 2018
 // modifié par Jonas FORLOT 28 février pour utilisation avec shield LCD DF ROBOT 
 #include  <LiquidCrystal.h>
LiquidCrystal lcd(8,9, 4, 5, 6, 7);
 int sensorIn = A1;   
 double total=0;
 double totalA2=0;
 float concentration = 0;
 byte smiley_pas_content[8] = {
   B00000,
   B10001,
   B00000,
   B00000,
   B01110,
   B10001,
   B00000,
 };
 byte smiley_content[8] = {
   B00000,
   B10001,
   B00000,
   B00000,
   B10001,
   B01110,
   B00000,
 };
 byte smiley_moyen[8] = {
   B00000,
   B10001,
   B00000,
   B00000,
   B11111,
   B00000,
   B00000,
 };
 void setup(){   
   pinMode(11,OUTPUT);
   pinMode(3,OUTPUT);
   pinMode(2,OUTPUT);
 Serial.begin(9600);   
   // Set the default voltage of the reference voltage 
    analogReference (DEFAULT);
    lcd.begin(16,2);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("   Mesure   Concentration ");//Print a message to the LCD.
    lcd.setCursor(0, 1);
    lcd.print("               CO2  ");//Print a message to the LCD. 
 // déplacement de 16 position vers la droite
   for (int i = 0; i < 10; i++) {
     lcd.scrollDisplayLeft();
     delay(300);
   }
 delay (100);
 } 
 void loop(){  
   //Lecture de la tension pour CO2 
   int sensorValue = analogRead(sensorIn);  
  total=0;
  totalA2=0;
  for (int i=1; i <= 50; i++){
       total=total+analogRead(1)  ;
       totalA2=totalA2+analogRead(2)  ;
       delay(20); 
       }
// Conversion en volts  
   float voltage = (total/50)*(5000/1024.0);     
if(voltage == 0)    {      
Serial.println("Problème");     
 lcd.clear();      
lcd.print("Problème");  
 }    

else if(voltage < 400)    {          
Serial.println("Préchauffage");        
 lcd.clear();         
 lcd.print("préchauffage");    
}    
else    {      
int voltage_diference=voltage-400;      
float concentration=voltage_diference*50.0/16.0; 
     lcd.clear();
     //Print CO2 concentration 
     Serial.print("CO2: ");
     Serial.print(concentration);
     Serial.println(" ppm"); //allumage des LED
 if  (concentration < 800) {   
     digitalWrite (2,HIGH);
     digitalWrite (3,LOW);
     digitalWrite (11,LOW);
     lcd.setCursor(0,0);
     lcd.print("CO2: ");
     lcd.print(concentration);
     lcd.print("ppm");
     lcd.createChar(0, smiley_content);
     lcd.setCursor(7,1);
     lcd.write(byte(0));
 delay(1000);
 }
 else if  (concentration > 1600) {
     digitalWrite (2,LOW);
     digitalWrite (3,LOW);
     digitalWrite (11,HIGH);
 lcd.setCursor(0,0); 
lcd.print("CO2: "); 
lcd.print(concentration); 
lcd.print("ppm"); 
lcd.createChar(0, smiley_pas_content); 
lcd.setCursor(7,1); 
lcd.write(byte(0));
 delay(1000);
 }
 else {
     digitalWrite (2,LOW);
     digitalWrite (3,HIGH);
     digitalWrite (11,LOW);
      lcd.setCursor(0,0);
     lcd.print("CO2: ");
     lcd.print(concentration);
     lcd.print("ppm");
     lcd.createChar(0, smiley_moyen);
     lcd.setCursor(7,1);
     lcd.write(byte(0));
 delay(1000);
 }
   }
 //maintenant la voie A2( facultative pour la lecture de CO2)
 //    lcd.setCursor(0,1);
 //    lcd.print("A2: ");
 //    lcd.print(totalA2/50);
 //    Serial.print("; A2: ");
 //    Serial.print(totalA2/50);
 //    Serial.print(" \n"); 
 } 

Un code Python est aussi proposé ici pour récupérer les données et tracer une courbe.

Dans cet article , je ne rentrerai pas dans les détails pour les étapes de récupération de données. Pour cela, je vous invite à consulter l’article qui explique ces différentes étapes sur ce lien :

Récupération des données d’une carte Arduino avec Python

Voici le code Python pour récupérer les données et tracer le graphe en temps réel


 #importation des modules
 import serial
 import serial.tools.list_ports # pour la communication avec le port série
 import matplotlib.pyplot as plt  # pour le tracé de graphe
 from matplotlib import animation # pour la figure animée
 import time # gestion du temps
 

 #initialisation des listes
 

 liste_temps_mesure =[] # liste pour stocker le temps"brut"
 liste_temps=[] # liste pour stocker les valeurs de temps en partant de t=0
 liste_CO2 = [] # liste pour stocker les valeurs de concentration
 

 t_acquisition = 100.0
 Cmax= 5000 # en ppm
 

 

 #pour le graphe en temps réel
 def animate(i):
     line1 = Data.readline()
     print (line1)
     # on retire les caractères d'espacement en début et fin de chaîne
     listeDonnees = line1.strip()
     # on sépare les informations reçues séparées par les espaces et on stocke ces informations dans une liste pour chacune de lignes
     listeDonnees = line1.split()
     print (listeDonnees)
 

 

     if len(listeDonnees)== 3 : # parfois des lignes de données vides peuvent être envoyées, il faut les "écarter"
         Concentration = float(listeDonnees[1].decode()) # après consulation des données, nous choisissons le 2ème élément de listeDonnees
         tempsmes = time.time()
         liste_temps_mesure.append(tempsmes) # temps mesuré "brut" stocké dans une liste
         tempsreel = tempsmes - liste_temps_mesure[0] # pour faire partir le temps de 0 (cette valeur de temps sera stockée dans une autre liste : liste_temps)
 

         while tempsreel <= t_acquisition:
             liste_CO2.append(Concentration)
             print("d = %f"%(Concentration), " ppm") # affichage de la valeur de la concentration
             liste_temps.append(tempsreel)
             print("temps mesuré = %f"%(tempsmes), " s") # affichage de la valeur du temps absolu
             print("temps réel= %f"%(tempsreel), " s") # affichage de la valeur du temps en partant de 0
             line.set_data(liste_temps,liste_CO2)
             return line,
 

 

 

 

 

 

 # Fonction pour la récupération des données série venant de la carte Arduino
 def recup_port_Arduino() :
     ports = list(serial.tools.list_ports.comports())
     for p in ports:
         if 'Arduino' in p.description :
             mData = serial.Serial(p.device,9600)
     print(mData.is_open) # Affiche et vérifie que le port est ouvert
     print(mData.name) # Affiche le nom du port
     return mData
 

 

 

 

 

 

 Data =recup_port_Arduino() #récupération des données
 

 # Création figure
 fig=plt.figure()
 line, = plt.plot([],[])
 plt.xlim(0, t_acquisition)
 plt.ylim(0,Cmax)
 plt.xlabel('temps en s')
 plt.ylabel('Concentration CO2 en ppm')
 plt.grid()
 

 

 #Animation
 ani = animation.FuncAnimation(fig, animate, frames=200,  interval=20,repeat=False)
 

 plt.show()
 

 plt.close(fig)
 Data.close() # pour arrêter la lecture des données série
 

 #Ecriture dans un fichier txt
 lines=['t\tC\n'] #première ligne du fichier txt
 for i in range (len (liste_CO2)):
     line = str(liste_temps[i]) +'\t'+ str(liste_CO2[i])+'\n'
     lines.append(line)
 

 fichier = open('U:\Documents\\data_arduino.txt', 'w').writelines(lines) #création d'un nouveau fichier texte

Lien Github avec les scripts :

https://github.com/jonasforlot/python-arduino/tree/main/Capteur%20CO2

Laisser un commentaire