Tabla de contenido:

Sistema para monitorear la calidad del aire en busca de contaminación por partículas: 4 pasos
Sistema para monitorear la calidad del aire en busca de contaminación por partículas: 4 pasos

Video: Sistema para monitorear la calidad del aire en busca de contaminación por partículas: 4 pasos

Video: Sistema para monitorear la calidad del aire en busca de contaminación por partículas: 4 pasos
Video: La contaminación del aire 2024, Mes de julio
Anonim
Sistema de control de la calidad del aire en busca de contaminación por partículas
Sistema de control de la calidad del aire en busca de contaminación por partículas
Sistema de control de la calidad del aire en busca de contaminación por partículas
Sistema de control de la calidad del aire en busca de contaminación por partículas

INTRO:

1 En este proyecto, muestro cómo construir un detector de partículas con visualización de datos, copia de seguridad de datos en la tarjeta SD e IOT. Visualmente, un anillo de neopíxeles indica la calidad del aire.

2 La calidad del aire es una preocupación cada vez más importante en la actualidad. existen sistemas para medir la tasa de polvo pero son muy costosos. Existen en el mercado detectores de partículas de alta calidad y bajo costo, como lo demuestran algunos estudios.

por ejemplo:

www.atmos-meas-tech.net/11/4823/2018/amt-1…

3 Por lo tanto, decidí construir un dispositivo capaz de medir el número de partículas por clases de tamaño (0,5 µm a 10 µm), visualmente con una simple visualización del resultado (anillo neo de píxeles), una visualización más detallada en una pantalla TFT y un copia de seguridad con sello de tiempo en una tarjeta SD.

4 Además he añadido un módulo de comunicación bluetooth para poder comunicarme con una aplicación android y así publicar los resultados en un servidor IOT.

5 El coste total del conjunto no supera los 60 €

Suministros

-Arduino uno R3

-Proto escudo Arduino

-Pantalla TFT ST7735

-Anillo de neopixel 24 led

-Plantower PMS5003

-Módulo bluetooth HC-06

Paso 1: Conexión de los componentes

Conexión de los componentes
Conexión de los componentes

los diferentes componentes están conectados de acuerdo con el diagrama anterior

Paso 2: biblioteca y programa Arduino

1 la biblioteca

para la pantalla TFT

github.com/adafruit/Adafruit-GFX-Library

para el anillo neo pixel

github.com/adafruit/Adafruit_NeoPixel

para la tarjeta sd

github.com/arduino-libraries/SD

2 el boceto de arduino

#include #include // Bibliothèque pour l'I2C #include "RTClib.h" // Bibliothèque pour le module RTC RTC_DS1307 RTC; #incluir

// ¿Qué pin del Arduino está conectado a los NeoPixels?

#define PIN 6 // En Trinket o Gemma, sugiera cambiar esto a 1

// ¿Cuántos NeoPixels están conectados al Arduino?

#define NUMPIXELS 24 // Tamaño de anillo de NeoPixel popular Adafruit_NeoPixel píxeles (NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); uint32_t vert = píxeles. Color (0, 250, 0); uint32_t naranja = píxeles. Color (250, 250, 0); uint32_t rouge = píxeles. Color (255, 0, 0);

SoftwareSerial pmsSerial (2, 3);

#define cs 10 #define dc 9 #define rst 8 // también puede conectar esto al reinicio de Arduino

#include // Biblioteca de gráficos principal

#include // Biblioteca específica de hardware #include #include const int cs_sd = 4; int temps; // temps d'acquisition double tempsInit; // inicialización du timer au démarrage du loop ()

# si está definido (_ SAM3X8E_)

#undef _FlashStringHelper:: F (string_literal) #define F (string_literal) string_literal #endif

// Opción 1: use cualquier alfiler pero un poco más lento

// Adafruit_ST7735 tft = Adafruit_ST7735 (cs, dc, mosi, sclk, rst);

// Opción 2: debe usar los pines SPI de hardware

// (para UNO eso es sclk = 13 y sid = 11) y el pin 10 debe ser // una salida. Esto es mucho más rápido - también es necesario si desea // utilizar la tarjeta microSD (vea el ejemplo de dibujo de la imagen) Adafruit_ST7735 tft = Adafruit_ST7735 (cs, dc, rst); float nombre_leds = 0; configuración vacía () {Serial.begin (9600); // Inicializar el enlace I2C Wire.begin (); // Inicializar el módulo de archivos RTC RTC.begin (); Serial.print ("init SD"); retraso (1000); if (! SD.begin (cs_sd)) // Condición vérifiant si la carte SD est présente dans l'appareil {Serial.print ("Defaut SD"); regreso; } Serial.print ("Carte SD OK");

