Tabla de contenido:
- Suministros
- Paso 1: Conexión de los componentes
- Paso 2: biblioteca y programa Arduino
- Paso 3: Programa MIT App Inventor 2
- Paso 4: EL RESULTADO
Video: Sistema para monitorear la calidad del aire en busca de contaminación por partículas: 4 pasos
2024 Autor: John Day | [email protected]. Última modificación: 2024-01-30 08:41
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
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
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:
PyonAir: un monitor de contaminación del aire de código abierto: 10 pasos (con imágenes)
PyonAir: un monitor de contaminación del aire de código abierto: PyonAir es un sistema de bajo costo para monitorear los niveles de contaminación del aire local, específicamente, material particulado. Basado en la placa Pycom LoPy4 y el hardware compatible con Grove, el sistema puede transmitir datos a través de LoRa y WiFi. Me encargué de este p
Detección de contaminación del aire + filtración de aire: 4 pasos
Detección de contaminación del aire + filtración del aire: los estudiantes (Aristobulus Lam, Victor Sim, Nathan Rosenzweig y Declan Loges) de German Swiss International School trabajaron con el personal de MakerBay para producir un sistema integrado de medición de la contaminación del aire y la eficacia de la filtración del aire. Esta
EqualAir: pantalla portátil NeoPixel activada por sensor de contaminación del aire: 7 pasos (con imágenes)
EqualAir: pantalla portátil NeoPixel activada por sensor de contaminación del aire: el objetivo del proyecto es hacer una camiseta portátil que muestre un gráfico evocador cuando la contaminación del aire esté por encima de un umbral establecido. El gráfico está inspirado en el clásico juego " romper ladrillos ", en el que el coche es como un remo que
Monitoreo de la calidad del aire con fotón de partículas: 11 pasos (con imágenes)
Monitoreo de la calidad del aire con fotón de partículas: en este proyecto, el sensor de partículas PPD42NJ se usa para medir la calidad del aire (PM 2.5) presente en el aire con fotón de partículas. No solo muestra los datos en la consola Particle y dweet.io, sino que también indica la calidad del aire usando LED RGB cambiándolo
Monitor de calidad del aire alimentado por partículas: 7 pasos
Monitor de calidad del aire alimentado por partículas: calidad del aire. Probablemente lo piense más ahora que nuestro aire limpio se ha convertido en una neblina permanente en el cielo. ¡Qué asco! Una cosa sobre la que sí tiene control es la calidad del aire dentro de su hogar. En este tutorial, te mostraré cómo construir un aire