Partículas en atmósfera

 

          Las partículas en suspensión en el aire son indicativo de la calidad de este. Son sólidas o liquidas de tamaños variables. En este caso nos centramos en la medida de entre 2,5 a 10 micras. Son las partículas "respirables" que son capaces de llegar (y quedarse) en lo más profundo de los alveolos pulmonares y ser responsables de enfermedades respiratorias. Más información en Wikipedia

          Normalmente se miden los datos por m3 de partículas con tamaños de 2,5µ y 10µ.
          Pueden consultarse datos mundiales de calidad del aire en esta web

          En PM3003 viene con un cable de conexión, pero ¡¡OJO!!, los cables rojo y negro no corresponden con el positivo y negativo, a la derecha tenemos las conexiones correctas.

          Para gestionar los datos he usado un esp8266 Nodemcu que se conecta por el Tx y Rx con niveles de 3,3 voltios. Recogidos los datos cada 5 minutos, se envían al NAS para que ParticulasProcesar.php los guarde en un dos ficheros de texto y un ParticulasGrafica.php genera la gráfica del día.
          Se guardan y grafican los datos de PM2,5 y PM10. También se guardan las medias de cada día para un visión anual.

          El sensor posee un pequeño ventilador para absorber el aire y contabilizar las partículas por medio de un laser y la dispersión provocada por estas y en función de una curva de tiempo, el microprocesador del sensor nos da las partículas por unidad de volumen.
          Montaje en una caja estanca de conexiones para exteriores. Al menos, dejar abiertos los agujeros inferiores. Absorción de aire con un cuello de botella encarada al ventilador del sensor. Todo sellado con pegamento térmico. Alimentación con 5 voltios y por lo menos 500mA.
          En este montaje he usado un sensor PM3003 con buena sensibilidad y precio razonable para detectar partículas entre 1 y 10µ, aunque solo usaré las de 2,5 a 10. La salida es por puerto serie con niveles 3,3 voltios, pero el sensor se alimenta a 5 voltios.
Medida del sensor muy cerca de carretera de doble via a cinco Km de centro urbano. Subidas que corresponden con las horas de ida y regreso de vehículos.
Otro día, con bastante viento matutino y calma total por la tarde.
Programa para Nodemcu

#include <ESP8266WiFi.h>
#include "PMS.h"                           //librería para PM3003
const char* ssid     = "Jopapa";
const char* password = "**************";
const char* host = "192.168.1.xxx";    //IP de mi NAS


long pmcf10=0;
long pmcf25=0;
long pmcf100=0;
long mPM2=0; long mPM10=0;
//long partitotal=0;
String dato1=""; String dato2="";String dato10="";
char buffer[3]=" ";
char* formato="%i";

PMS pms(Serial);
PMS::DATA data;

void setup()
{
Serial.begin(9600);  
IPAddress ip(192, 168, 1, 79);     //IP statica para el Nodemcu
IPAddress gateway(192,168,1,1);
IPAddress subnet (255,255,255,0);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password); 
WiFi.config(ip,gateway,subnet);
while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print(".");
}
pms.passiveMode();    // Switch to passive mode
}