Datos de archivo = SD.open ("donnees.txt", FILE_WRITE); // Ouvre le fichier "donnees.txt"

data.println (""); data.println ("Adquisición de démarrage"); // Ecrit dans ce fichier data.close (); tft.initR (INITR_GREENTAB); // inicializar un chip ST7735S, pestaña negra Serial.println ("init"); // nuestra salida de depuración tft.fillScreen (ST7735_BLACK); // la velocidad en baudios del sensor es 9600 pmsSerial.begin (9600);

pixels.begin (); // INICIALIZAR el objeto de tira de NeoPixel (OBLIGATORIO)

pixels.setBrightness (2);

}

struct pms5003data {

uint16_t framelen; uint16_t pm10_standard, pm25_standard, pm100_standard; uint16_t pm10_env, pm25_env, pm100_env; uint16_t partículas_03um, partículas_05um, partículas_10um, partículas_25um, partículas_50um, partículas_100um; uint16_t no utilizado; uint16_t suma de comprobación; };

struct pms5003data data; bucle vacío () {píxeles.clear (); // Establecer todos los colores de los píxeles en 'off' DateTime now = RTC.now (); // Récupère l'heure et le date courante // affiche_date_heure (ahora);

temps = ((milis () - tempsInit)) / 1000; // Démarrage du chrono

if (readPMSdata (& pmsSerial)) {// tft.fillScreen (ST7735_BLACK); tft.setCursor (10, 5); tft.setTextColor (ST7735_WHITE); tft.println ("nbre partes / 0,1 l");

tft.setCursor (10, 17); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.setCursor (10, 17); tft.print ("0.3 um"); tft.print (data.particles_03um); tft.print ("");

tft.setCursor (10, 29);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("0.5 um"); tft.print (data.particles_05um); tft.print ("");

tft.setCursor (10, 41);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("1.0 um"); tft.print (datos.partículas_10um); tft.print ("");

tft.setCursor (10, 53);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("2.5 um"); tft.print (data.particles_25um); tft.print ("");

tft.setCursor (10, 65);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("5.0 um"); tft.print (datos.partículas_50um); tft.print ("");

tft.setCursor (10, 77);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("10 um"); tft.print (datos.partículas_100um); tft.print ("");

tft.setCursor (2, 89);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("PM 1.0"); tft.setTextColor (ST7735_YELLOW, ST7735_BLACK); tft.print (data.pm10_standard); tft.print (""); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.print (" microg / m3 ");

tft.setCursor (2, 100); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("PM 2.5"); tft.setTextColor (ST7735_YELLOW, ST7735_BLACK); tft.print (data.pm25_standard); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.print ("microg / m3");

tft.setCursor (2, 110);

tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.setTextSize (1); tft.print ("PM 10"); tft.setTextColor (ST7735_YELLOW, ST7735_BLACK); tft.print (data.pm100_standard); tft.setTextColor (ST7735_GREEN, ST7735_BLACK); tft.print ("microg / m3");

tft.setCursor (10, 5);

tft.setTextColor (ST7735_WHITE, ST7735_BLACK); tft.setTextSize (1); tft.println ("nbre partes / 0,1 l");

// Serial.print (temps);

// Serial.print (""); Serial.print ("#"); Serial.print ("03µm"); Serial.print (data.particles_03um); Serial.print (""); Serial.print ("05µm"); Serial.print (data.particles_05um); Serial.print (""); Serial.print ("1µm"); Serial.print (data.particles_10um); Serial.print (""); Serial.print ("25µm"); Serial.print (data.particles_25um); Serial.print (""); Impresión en serie ("50 µm"); Serial.print (data.particles_50um); Serial.print (""); Serial.print ("100µm"); Serial.print (data.particles_100um); Serial.println (""); nombre_leds = int (((float (data.particles_03um) / 65535) * 24)); // nombre_leds = (8); Serial.println (nombre_leds);

if ((nombre_leds = 1)) {

pixels.fill (vert, 0, nombre_leds); } else if ((nombre_leds = 8)) {pixels.fill (vert, 0, 8); pixels.fill (naranja, 8, ((nombre_leds) -8)); } else if (nombre_leds> 16) {

píxeles.fill (vert, 0, 8); píxeles.fill (naranja, 8, 8); pixels.fill (colorete, 16, ((nombre_leds) -16)); } else if (nombre_leds <= 1) {pixels.fill (vert, 0, 1); } píxeles.show (); // Envía los colores de píxeles actualizados al hardware.

// Définition données String PM03 = String (data.particles_03um); String PM05 = String (data.particles_05um); String PM10 = String (data.particles_10um); String PM25 = String (data.particles_25um); String PM50 = String (data.particles_50um); String PM100 = String (data.particles_100um); String PMS10 = String (data.pm10_standard); String PMS25 = String (data.pm25_standard); String PMS100 = String (data.pm100_standard); String Temps = String (temps);

// Ecriture des données dans le fichier texte

Datos de archivo = SD.open ("donnees.txt", FILE_WRITE); data.println (Temps + "" + PM03 + "" + PM05 + "" + PM10 + "" + PM25 + "" + PM50 + "" + PM100 + "" + PMS10 + "" + PMS25 + "" + PMS100 + ""); data.close (); }

}

