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 <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Arduino.h>

#include <ESP8266WiFiMulti.h>

ESP8266WiFiMulti WiFiMulti;

//unsigned long lastTime = 0;
//unsigned long timerDelay = 10000;
 
void setup() {
  // our debugging output
  Serial.begin(9600);
  Serial.println();

  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }
  //WiFi.begin(ssid, password);
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("ec_temporal", "*******");
  Serial.println("Connecting");
  
  while(WiFiMulti.run() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.");
  
}
 
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;
    
void loop() {
 
  if (readPMSdata(&Serial)) {
    // reading data was successful!

    //if ((millis() - lastTime) > timerDelay) {
      // Check WiFi connection status
      if(WiFiMulti.run() == WL_CONNECTED){
        httpGETRequest(String(data.pm25_standard));
        Serial.println(String(data.pm25_standard));
      } else {
        Serial.println("WiFi Disconnected");
      }
      //lastTime = millis();
    //}
  }
  ESP.deepSleep(30e6);
}
 
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;
}


String httpGETRequest(String val) {
  HTTPClient http;
  WiFiClient client;
    
  // Your IP address with path or Domain name with URL path 
  http.begin(client,"http://steam.iesportdalcudia.org/send.php?estacio=1&val=" + val);
  
  // 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();

  return payload;
}



5. Lloc web

Codi Web




6. Fotografies de muntatges

Pendent de publicació