Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 200 additions & 0 deletions Maca_IoT.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
#include <Wire.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <U8g2lib.h>
#include <Arduino.h>

// ======================= ATENCIÓN =======================
// Cada placa debe tener un nombre ÚNICO en la variable Nombre_Esp32.
// Modifica el nombre antes de cargar el programa en la placa.
// =========================================================

String Nombre_Esp32 = "Bloque1-120"; // Cambiar nombre para cada placa

// Datos de red WiFi
const char* ssid = "Admin";
const char* password = "aD.*/i6t";

// Datos MQTT
const char *mqtt_server = "207.180.207.150"; //vps.macatdea.com
const int mqtt_port = 1883;
const char *mqtt_user = "web_iot_cliente";
const char *mqtt_pass = "Maca2025TdeA+";

// Datos Suscripcion a MQTT
const String Topic_Init = "Maca";
const String DataOut = "/DataOut";
//TOPIC Maca/DataOut/#

WiFiClient espClient;
PubSubClient client(espClient);

// Configura la pantalla OLED - Display U8g2 (para SH1106 a 128x64)
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// Configuración del sensor
#define SoundPin 35
#define VREF 3.3
// Factor de conversión para el sensor SEN0232
float factor = 50.0; // Ajusta el valor si es necesario

// Timers
unsigned long lastDisplayUpdate = 0;
unsigned long lastSerialUpdate = 0;
unsigned long lastMqttPublish = 0;

float Nivel_Dba = 0;
String Mensaje_Alerta = "";

void setup_wifi();
void reconnect();
void actualizarDisplay();
void calcularNivel();

void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);

delay(1500);

Serial.println();
Serial.print("La direccion MAC de la placa es: ");
Serial.println(WiFi.macAddress());

// Inicializar la pantalla
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB14_tr); // u8g2.setFont(u8g2_font_fub30_tr); Fuente más grande
u8g2.drawStr(28, 32, "MACA"); // u8g2.drawStr(10, 40, "MACA"); Ajustar posición X,Y
u8g2.sendBuffer();
delay(2000);
u8g2.clearBuffer();
u8g2.sendBuffer();
}

void loop() {
if (!client.connected()) { //Verificar si el ESP32 sigue conectado al broker MQTT
reconnect(); //Si se cae el MQTT, se vuelve a conectar.
}
client.loop(); //Mantiene la conexión activa - servicio MQTT

unsigned long now = millis();

// Refrescar pantalla cada 0.5 segundos
if (now - lastDisplayUpdate > 500) {
lastDisplayUpdate = now;
calcularNivel();
actualizarDisplay();
}

// Mostrar en Serial cada 2 segundo
if (now - lastSerialUpdate > 2000) {
lastSerialUpdate = now;
Serial.print("Nivel de sonido: ");
Serial.print(Nivel_Dba, 1);
Serial.println(" DB");
}

// Publicar en MQTT cada 1min = 60000, 5 min=300000
if (now - lastMqttPublish > 1000) {
lastMqttPublish = now;

String StrMsg = String(Nombre_Esp32) + "@" + String(Nivel_Dba, 2) + "@" + String(Mensaje_Alerta);
int str_len = StrMsg.length() + 1;
char char_Msg[str_len];
StrMsg.toCharArray(char_Msg, str_len);

Serial.print("Dato enviado al Broker: ");
Serial.println(StrMsg);

String StrTopic = Topic_Init + DataOut;
str_len = StrTopic.length() + 1;
char char_Topic[str_len];
StrTopic.toCharArray(char_Topic, str_len);

client.publish(char_Topic, char_Msg);
}
}