boolean readPMSdata (Stream * s) {

if (! s-> available ()) {return false; } // Lee un byte a la vez hasta que lleguemos al byte de inicio especial '0x42' if (s-> peek ()! = 0x42) {s-> read (); falso retorno; }

// Ahora lee los 32 bytes

if (s-> available () readBytes (búfer, 32);

// preparar la suma de comprobación

para (uint8_t i = 0; i <30; i ++) {suma + = búfer ; }

/ * depuración

para (uint8_t i = 2; i <32; i ++) {Serial.print ("0x"); Serial.print (búfer , HEX); Serial.print (","); } Serial.println (); * / // Los datos vienen en endian'd, esto lo resuelve para que funcione en todas las plataformas uint16_t buffer_u16 [15]; para (uint8_t i = 0; i <15; i ++) {buffer_u16 = buffer [2 + i * 2 + 1]; buffer_u16 + = (buffer [2 + i * 2] << 8); }

// ponerlo en una buena estructura:)

memcpy ((void *) & data, (void *) buffer_u16, 30);

if (suma! = data.checksum) {

Serial.println ("Fallo en la suma de comprobación"); falso retorno; } // ¡éxito! devuelve verdadero; }

// Converti le numéro de jour en jour /! / La semaine commence un dimanche

String donne_jour_semaine (uint8_t j) {switch (j) {case 0: return "DIM"; caso 1: devuelve "LUN"; caso 2: devuelve "MAR"; caso 3: devuelve "MER"; caso 4: devuelve "JEU"; caso 5: devuelve "VEN"; caso 6: devuelve "SAM"; predeterminado: volver ""; }}

// affiche la date et l'heure sur l'écran

void affiche_date_heure (DateTime datetime) {// Date String jour = donne_jour_semaine (datetime.dayOfTheWeek ()) + "" + Vers2Chiffres (datetime.day ()) + "/" + Vers2Chiffres (datetime.month ()) + "/" + String (datetime.year (), DEC); // heure String heure = ""; heure = Vers2Chiffres (datetime.hour ()) + ":" + Vers2Chiffres (datetime.minute ()) + ":" + Vers2Chiffres (datetime.second ());

Serial.print (diario); Serial.print (""); Serial.print (heure); //Serial.print (""); Datos de archivo = SD.open ("donnees.txt", FILE_WRITE); data.print (jour + "" + heure + ""); data.close ();

tft.setCursor (2, 120);

tft.setTextColor (ST7735_GREEN); tft.setTextSize (1); tft.print ("fecha"); tft.setTextColor (ST7735_YELLOW); tft.print (jour); tft.setTextColor (ST7735_GREEN); tft.setCursor (2, 130); tft.print ("heure"); tft. setTextColor (ST7735_YELLOW); tft.print (heure);

retraso (500);

}

// permet d'afficher les nombres sur deux chiffres

String Vers2Chiffres (byte nombre) {String resultante = ""; if (nombre <10) resultat = "0"; return resultat + = String (nombre, DEC); }

Paso 3: Programa MIT App Inventor 2

Programa MIT App Inventor 2
Programa MIT App Inventor 2

este es el bloque de código del inventor de la aplicación MIT

Paso 4: EL RESULTADO

aquí está el video del resultado

Recomendado: