====== 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
{{:wiki:projets:open-air:home:journal: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-131|Détecteur de NO2, O3 et CL2|
|MICS-2714|Détecteur de NO2 et H2|
|SGX-4NO2 |Détecteur de NO2|
|MICS-2614|Détecteur de O3|
|SHARP GP2Y1010AU0F|Détecteur de PM 2.5|
|SHINYEI PPD42NS|Dé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.
{{ :wiki:projets:open-air:home:testcapteurs:particules.png?nolink&331x288 }}
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:
{{ :wiki:projets:open-air:home:testcapteurs:sharpconnect.png?nolink&634x226 }}
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
#include
//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 86400000){
jour= temps/86400000;
temps=temps400000;
}
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
#include
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= 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=temps400000;
}
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.
{{ :wiki:projets:open-air:home:gazsensor.png?nolink&516x222 }}
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
#include
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=temps400000;
}
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.
{{ :wiki:projets:open-air:home:testcapteurs:09-12-2015.png?nolink&603x453 }}
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é.