Mesura de la qualitat de l'aire PM 2.5

IES Port d'Alcúdia 2021



1. Introducció
El present projecte, desenvolupat a l'IES Port d'Alcúdia, es basa en la construcció d'un dispositiu de baix cost per mesurar les partícules de contaminació atmofèrica. Les dades obtingudes pel sensor es traspassen a una web en temps real (quan el dispositiu està en funcionament). Es mesuren les partícules PM1, PM2.5 i PM 10 en ug/m3. A les web es mostren els valors instantanis actuals i les sèries temporals històriques de les mesures


2. Components
pms5003
Sensor de partícules PMS5003
Controlador NodeMCU Lolin v3
Router SIM 4G portàtil

Power Bank solar


3. Esquema


A la següent imatge es mostren les connexions que s'han de realitzar. A part d'aquestes s'ha d'unir el pin D0 amb el pin RST del nodemcu per tal de poder fer un deep sleep i després continuar. Això es fa per optimitzar la energia que es conumeix del power bank.






4. Codi arduino

A l'IDE s'ha de seleccionar la placa: NodeMCU 1.0 (ESP-12E Module)

 
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
#include <Arduino.h>
 
#include <ESP8266WiFiMulti.h>
 
ESP8266WiFiMulti WiFiMulti;
 
struct pms5003data {
  uint16_t framelen;
  uint16_t pm10_standard, pm25_standard, pm100_standard;
  uint16_t pm10_env, pm25_env, pm100_env;
  uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
  uint16_t unused;
  uint16_t checksum;
};
 
struct pms5003data data;
 
HTTPClient http;
WiFiClient client;
 
void setup() {
 
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("ec_temporal", "*******");
  WiFiMulti.addAP("SATALAIA", "********");
  WiFiMulti.addAP("tsalasWIFI", "******");
 
  while(WiFiMulti.run() != WL_CONNECTED) {
    delay(250);
    //Serial.print(".");
  }
 
  //Serial.println("");
  //Serial.print("Connectat a la WIFI amb la ip: ");
  //Serial.println( WiFi.localIP() );
 
  Serial.flush();
  delay(500);
  while (not (readPMSdata(&Serial))) {  
  }
 
  if( WiFiMulti.run() == WL_CONNECTED ) {
    httpGETRequest( String( data.pm10_standard ), String( data.pm25_standard ), String( data.pm100_standard ) );
    //Serial.println(String(data.pm25_standard));
  } else {
     //Serial.println("WiFi Disconnected");
  }
 
  //Serial.println("Dormint 30s...");
  ESP.deepSleep(30e6);
 
}
 
void loop() {
}
 
boolean readPMSdata(Stream *s) {
  if (! s->available()) {
    return false;
  }
 
  // Read a byte at a time until we get to the special '0x42' start-byte
  if (s->peek() != 0x42) {
    s->read();
    return false;
  }
 
  // Now read all 32 bytes
  if (s->available() < 32) {
    return false;
  }
 
  uint8_t buffer[32];    
  uint16_t sum = 0;
  s->readBytes(buffer, 32);
 
  // get checksum ready
  for (uint8_t i=0; i<30; i++) {
    sum += buffer[i];
  }
 
  // The data comes in endian'd, this solves it so it works on all platforms
  uint16_t buffer_u16[15];
  for (uint8_t i=0; i<15; i++) {
    buffer_u16[i] = buffer[2 + i*2 + 1];
    buffer_u16[i] += (buffer[2 + i*2] << 8);
  }
 
  // put it into a nice struct :)
  memcpy((void *)&data, (void *)buffer_u16, 30);
 
  if (sum != data.checksum) {
    //Serial.println("Checksum failure");
    return false;
  }
  // success!
  return true;
}
 
 
void httpGETRequest(String val1, String val2, String val3) {
 
  // url 
  http.begin( client,"http://steam.iesportdalcudia.org/send.php?estacio=1&val1=" + val1 + "&val2=" + val2 + "&val3=" + val3 ); // PM 1.0, PM 2.5, PM 10
 
  // Send HTTP POST request
  int httpResponseCode = http.GET();
 
  String payload = "{}"; 
 
  if (httpResponseCode>0) {
    //Serial.print("HTTP Response code: ");
    //Serial.println(httpResponseCode);
    payload = http.getString();
  }
  else {
    //Serial.print("Error code: ");
    //Serial.println(httpResponseCode);
  }
  // Free resources
  http.end();
}


5. Lloc web

Codi Web




6. Fotografies de muntatges

Pendent de publicació