//#include <WiFi.h>
//#include <PubSubClient.h>
// --------------------- CONSTANTES ---------------------
#define BOTON_PIN 15
#define SENSOR_ANALOGICO 35
#define SENSOR_LUZ 34
#define LED_PIN 2
#define BUZZER_PIN 4
#define UMBRAL_SONIDO_BAJO 1000
#define UMBRAL_SONIDO_MEDIO 2000
#define UMBRAL_LUZ_ALTA 3500
#define UMBRAL_LUZ_MEDIA 2000
#define DURACION_NOTIFICACION 3000
#define INTERVALO_LECTURA 100
#define FRECUENCIA_BUZZER_BAJA 500
#define FRECUENCIA_BUZZER_MEDIA 1000
#define FRECUENCIA_BUZZER_ALTA 2000
//#define WIFI_SSID "TU_WIFI_SSID"
//#define WIFI_PASSWORD "TU_WIFI_PASSWORD"
/*#define MQTT_BROKER "industrial.api.ubidots.com"
#define MQTT_PORT 1883
#define MQTT_USER "BBUS-GvjZYx9q0dvsWlYvjV2JNRBjHPWQzo" // Token de Ubidots
#define MQTT_CLIENT_ID "esp32_grupoL3"
#define MQTT_TOPIC_CONTROL "/v1.6/devices/grupoL3/alarma"
//#define MQTT_TOPIC_LUZ "/v1.6/devices/grupoL3/luz"
//#define MQTT_TOPIC_SONIDO "/v1.6/devices/grupoL3/sonido"
//#define MQTT_TOPIC_NIVEL "/v1.6/devices/grupoL3/nivel_alarma"*/
// --------------------- ENUMERACIONES ---------------------
enum Estado
{
STAND_BY,
MONITOREANDO,
PELIGRO_ALTO,
PELIGRO_MEDIO,
PELIGRO_BAJO,
CONSULTOR
};
enum Evento
{
EVENTO_NINGUNO,
EVENTO_PULSADOR,
EVENTO_PELIGRO_BAJO,
EVENTO_PELIGRO_MEDIO,
EVENTO_PELIGRO_ALTO,
EVENTO_TIMEOUT,
EVENTO_MQTT_ACTIVAR
};
enum PeligroSonido
{
BAJA_SONIDO,
MEDIA_SONIDO,
ALTA_SONIDO
};
enum PeligroLuz
{
BAJA_LUZ,
MEDIA_LUZ,
ALTA_LUZ
};
enum NivelAlarma
{
ALARMA_BAJA,
ALARMA_MEDIA,
ALARMA_ALTA
};
// --------------------- VARIABLES GLOBALES ---------------------
Estado estado_actual = STAND_BY;
Estado estado_anterior = STAND_BY;
Evento evento_actual = EVENTO_NINGUNO;
PeligroSonido peligro_sonido = BAJA_SONIDO;
PeligroLuz peligro_luz = BAJA_LUZ;
unsigned long tiempo_actual = 0;
unsigned long tiempo_inicio_notificacion = 0;
unsigned long tiempo_anterior = 0;
bool alarma_activada = false;
int vector_promedio_sonido[10] = {0}; // todos los valores se inicializan en 0
int indice_vector_sonido = 0;
int indice_sensor = 0;
/*WiFiClient espClient;
PubSubClient client(espClient);
String mensaje_mqtt = "";
String ultimo_mensaje_mqtt = "";*/
// --------------------- PROTOTIPOS ---------------------
void verificarPulsador();
void verificarSensorSonido();
void verificarSensorLuz();
void verificarTemporizador();
void getEvent();
void calcularPeligro();
void activarAlarma(NivelAlarma nivel_alarma);
void desactivarAlarma();
void fsm();
void wifisetup();
void verificarComunicacionMQTT();
void reconnect_mqtt();
void callback_mqtt();
// --------------------- ARREGLO DE FUNCIONES ---------------------
void (*const verificar_sensor[4])() =
{
verificarPulsador,
verificarSensorSonido,
verificarSensorLuz,
verificarTemporizador,
//verificarComunicacionMQTT
};
// --------------------- FUNCIONES ---------------------
void verificarTemporizador()
{
tiempo_actual = millis();
if (alarma_activada && (tiempo_actual - tiempo_inicio_notificacion > DURACION_NOTIFICACION))
{
evento_actual = EVENTO_TIMEOUT;
alarma_activada = false;
}
else
{
evento_actual = EVENTO_NINGUNO;
}
}
void verificarPulsador()
{
if (digitalRead(BOTON_PIN) == LOW)
{
evento_actual = EVENTO_PULSADOR;
}
else
{
evento_actual = EVENTO_NINGUNO;
}
}
void verificarSensorSonido()
{
int sonido = 0;
vector_promedio_sonido[indice_vector_sonido] = analogRead(SENSOR_ANALOGICO);
indice_vector_sonido = (indice_vector_sonido + 1) % 10;
sonido = (vector_promedio_sonido[0] + vector_promedio_sonido[1] +
vector_promedio_sonido[2] + vector_promedio_sonido[3] +
vector_promedio_sonido[4] + vector_promedio_sonido[5] +
vector_promedio_sonido[6] + vector_promedio_sonido[7] +
vector_promedio_sonido[8] + vector_promedio_sonido[9] )/ 10;
Serial.print("Valor de sonido: ");
Serial.println(sonido);
if (sonido < UMBRAL_SONIDO_BAJO)
{
peligro_sonido = BAJA_SONIDO;
}
else if (sonido < UMBRAL_SONIDO_MEDIO)
{
peligro_sonido = MEDIA_SONIDO;
}
else
{
peligro_sonido = ALTA_SONIDO;
}
calcularPeligro();
}
void verificarSensorLuz()
{
int luz = analogRead(SENSOR_LUZ);
if (luz >= UMBRAL_LUZ_ALTA)
{
peligro_luz = ALTA_LUZ;
}
else if (luz >= UMBRAL_LUZ_MEDIA)
{
peligro_luz = MEDIA_LUZ;
}
else
{
peligro_luz = BAJA_LUZ;
}
calcularPeligro();
}
/*void verificarComunicacionMQTT()
{
if (!client.connected())
{
reconnect_mqtt();
}
client.loop();
if (ultimo_mensaje_mqtt == "ACTIVAR")
{
evento_actual = EVENTO_MQTT_ACTIVAR;
ultimo_mensaje_mqtt = ""; // Limpiamos para que no se repita
}
else
{
evento_actual = EVENTO_NINGUNO;
}
}*/
void getEvent()
{
tiempo_actual = millis();
if ((tiempo_actual - tiempo_anterior) > INTERVALO_LECTURA)
{
verificar_sensor[indice_sensor]();
indice_sensor = (indice_sensor + 1) % 4;
tiempo_anterior = tiempo_actual;
}
else
{
evento_actual = EVENTO_NINGUNO;
}
}
void calcularPeligro()
{
if (peligro_sonido == ALTA_SONIDO || peligro_luz == ALTA_LUZ)
{
evento_actual = EVENTO_PELIGRO_ALTO;
}
else if (peligro_sonido == BAJA_SONIDO && peligro_luz == BAJA_LUZ)
{
evento_actual = EVENTO_PELIGRO_BAJO;
}
else
{
evento_actual = EVENTO_PELIGRO_MEDIO;
}
}
void activarAlarma(NivelAlarma nivel_alarma)
{
switch (nivel_alarma)
{
case ALARMA_BAJA:
tone(BUZZER_PIN, FRECUENCIA_BUZZER_BAJA);
break;
case ALARMA_MEDIA:
tone(BUZZER_PIN, FRECUENCIA_BUZZER_MEDIA);
break;
case ALARMA_ALTA:
tone(BUZZER_PIN, FRECUENCIA_BUZZER_ALTA);
break;
}
digitalWrite(LED_PIN, HIGH);
}
void desactivarAlarma()
{
noTone(BUZZER_PIN);
digitalWrite(LED_PIN, LOW);
}
/*void setup_wifi()
{
Serial.println("Conectando a WiFi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
unsigned long startAttemptTime = millis();
const unsigned long TIMEOUT = 10000;
while (WiFi.status() != WL_CONNECTED && millis() - startAttemptTime < TIMEOUT)
{
// No usamos delay, solo esperamos sin bloquear
client.loop(); // mantenemos MQTT vivo por si lo necesitamos
}
if (WiFi.status() == WL_CONNECTED)
{
Serial.println("WiFi conectado!");
}
else
{
Serial.println("Error: no se pudo conectar a WiFi");
}
}*/
/*void reconnect_mqtt()
{
static unsigned long last_attempt = 0;
const unsigned long RETRY_INTERVAL = 5000; // ESTO ES UNA CONSTANTE CAMBIARLO!
if (millis() - last_attempt >= RETRY_INTERVAL)
{
last_attempt = millis();
Serial.print("Intentando conectar al broker MQTT... ");
if (client.connect(MQTT_CLIENT_ID, MQTT_USER, ""))
{
Serial.println("Conectado!");
client.subscribe(MQTT_TOPIC_CONTROL);
}
else
{
Serial.print("Fallo. Código: ");
Serial.println(client.state());
}
}
}*/
/*void callback_mqtt(char* topic, byte* payload, unsigned int length)
{
ultimo_mensaje_mqtt = "";
for (int i = 0; i < length; i++)
{
ultimo_mensaje_mqtt += (char)payload[i];
}
Serial.print("Mensaje recibido: ");
Serial.println(ultimo_mensaje_mqtt);
}*/
void fsm()
{
getEvent();
switch(estado_actual)
{
case STAND_BY:
switch (evento_actual)
{
case EVENTO_PULSADOR:
estado_actual = MONITOREANDO;
break;
default:
break;
}
break;
case MONITOREANDO:
switch (evento_actual)
{
case EVENTO_PELIGRO_BAJO:
estado_actual = PELIGRO_BAJO;
activarAlarma(ALARMA_BAJA);
break;
case EVENTO_PELIGRO_MEDIO:
estado_actual = PELIGRO_MEDIO;
activarAlarma(ALARMA_MEDIA);
break;
case EVENTO_PELIGRO_ALTO:
estado_actual = PELIGRO_ALTO;
activarAlarma(ALARMA_ALTA);
break;
default:
break;
}
break;
case PELIGRO_BAJO:
case PELIGRO_MEDIO:
case PELIGRO_ALTO:
switch (evento_actual)
{
case EVENTO_PULSADOR:
tiempo_inicio_notificacion = millis();
alarma_activada = true;
estado_actual = CONSULTOR;
break;
default:
break;
}
break;
case CONSULTOR:
switch (evento_actual)
{
case EVENTO_PULSADOR:
estado_actual = MONITOREANDO;
break;
case EVENTO_TIMEOUT:
estado_actual = STAND_BY;
desactivarAlarma();
break;
default:
break;
}
break;
}
}
void setup()
{
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
pinMode(BOTON_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
/*setup_wifi();
client.setServer(MQTT_BROKER, MQTT_PORT);
client.setCallback(callback_mqtt);*/
tiempo_anterior = millis();
}
void loop()
{
fsm();
}