#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
// --- CREDENCIALES ---
#define WLAN_SSID "Wokwi-GUEST"
#define WLAN_PASS ""
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "Benja12zy"
#define AIO_KEY "aio_ngMm81qVUgIuL3l3j7ftUgLRUlWc"
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish feedTemp = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/temperatura");
Adafruit_MQTT_Publish feedRelay = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/estado_rele");
const int potPin = 34;
const int botonPin = 26;
const int relayPin = 18;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// --- VARIABLES DE CONTROL ---
bool sistemaDetenido = false;
float temp = 0.0;
unsigned long ultimoEnvio = 0;
// Variables para el Anti-rebote y Conteo de Clics
int contadorPulsos = 0;
unsigned long tiempoUltimoCambio = 0;
unsigned long tiempoEsperaDobleClic = 400; // Ventana de 0.4 seg para el segundo clic
bool estadoBotonAnterior = LOW;
bool procesandoPulsos = false;
void setup() {
Serial.begin(115200);
pinMode(botonPin, INPUT); // RECUERDA: La resistencia física a GND es vital
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW);
Wire.begin(21, 22);
lcd.init();
lcd.backlight();
lcd.print("SISTEMA LISTO");
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) { delay(500); }
lcd.clear();
}
void loop() {
if (!mqtt.connected()) {
while (mqtt.connect() != 0) { mqtt.disconnect(); delay(5000); }
}
temp = (analogRead(potPin) / 4095.0) * 100.0;
// --- LÓGICA DE BOTÓN ANTI-CONFUSIÓN ---
bool lecturaActual = digitalRead(botonPin);
// Detectar solo el momento exacto en que se presiona (Flanco de subida)
if (lecturaActual == HIGH && estadoBotonAnterior == LOW && (millis() - tiempoUltimoCambio > 50)) {
contadorPulsos++;
tiempoUltimoCambio = millis();
procesandoPulsos = true;
// Feedback visual inmediato en el LCD
lcd.setCursor(15, 1);
lcd.print(contadorPulsos);
}
estadoBotonAnterior = lecturaActual;
// Esperar a que pase el tiempo del "doble clic" para actuar
if (procesandoPulsos && (millis() - tiempoUltimoCambio > tiempoEsperaDobleClic)) {
if (contadorPulsos == 1) {
// ACCIÓN 1: STOP/RUN
sistemaDetenido = !sistemaDetenido;
if (sistemaDetenido) digitalWrite(relayPin, LOW);
lcd.clear();
lcd.setCursor(0,1);
lcd.print(sistemaDetenido ? ">>> STOP <<<" : ">>> RUN <<<");
delay(800);
}
else if (contadorPulsos >= 2) {
// ACCIÓN 2: RESET
lcd.clear();
lcd.print("REINICIANDO...");
delay(1000);
ESP.restart();
}
contadorPulsos = 0;
procesandoPulsos = false;
}
// --- LÓGICA DE CONTROL ---
if (!sistemaDetenido) {
if (temp >= 50.0) digitalWrite(relayPin, HIGH);
else if (temp <= 45.0) digitalWrite(relayPin, LOW);
}
actualizarLCD();
if (millis() - ultimoEnvio >= 5000) {
ultimoEnvio = millis();
feedTemp.publish(temp);
int32_t valRelay = digitalRead(relayPin);
feedRelay.publish(valRelay);
}
}
void actualizarLCD() {
lcd.setCursor(0, 0);
lcd.print("T:"); lcd.print(temp, 1); lcd.print("C ");
lcd.print(sistemaDetenido ? "STOP" : "RUN ");
if (!procesandoPulsos) {
lcd.setCursor(0, 1);
lcd.print("RELE: ");
lcd.print(digitalRead(relayPin) ? "ON " : "OFF ");
}
}Loading
esp32-devkit-c-v4
esp32-devkit-c-v4