Table des matières

Avril

Pour le moi d'Avril l'objectif est dans un premier temps de réaliser le test des capteurs avec les lycéens. Le dessin de la boite sous FreeCAD ainsi qu'une étude préliminaire des composants à implanter sera mener. Le but est d'être prêt à passer à la conception sous KiCAD à la fin du mois.

01/04 au 12/04

Atelier OpenAirV1.1

La première semaine du projet à été principalement consacrée à l'élaboration de l'atelier pour les lycéens. Le compte rendu de la conception techniques se trouve dans le document suivant: test_de_capteur_open_air_v1.pdf

Les documents annexes sont ici:

Dessin V2

Le dessin de la version 2 a également progressé avec la conclusion du module extérieur. La taille est déjà imposante avec 10x10x7 cm environ. mouviev8.zip

13/04

Observation des différents module GPS existant dans le but d'avoir une idée de l'empreinte à ajouter sur le dessin: 1850751.pdf

1821035.pdf

em506_um.pdf

La solution proposée par maestro semble la plus satisfaisante (à vérifier).

Le dessin à ainsi était développé avec la conception de la boite extérieur contenant les COV le chargeur de batterie et le module WI-FI.

Une autre version pourra être conçu sans module intérieur puisque l'un des capteur (le MICS 5524) est bivalent et mesure à la fois NO2 et COV.

Une version avec module wifi sur la version portable peut également être établie.

Version actuel (module wifi à ajouter): mouviev9.zip

14/04

Un bilan de la conception des capteurs via freecad a été réalisé. 3 solutions ont put être présentée une complète, une sans module fixe et une compact. conception_du_capteur_mouvie.pdf freecad.zip

19/04

Après présentation dessins effectués plusieurs retours ont été effectué. La version compacte répond d'avantage aux attentes même si quelques point à améliorer ont été relevés. Le traitement de flux d'aire tout d'abord. En effet de manière à limiter un maximum les turbulence l'air passant par le capteur doit circuler de manière fluide de l'entrée à la sortie. Le placement des capteurs doit donc être adapté de manière à être optimal pour chacun des capteur. De part la singularité géométrique de chacun des composants il sera difficile d'adapté une boite commune à chacun, une solution doit être imaginée.

L'autre remarque concerne l'utilisation du bluetooth, en effet si un module Wifi peut être utilisé il serai judicieux de remplacer le module RFduino par un composant similaire mais permettant la transmission Wifi.

De même avant de se lancer dans la conception de bluetooth une étude préalable des différentes techniques de transmission peut-être effectuée. Une étude de l'utilisation de chacun des moyens de transmission est disponible sur le site de libelium.

http://www.libelium.com/development/waspmote/documentation/?cat=networking

WiFi

L'ESP8266 est un module de faible taille permettant de transmettre des données en WiFi et possède également un microcontrôleur compatible avec l'IDE Arduino.

L'avantage principal est son faible cout, le problème vient en revanche de la difficulté de la programmation des points d'accès

Sigfox

La sigfox est un processus de communication développé pour répondre a la demande des objets connectés. Il s'agit d'une norme peu gourmande en énergie et capable de transmettre des données sur de larges distance.

Des modules compatible arduino existent toutefois le prix est encore un peu élevé

20/04

Dans l'attente des cartes wi-fi et dans l'optique de déterminer le layout de chacun des capteurs, les composant RFduino ont été testés.

Le composant RFduino est décrit de la manière suivante

Les données sont traitées directement dans le capteur avant d'être envoyées via une trame à l'arduino. Les branchements devront s'effectuer de la manière suivante.

ATTENTION: le RX du DFRobot se branche sur le TX de l'Arduino et inversement!

Le code fournit par DFRobot est décrit de la manière suivante:

//******************************
 //*Copyright (c) 2015, DFRobot
 //*All rights reserved
 //*Abstract: Read value of PM1, PM2.5 and PM10 of air quality
 //*
 //*Version:V2.0
 //*Author:Jason, jason.ling@dfrobot.com
 //*Date:Feb.2016
 //******************************
#include <Arduino.h>
#define LENG 32
char buf[LENG];
 
int PM01Value=0;          //define PM1.0 value of the air detector module
int PM2_5Value=0;         //define PM2.5 value of the air detector module
int PM10Value=0;         //define PM10 value of the air detector module
 
void setup()
{
  Serial.begin(9600);
}
 
void loop()
{
  if(Serial.available()) 
  {
    Serial.readBytes(buf,LENG);
    if(buf[0] == 0x42 && buf[1] == 0x4d){
      if(checkValue(buf,LENG)){
        PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
        PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
        PM10Value=transmitPM10(buf); //count PM10 value of the air detector module 
      }           
    } 
  }
  static unsigned long OledTimer=millis();  
    if (millis() - OledTimer >=1000) //Print the PM data every one second. range 0-50 days
    {
      OledTimer=millis(); 
       
      Serial.print("PM1.0: ");  //send PM1.0 data to bluetooth
      Serial.print(PM01Value);
      Serial.println("  ug/m3");            
     
      Serial.print("PM2.5: ");  //send PM1.0 data to bluetooth
      Serial.print(PM2_5Value);
      Serial.println("  ug/m3");     
       
      Serial.print("PM10:  ");  //send PM1.0 data to bluetooth
      Serial.print(PM10Value);
      Serial.println("  ug/m3");   
    }
   
}
char checkValue(char *thebuf, char leng)
{  
  char receiveflag=0;
  int receiveSum=0;
  char i=0;
 
  for(i=0;i<leng;i++)
  {
  receiveSum=receiveSum+thebuf[i];
  }
    
  if(receiveSum==((thebuf[leng-2]<<8)+thebuf[leng-1]+thebuf[leng-2]+thebuf[leng-1]))  //check the serial data 
  {
    receiveSum=0;
    receiveflag=1;
  }
  return receiveflag;
}
 
int transmitPM01(char *thebuf)
{
  int PM01Val;
  PM01Val=((thebuf[4]<<8) + thebuf[5]); //count PM1.0 value of the air detector module
  return PM01Val;
}
 
//transmit PM Value to PC
int transmitPM2_5(char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[6]<<8) + thebuf[7]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }
 
//transmit PM Value to PC
int transmitPM10(char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[8]<<8) + thebuf[9]); //count PM10 value of the air detector module  
  return PM10Val;
}

ATTENTION le branchement et le téléversement du code doit se faire selon un ordre précis pour éviter de rencontrer des problèmes de traitement des données. L'arduino doit tout d'abord être branchée seule pour être programmée. Le capteur peut ensuite être branché. L'arduino doit être débranchée puis rebranchée avant de lancer le programme à nouveau.

Plusieurs fonction ont été ajoutée au programme comme le temps et le moyennage des données sur une durée fixée. La prochaine étape devrait consister à enregistrer les données sous carte SD, jusqu'à présent la démarche s'est avérée compliquée.

#include <Arduino.h>
#include <SPI.h>
#include <SD.h>

#define LENG 32
char buf[LENG];
 
int PM01Value=0;          //define PM1.0 value of the air detector module
int PM2_5Value=0;         //define PM2.5 value of the air detector module
int PM10Value=0;         //define PM10 value of the air detector module
int TotalPM01;            // quantité total PM1.0 mesurée sur la durée de moyennage
int TotalPM2_5;           // quantité total PM2.5 mesurée sur la durée de moyennage
int TotalPM10;            // quantité total PM10 mesurée sur la durée de moyennage

int duree_moyenage=60; //durée de la période de moyennage en seconde
int counter=0; //compteur de secondes

int jour=0;
int heure=0;
int minute=0;
int seconde=0;
unsigned long temps;
 static unsigned long OledTimer;
 // carte sd commande
