Outils pour utilisateurs

Outils du site


wiki:projets:open-air:proto

Ceci est une ancienne révision du document !


Contexte du projet


Chaque jour, l’air que nous respirons est plus ou moins pollué, chaud et humide. Il varie selon l’heure, selon la météo et les sources d’émission de polluants, selon vos activités (à l’intérieur ou à l’extérieur, à proximité du trafic, dans un parc, …). Quel est l’air que vous respirez ? Il nous entoure, on le respire… mais il est invisible, sauf en cas de forte pollution. L’évaluation de la qualité de l’air (confort thermique et pollution) est possible par la mesure de paramètres météorologiques et de polluants atmosphériques.
Au quotidien, nous sommes informé(e)s sur la qualité de l’air et la météo, via les médias, sites internet et panneaux d’affichage municipaux. Pour l’Île-de-France, cette information est principalement issue des mesures de l’air par MétéoFrance et AirParif, mesures réalisées ponctuellement dans des stations. Elles n’indiquent pas votre propre exposition à la pollution de l’air selon vos activités, et les changements de températures et d’humidité selon les espaces fréquentés.


Les fablab, « laboratoire de fabrication numérique », mettent à disposition des outils permettant à tous de créer des objets, électroniques ou non, tels que des drones, des figurines ou encore des capteurs environnementaux. Ils font partie d’un mouvement de démocratisation de la science où chaque citoyen peut créer des capteurs et collecter des données grâce à des tutoriaux ouverts à tous, disponibles généralement sur internet, et à de l’électronique à bas prix. La collecte de données citoyennes permet à chacun de créer sa propre information sur ses expositions environnementales par exemple, voire d’enrichir une base de données scientifiques (sciences citoyennes).

Premier prototype sur breadboard

Développement v1

Nous avons développé une première version du capteur en Septembre 2015. Cette version se présente sous la forme d'un kit et comprend deux capteurs: un capteur de température et d'humidité relative (DHT22) et un capteur de particules fines (SHARP GP2Y1010AU0F).
La communication vers le smartphone (Android ou iOS) se fait via Bluetooth Low Energy (4.0) grâce à un RFDuino.
Le schéma sous Eagle
Et le PCB

Principe de la station connectée et contenu du kit


La station connectée que vous allez assembler et utiliser contient essentiellement deux capteurs : un capteur de température & humidité, le DHT22, qui va convertir ces grandeurs physiques en signal électrique ; un capteur de particules fines basé sur le principe de diffusion de la lumière qui va convertir la lumière déviée par les particules entrant dans le capteur en signal électrique. Pour fonctionner, ces capteurs utiliseront l’énergie fournie par une batterie rechargeable via le port USB d’un ordinateur par exemple. Les signaux électriques qu’il vont générer seront transmis par l’intermédiaire de la puce RFDUINO en bluetooth vers une application installable sur un smartphone (ANDROID ou IOS). Cette application permettra au “citoyen participatif” d’envoyer la donnée et ses coordonnées temporelles et GPS vers un serveur sur internet permettant une cartographie des mesures enregistrées au sein d’une base de données.

Montage de la station OpenAir


Le montage de la station se déroule en plusieurs étapes :
- 5 blocs à souder : (1) le chargeur de batterie, (2) les résistances, (3) les diodes électroluminescentes (LEDs), (4) le gros condensateur, (5) le capteur de température-humidité (DHT22)
- puis 2 blocs à brancher : (6) le capteur de particules fines (Sharp) et (7) la batterie. Après il ne reste plus qu’à insérer le tout dans le boîtier fabriqué avec une imprimante 3D et un couvercle avec une découpeuse laser.

1 - Le chargeur de batterie

  • 1) positionner le régulateur sur le PCB à l’emplacement A, pour voir comment le plier

  • 2) l’insérer sur le PCB par le dessus
  • 3) souder les pattes
  • 4) les couper si possible de manière identique, environ 2 mm

  • 5) l’interrupteur : insérer à l’emplacement B, par le dessus ; souder. Mettre le bouton de l’interrupteur vers la droite en position “éteint”.

  • 6) les condensateurs : 
