//El sistema integra dos sensores principales: un sensor de temperatura LM35 y un sensor de luz LDR.
//El LM35 mide la temperatura en grados Celsius y el LDR mide la cantidad de luz ambiental.
//Estos valores se leen continuamente a través de los pines analógicos del ESP32,
//y los datos se envían en tiempo real a través de MQTT a la app IoT MQTT Panel),
//donde se pueden visualizar y controlar. Además, el sistema incluye un ventilador controlado
//por PWM (Modulación de Ancho de Pulso), que puede operar en dos modos:
//automático, donde el ventilador se enciende si la temperatura supera un umbral determinado,
//y manual, donde el usuario puede controlar el ventilador directamente desde la aplicación móvil.
// Esta funcionalidad se logra gracias a la comunicación bidireccional con el servidor MQTT,
//que permite recibir comandos para encender o apagar el ventilador.
//El widget de temperatura mostrará el valor de la temperatura leída desde el ESP32 18° c A 45°C
//El slider de luz mostrará el valor de la luz (el LDR)
//El switch de control del ventilador permitirá comandos ON o OFF al ESP32
//El switch de estado del ventilador reflejará si el ventilador está encendido o apagado
//LED AZUL ESTADO DEL VENTILADOR
//ROJO FUENTE
#include <WiFi.h>
#include <PubSubClient.h>
// Definición de pines
#define LM35_PIN 34
#define LDR_PIN 35
#define FAN_PIN 15
#define LED_PIN 2
#define BUTTON_PIN 4 // permite alternar entre los dos modos de control del ventiladoR automático y manual //Presionarlo alterna entre el modo automático (dependiente de la temperatura) y el modo manual (controlado por el usuario vía MQTT).
// Variables
int manualFanControl = 0;
int fanState = 0;
// MQTT Configuración
String clientId = "myClient";
String broker = "broker.emqx.io";
int port = 1883;
String topicPublishTemp = "panel/temperatura";
String topicPublishLight = "panel/luz";
String topicPublishFan = "panel/ventilador";
String topicSubscribeControl = "panel/ventilador/control";
WiFiClient wifiClient;
PubSubClient wifiMQTT(wifiClient);
void mqttCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Topic: ");
Serial.println(topic);
String mqttdata = "";
for (int i = 0; i < length; i++) {
mqttdata += (char)payload[i];
}
Serial.println(mqttdata);
if (mqttdata == "ON") {
fanState = 1;
} else if (mqttdata == "OFF") {
fanState = 0;
}
}
void setup() {
Serial.begin(115200);
pinMode(FAN_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial.print("Connecting to WiFi");
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
wifiMQTT.setServer(broker.c_str(), port);
wifiMQTT.setCallback(mqttCallback);
clientId += (String)random(1, 1000);
Serial.print("MQTT id: ");
Serial.println(clientId);
if (wifiMQTT.connect(clientId.c_str())) {
Serial.println("MQTT Connected!");
wifiMQTT.subscribe(topicSubscribeControl.c_str());
Serial.print("MQTT subscribe: ");
Serial.println(topicSubscribeControl);
} else {
Serial.println("MQTT error!");
}
}
void loop() {
if (!wifiMQTT.connected()) {
reconnectMQTT();
}
wifiMQTT.loop();
int tempValue = analogRead(LM35_PIN);
float temperature = tempValue * (3.3 / 4095.0) * 100.0;
int lightValue = analogRead(LDR_PIN);
if (manualFanControl == 0) {
fanState = (temperature > 30.0) ? 1 : 0;
}
analogWrite(FAN_PIN, fanState * 255);
digitalWrite(LED_PIN, fanState);
Serial.print("Temperatura: ");
Serial.print(temperature);
Serial.print(" °C, Luz: ");
Serial.println(lightValue);
wifiMQTT.publish(topicPublishTemp.c_str(), String(temperature).c_str());
wifiMQTT.publish(topicPublishLight.c_str(), String(lightValue).c_str());
wifiMQTT.publish(topicPublishFan.c_str(), fanState ? "ON" : "OFF");
if (digitalRead(BUTTON_PIN) == LOW) {
manualFanControl = !manualFanControl;
delay(300);
}
delay(1000);
}
void reconnectMQTT() {
while (!wifiMQTT.connected()) {
Serial.print("Conectando a MQTT...");
if (wifiMQTT.connect(clientId.c_str())) {
Serial.println("Conectado!");
} else {
Serial.print("Error, rc=");
Serial.print(wifiMQTT.state());
Serial.println(" Reintentando en 5 segundos...");
delay(5000);
}
}
}