void calcularNivel() {
float voltageValue = analogRead(SoundPin) / 4095.0 * VREF;
Nivel_Dba = voltageValue * factor;

if (Nivel_Dba <= 20) {
Mensaje_Alerta = "RUIDO BAJO";
} else if (Nivel_Dba <= 40) {
Mensaje_Alerta = "RUIDO MODERADO";
} else if (Nivel_Dba <= 60) {
Mensaje_Alerta = "RUIDO NORMAL";
} else if (Nivel_Dba <= 80) {
Mensaje_Alerta = "RUIDO ALTO";
} else if (Nivel_Dba <= 100) {
Mensaje_Alerta = "RUIDO ELEVADO";
} else if (Nivel_Dba <= 120) {
Mensaje_Alerta = "RUIDO DAÑINO";
} else if (Nivel_Dba <= 130) {
Mensaje_Alerta = "RUIDO EXTREMO";
} else {
Mensaje_Alerta = "FUERA RANGO";
}
}

void actualizarDisplay() {
u8g2.clearBuffer();

// Mensaje Alerta
u8g2.setFont(u8g2_font_6x13B_tf);
uint16_t textWidth = u8g2.getStrWidth(Mensaje_Alerta.c_str());
u8g2.drawStr((128 - textWidth) / 2, 15, Mensaje_Alerta.c_str());

// Nivel dB
u8g2.setFont(u8g2_font_fub17_tr);
String Nivel_DbaStr = String(Nivel_Dba, 1) + " dB";
textWidth = u8g2.getStrWidth(Nivel_DbaStr.c_str());
u8g2.drawStr((128 - textWidth) / 2, 40, Nivel_DbaStr.c_str());

// Barra de progreso
int progress = map(Nivel_Dba, 0, 130, 0, 120); // Mapea a 120px de ancho
u8g2.drawFrame(4, 50, 120, 10); // Marco
u8g2.drawBox(5, 51, progress, 8); // Barra

u8g2.sendBuffer();
}

void setup_wifi() {
delay(10); //espera de 10 milisegundos
Serial.println();
Serial.print("Conectando a ");
Serial.println(ssid);

WiFi.begin(ssid, password); // conexion a wifi

while (WiFi.status() != WL_CONNECTED) {
delay(500); // espera medio segundo para reconectarse
Serial.print(".");
}

Serial.println();
Serial.println("Conectado a red WiFi!");
Serial.println("Dirección IP: ");
Serial.println(WiFi.localIP());
}

