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')
fichier.writelines(lines) #création d'un nouveau fichier texte
Lien Github avec les scripts :
https://github.com/jonasforlot/python-arduino/tree/main/Capteur%20CO2