La plus petite patte / avec le (-) écrit = la masse
Insérer les condensateurs à l’emplacement C, par le dessus, avec la masse à droite pour le condensateur en haut et la masse en haut pour le condensateur en bas. Plier les pattes derrière pour faciliter la soudure. Les souder et les couper.

  • 7) insérer puis souder les broches de connexion dans le chargeur de batterie (le petit côté par le dessous du chargeur)
  • 8) insérer et souder alors le chargeur sur le PCB à l’emplacement D par le dessous

2 - Les résistances


Insérer les pattes des résistances par le dessus :

  • A : 2 rouges
  • B : 1 bleue
  • C : 1 rouge en haut, 1 bleue en bas


Les tordre pour faciliter la soudure. Les souder et les couper.

3 - Les diodes électroluminescentes (LEDs) et le petit condensateur

  • 1) Préparer les pattes des LEDs tricolores :

Les petites à gauche, les grandes à droite.
La première vers l’arrière, la seconde vers l’avant, etc.

  • 2) Les insérer à l’emplacement A, par le dessus, les petites pattes sur la gauche, les grandes vers la droite
  • 3) Tordre les pattes pour aider et souder (et c’est parti pour 12 soudures !)… et couper
  • 4) « Découder » les pattes du condensateur, à la pince
  • 5) L’insérer par le dessus, à l’emplacement B, souder, couper

4 - Le gros condensateur


Insérer le condensateur par le dessus, à l’emplacement A, avec la masse (petite patte ou le signe -) vers le bas du PCB. Le plier pour qu’il soit plus bas que les LEDs. Souder, couper.

5- Le capteur de température-humidité 
(DHT22)

  • 1) Plier les pattes

  • 2) Insérer à l’emplacement B, par le dessous, la grille vers l’extérieur

  • 3) Souder


Voilà, on a fini de souder les différents composants au circuit imprimé, alias le PCB ! Il reste deux blocs à brancher pour finaliser la station environnementale.

6 - Le capteur de particules fines (Sharp)

Brancher le capteur à l’emplacement C. On peut repérer le sens : avec les 2 encoches vers l’extérieur.

7 - La batterie

Brancher la batterie à l’emplacement D, ATTENTION par le dessous du circuit imprimé. Si tout va bien, ça s’allume !


Et on rentre le montage dans un des 2 boîtiers.

Que mesurons-nous ?

La température et l’humidité de l’air :
La température est, en physique, le degré d’agitation moléculaire des particules d’un corps. Ici elle est donnée en °Celsius (où 0°C correspond à la température de l’eau qui gèle et 100°C). La station OpenAir mesure la température de l’air.


Source : Wikipédia


L’humidité relative est le rapport entre la quantité de vapeur d’eau contenue dans l’air et la quantité maximale de vapeur d’eau que pourrait contenir l’air (variable selon la température). Elle est donnée en %. Une valeur de 100% indique la saturation de l’air et donc une condensation de la vapeur d’eau. L’indice de confort thermique Humidex intègre les données d’humidité et de température de l’air. Il permet d’estimer un degré d’inconfort : de aucun à un coup de chaleur.


Les concentrations de particules
Les particules sont « les poussières respirables par l’homme ». Leur diamètre est tellement fin qu’elles pénètrent facilement dans les voies respiratoires. Elles ont des conséquences sur la santé (maladies respiratoires, cardio-vasculaires, cancers, perturbateurs endocriniens…). Les capteurs montés mesurent plus particulièrement les particules les plus fines (d’un diamètre inférieur à 2,5 µm). La principale source d’émission est le trafic routier, mais il existe d’autres sources tels que la fumée des feux de cheminée, les rejets des usines, l’épandage dans les zones agricoles…

Utilisation de la station

  • Allumer / éteindre la station avec l’interrupteur
  • Signification des LEDs

  • Temps d’autonomie et recharge

Le temps d’autonomie est fonction de l’utilisation de la station. En conditions normales, la batterie est prévue pour une autonomie d’environ 7h. Pour recharger la station, ATTENTION, il faut la brancher sur l’adaptateur secteur (présent dans le kit). Environ 1h.

  • Installation de l’application

Pour Android:

Pour iOS AppStore

  • Utilisation de l'application

Quand on lance l’application :

ASCII

Lien utiles :

Code Source :

//Bibliothèques utilisées
#include "DHT.h"
#include <RFduinoBLE.h>

//A commenter pour désactiver les messages de debug sur le port série
#define DEBUG