int sd_cs=4;
int sd_mosi=11;
int sd_miso=12;
int sck_sd=13;
File fichier;


void setup()
{
  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("dataDFRobot.txt")==true){
//  Serial.println("Supression des anciennes données...");
//SD.remove("dataDFRobot.txt");
//Serial.println("Fichier supprimé");
//delay(1000);
//}
//fichier=SD.open("data.txt", FILE_WRITE);
//if (fichier) {
//  fichier.print("Jour;Heure;PM1.0;PM2.5;PM10");
//}
// fichier.close();

//Serial.println("Saisir la durée de moyennage en s:");
//while (duree_moyenage<1){
//  if (Serial.available()) {
//duree_moyenage=Serial.read();
//duree_moyenage=duree_moyenage-'0';
//Serial.println(duree_moyenage);
//  }
//}

}
 
void loop()
{
  if(Serial.available()) 
  {
    Serial.readBytes(buf,LENG);
    if(buf[0] == 0x42 && buf[1] == 0x4d){
      if(checkValue(buf,LENG)){
        PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
        PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
        PM10Value=transmitPM10(buf); //count PM10 value of the air detector module 
      }           
    } 
  }
 
    if (millis() - OledTimer >=1000) //Print the PM data every one second. range 0-50 days
    {
      OledTimer=millis(); 
       TotalPM01=TotalPM01+PM01Value;
       TotalPM2_5=TotalPM2_5+PM2_5Value;
       TotalPM10=TotalPM10+PM10Value;
        counter++;
        Serial.print(counter);
       if(counter==duree_moyenage){
        PM01Value=TotalPM01/counter;
        PM2_5Value=TotalPM2_5/counter;
        PM10Value=TotalPM10/counter;

        date();
        
      Serial.print("PM1.0: ");  //send PM1.0 data
      Serial.print(PM01Value);
      Serial.println("  ug/m3");            
     
      Serial.print("PM2.5: ");  //send PM2.5 data
      Serial.print(PM2_5Value);
      Serial.println("  ug/m3");     
       
      Serial.print("PM10:  ");  //send PM10 data
      Serial.print(PM10Value);
      Serial.println("  ug/m3"); 
       
//       fichier=SD.open("dataDFRobot.txt", FILE_WRITE);
//    if (fichier) {
//      Serial.print("Enregistrement sur carte SD...");
//      
//      //send PM1.0 data
//      fichier.print(PM01Value);
//      fichier.print(";");            
//     
//      //send PM2.5 data
//      fichier.print(PM2_5Value);
//      fichier.print(";");     
//       
//      //send PM10 data
//      fichier.println(PM10Value);
//      fichier.close();
//      
//      Serial.println("Enregistrement terminé");
//    }
//    else {
//      Serial.println ("erreur à l'ouverture");
//    }      

      TotalPM01=0;
      TotalPM2_5=0;
      TotalPM10=0;
      counter=0;
       }
    }
   
}
char checkValue(char *thebuf, char leng)
{  
  char receiveflag=0;
  int receiveSum=0;
  char i=0;
 
  for(i=0;i<leng;i++)
  {
  receiveSum=receiveSum+thebuf[i];
  }
    
  if(receiveSum==((thebuf[leng-2]<<8)+thebuf[leng-1]+thebuf[leng-2]+thebuf[leng-1]))  //check the serial data 
  {
    receiveSum=0;
    receiveflag=1;
  }
  return receiveflag;
}
 
int transmitPM01(char *thebuf)
{
  int PM01Val;
  PM01Val=((thebuf[4]<<8) + thebuf[5]); //count PM1.0 value of the air detector module
  return PM01Val;
}
 
//transmit PM Value to PC
int transmitPM2_5(char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[6]<<8) + thebuf[7]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }
 
//transmit PM Value to PC
int transmitPM10(char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[8]<<8) + thebuf[9]); //count PM10 value of the air detector module  
  return PM10Val;
}

