Outils pour utilisateurs

Outils du site


wiki:projets:open-air:home:journal:decembre

Décembre

Le mois de Décembre a été principalement caractérisé par l'élaboration d'un banc de test ayant pour but d'évaluer chacun des capteurs fournis par le PMClab.

Matériel à disposition

LATMOS

Pour caractériser un capteur, l'utilisation d'instrument de mesure servant de référence est essentiel. Le LATMOS possède des outil de précision et calibré récemment, destinés à la mesure de particules fines, d'ozones et de dioxyde d'azote. Chacun de ces instruments a été répertorié dans le tableau qui suit

description_des_instruments_de_reference.pdf

Le LATMOS possède 2 OSIRIS, 1 DUSTMATE, 2 POM et 1 NOx.

Même si la qualité de ces appareils semble satisfaisante, il conviendra, au préalable, de comparer les résultats obtenus par les instruments du LATMOS avec les mesures effectuées par AirParif. Des campagnes seront ainsi prévues afin de vérifier la précision des outils de références.

Fablab

Les équipement du Fablab (découpe laser, photogravure, etc) seront utilisé pour mettre en place une enceinte de test dans laquelle les différents capteur seront testé et étalonnés.

Caractérisation capteur

On se propose ici d’effectuer l’étude de différents capteurs de gaz et de particules fines. En effet pour l’élaboration de nos capteurs il est intéressant d’avoir une indication sur le taux de NO2, d’ozone et des micro particules contenus dans l’air. L’objectif est de récupérer les données de ces capteurs et de tester leurs exactitudes.

Listes des capteurs à tester

Le Fablab possède différents capteurs de gaz qu'il est intéressant de tester:

Nom Fonction
MSQ-131Détecteur de NO2, O3 et CL2
MICS-2714Détecteur de NO2 et H2
SGX-4NO2 Détecteur de NO2
MICS-2614Détecteur de O3
SHARP GP2Y1010AU0FDétecteur de PM 2.5
SHINYEI PPD42NSDétecteur de PM 2.5

Mise en place du banc de test

L’idée est de concevoir une expérience permettant de comparer deux capteurs différents. Le processus envisagé pour chacun des éléments sera le suivant. On prend pour chacun des produits à comparer au minimum 3 échantillons différents. On connecte tout ces échantillons à une Arduino Uno et on effectue les mesures pour une durée de quelques jours. Un instrument de mesure plus précis sera aussi installé pour cette même durée afin d’obtenir des résultats de référence. Il est possible d’émettre au cours du test différentes contraintes significative afin d’observer la réaction de chacun des éléments à tester.

Capteur de particule fines

Un capteur de particule, comme son nom l'indique, permet de détecter les micro-poussières susceptibles d'avoir des effets néfaste sur la santé.Ce composant est constitué d'un laser émettant un rayon au travers d'une cuve contenant un échantillon d'air. En rencontrant une particule le laser sera plus ou moins diffracté (angle et intensité différentes). C'est en captant ces rayons dérivés avec une photodiode qu'il sera possible de détecter la quantité de particule.

D'un point de vue de l'électronique, le signal optique du laser est récupéré par une photodiode qui converti le signal optique en signal électrique. Ce signal sera ensuite amplifié puis filtré avant d'être envoyé à la sortie. Selon la valeur de la tension on pourra déterminer la concentration de particules dans l'aire après traitement par microcontrôleur.

Connectiques SHARP et SHINYEI

Pour chacun des composants à tester les branchements sont explicités dans la datasheet.

Pour le SHARP, l'élément est alimenté avec 6 broches: 3 pour la LED et 3 pour le récepteur. Des connecteurs S6B-ZR-SM4A-TF sont utilisés pour ce type de communications. Il est assez contraignant d'utiliser ce type de connexion, il convient donc de réfléchir à une solution plus simple d'utilisation. Ainsi, pour nos tests on observera les résultats avec les nappes du S6B-ZR-SM4A-TF d'une part et avec de simples fils souder sur le PCB d'autre part afin de déterminer l'impact de la connectique sur les résultats.