//Déclaration du pinout
#define BATT_SENS_PIN 2
#define DUST_SENSOR_PIN 3
#define LED_POWER_PIN 4
#define DHT_PIN 5
#define LEDS_PIN 6 // Indicateurs à leds
#define LED_AIR 0
#define LED_HUMIDEX 1
#define LED_BLUETOOTH 2
#define NB_PIXELS 3

//RGB pour traversants, GRB pour CMS
//#define LED_MODE_GRB

const int nb_leds = NB_PIXELS*3;
uint8_t leds[nb_leds];

//Initialisation de la bibliothèque DHT
DHT dht(DHT_PIN, DHT22);

// Variables globales
int i;
float ppm;

long last_time;
int sample_rate = 1000; // en millisecondes
boolean ble_connected = false;

union _floatToChar { // Utilitaire de conversion
  float f;
  char c[4];
} floatToChar;

void setup() {
  #ifdef DEBUG
  Serial.begin(9600); // Initialisation du port série de debug
  Serial.println("OpenAir !");
  #endif

  pinMode(LEDS_PIN, OUTPUT);
  setRGB(LED_BLUETOOTH, 0, 55, 200);
  setRGB(LED_AIR, 0, 55, 200);
  setRGB(LED_HUMIDEX, 0, 55, 200);
  showLeds();

  analogReference(VBG); // Référence de 1.2V interne

  dht.begin(); // Initialisation du DHT22

  pinMode(BATT_SENS_PIN, INPUT); // Initialisation du moniteur de batterie

  pinMode(LED_POWER_PIN, OUTPUT); // Initialisation du capteur de particules fines
  pinMode(DUST_SENSOR_PIN, INPUT);

  i = 0;
  ppm = 0;
  last_time = millis(); // Initialisation de la base de temps

  RFduinoBLE.deviceName = "OpenAir"; // Initialisation de la connexion bluetooth
  RFduinoBLE.advertisementData = "FDS06"; // Numéro de série
  RFduinoBLE.begin();

  setRGB(LED_BLUETOOTH, 0, 0, 0);
  setRGB(LED_AIR, 0, 0, 0);
  setRGB(LED_HUMIDEX, 0, 0, 0);
  showLeds();
}

void loop() {
  // On vérifie que la radio n'utilise pas les ressources
  while (!RFduinoBLE.radioActive);
  while (RFduinoBLE.radioActive);

  // Lecture du capteur de particules fines
  i++;
  digitalWrite(LED_POWER_PIN, LOW);
  delayMicroseconds(280);
  ppm += analogRead(DUST_SENSOR_PIN)*3.6 / 1023.0;
  delayMicroseconds(40);
  digitalWrite(LED_POWER_PIN, HIGH);
  delayMicroseconds(9680);

  if (millis() - last_time> sample_rate) {
    float voltage = ppm / i;
    float ppmpcf = (voltage - 0.0356) * 120000 / 100;
    float humidity = dht.readHumidity();
    float temperature = dht.readTemperature();
    float batterie = (float) analogRead(BATT_SENS_PIN) * 3.6 * 2.0 / 1023.0 ;
    #ifdef DEBUG
      if (isnan(temperature) || isnan(humidity)) {
        Serial.println("Erreur lors de la lecture du DHT22");
      }
    #endif
    sendData(ppmpcf, humidity, temperature, batterie);
    setLedAirQuality(ppmpcf);
    setLedHumidex(humidity, temperature);
    setRGB(LED_BLUETOOTH, 0, 0, (ble_connected) ? 255 : 0);
    showLeds();
    i = 0;
    ppm = 0;
    last_time = millis();
  }
}

void RFduinoBLE_onConnect() {
  ble_connected = true;
  // Selection d'un interval de connection plus lent, pour économiser la batterie et
  // laisser le temps aux zones de code critiques de s'executer sans que la radio reprenne
  // la main.
  RFduinoBLE_update_conn_interval(900, 1000);
}

void RFduinoBLE_onDisconnect() {
  ble_connected = false;
}

void RFduinoBLE_onReceive(char *data, int len) {
  if (len> 0) {
    Serial.println(data);
  }
}