void date ()
{
  temps=millis();
  if (temps >= 86400000){
  jour= temps/86400000;
  temps=temps%86400000;
  }
 
  if (temps >= 3600000){
  heure= temps/3600000;
  temps=temps%3600000;
  }
 
  if (temps >= 60000){
  minute= temps/60000;
  temps=temps%60000;
  }
 
 
  seconde= temps/1000;
   Serial.print ("Jour ");
 Serial.print (jour);
 Serial.print (";");
 Serial.print (heure);
 Serial.print (" : ");
  Serial.print (minute);
 Serial.print (":");
 Serial.println (seconde);
 
//fichier=SD.open("dataDFRobot.txt", FILE_WRITE);
//    if (fichier) {
//fichier.print (jour);
// fichier.print (";");
// fichier.print (heure);
// fichier.print (" : ");
//  fichier.print (minute);
// fichier.print (":");
// fichier.print (seconde);
// fichier.print (";");
// fichier.close();
//      
//      Serial.println("Enregistrement terminé");
//    }
//    else {
//      Serial.println ("erreur à l'ouverture");
//    }
             

}

21/04

Un problème à été identifié au niveau des capteur, l'une des nappe est défectueuse ceci ayant pour conséquence la non transmission des donnée. Une nouvelle nappe sera livrée sous une dizaine de jour. La difficulté à stocker les données sur carte SD ne venait donc pas du code mais du capteur en lui même. En passant à l'enregistrement le non du fichier avait également était modifié ayant pour conséquence un non respect de la convention de nommage 8.3, à savoir pas plus de 8 caractères pour le nom et 3 pour l'extension.

En ayant effectué toute ces modifications l'enregistrement sous carte SD peut s’effectuer.

Test capteur DFRobot

En comparant les résultats de l'OSIRIS avec ceux du capteur les courbes suivantes sont obtenues.

On observe plusieurs choses un décalage temporel avant l'apparition des pics et également des valeurs inférieurs à celles de l'OSIRIS. Concernant le décalage celui vient du fait d'une saturation de l'appareil lors d'un passage brusque d'un niveau de poussière à un seuil plus élevé les valeurs sont instables et ne seront pas pris en compte. Il faut attendre un certain temps avant que les données se stabilisent. Concernant la différence de niveau ceci peut venir d'un problème de calibration mais également d'une erreur de conversion entre nombre de particules et concentration en µg/m3. Pour la calibration après avoir démonter un appareil il est difficile de procéder à des modification directement sur le capteur.

Pour la conversion en revanche si l'on suit le wiki fournit par DFRobot (http://www.dfrobot.com/wiki/index.php?title=PM2.5_laser_dust_sensor_SKU:SEN0177) il semble possible de récupérer dans la tram les valeur brut indiquant le nombre de particules dans l'aire. Ainsi en jouant sur la conversion il sera possible de calibrer les appareils. Toutefois la tram réel récupoérée par le code est très différente de celle décrite dans la notice il faudra donc étudier en détail la tram pour la caractériser convenablement et repérer les indication correspondante.

Exemple de tram (en décimal): 66 77 0 28 0 9 0 12 0 9 0 12 0 12 6 87 1 -35 0 69 0 5 0 0 1 0 0 0 81 0 2 -61 Dans un tel cas les résultats donne PM1: 9µg/m3; PM2.5: 12µg/m3 et PM10: 12µg/m3. On repère donc facilement les starting bits (0 et 1) et les donnée en µg/m3 (5, 7, 9) le reste est moins intuitif.

Bilan Avril

Au cour de ce mois un premier aperçu du capteur a pu être dressé. Quelques modifications sont encore nécessaire toutefois la structure générale semble fixée. En parallèle une étude des différents outils de transmissions a pu être entamée il serait intéressant par la suite de poursuivre ces observations avec une discussion entre les différents acteurs du projet.