Les connections sur la LED sont définis de la manière suivante:

Un signal créneau doit être envoyé sur la patte 3 du composant afin d'activer la diode. De même on s'assurera qu'une capa ainsi qu'une résistance sont bien reliées sur la première pin du capteur.

Concernant le SHINYEI, le branchement est “plus classique” avec uniquement une broche pour l'alimentation, une pour la masse et une dernière pour le signal à récupérer. Le taux de particule sera donnée en mesurant la durée pour laquelle le signal mesuré est à l'état bas sur une période données.

Pour chacun des capteurs c'est la carte Arduino Uno qui est utilisée pour le traitement des données. Le stockage sera quant à lui réalisé sur une carte SD. La partie matériel étant définie il convient désormais de définir le code utilisé par l'Arduino.

Code V1

De part la nature du signal à mesurer on aura deux codes différents selon le capteur. Pour chacun la dernière version est décrite dans l'architecture qui suit:

''//capteur sharp''

#include <SPI.h>

#include <SD.h>

//déclaration PIN
int capteur;//sortie capteur
int sd_cs=4; // carte sd commande
int sd_mosi=11;
int sd_miso=12;
int sck_sd=13;

//Alim Led
int interupteur=2;
int charge=280;
int lecture=40;
float offTime=9680;

//conversions
float in_max=1023.0;
float in_min=0;
float out_max=5.0;
float out_min=0;
float taux=0;//données brutes
unsigned long temps;
float tauxconv=0;//données converties
float data=0;

//date
unsigned long jour=0;
unsigned long heure=0;
unsigned long minute=0;
unsigned long seconde=0;

//autre
unsigned long tempsmesure=30000; //durée d'une mesure
unsigned long debut=0;// temps du début de la mesure
unsigned long totalduration=0; //durée de l'échantillonage mesure
int capteurmax=1000; //nombre de capteurs connectés
int compteur=0;
float somme[6]={0,0,0,0,0};

File fichier;

void setup()
{

// init port série

  Serial.begin(9600);

 //initialisation de la carte sd
Serial.print("Initialisation de la carte SD...");
  if (!SD.begin(sd_cs)) {
    Serial.println("Carte non reconnue");
    return;
  }
  Serial.println("OK!");
delay(1000);
if (SD.exists("data.txt")==true){
  Serial.println("Supression des anciennes données...");
SD.remove("data.txt");
Serial.println("Fichier supprimé");
delay(1000);
}
pinMode(interupteur, OUTPUT);

Serial.println("Saisir le nombre de capteur:");
while (capteurmax>6){
  if (Serial.available()> 0) {
capteurmax=Serial.read();
capteurmax=capteurmax-'0';
Serial.println(capteurmax);
  }
}

fichier=SD.open("data.txt", FILE_WRITE);
if (fichier) {
  fichier.print("Jour;Heure;");
}
fichier.close();
delay(100);
for (capteur=0;capteur<=capteurmax; capteur++){
delay(100);
fichier=SD.open("data.txt", FILE_WRITE);
    if (fichier) {
       if (capteur<capteurmax){
         fichier.print("Capteur");
      fichier.print(capteur);
      fichier.print(";");
      }
      else{
        fichier.print("Capteur");
      fichier.println(capteur);
      }
      fichier.close();
    }
else {
      Serial.println ("erreur à l'ouverture");
}
}
debut=millis();
Serial.print("Debut mesure: ");
}

void loop()
{

 compteur++;

  digitalWrite(interupteur,LOW); // active la LED
  delayMicroseconds(charge);
  //mesure du temps
  temps= millis();
    if (temps> 86400000){
  jour= temps/86400000;
  temps=temps†400000;
  }

  if (temps> 3600000){
  heure= temps/3600000;
  temps=temps600000;
  }

  if (temps> 60000){
  minute= temps/60000;
  temps=temps`000;
  }

  seconde= temps/1000;

 for (capteur=0; capteur<=capteurmax-1; capteur++){
  //Lecture des données brut

 taux=analogRead(capteur);

// conversion des données
  tauxconv = conversion(taux,in_min,in_max,out_min,out_max);
  data=conversion(tauxconv,0.5,4.0,0.0,0.59);

  somme[capteur]= somme[capteur]+data;
}
// calcul de la durée de l'expérience
  totalduration=millis()-debut;

 if (totalduration>= tempsmesure){

  delayMicroseconds(lecture);
  digitalWrite(interupteur,HIGH); // éteind la led
   for (capteur=0; capteur<=capteurmax-1; capteur++){
  float average=0;
average= somme[capteur]/compteur;
if(capteur==0){
  Serial.print ("Jour ");
Serial.print (jour);
Serial.print (" ");
Serial.print (heure);
Serial.print (" h ");
  Serial.print (minute);
Serial.print (" min ");
Serial.print (seconde);
Serial.println (" s ");
}
Serial.print ("CAPTEUR ");
Serial.println(capteur);
//  Serial.print(" Voltage : ");
//  Serial.println(taux conv);
  Serial.print(" Taux de particule (mg/mcube) : ");
  Serial.println(average);

//stockage dans la carte sd

//ouverture du fichier

fichier=SD.open("data.txt", FILE_WRITE);

if (fichier) {
      Serial.print("Enregistrement sur carte SD...");
//enregistrer
if(capteur==0){
fichier.print ("Jour ");
fichier.print (jour);
fichier.print (" ; ");
fichier.print (heure);
fichier.print (" h ");
fichier.print (minute);
fichier.print (" min ");
fichier.print (seconde);
fichier.print (" s ;");
delay(100);
}
fichier.print(average);
  fichier.print(";");
if (capteur==4){
fichier.println();
}
delay(1000);
//fermeture

fichier.close();
Serial.println("Enregistrement terminé");
    }
    else {
      Serial.println ("erreur à l'ouverture");
    }
    somme[capteur]=0;
   }

compteur=0;
debut=millis();

}

  delayMicroseconds(lecture);
  digitalWrite(interupteur,HIGH); // éteind la led
  delayMicroseconds(offTime);
}

   //fonction conversion des données brutes
float conversion (float in, float x_min, float x_max, float y_min, float y_max)
{
  float out=0;
  out = (in-x_max)*((y_max-y_min)/(x_max-x_min))+y_max;
  return out;
}

//capteur shinyei

#include <SPI.h>

#include <SD.h>
int sd_cs=4; // carte sd commande
int sd_mosi=11;
int sd_miso=12;
int sck_sd=13;
int capteur;
int capteurmax=1000;
int pin;

unsigned long duration[7]={0,0,0,0,0,0}; //durée de la mesure
unsigned long start=0; //heure de passage à l'état bas
unsigned long stopp=0; //heure de passage à l'état haut
unsigned long totallow[7]={0,0,0,0,0,0}; //durée à l'état bas
unsigned long debut=0;// temps du début de la mesure
unsigned long temps; //temps depuis le début du test
unsigned long tempsmesure=30000; //durée d'une mesure
unsigned long totalduration=0; //durée de l'échantillonage mesure
float tauxparticules[7]={0.0,0.0,0.0,0.0,0.0,0.0}; // concentration en particules
float ratio[7]={0,0,0,0,0,0}; //pourcentage de temps à l'état bas
int etat[7]={1,1,1,1,1,1}; //envoie l'état logique en sortie
int previous[7]={1,1,1,1,1,1}; // etat logique précédent
int jour=0;
int heure=0;
int minute=0;
int seconde=0;
File fichier;

void setup() {

  //ouverture connection série
Serial.begin(9600);

 //initialisation de la carte sd
 Serial.print("Initialisation de la carte SD...");
  if (!SD.begin(sd_cs)) {
    Serial.println("Carte non reconnue");
    return;
  }
  Serial.println("OK!");
delay(1000);
if (SD.exists("data.txt")==true){
  Serial.println("Supression des anciennes données...");
SD.remove("data.txt");
Serial.println("Fichier supprimé");
delay(1000);
}

Serial.println("Saisir le nombre de capteur:");
while (capteurmax>6){
  if (Serial.available()> 0) {
capteurmax=Serial.read();
capteurmax=capteurmax-1-'0';
Serial.println(capteurmax);
  }
}

   //définition de la PIN comme entrée
fichier=SD.open("data.txt", FILE_WRITE);
if (fichier) {
  fichier.print("Jour;Heure;");
}
 fichier.close();
 delay(100);
for (capteur=0;capteur<=capteurmax; capteur++){
pin=capteur+14;
pinMode (pin, INPUT);
delay(100);
fichier=SD.open("data.txt", FILE_WRITE);
    if (fichier) {
       if (capteur<capteurmax){
         fichier.print("Capteur");
      fichier.print(capteur);
      fichier.print(";");
      }
      else{
        fichier.print("Capteur");
      fichier.println(capteur);
      }
      fichier.close();
    }
 else {
      Serial.println ("erreur à l'ouverture");
}
}
debut=millis();
Serial.print("Debut mesure: ");
date();

}
void loop() {

  //boucle sur chaque capteur
  for (capteur=0;capteur<=capteurmax; capteur++){
pin=capteur+14;
  // Vérifie l'état du capeur
  previous[capteur]=etat[capteur];

  etat[capteur]=digitalRead (pin);
  if(etat[capteur]==LOW && previous[capteur]==HIGH){
    start=millis();
  }
  else if(previous[capteur]==LOW && etat[capteur]==HIGH){
     stopp=millis();
  duration[capteur]= stopp-start;

   //mesure de la durée total de l'état bas
  totallow[capteur]=totallow[capteur]+duration[capteur];

  }
  }

  // calcul de la durée de l'expérience
  totalduration=millis()-debut;

  //affichage du taux de particule en pcs toute les 30 secondes
  if (totalduration>= tempsmesure){
    date();
    fichier=SD.open("data.txt", FILE_WRITE);
    fichier.print ("Jour ");
 fichier.print (jour);
 fichier.print (";");
 fichier.print (heure);
 fichier.print (":");
  fichier.print (minute);
 fichier.print (":");
 fichier.print (seconde);
 fichier.print (";");
 fichier.close();
    for (capteur=0;capteur<=capteurmax; capteur++){
      Serial.print("Capteur ");
      Serial.println(capteur);
      Serial.println (totallow[capteur]);
    ratio[capteur] = (totallow[capteur]*100.0)/tempsmesure;
    tauxparticules[capteur]=1.1*pow(ratio[capteur],3)-3.8*pow(ratio[capteur],2)+520*ratio[capteur]+0.62;
    Serial.println (tauxparticules[capteur]);
    fichier=SD.open("data.txt", FILE_WRITE);
    if (fichier) {
      Serial.print("Enregistrement sur carte SD...");
      if (capteur<5){
      fichier.print(tauxparticules[capteur]);
      fichier.print(";");
      }
      else{
      fichier.println(tauxparticules[capteur]);
      }
      fichier.close();

      Serial.println("Enregistrement terminé");
    }
    else {
      Serial.println ("erreur à l'ouverture");
    }
    totallow[capteur]=0;
    duration[capteur]=0;
    debut=millis();
  }

    }

}

void date ()
{
  temps=millis();
  if (temps> 86400000){
  jour= temps/86400000;
  temps=temps†400000;
  }

  if (temps> 3600000){
  heure= temps/3600000;
  temps=temps600000;
  }

  if (temps> 60000){
  minute= temps/60000;
  temps=temps`000;
  }

  seconde= temps/1000;
   Serial.print ("Jour ");
 Serial.print (jour);
 Serial.print (" ");
 Serial.print (heure);
 Serial.print (" h ");
  Serial.print (minute);
 Serial.print (" min ");
 Serial.print (seconde);
 Serial.println (" s ");

}

