[Tuto] Mesurer la qualité de l'air de votre intérieur
Publié : 01 déc. 2017, 18:37
Bonjour à tous,
Ma maison est très poussiéreuse (pourtant récente...) et nous n'avons pas forcément le réflexe d'aérer tous les jours... Après avoir lu un article sur le calcul de la qualité de l'air en intérieur, j'ai imaginé un boitier avec écran qui donnerait l'info en temps réel et l'enverrait à Domoticz... Et c'est parti !!!
Tout d'abord, full credits à l'auteur du code original dont je me suis inspiré. Son site est génial et pleins d'infos. Je le consulte régulièrement :
https://projetsdiy.fr & https://projetsdiy.fr/calculer-indice-q ... o-esp8266/.
UN GRAND MERCI A LUI !
Ceci est la première version de mon projet. Il s'appuie sur un capteur à led DSM501A qui nécessite un temps de chauffe d'une minute avant de lancer une mesure et qui effectue la mesure sur 5mn... Il vous faudra donc être très patient avant de collecter les premières infos. Par contre, dans le code je fais envoyer un premier signal à Domoticz au bout de 2mn30. Vous verrez donc les custom sensors se mettrent à jour avant d'avoir les premières mesures.
Je ne sais pas si ce capteur est très fiable... A vous de vous faire votre propre avis mais en fouinant sur le web au sujet de la qualité de l'air, j'ai vu que le capteur DSM501A utilisé dans ce tuto équipe par exemple le purificateur d'air de Rowenta (Intense Pure Air XL par ex). D'ailleurs la finalité de ce projet est de me construire moi-même un purificateur piloté par Domoticz dans les semaines à venir...
J'habite à proximité d'un grand axe routier sur lequel des mesures de qualité ont été effectuées il y a peu. J'ai lu le rapport mais ce n'est pas concluant... J'ai également trouvé des articles au sujet de la pollution de l'air aux particules fines à proximité des grands axes routiers / industries et leurs effets sur la santé...
Bref, je suis également tombé sur un projet qui m'a tout de suite plu. Ce projet s'appuie sur un capteur laser cette fois. J'ai commandé le capteur en question et je vais me lancer dans le projet : http://luftdaten.info/fr/accueil/
N'étant pas un pro de la programmation, j'ai passé plusieurs heures sur ce projet... Alors, voici ma bête :
Gallerie : https://drive.google.com/open?id=1RE81_ ... _h92BB9uBP
J'ajouterai une vidéo


