Outils pour utilisateurs

Outils du site


wiki:projets:open-air:home:testcapteurs:particules

Test capteur de particules

L'objectif est ici de déterminer lequel des composants SHARP GP2Y1010AU0F ou SHINYEI PPD42 est le plus adapté  notre application. On cherche aussi calibrer ces composants de manière à  obtenir le bon rapport voltage/taux de particules.

Généralités

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

Pour chacun des composants 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 connection, 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

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 ");

}

Compte rendu tests

~~COMPLEX_TABLES~~

Test du 9/12/2015

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

L'enceinte de test est constitué 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ées.

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 au contrainte extérieur, la perte de résultat ne permet malheureusement pas de définir la précision des composants.

Test du 4/01/2016

Pour cette manipulation les composants SHINYEI et SHARP sont évalués. Le code a été retravaillé en incluant des pauses avant les enregistrements sur carte SD de même quelques erreurs ont été corrigée. La boite conçue par le fablab est toujours en cour de réalisation, une autre boite devra être utilisée pour effectuer le test. Il s'agit du caisson utilisé pour contenir l'OSIRIS en extérieur. Un ventilateur est placé au niveau des orifices de la boite, les autres ouverture ont été colmatée.

Les 11 capteur sont placés aléatoirement dans la boite et l'OSIRIS placé à l'extérieur va venir prélever l'air présent à l'intérieur du caisson. De l'étain mis au contact d'un fer à souder est un émetteur de fumées qui seront utilisées pour polluer l'environnement de test.

Résultats:

Alors que lors des tests effectués à court terme (environ 1 heure) l'enregistrement sur carte SD était concluant, le passage au test à donner des résultats endommagé. Comme pour l'expérience précédente, le fichier texte obtenu donne des lignes de caractère “yyyyyyyy” avant de reprendre l'enregistrement pour s'arrêter de nouveau. Il semble que les cartes SD soit endommagée puisque l'espace de stockage ne semble être que de quelques Mo contre les 4Go attendus.

La boite est quand à elle fonctionnelle, la ventilation doit toutefois être retravaillée de manière à faire passer le flux d'air à travers tous les capteurs.

Test du 20/01/2016

Suite à une alerte de pollution aux particules fines, lancée par la plateforme OCAPI, il s’est avéré intéressant de tester les instruments de mesures en zones polluée. L’objectif de ces tests est donc de comparer les mesures faites par les équipements OSIRIS et DUSTMATE et de comparer les résultats avec ceux d’AirParif. Les capteurs de PM utilisés pour la conception du module portable seront également testés. La zone contaminée est principalement située à l’ouest de Paris. Les mesures seront donc effectuée porte d’Auteuil, à côté de la borne AirParif. Deux OSIRIS sont lancés en même temps afin de vérifier qu’il y a bien une corrélation entre les mesures. Le DUSTMATE sera également mis en route ainsi que les 3 capteurs SHINYEI de manière à estimer la réponse de ces appareils. Un shield lecteur de carte sd a été ajouté, ainsi les connections semblent meilleures et les données sont bien sauvegardée. L'ensemble des mesures a été effectué pendant environ 2h sur un point fixe Déroulement de l'expérience: Les mesures ont été lancées en même temps à 13h42 sur le Dustmate. A 14h12 le Dustmate a été changé de position afin de le placer d’avantage auprès des OSIRIS A 14h26 l’OSRIS 3588 s’est arrêté pour cause « d’Airflow error ». Le problème semble venir de la pompe après quelques réglage l’appareil est relancé à 14h30 15h30 : fin de l’expérience La température est restée relativement fixe autour de 0° avec un vent modéré.

Les données récupérées ont permis d’obtenir les graphiques suivants :

Il est tout d’abord à notifier que chacun des appareils semblent repérer les même piques de pollutions à différents instants. Les valeurs en revanche fluctuent d’un instrument à l’autre. Ainsi lorsque l’on observe les différentes courbes de corrélation ci-dessous, des disparités sont observables.

Cet écart et probablement dut au fait que la prise de mesure est échantillonnée sur une durée beaucoup trop faible pour donner des résultats précis. En effet lorsque l’on moyenne sur une heure, non seulement les données sont similaires d’un appareil à l’autre mais sont aussi conforme aux mesures effectuées par la borne AirParif.

Il serait donc intéressant d’effectuer à nouveau des mesures sur une durée plus longue cette fois ci. Concernant les capteurs Shinyei, la mesure est très bruitée et il est difficile d’identifier des similitudes avec les instruments de mesures et ceux même en enlevant les points aberrants.

Il est toutefois remarquable, qu’en moyennant les trois capteurs il est possible de trouver une courbe relativement similaire avec les mesures de tout type de particules.

Un moyennage sur la durée pourra aussi apporter des précisions.

En conclusion:

  • Instrument relativement fiable
  • Fiabilité à tester sur une durée plus longue
  • Capteur pertinent si grand nombre et durée d’échantillonnage élevée

Test du21/01/2016

Dans la même optique que pour le test du 20/01/2016 on va cette fois ci mesurer le taux de particule à l’intérieur de Paris. Un trajet du parc André Citroën à Jussieu a ainsi été effectué.

Comme pour l’expérience précédente on test deux OSIRIS ainsi que le DUSTMATE. Les capteurs utilisés seront cette fois ci les SHARP pour les particules fines. Des composants mesurant l’ozone ont aussi été emmenés. Le trajet emprunté a suivi la ligne 10 du métro. A chaque station rencontrée l’heure a été notée. Le début de l’expérience a eu lieu à 16h18 et c’est terminé à 18h08. Un problème d’airflow a de nouveau été rencontré dans le TNO3588 ne permettant une prise de mesure qu’à partir de 16h55

Les courbes obtenues en résultat sont véritablement satisfaisantes. Seul un léger problème de synchronisation des appareils à causer un léger décalage mais on observe très franchement une concordance dans les mesures des appareils.

Pour les capteurs SHARP en revanche les mesures sont toute faussé et fourni uniquement des mesures à -0.8µg/m3. Cette erreur est très probablement due à un problème de branchement. Les mesures d’ozone sont quant à elle bien corrélée d’un capteur à l’autre. Une mesure avec un instrument de mesure plus précis semble désormais nécessaire pour établir un algorithme de conversion tension/concentration.

En conclusion:

  • Mesures des appareils satisfaisantes, même si une maintenance doit être effectuée sur l’un des OSIRIS
  • Procéder à l’élaboration d’un PCB pour faciliter les branchements des capteurs SHARP
  • Procéder à un étalonnage des capteurs d’ozones
wiki/projets/open-air/home/testcapteurs/particules.txt · Dernière modification: 2016/09/11 13:17 (modification externe)