Capteurs de Gaz

Un capteur de gaz est un élément constitué de différentes couches de semi conducteurs sensible à la présence de certains composés gazeux. De manière générale l'objectif est de mesurer la valeur de la résistance interne du capteur qui va varier selon le taux de gaz présent dans l'air. En réalisant un pont diviseur de tension il est possible d'obtenir la valeur de cette résistance sensible. Il est aussi possible de noter la présence d'une résistance de chauffage qui aura pour but de placer le capteur dans les conditions optimal pour les mesures.

Pour chacun des capteurs à tester on aura une connectique légèrement différente, la logique restera néanmoins toujours la même. Les données seront récupérée via une carte Arduino uno et stockée sur carte SD. Il faut donc désormais définir le code à utiliser.

Code V1

Le code qui suit correspond à la première version utilisée pour nos tests.

#include <SPI.h>
 
#include <SD.h>
 
int sd_cs=4; // carte sd commande
int sd_mosi=11;
int sd_miso=12;
int sck_sd=13;
int capteur;
int capteurmax= 19;
 
unsigned long debut=0;// temps depuis le démarrage de la dernière mesure
unsigned long temps=0; //temps depuis le début du test
unsigned long tempsmesure=300000; //temps de moyennage avant affichage
unsigned long totalduration=0; //durée de la mesure
float mesure[6]={0.0,0.0,0.0,0.0,0.0};
float tension[6]={0.0,0.0,0.0,0.0,0.0}; // tension mesurée par chacun des capteurs
float totaltension[6]={0.0,0.0,0.0,0.0,0.0}; // moyenne des mesures
float tauxgazs[6]={0.0,0.0,0.0,0.0,0.0}; // concentration en particules
float in_max=1023.0;
float in_min=0;
float out_max=100.0;
float out_min=0;
 