void reconnect() { // reconectar al mqtt
while (!client.connected()) {
Serial.print("Intentando conexión MQTT...");
String clientId = "esp32_";
clientId += String(random(0xffff), HEX); // id unico
if (client.connect(clientId.c_str(), mqtt_user, mqtt_pass)) {
Serial.println("Conectado!");
String StrTopic = Topic_Init + "//DataIn";
client.subscribe(StrTopic.c_str());
} else {
Serial.print("falló, rc=");
Serial.print(client.state());
Serial.println(" intentando de nuevo en 5 segundos");
delay(5000);
}
}
}
78 changes: 71 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,82 @@
![marca.png](https://i.postimg.cc/hjr0qm6d/marca.png)

# MONITOREO Y ALERTA DE CONTAMINACIÓN ACÚSTICA
# MACA - MONITOREO Y ALERTA DE CONTAMINACIÓN ACÚSTICA EN AMBIENTES EDUCATIVOS
### 🔗 [www.macatdea.com](https://macatdea.com/)

## 💻 Desarrollado por:
🧑🏽‍💻Yorbis Aragón Bedoya
👨🏻‍💻 Daniel Álvarez Echeverry

<!-- ## 👨‍🏫 Asesores
- María Nelcy González
- Silvana Vallejo Córdoba
- Juan David Tamayo -->

## 🧩 Introducción

MACA es un sistema IoT de bajo costo diseñado para monitorear y alertar sobre los niveles de contaminación acústica en instituciones de educación superior.
El proyecto busca contribuir al bienestar ambiental y académico, promoviendo espacios más saludables mediante la recolección y visualización de datos en tiempo real.

## ⚙️ Características principales
- 📡 **Monitoreo en tiempo real** de niveles de ruido ambiental.
- 🎛️ **Sensores de sonido** integrados (compatibles con MAX4466, INMP441, SEN0232).
- 💾 **Procesamiento local** mediante **ESP32** para adquisición y envío de datos.
- ☁️ **Conectividad IoT** con soporte para **MQTT** y plataformas en la nube.
- 📊 **Visualización de datos** en dashboards web o móviles.
- 🚨 **Alertas configurables** ante niveles de ruido que superen los umbrales establecidos.
- 🔋 **Bajo consumo energético** y fácil integración en entornos educativos.

## 🎯 Objetivo General
Desarrollar un sistema de bajo costo utilizando sensores de sonido y placas ESP32 para el monitoreo en tiempo real de la contaminación acústica.

## 🎯 Objetivos Específicos
- Diseñar un prototipo para adquirir variables acústicas (intensidad, frecuencia, duración).
- Implementar una plataforma central para reportes, alertas y visualización.
- Validar el sistema mediante pruebas funcionales, de precisión y usabilidad.

## 📌 Contexto
La **Resolución 627 de 2006** del Ministerio de Ambiente en Colombia establece límites permisibles para la exposición al ruido. Sin embargo, en entornos educativos no se suele hacer medición ni control, afectando la concentración y salud de los estudiantes.

## ⚙️ Metodología
Se utilizó una metodología híbrida:
- **Waterfall** para el desarrollo del hardware.
- **Scrum** con 6 sprints para el desarrollo del software.

## 🧪 Alcance del Sistema
- Medición en vivo del ruido ambiental.
- Alerta automática cuando se exceden los límites.
- Visualización en tiempo real vía plataforma web (Grafana).
- Registro y análisis de datos en base de datos relacional y NoSQL.

## 🧩 Arquitectura del Sistema
![Arquitectura-del-sistema-drawio.png](https://i.postimg.cc/4x9qR85H/Arquitectura-del-sistema-drawio.png)

## 🛠️ Tecnologías Utilizadas
- **Hardware:** ESP32, Sensor de sonido, Pantalla OLED.
- **Backend:** Node.js, Broker MQTT, MySQL.
- **Frontend:** Grafana para visualización.
- **Despliegue:** VPS (Ubuntu), Nginx.

## 📊 Resultados
Durante una prueba de 30 días:
- Se registraron más de **250,000 mediciones** en aulas, biblioteca y cafetería.
- El **bloque 5 y la cafetería** presentaron los niveles más altos.
- El sistema mostró un **coeficiente de determinación R² de 0.97** y un **MAE del 2.5%**, comparable con equipos profesionales.


## 📚 Referencias
- [Manual de Efectos de Ruido – EPA](https://www.nonoise.org/library/handbook/handbook.htm)
- [Estudios de impacto del ruido en estudiantes](http://dspace.tecnologicosudamericano.edu.ec/jspui/handle/123456789/610)
- [Diseño de sistemas de monitoreo IoT acústico](https://hdl.handle.net/20.500.12867/3479)

## 🎥 Mockups
![1.png](https://i.postimg.cc/3JcQT0QV/1.png)
![2.png](https://i.postimg.cc/s2FFBFXJ/2.png)
![3.png](https://i.postimg.cc/h4Mq23yS/3.png)
![4.png](https://i.postimg.cc/NfVSVh1w/4.png)
![5.png](https://i.postimg.cc/9FzsJXwp/5.png)
![6.png](https://i.postimg.cc/3rtPX0NN/6.png)
![7.png](https://i.postimg.cc/SR13k33C/7.png)
![8.png](https://i.postimg.cc/qqvWf4bp/8.png)
![9.png](https://i.postimg.cc/vBzCScvP/9.png)
![10.png](https://i.postimg.cc/nzZ6kvqj/10.png)
# ARQUITECTURA
![Arquitectura-del-sistema-drawio.png](https://i.postimg.cc/4x9qR85H/Arquitectura-del-sistema-drawio.png)
![11.png](https://i.postimg.cc/tgFKWrnG/11.png)
![12.png](https://i.postimg.cc/htQWP4Sj/12.png)