#include <WiFi.h>
#include <LiquidCrystal_I2C.h>
#include <HTTPClient.h>
#include <DHTesp.h>
#include <DHT.h>
#include <ESP32Servo.h>
#include <Adafruit_PWMServoDriver.h>
// Librerías de Adafruit para manejo de MQTT
#include <Adafruit_MQTT.h>
#include <Adafruit_MQTT_Client.h>
// Credenciales para la conexión al servidor de Adafruit IO
#define AIO_SERVIDOR "io.adafruit.com" // Dirección del servidor MQTT de Adafruit IO
#define AIO_PUERTOSERVIDOR 1883 // Puerto estándar para conexión MQTT
#define AIO_USUARIO "Adelin" // Usuario de Adafruit IO
#define AIO_KEY "aio_jkNe15bDsXGQ9z83S6GJaHMDMW9E" // Llave API para autenticación
#define DHTPIN1 15
#define PIRPIN1 14
#define LED1 12
#define LED2 13
#define LED3 25
#define LED4 26
#define LED5 32
#define LED6 33
#define BUZZER 35
#define DOOR_SERVO_PIN1 18
#define WINDOW_SERVO_PIN1 19
#define FAN_SERVO_PIN1 5
#define DOOR_SERVO_PIN2 16
#define WINDOW_SERVO_PIN2 4
#define TRIG_PIN1 2
#define ECHO_PIN1 3
#define DHTTYPE DHT22
DHT dht1(DHTPIN1, DHTTYPE);
Servo doorServo1, windowServo1, fanServo1;
Servo doorServo2, windowServo2, fanServo2;
const int DHT_PIN = 15;
const int DHT_PIN2 = 4;
const int servo_PIN=23;
float temperatura=0.0, humedad;
const char* WIFI_NAME= "Wokwi-GUEST";
const char* WIFI_PASSWORD = "";
WiFiClient client;
// Cliente MQTT de Adafruit, configurado con los datos de conexión
Adafruit_MQTT_Client mqtt(&client, AIO_SERVIDOR, AIO_PUERTOSERVIDOR, AIO_USUARIO, AIO_KEY);
// Suscripciones a los feeds de Adafruit IO
Adafruit_MQTT_Subscribe susc_amarillo = Adafruit_MQTT_Subscribe(&mqtt, AIO_USUARIO "/feeds/led_amarillo");
Adafruit_MQTT_Subscribe susc_azul = Adafruit_MQTT_Subscribe(&mqtt, AIO_USUARIO "/feeds/led_azul");
Adafruit_MQTT_Subscribe susc_verde = Adafruit_MQTT_Subscribe(&mqtt, AIO_USUARIO "/feeds/led_verde");
Adafruit_MQTT_Subscribe susc_rojo = Adafruit_MQTT_Subscribe(&mqtt, AIO_USUARIO "/feeds/foco_morado");
Adafruit_MQTT_Subscribe susc_morado = Adafruit_MQTT_Subscribe(&mqtt, AIO_USUARIO "/feeds/foco_naranja");
Adafruit_MQTT_Subscribe susc_naranja = Adafruit_MQTT_Subscribe(&mqtt, AIO_USUARIO "/feeds/foco_rojo");
Adafruit_MQTT_Subscribe susc_door = Adafruit_MQTT_Subscribe(&mqtt, AIO_USUARIO "/feeds/door");
// Publicadores para los feeds
Adafruit_MQTT_Publish pub_temperatura = Adafruit_MQTT_Publish(&mqtt, AIO_USUARIO "/feeds/temperatura");
Adafruit_MQTT_Publish pub_humedad = Adafruit_MQTT_Publish(&mqtt, AIO_USUARIO "/feeds/humedad");
// Creamos dos instancias del sensor DHTesp
DHTesp dhtSensor;
// Creamos las dos instancias para las pantallas LCD
LiquidCrystal_I2C lcd(0x27,16,2);
LiquidCrystal_I2C lcd2(0x3F,16,2);
// Controlador para el servomotor
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// Configuración del servomotor
#define SERVOMIN 120 // Pulso mínimo (posición cerrada)
#define SERVOMAX 600 // Pulso máximo (posición abierta)
#define SERVO_CHANNEL 16 // Canal donde está conectado el servo
// Estado de la puerta
bool isDoorOpen = false;
const int LED_AMARILLO=26;
const int LED_AZUL=32;
const int LED_VERDE=33;
const int LED_ROJO=12;
const int LED_MORADO=13;
const int LED_NARANJA=25;
// Declarar objetos y pines
Servo ventilador; // Objeto para el servomotor
const int pinServo = 5; // Pin donde conectaremos el servomotor
const int pinSensor = 15; // Pin ADC para el sensor de temperatura (simulado)
// Variables
const float umbralTemp = 50.0; // Temperatura umbral en grados Celsius
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32!");
pinMode(LED_AMARILLO, OUTPUT);
pinMode(LED_AZUL, OUTPUT);
pinMode(LED_VERDE, OUTPUT);
pinMode(LED_ROJO, OUTPUT);
pinMode(LED_MORADO, OUTPUT);
pinMode(LED_NARANJA, OUTPUT);
pinMode(servo_PIN, OUTPUT);
ventilador.attach(pinServo); // Conectar el servomotor al pin definido
ventilador.write(0); // Asegurarse de que el ventilador esté detenido
Serial.println("Sistema iniciado");
// Lectura de datos del primer sensor
dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
lcd.init();
lcd.backlight();
WiFi.begin(WIFI_NAME,WIFI_PASSWORD);
while(WiFi.status()!=WL_CONNECTED){
delay(1000);
Serial.println("WiFi no conectado");
}
Serial.println("Wifi conectado");
//Registro de las suscripciones MQTT
mqtt.subscribe(&susc_amarillo);
mqtt.subscribe(&susc_azul);
mqtt.subscribe(&susc_verde);
mqtt.subscribe(&susc_morado);
mqtt.subscribe(&susc_naranja);
mqtt.subscribe(&susc_rojo);
mqtt.subscribe(&susc_door);
// Inicializar el controlador del servo
pwm.begin();
pwm.setPWMFreq(50); // Frecuencia ideal para servos
delay(10);
// Configurar la posición inicial del servo (puerta cerrada)
pwm.setPWM(SERVO_CHANNEL, 16, SERVOMIN);
Serial.println("Puerta inicializada (cerrada)");
delay(2000);
windowServo2.attach(WINDOW_SERVO_PIN2); // Conectar el servo a pin 23
windowServo2.writeMicroseconds(SERVOMIN); // Inicialmente, la ventana está cerrada
delay(2000);
}
void loop() {
MQTT_connect(); //Asegura que la conexion MQTT esté activa
Adafruit_MQTT_Subscribe* suscription;
while(suscription=mqtt.readSubscription(2000)){ // Espera datos durante 2 segundos
if(suscription==&susc_amarillo){
Serial.println("Se ha presionado el boton");
int estado_led=atoi((char*)susc_amarillo.lastread);
digitalWrite(LED_AMARILLO,estado_led);
}
if(suscription==&susc_azul){
Serial.println("Se ha presionado el boton");
int estado_led=atoi((char*)susc_azul.lastread);
digitalWrite(LED_AZUL,estado_led);
}
if(suscription==&susc_verde){
Serial.println("Se ha presionado el boton");
int estado_led=atoi((char*)susc_verde.lastread);
digitalWrite(LED_VERDE,estado_led);
}
if(suscription==&susc_rojo){
Serial.println("Se ha presionado el boton");
int estado_led=atoi((char*)susc_rojo.lastread);
digitalWrite(LED_ROJO,estado_led);
}
if(suscription==&susc_morado){
Serial.println("Se ha presionado el boton");
int estado_led=atoi((char*)susc_morado.lastread);
digitalWrite(LED_MORADO,estado_led);
}
if(suscription==&susc_naranja){
Serial.println("Se ha presionado el boton");
int estado_led=atoi((char*)susc_naranja.lastread);
digitalWrite(LED_NARANJA,estado_led);
}
if (suscription==&susc_door){
Serial.println("Se ha precionado el boton");
// Cambiar estado de la puerta
int command=atoi((char*)susc_door.lastread);
Serial.print("Comando recibido: ");
Serial.println(command);
if (command == HIGH && !isDoorOpen) { // Abrir puerta
windowServo2.writeMicroseconds(SERVOMAX);
Serial.println("Ventana abierta");
isDoorOpen = true;
} else if (command == LOW && isDoorOpen) { // Cerrar puerta
windowServo2.writeMicroseconds(SERVOMIN);
Serial.println("Ventana cerrada");
isDoorOpen = false;
}
}
/*
// Convertir el valor a temperatura (simulación)
temperatura = (pinSensor / 4095.0) * 330.0; // Conversión para el rango 0-3.3V, suponiendo LM35
// Mostrar temperatura por el puerto serie
Serial.print("Temperatura: ");
Serial.print(temperatura);
Serial.println(" °C");
// Control del servomotor
if (temperatura >= umbralTemp) {
// Hacer girar el servomotor como un ventilador
for (int angulo = 0; angulo <= 180; angulo += 10) {
ventilador.write(angulo);
delay(50); // Pequeña pausa para simular movimiento suave
}
for (int angulo = 180; angulo >= 0; angulo -= 10) {
ventilador.write(angulo);
delay(50);
}
} else {
// Detener el ventilador
ventilador.write(0);
}
*/
//delay(500); // Pequeña pausa antes de la próxima lectura
}
static unsigned long lastSend = 0; // Marca de tiempo de la última publicación
if (millis() - lastSend > 5000) { // Verifica si han pasado 5 segundo
// Lectura del primer sensor
TempAndHumidity lectura= dhtSensor.getTempAndHumidity();
temperatura=lectura.temperature;
humedad=lectura.humidity;
// Mostrar datos del primer sensor en la pantalla LCD
lcd.setCursor(0,0);
lcd.print("Temp:" + String(temperatura,2) + " c");
lcd.setCursor(0,1);
lcd.print("Humedad:" + String(humedad,2) + " %");
// Publicar datos del primer sensor
lastSend = millis(); // Actualiza el tiempo de la última publicación
if (!pub_temperatura.publish(String(temperatura).c_str())) { // Convierte a cadena y publica
Serial.println(F("Error al publicar temperatura"));
} else {
Serial.println(F("Temperatura enviada con éxito"));
}
if (!pub_humedad.publish(String(humedad).c_str())) { // Convierte a cadena y publica
Serial.println(F("Error al publicar temperatura"));
} else {
Serial.println(F("Temperatura enviada con éxito"));
}
}
// Control del servomotor
if (temperatura >= umbralTemp) {
// Hacer girar el servomotor como un ventilador
for (int angulo = 0; angulo <= 180; angulo += 10) {
ventilador.write(angulo);
Serial.println(angulo);
delay(25); // Pequeña pausa para simular movimiento suave
}
for (int angulo = 180; angulo >= 0; angulo -= 10) {
ventilador.write(angulo);
Serial.println(angulo);
delay(25);
}
} else {
// Detener el ventilador
ventilador.write(0);
}
//delay(500); // Pequeña pausa antes de la próxima lectura
}
void MQTT_connect() {
int8_t ret;
// Verifica si ya está conectado al servidor MQTT
if (mqtt.connected()) {
return; // Si está conectado, no hace nada
}
Serial.print("Connecting to MQTT...");
uint8_t retries = 3; // Número máximo de reintentos
// Intenta conectar al servidor MQTT
while (ret = mqtt.connect() != 0) {
Serial.println(mqtt.connectErrorString(ret)); // Imprime el error de conexión
Serial.println("reintentando conectar en 5 segundos...");
mqtt.disconnect(); // Desconecta el cliente MQTT
delay(5000); // Espera 5 segundos antes de reintentar
if (retries == 0) {
while (1); // Si falla, se queda en un bucle infinito
}
}
Serial.println("mqtt Conectado!!!");
}