int jour=0;
int heure=0;
int minute=0;
int seconde=0;
int compteur=0
File fichier;
 
void setup() {
 
  //ouverture connection série
Serial.begin(9600);
 
 //initialisation de la carte sd
 Serial.print("Initialisation de la carte SD...");
  if (!SD.begin(sd_cs)) {
    Serial.println("Carte non reconnue");
    return;
  }
  Serial.println("OK!");
delay(1000);
if (SD.exists("data.txt")==true){
  Serial.println("Supression des anciennes données...");
SD.remove("data.txt");
Serial.println("Fichier supprimé");
delay(1000);
}
 
//Serial.println("Saisir le nombre de capteur:");
//while (capteurmax>6){
//  if (Serial.available()> 0) {
//capteurmax=Serial.read();
//capteurmax=capteurmax-'0';
//Serial.println(capteurmax);
//  }
//}
//  capteurmax=capteurmax+14;
 
   //définition de la PIN comme entrée
for (capteur=14;capteur<=capteurmax; capteur++){
pinMode (capteur, INPUT);
delay(100);
fichier=SD.open("data.txt", FILE_WRITE);
    if (fichier) {
       if (capteur<19){
         fichier.print("Capteur");
      fichier.print(capteur);
      fichier.print(";");
      }
      else{
        fichier.print("Capteur");
      fichier.println(capteur);
      }
      fichier.close();
    }
 
}
debut=millis();
Serial.print("Debut mesure: ");
date();
 
}
 