void loop(){
  Serial.println("Despertando, esperar 25 segundos para lectura fiable");
  pms.wakeUp();
  delay(19000);
//  partitotal=0;
  mPM2=0; mPM10=0;
  for (int i=0; i<=4; i++){   //Se hacen 5 medidas separadas y saco media
   pms.requestRead();
   if (pms.readUntil(data)){
    Serial.print("PM 1.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_1_0);
    pmcf10 = data.PM_AE_UG_1_0;
    Serial.print("PM 2.5 (ug/m3): ");
    Serial.println(data.PM_AE_UG_2_5);
    pmcf25 = data.PM_AE_UG_2_5;  
    Serial.print("PM 10.0 (ug/m3): ");
    Serial.println(data.PM_AE_UG_10_0);
    pmcf100 = data.PM_AE_UG_10_0;
   }
   else
   {
    Serial.println("Sin datos.");
   }
   mPM2 = mPM2+pmcf25;
   mPM10 = mPM10+pmcf100;
   delay(1000);  //cinco segundos en total
  } 
  mPM2=mPM2/5;
  mPM10=mPM10/5;
  Serial.println(mPM2);
  Serial.println(mPM10);
  Serial.println("Modo sleep por 4' 30''");  //En total, son 5'
  pms.sleep();     //Modo Sleep con detención del ventilador
 
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
  Serial.println("Fallo de conexión");
  return;
}
  String url = "/consumovatios/src/consumo/ParticulasProcesar.php";
//  String dato1 = "?PM1=";
  String dato2 = "?PM2=";
  String dato10 = "&PM10=";
client.print(String("GET ") + url + dato2 + mPM2 + dato10 + mPM10 + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");


for(int i=0; i<=8; i++){
  delay(30000);


}
PARTICULASPROCESAR.PHP, guarda los datos de 2,5 y 10 micras en dos ficheros txt

<?

//Si faltan 6' para las 00h, borra el fichero
$localtime = localtime();  //pone tiempo en array
$hora=($localtime[2]);  //la hora en posición 2 del array
$minuto=($localtime[1]);
if ($hora==23){
  if ($minuto <= 59 and $minuto >54) {   //echo "Borrar fichero antes de las 12 de la noche"
   $ydata2 = str_getcsv(file_get_contents('ParticulasDatos2.txt'));  //convierte a array el fichero .txt
   $ydata10 = str_getcsv(file_get_contents('ParticulasDatos10.txt'));  //convierte a array el fichero .txt
   $cuenta = count($ydata2);   //cuenta # de datos
   $media_dia2=0;
   for ($i = 0; $i <= $cuenta-2 ; $i++) {   //Se calcula la media del dia
    $media_dia2=$media_dia2+$ydata2[$i];
   }
   for ($i = 0; $i <= $cuenta-2 ; $i++) {   //Se calcula la media del dia
    $media_dia10=$media_dia10+$ydata10[$i];
   }
   $media_dia2=($media_dia2/($cuenta-1)); $media_dia10=($media_dia10/($cuenta-1));
   $media_dia2=round($media_dia2); $media_dia10=round($media_dia10);
   $file2=fopen("ParticulasMediaDiaria2.txt","a");  //Abre el fichero para guardar la media diaria PM2.5
   $file10=fopen("ParticulasMediaDiaria10.txt","a");  //Abre el fichero para guardar la media diaria PM10
   fputs($file2, $media_dia2);   fputs($file10, $media_dia10); //vamos añadiendo el contenido mas una coma
   fputs($file2, ","); fputs($file10, ",");     
   fclose($file2);  fclose($file10);
   unlink('ParticulasDatos2.txt'); unlink('ParticulasDatos10.txt'); //Borra los datos diarios
  }
}


//$wa1 = $_GET['PM1'];   //captura el valor enviado por esp8266. No usado
$wa2 = $_GET['PM2'];   //captura el valor enviado por esp8266
$wa10 = $_GET['PM10'];   //captura el valor enviado por esp8266
$wa= $wa2+$wa10;

$file2=fopen("ParticulasDatos2.txt","a");  //Abre el fichero de datos.txt
fputs($file2, $wa2);  //vamos añadiendo el contenido mas una coma
fputs($file2, ",");    
fclose($file2); 

$file10=fopen("ParticulasDatos10.txt","a");  //Abre el fichero de datos.txt
fputs($file10, $wa10);  //vamos añadiendo el contenido mas una coma
fputs($file10, ",");    
fclose($file10); 

?>
ParticulasGrafica.php

<?
// content="text/plain; charset=utf-8"

require_once ('../jpgraph.php');
require_once ('../jpgraph_line.php');

$ydata2 = str_getcsv(file_get_contents('ParticulasDatos2.txt'));  //convierte a array el fichero amperios.txt
$ydata10 = str_getcsv(file_get_contents('ParticulasDatos10.txt'));  //convierte a array el fichero amperios.txt
//$ydata2  = array(1,56,150,49,38,);


//Valor actual consumo y la media
$cuenta = count($ydata2);
$nada2=$ydata2[$cuenta-2]; $nada10=$ydata10[$cuenta-2];

$media2=0; $media10=0;                      
for ($i = 0; $i <= $cuenta-2 ; $i++) {        //Para PM2,5
   $media2=$media2+$ydata2[$i];
}
$media2=($media2/($cuenta-1));
$media2=round($media2);
//$nada2=round($nada2);
                 
for ($i = 0; $i <= $cuenta-2 ; $i++) {          //Para PM10
   $media10=$media10+$ydata10[$i];
}
$media10=($media10/($cuenta-1));
$media10=round($media10);
//$nada=round($nada);


$nada2="Particulas ahora: " . "PM2,5: " . "$nada2" . " media de " . "$media2" ." -- PM10: " . "$nada10" . " media de " . "$media10";
//$nada2="Particulas ahora: " . "PM2,5: " . "$nada2" . " y " . "con una media de " . "$media2";


//las marcas del eje x cada 5'
$datax=array("00",".",".",".",".",".",".",".",".",".",".",".", "1",".",".",".",".",".",".",".",".",".",".",".",
"2",".",".",".",".",".",".",".",".",".",".",".", "3",".",".",".",".",".",".",".",".",".",".",".",
"4",".",".",".",".",".",".",".",".",".",".",".", "5",".",".",".",".",".",".",".",".",".",".",".",
"6",".",".",".",".",".",".",".",".",".",".",".", "7",".",".",".",".",".",".",".",".",".",".",".",
"8",".",".",".",".",".",".",".",".",".",".",".", "9",".",".",".",".",".",".",".",".",".",".",".",
"10",".",".",".",".",".",".",".",".",".",".",".", "11",".",".",".",".",".",".",".",".",".",".",".",
"12",".",".",".",".",".",".",".",".",".",".",".", "13",".",".",".",".",".",".",".",".",".",".",".",
"14",".",".",".",".",".",".",".",".",".",".",".", "15",".",".",".",".",".",".",".",".",".",".",".",
"16",".",".",".",".",".",".",".",".",".",".",".", "17",".",".",".",".",".",".",".",".",".",".",".",
"18",".",".",".",".",".",".",".",".",".",".",".", "19",".",".",".",".",".",".",".",".",".",".",".",
"20",".",".",".",".",".",".",".",".",".",".",".", "21",".",".",".",".",".",".",".",".",".",".",".",
"22",".",".",".",".",".",".",".",".",".",".",".", "23",".",".",".",".",".",".",".",".",".",".",".", );



// Create the graph. These two calls are always required
$graph = new Graph(1880,500);
$graph->SetScale("textlin");

// Crea la linea plot de $ydata
$lineplot=new LinePlot($ydata2);
//$lineplot->SetStepStyle();      //línea de gráfica en escalones
$lineplot->SetWeight( 2 );   // línea de gráfica "normal"
$graph->Add($lineplot);   // Add the plot to the graph

////////////////////////////////// Crea la linea plot de $ydata2
$lineplot2=new LinePlot($ydata10);
$lineplot->SetWeight( 2 );   // línea de gráfica "normal"
$graph->Add($lineplot2);

$graph->img->SetMargin(40,20,20,40);
$graph->title->Set("Particulas PM2,5 y PM10 en µg/m³ desde las 00 horas y medido cada 5 minutos");
//$graph->xaxis->SetPos("min");
$graph->yaxis->title->Set("µg/m³");
$graph->xaxis->title->Set("Horas");

$graph->xaxis->SetTickLabels($datax);


$t1 = new Text($nada2);      //Etiqueta para mostrar último valor de watios y media
$t1->SetPos(0.025,0.01);
$t1->SetOrientation("h");
$t1->SetFont(FF_FONT2,FS_BOLD);
$t1->SetBox("white","black","gray");
$t1->SetColor("black");

$colorR="PM2,5";
$t2 = new Text($colorR);      //Etiqueta para mostrar último valor de watios y media
$t2->SetPos(0.025,30.01);
$t2->SetOrientation("h");
$t2->SetFont(FF_FONT2,FS_BOLD);
$t2->SetBox("white","black","gray");
$t2->SetColor("blue");

$colorA="PM10";
$t3 = new Text($colorA);      //Etiqueta para mostrar último valor de watios y media
$t3->SetPos(105.25,30.1);
$t3->SetOrientation("h");
$t3->SetFont(FF_FONT2,FS_BOLD);
$t3->SetBox("white","black","gray");
$t3->SetColor("red");

$graph->AddText($t1);
$graph->AddText($t2);
$graph->AddText($t3);
// Display the graph
$graph->Stroke();

?>
Menu