C'est parti :
__________________________________________________________________________________________________________________
MATERIEL REQUIS :
1 x WEMOS D1 mini (ou ESP8266) : https://fr.aliexpress.com/item/5pcs-lot ... 0.0.JyPFhD
1 x module DSM501A : https://fr.aliexpress.com/item/DSM501A- ... 72840.html
1 x Ecran OLED 128x64 0,96" : https://fr.aliexpress.com/store/product ... b1d7x8ZYYo
1 x mini plaque montage (optionnel c'est uniquement pour connecter les masses donc vous pouvez souder les fils)
Quelques fils Dupont wire et 1 vis !
Et si vous avez accès à une imprimante 3D : du fil, un pistolet à colle et un peu de colle liquide
__________________________________________________________________________________________________________________
BRANCHEMENTS :
COTE DSM501A - DE GAUCHE A DROITE :
1er fil : Inutilisé
2ème fil : Broche D0 du Wemos
3ème fil : +5v du Wemos
4ème fil : Broche D5 du Wemos
5ème fil : sur le Ground du Wemos
COTE ECRAN OLED :
GND : sur le ground du Wemos
VCC : sur le 3.3V
SCL : sur la broche D1 du Wemos
SDA : sur la broche D2 du Wemos
__________________________________________________________________________________________________________________
COTE DOMOTICZ :
- Création d'un Custom Sensor "PM 10" avec comme unité : µg/m3
- Création d'un Custom Sensor "PM 2.5" avec comme unité µg/m3
- Création d'un custom sensor texte
__________________________________________________________________________________________________________________
PROGRAMMATION :
Pour la partie programmation, vous aurez besoin :
- Drivers CH341SER https://drive.google.com/open?id=1Z7eb5 ... OcKusoSHQc
- Arduino IDE (1.6.5)
- Les librairies Arduino suivantes :
<SimpleTimer.h>
<ESP8266WiFi.h>
ESP8266HTTPClient.h>
<SPI.h>
<Wire.h>
<Adafruit_GFX.h>
<Adafruit_SSD1306.h>
Je ne détaillerai pas ici comment inclure l'ESP8266 dans l'Arduino IDE, vous trouverez facilement des tutos.
ATTENTION, des réglages dans le fichier Adafruit_SSD1306.h de la librairie sont nécessaires pour bien déclarer votre écran OLED.
Voici ci-dessous le code dans lequel il vous faudra modifier :
- Ligne 47 : le nom de votre réseau Wifi
- Ligne 48 : le mot de passe de votre wifi
- Ligne 49 : l'adresse IP de Domoticz
- Ligne 50 : le port de Domoticz
- Ligne 234 : mettre l'IDX du custom sensor PM 10 à la place de VOTREIDXPM10
- Ligne 239 : mettre l'IDX du custom sensor PM 2.5 à la place de VOTREIDXPM25
- Ligne 244 : mettre l'IDX du text sensor Qualité de l'air intérieur à la place de QUALITEAIR
__________________________________________________________________________________________________________________
COTE BOITIER, IMPRESSION 3D :
https://drive.google.com/open?id=1nQmcn ... f-7ihyVsvS
VERSION 1.1 : https://drive.google.com/open?id=1P44vB ... zWaRCJU0ZI
ou
https://www.thingiverse.com/thing:2683047
Ma maison est très poussiéreuse (pourtant récente...) et nous n'avons pas forcément le réflexe d'aérer tous les jours... Après avoir lu un article sur le calcul de la qualité de l'air en intérieur, j'ai imaginé un boitier avec écran qui donnerait l'info en temps réel et l'enverrait à Domoticz... Et c'est parti !!!
Tout d'abord, full credits à l'auteur du code original dont je me suis inspiré. Son site est génial et pleins d'infos. Je le consulte régulièrement :
https://projetsdiy.fr & https://projetsdiy.fr/calculer-indice-q ... o-esp8266/.
UN GRAND MERCI A LUI !
Ceci est la première version de mon projet. Il s'appuie sur un capteur à led DSM501A qui nécessite un temps de chauffe d'une minute avant de lancer une mesure et qui effectue la mesure sur 5mn... Il vous faudra donc être très patient avant de collecter les premières infos. Par contre, dans le code je fais envoyer un premier signal à Domoticz au bout de 2mn30. Vous verrez donc les custom sensors se mettrent à jour avant d'avoir les premières mesures.
Je ne sais pas si ce capteur est très fiable... A vous de vous faire votre propre avis mais en fouinant sur le web au sujet de la qualité de l'air, j'ai vu que le capteur DSM501A utilisé dans ce tuto équipe par exemple le purificateur d'air de Rowenta (Intense Pure Air XL par ex). D'ailleurs la finalité de ce projet est de me construire moi-même un purificateur piloté par Domoticz dans les semaines à venir...
J'habite à proximité d'un grand axe routier sur lequel des mesures de qualité ont été effectuées il y a peu. J'ai lu le rapport mais ce n'est pas concluant... J'ai également trouvé des articles au sujet de la pollution de l'air aux particules fines à proximité des grands axes routiers / industries et leurs effets sur la santé...
Bref, je suis également tombé sur un projet qui m'a tout de suite plu. Ce projet s'appuie sur un capteur laser cette fois. J'ai commandé le capteur en question et je vais me lancer dans le projet : http://luftdaten.info/fr/accueil/
N'étant pas un pro de la programmation, j'ai passé plusieurs heures sur ce projet... Alors, voici ma bête :
Gallerie : https://drive.google.com/open?id=1RE81_ ... _h92BB9uBP
J'ajouterai une vidéo


C'est parti :
__________________________________________________________________________________________________________________
MATERIEL REQUIS :
1 x WEMOS D1 mini (ou ESP8266) : https://fr.aliexpress.com/item/5pcs-lot ... 0.0.JyPFhD
1 x module DSM501A : https://fr.aliexpress.com/item/DSM501A- ... 72840.html
1 x Ecran OLED 128x64 0,96" : https://fr.aliexpress.com/store/product ... b1d7x8ZYYo
1 x mini plaque montage (optionnel c'est uniquement pour connecter les masses donc vous pouvez souder les fils)
Quelques fils Dupont wire et 1 vis !
Et si vous avez accès à une imprimante 3D : du fil, un pistolet à colle et un peu de colle liquide
__________________________________________________________________________________________________________________
BRANCHEMENTS :
COTE DSM501A - DE GAUCHE A DROITE :
1er fil : Inutilisé
2ème fil : Broche D0 du Wemos
3ème fil : +5v du Wemos
4ème fil : Broche D5 du Wemos
5ème fil : sur le Ground du Wemos
COTE ECRAN OLED :
GND : sur le ground du Wemos
VCC : sur le 3.3V
SCL : sur la broche D1 du Wemos
SDA : sur la broche D2 du Wemos
__________________________________________________________________________________________________________________
COTE DOMOTICZ :
- Création d'un Custom Sensor "PM 10" avec comme unité : µg/m3
- Création d'un Custom Sensor "PM 2.5" avec comme unité µg/m3
- Création d'un custom sensor texte
__________________________________________________________________________________________________________________
PROGRAMMATION :
Pour la partie programmation, vous aurez besoin :
- Drivers CH341SER https://drive.google.com/open?id=1Z7eb5 ... OcKusoSHQc
- Arduino IDE (1.6.5)
- Les librairies Arduino suivantes :
<SimpleTimer.h>
<ESP8266WiFi.h>
ESP8266HTTPClient.h>
<SPI.h>
<Wire.h>
<Adafruit_GFX.h>
<Adafruit_SSD1306.h>
Je ne détaillerai pas ici comment inclure l'ESP8266 dans l'Arduino IDE, vous trouverez facilement des tutos.
ATTENTION, des réglages dans le fichier Adafruit_SSD1306.h de la librairie sont nécessaires pour bien déclarer votre écran OLED.
Voici ci-dessous le code dans lequel il vous faudra modifier :
- Ligne 47 : le nom de votre réseau Wifi
- Ligne 48 : le mot de passe de votre wifi
- Ligne 49 : l'adresse IP de Domoticz
- Ligne 50 : le port de Domoticz
- Ligne 234 : mettre l'IDX du custom sensor PM 10 à la place de VOTREIDXPM10
- Ligne 239 : mettre l'IDX du custom sensor PM 2.5 à la place de VOTREIDXPM25
- Ligne 244 : mettre l'IDX du text sensor Qualité de l'air intérieur à la place de QUALITEAIR
Code : Tout sélectionner
#include <SimpleTimer.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
/* D'après le code original de ProjetsDIY : https://projetsdiy.fr
* Source : https://projetsdiy.fr/calculer-indice-qualite-air-iaq-ciqa-iqa-dsm501-arduino-esp8266/
* Code adapté par Steph D. pour Easydomoticz : https://easydomoticz.com/forum/viewtopic.php?f=24&t=5412
* Branchements :
COTE DSM501A - DE GAUCHE A DROITE :
1er fil : Inutilisé
2ème fil : Broche D0 du Wemos
3ème fil : +5v du Wemos
4ème fil : Broche D5 du Wemos
5ème fil : sur le Ground du Wemos
COTE ECRAN OLED :
GND : sur le ground du Wemos
VCC : sur le 3.3V
SCL : sur la broche D1 du Wemos
SDA : sur la broche D2 du Wemos
*/
#define DUST_SENSOR_DIGITAL_PIN_PM10 D0 // DSM501 Pin 2 of DSM501 (jaune / Yellow)
#define DUST_SENSOR_DIGITAL_PIN_PM25 D5 // DSM501 Pin 4 (rouge / red)
#define COUNTRY 0 // 0. France, 1. Europe, 2. USA/China
#define EXCELLENT "EXCELLENT"
#define GOOD "BON"
#define ACCEPTABLE "MOYEN"
#define MODERATE "MEDIOCRE"
#define HEAVY "MAUVAIS"
#define SEVERE "TRES_MAUVAIS"
#define HAZARDOUS "DANGEREUX"
#define OLED_RESET -1
Adafruit_SSD1306 display(OLED_RESET);
const char* ssid = "VOTRE SSID"; // SSID
const char* password = "VOTRE PASSWORD"; // Password
const char* host = "IP DE DOMOTICZ"; // IP serveur - Server IP
const int port = PORT DE DOMOTICZ; // Port serveur - Server Port
// NE PLUS RIEN MODIFIER EN DESSOUS DE CETTE LIGNE SAUF LES 3 IDX DOMOTICZ
const int watchdog = 150000; // Fréquence du watchdog - Watchdog frequency
unsigned long previousMillis = millis();
HTTPClient http;
unsigned long duration;
unsigned long starttime;
unsigned long endtime;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
unsigned long SLEEP_TIME = 5 * 1000; // Sleep time between reads (in milliseconds)
unsigned long sampletime_ms = 5 * 60 * 1000; // Durée de mesure - sample time (ms)
struct structAQI{
// variable enregistreur - recorder variables
unsigned long durationPM10;
unsigned long lowpulseoccupancyPM10 = 0;
unsigned long durationPM25;
unsigned long lowpulseoccupancyPM25 = 0;
unsigned long starttime;
unsigned long endtime;
// Sensor AQI data
float concentrationPM25 = 0;
float concentrationPM10 = 0;
int AqiPM10 = -1;
int AqiPM25 = -1;
// Indicateurs AQI - AQI display
int AQI = 0;
String AqiString = "";
int AqiColor = 0;
};
struct structAQI AQI;
SimpleTimer timer;
void updateAQILevel(){
AQI.AQI = AQI.AqiPM10;
}
void updateAQI() {
// Actualise les mesures - update measurements
AQI.endtime = millis();
float ratio = AQI.lowpulseoccupancyPM10 / (sampletime_ms * 10.0);
float concentration = 1.1 * pow( ratio, 3) - 3.8 *pow(ratio, 2) + 520 * ratio + 0.62; // using spec sheet curve
if ( sampletime_ms < 3600000 ) { concentration = concentration * ( sampletime_ms / 3600000.0 ); }
AQI.lowpulseoccupancyPM10 = 0;
AQI.concentrationPM10 = concentration;
ratio = AQI.lowpulseoccupancyPM25 / (sampletime_ms * 10.0);
concentration = 1.1 * pow( ratio, 3) - 3.8 *pow(ratio, 2) + 520 * ratio + 0.62;
if ( sampletime_ms < 3600000 ) { concentration = concentration * ( sampletime_ms / 3600000.0 ); }
AQI.lowpulseoccupancyPM25 = 0;
AQI.concentrationPM25 = concentration;
Serial.print("Concentrations => PM2.5: "); Serial.print(AQI.concentrationPM25); Serial.print(" | PM10: "); Serial.println(AQI.concentrationPM10);
AQI.starttime = millis();
// Actualise l'AQI de chaque capteur - update AQI for each sensor
if ( COUNTRY == 0 ) {
// France
AQI.AqiPM25 = getATMO( 0, AQI.concentrationPM25 );
AQI.AqiPM10 = getATMO( 1, AQI.concentrationPM10 );
} else if ( COUNTRY == 1 ) {
// Europe
AQI.AqiPM25 = getACQI( 0, AQI.concentrationPM25 );
AQI.AqiPM10 = getACQI( 1, AQI.concentrationPM10 );
} else {
// USA / China
AQI.AqiPM25 = getAQI( 0, AQI.concentrationPM25 );
AQI.AqiPM10 = getAQI( 0, AQI.concentrationPM10 );
}
// Actualise l'indice AQI - update AQI index
updateAQILevel();
updateAQIDisplay();
Serial.print("AQIs => PM25: "); Serial.print(AQI.AqiPM25); Serial.print(" | PM10: "); Serial.println(AQI.AqiPM10);
Serial.print(" | AQI: "); Serial.println(AQI.AQI); Serial.print(" | Message: "); Serial.println(AQI.AqiString);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.setRotation(2);
display.display();
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(37,24);
display.println("DEMARRAGE");
display.print(" SYSTEME ");
display.display();
delay(2000);
display.clearDisplay();
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(22,20);
display.print("WiFi CONNECTE!");
delay(2000);
display.display();
display.clearDisplay();
pinMode(DUST_SENSOR_DIGITAL_PIN_PM10,INPUT);
pinMode(DUST_SENSOR_DIGITAL_PIN_PM25,INPUT);
// wait 60s for DSM501 to warm up
for (int i = 1; i <= 60; i++)
{
delay(1000); // 1s
Serial.print(i);
Serial.println(" s (wait 60s for DSM501 to warm up)");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(19,20);
display.println("Chauffe capteur");
display.setCursor(34,36);
display.print(i); display.print(" s / 60s");
delay(1);
display.display();
display.clearDisplay();
}
Serial.println("Ready!");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("CAPTEUR OK");
display.println("MESURE...");
display.println("PATIENTEZ");
delay(2000);
display.display();
display.clearDisplay();
AQI.starttime = millis();
timer.setInterval(sampletime_ms, updateAQI);
}
void loop() {
AQI.lowpulseoccupancyPM10 += pulseIn(DUST_SENSOR_DIGITAL_PIN_PM10, LOW);
AQI.lowpulseoccupancyPM25 += pulseIn(DUST_SENSOR_DIGITAL_PIN_PM25, LOW);
timer.run();
unsigned long currentMillis = millis();
if ( currentMillis - previousMillis > watchdog ) {
previousMillis = currentMillis;
if(WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi not connected !");
} else {
Serial.println("Send data to Domoticz");
float PM10 = (AQI.concentrationPM10);
float PM25 = (AQI.concentrationPM25);
String url = "/json.htm?type=command¶m=udevice&idx=VOTREIDXPM10&nvalue=0&svalue=";
url += String(PM10);
sendDomoticz(url);
String url2 = "/json.htm?type=command¶m=udevice&idx=VOTREIDXPM25&nvalue=0&svalue=";
url2 += String(PM25);
sendDomoticz(url2);
String url3 = "/json.htm?type=command¶m=udevice&idx=QUALITEAIR&nvalue=0&svalue=";
url3 += String(AQI.AqiString);
sendDomoticz(url3);
display.setTextSize(1);
display.setTextColor(BLACK, WHITE);
display.setCursor(0,0);
display.println(" IQA DE STEPH ");
display.setTextColor(WHITE);
display.println("");
display.print("PM10 = "); display.print(PM10); display.println(" ug/m3");
display.println("");
display.print("PM2.5 = "); display.print(PM25); display.println(" ug/m3");
display.println("");
display.print("AIR : "); display.print(AQI.AqiString);
delay(1);
display.display();
display.clearDisplay();
}
}
}
/*
* Calcul l'indice de qualité de l'air français ATMO
* Calculate French ATMO AQI indicator
*/
int getATMO( int sensor, float density ){
if ( sensor == 0 ) { //PM2,5
if ( density <= 11 ) {
return 1;
} else if ( density > 11 && density <= 24 ) {
return 2;
} else if ( density > 24 && density <= 36 ) {
return 3;
} else if ( density > 36 && density <= 41 ) {
return 4;
} else if ( density > 41 && density <= 47 ) {
return 5;
} else if ( density > 47 && density <= 53 ) {
return 6;
} else if ( density > 53 && density <= 58 ) {
return 7;
} else if ( density > 58 && density <= 64 ) {
return 8;
} else if ( density > 64 && density <= 69 ) {
return 9;
} else {
return 10;
}
} else {
if ( density <= 6 ) {
return 1;
} else if ( density > 6 && density <= 13 ) {
return 2;
} else if ( density > 13 && density <= 20 ) {
return 3;
} else if ( density > 20 && density <= 27 ) {
return 4;
} else if ( density > 27 && density <= 34 ) {
return 5;
} else if ( density > 34 && density <= 41 ) {
return 6;
} else if ( density > 41 && density <= 49 ) {
return 7;
} else if ( density > 49 && density <= 64 ) {
return 8;
} else if ( density > 64 && density <= 79 ) {
return 9;
} else {
return 10;
}
}
}
void sendDomoticz(String url){
Serial.print("connecting to ");
Serial.println(host);
Serial.print("Requesting URL: ");
Serial.println(url);
http.begin(host,port,url);
int httpCode = http.GET();
if (httpCode) {
if (httpCode == 200) {
String payload = http.getString();
Serial.println("Domoticz response ");
Serial.println(payload);
}
}
Serial.println("closing connection");
http.end();
}
void updateAQIDisplay(){
/*
* 1 EXCELLENT
* 2 GOOD
* 3 ACCEPTABLE
* 4 MODERATE
* 5 HEAVY
* 6 SEVERE
* 7 HAZARDOUS
*/
if ( COUNTRY == 0 ) {
// Système ATMO français - French ATMO AQI system
switch ( AQI.AQI) {
case 10:
AQI.AqiString = SEVERE;
break;
case 9:
AQI.AqiString = HEAVY;
break;
case 8:
AQI.AqiString = HEAVY;
break;
case 7:
AQI.AqiString = MODERATE;
break;
case 6:
AQI.AqiString = MODERATE;
break;
case 5:
AQI.AqiString = ACCEPTABLE;
break;
case 4:
AQI.AqiString = GOOD;
break;
case 3:
AQI.AqiString = GOOD;
break;
case 2:
AQI.AqiString = EXCELLENT;
break;
case 1:
AQI.AqiString = EXCELLENT;
break;
}
} else if ( COUNTRY == 1 ) {
// European CAQI
switch ( AQI.AQI) {
case 25:
AQI.AqiString = GOOD;
break;
case 50:
AQI.AqiString = ACCEPTABLE;
break;
case 75:
AQI.AqiString = MODERATE;
break;
case 100:
AQI.AqiString = HEAVY;
break;
default:
AQI.AqiString = SEVERE;
}
} else if ( COUNTRY == 2 ) {
// USA / CN
if ( AQI.AQI <= 50 ) {
AQI.AqiString = GOOD;
} else if ( AQI.AQI > 50 && AQI.AQI <= 100 ) {
AQI.AqiString = ACCEPTABLE;
} else if ( AQI.AQI > 100 && AQI.AQI <= 150 ) {
AQI.AqiString = MODERATE;
} else if ( AQI.AQI > 150 && AQI.AQI <= 200 ) {
AQI.AqiString = HEAVY;
} else if ( AQI.AQI > 200 && AQI.AQI <= 300 ) {
AQI.AqiString = SEVERE;
} else {
AQI.AqiString = HAZARDOUS;
}
}
}
/*
* CAQI Européen - European CAQI level
* source : http://www.airqualitynow.eu/about_indices_definition.php
*/
int getACQI( int sensor, float density ){
if ( sensor == 0 ) { //PM2,5
if ( density == 0 ) {
return 0;
} else if ( density <= 15 ) {
return 25 ;
} else if ( density > 15 && density <= 30 ) {
return 50;
} else if ( density > 30 && density <= 55 ) {
return 75;
} else if ( density > 55 && density <= 110 ) {
return 100;
} else {
return 150;
}
} else { //PM10
if ( density == 0 ) {
return 0;
} else if ( density <= 25 ) {
return 25 ;
} else if ( density > 25 && density <= 50 ) {
return 50;
} else if ( density > 50 && density <= 90 ) {
return 75;
} else if ( density > 90 && density <= 180 ) {
return 100;
} else {
return 150;
}
}
}
/*
* AQI formula: https://en.wikipedia.org/wiki/Air_Quality_Index#United_States
* Arduino code https://gist.github.com/nfjinjing/8d63012c18feea3ed04e
* On line AQI calculator https://www.airnow.gov/index.cfm?action=resources.conc_aqi_calc
*/
float calcAQI(float I_high, float I_low, float C_high, float C_low, float C) {
return (I_high - I_low) * (C - C_low) / (C_high - C_low) + I_low;
}
int getAQI(int sensor, float density) {
int d10 = (int)(density * 10);
if ( sensor == 0 ) {
if (d10 <= 0) {
return 0;
}
else if(d10 <= 120) {
return calcAQI(50, 0, 120, 0, d10);
}
else if (d10 <= 354) {
return calcAQI(100, 51, 354, 121, d10);
}
else if (d10 <= 554) {
return calcAQI(150, 101, 554, 355, d10);
}
else if (d10 <= 1504) {
return calcAQI(200, 151, 1504, 555, d10);
}
else if (d10 <= 2504) {
return calcAQI(300, 201, 2504, 1505, d10);
}
else if (d10 <= 3504) {
return calcAQI(400, 301, 3504, 2505, d10);
}
else if (d10 <= 5004) {
return calcAQI(500, 401, 5004, 3505, d10);
}
else if (d10 <= 10000) {
return calcAQI(1000, 501, 10000, 5005, d10);
}
else {
return 1001;
}
} else {
if (d10 <= 0) {
return 0;
}
else if(d10 <= 540) {
return calcAQI(50, 0, 540, 0, d10);
}
else if (d10 <= 1540) {
return calcAQI(100, 51, 1540, 541, d10);
}
else if (d10 <= 2540) {
return calcAQI(150, 101, 2540, 1541, d10);
}
else if (d10 <= 3550) {
return calcAQI(200, 151, 3550, 2541, d10);
}
else if (d10 <= 4250) {
return calcAQI(300, 201, 4250, 3551, d10);
}
else if (d10 <= 5050) {
return calcAQI(400, 301, 5050, 4251, d10);
}
else if (d10 <= 6050) {
return calcAQI(500, 401, 6050, 5051, d10);
}
else {
return 1001;
}
}
}__________________________________________________________________________________________________________________
COTE BOITIER, IMPRESSION 3D :
https://drive.google.com/open?id=1nQmcn ... f-7ihyVsvS
VERSION 1.1 : https://drive.google.com/open?id=1P44vB ... zWaRCJU0ZI
ou
https://www.thingiverse.com/thing:2683047