void loop() {
compteur++
  //boucle sur chaque capteur
  for (capteur=0;capteur<=capteurmax-14; capteur++){
 
  // Mesure la tension du capteur
  mesure[capteur]=analogRead(capteur);
 // conversion des données
  tension[capteur]= conversion(mesure[capteur],in_min,in_max,out_min,out_max);
 
   //mesure de la durée total de l'état bas
  totaltension[capteur]=(totaltension[capteur]+tension[capteur]/compteur);
 
  totalduration=millis()-debut;
 
  //affichage du taux de gaz
  if (totalduration>= tempsmesure){
    date();
    fichier=SD.open("data.txt", FILE_WRITE);
    fichier.print ("Jour ");
 fichier.print (jour);
 fichier.print (";");
 fichier.print (heure);
 fichier.print (":");
  fichier.print (minute);
 fichier.print (":");
 fichier.print (seconde);
 fichier.print (";");
 fichier.close();
    for (capteur=0;capteur<=capteurmax-14; capteur++){
      Serial.print("Capteur ");
      Serial.println(capteur);
      Serial.println (tension[capteur]);
    //faire conversion selon le capteur
//...
 
    fichier=SD.open("data.txt", FILE_WRITE);
    if (fichier) {
      Serial.print("Enregistrement sur carte SD...");
      if (capteur<5){
      fichier.print(tension[capteur]);
      fichier.print(";");
      }
      else{
      fichier.println(tension[capteur]);
      }
      fichier.close();
 
      Serial.println("Enregistrement terminé");
    }
    else {
      Serial.println ("erreur à l'ouverture");
    }
 
    duration[capteur]=0;
    debut=millis();
  }
 }
    }
 
}
// affichage de la date sur le port série
void date ()
{
  temps=millis();
  if (temps> 86400000){
  jour= temps/86400000;
  temps=temps†400000;
  }
 
  if (temps> 3600000){
  heure= temps/3600000;
  temps=temps600000;
  }
 
  if (temps> 60000){
  minute= temps/60000;
  temps=temps`000;
  }
 
  seconde= temps/1000;
   Serial.print ("Jour ");
 Serial.print (jour);
 Serial.print (" ");
 Serial.print (heure);
 Serial.print (" h ");
  Serial.print (minute);
 Serial.print (" min ");
 Serial.print (seconde);
 Serial.println (" s ");
 
}
 //fonction conversion des données brutes
float conversion (int in, float x_min, float x_max, float y_min, float y_max)
{
  float out=0;
  out = (in-x_max)*((y_max-y_min)/(x_max-x_min))+y_max;
  return out;
}

9/12/2015

Pour cette manipulation seul les composant de type SHARP ont été testés. Trois d'entre eux utilisent les nappes de connexion de type S6-BR-ZR-SM4A-TF et deux sont reliés à la carte Arduino avec des fils simplement étanés sur le PCB.

L'enceinte de test est constituée d'une boite contenant les capteurs à tester mais aussi l'instrument de mesure OSIRIS. Un couvercle couvrira partiellement le contenant de manière à laisser passer l'air.

L'expérience durera 24 h en grande partie sous aire ambiant mais avec ajout de fumés à des instants donnés.

Le but ici n'est pas tant d'obtenir des résultats que de vérifier si la procédure de test est satisfaisante.

Après récupération des résultats plusieurs constats peuvent être fait. Tout d'abord le stockage sur carte SD doit être retravailler car l'arrivé trop rapide de données engendre une perte des résultats.

L'enceinte de test est également peu fiable car l'absence de ventilation ne permet de faire circuler la fumée dans l'ensemble de la boite. Un espace de test plus efficace avec ventilateur devra donc être réalisé.

Du point de vue résultats les capteurs semblent bien répondre aux contraintes extérieures, la perte de résultat ne permet malheureusement pas de définir la précision des composants.

Bilan Décembre

Ce premier mois à été d'avantage consacré à la pris en main des instruments de mesures et à l'étude des capteurs. Un premier test à pu être élaboré, les résultats obtenue ne permette pas de tirer de réel conclusion sur les composants, l'enceinte de test ainsi que le code utilisé devront être retravaillé.

wiki/projets/open-air/home/journal/decembre.txt · Dernière modification: 2016/09/11 13:17 (modification externe)