void sendData(float ppmpcf, float humidity, float temperature, float batterie) {
  #ifdef DEBUG
    Serial.print("ppmpcf: ");
    Serial.print(ppmpcf);
    Serial.print("\tHumidity: ");
    Serial.print(humidity);
    Serial.print(" %\tTemperature: ");
    Serial.print(temperature);
    Serial.print(" *C\t Batterie :");
    Serial.print(batterie);
    Serial.println(" V");
  #endif
  char data[16];
  floatToChar.f = ppmpcf;
  data[0] = floatToChar.c[0];data[1] = floatToChar.c[1];
  data[2] = floatToChar.c[2];data[3] = floatToChar.c[3];

  floatToChar.f = humidity;
  data[4] = floatToChar.c[0];data[5] = floatToChar.c[1];
  data[6] = floatToChar.c[2];data[7] = floatToChar.c[3];

  floatToChar.f = temperature;
  data[8] = floatToChar.c[0];data[9] = floatToChar.c[1];
  data[10] = floatToChar.c[2];data[11] = floatToChar.c[3];

  floatToChar.f = batterie;
  data[12] = floatToChar.c[0];data[13] = floatToChar.c[1];
  data[14] = floatToChar.c[2];data[15] = floatToChar.c[3];

  RFduinoBLE.send(data, 16);
}

void setLedAirQuality(float ppmpcf) {
  if (ppmpcf <75) { // Excellent
    setRGB(LED_AIR, 0, 255, 0);
  } else if (ppmpcf <150) { // Very good
    setRGB(LED_AIR, 55, 200, 0);
  } else if (ppmpcf <300) { // Good
    setRGB(LED_AIR, 110, 145, 0);
  } else if (ppmpcf <1050) { // Fair
    setRGB(LED_AIR, 145, 110, 0);
  } else if (ppmpcf <3000) { // Poor
    setRGB(LED_AIR, 200, 55, 0);
  } else { // Very poor
    setRGB(LED_AIR, 255, 0, 0);
  }
}

// https://fr.wikipedia.org/wiki/Indice_humidex
// http://www.physlink.com/Education/AskExperts/ae287.cfm
void setLedHumidex(float H, float T) {
  float e = 6.112 * pow(10, 7.5*T / (237.7+T)) * H/100.0;
  float humidex = T + 5.0/0.9 * (e - 10.0);
  #ifdef DEBUG
    Serial.print("Humidex : ");
    Serial.println(humidex);
  #endif
  if (humidex <29) { // Aucun inconfort
    setRGB(LED_HUMIDEX, 0, 255, 0);
  } else if (humidex <150) { // Un certain inconfort
    setRGB(LED_HUMIDEX, 55, 200, 0);
  } else if (humidex <300) { // Beaucoup d'inconfort : évitez les efforts
    setRGB(LED_HUMIDEX, 110, 145, 0);
  } else if (humidex <1050) { // Danger
    setRGB(LED_HUMIDEX, 145, 110, 0);
  } else { // Coup de chaleur imminent
    setRGB(LED_HUMIDEX, 255, 0, 0);
  }
}

void setRGB(int led, uint8_t r, uint8_t g, uint8_t b) {
  #ifdef LED_MODE_GRB
    leds[led*3] = g*0.3;
    leds[led*3+1] = r*0.3;
  #else
    leds[led*3] = r*0.3;
    leds[led*3+1] = g*0.3;
  #endif
  leds[led*3+2] = b*0.3;
}

void showLeds() {
  noInterrupts();
  for (int wsOut = 0; wsOut <nb_leds; wsOut++) {
    for (int x=7; x>=0; x--) {
      NRF_GPIO->OUTSET = (1UL <<LEDS_PIN);
      if (leds[wsOut] & (0x01 <<x)) {
        __ASM ( \
                  " NOP\n\t" \
                  " NOP\n\t" \
                  " NOP\n\t" \
                  " NOP\n\t" \
                  " NOP\n\t" \
                  );
        NRF_GPIO->OUTCLR = (1UL <<LEDS_PIN);
      } else {
        NRF_GPIO->OUTCLR = (1UL <<LEDS_PIN);
        __ASM ( \
                  " NOP\n\t" \
                  " NOP\n\t" \
                  " NOP\n\t" \
                  );
      }
    }
  }
  delayMicroseconds(50); // latch and reset WS2812.
  interrupts();
}

Développement v2

Nous sommes en train de travailler sur la version 2 de la station qui intégrera des capteurs de gaz (Ozone et NO2).

Retour à la page principage

wiki/projets/open-air/proto.1505658587.txt.gz · Dernière modification: 2017/09/17 14:29 de Vincent Dupuis