#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define WIFI_CHANNEL 6
const char *MQTT_BROKER_ADRESS = "broker.mqtt.cool";
const uint16_t MQTT_PORT = 1883;
const char *MQTT_CLIENT_NAME = "nazalopez";
const char *MQTT_USER = "a";
const char *MQTT_PASS = "b";
#define buttonA 35
#define buttonB 33
#define buttonC 14
#define ledAzul 22
#define ledVerde 19
#define ledNaranja 18
#define DESARMADA 0
#define ARMADA 1
#define FUNCIONAMIENTO 2
#define ALERTA 3
int state = DESARMADA;
volatile bool buttonA_released = false;
volatile bool buttonB_released = false;
volatile bool buttonC_released = false;
volatile bool timerBlink_interrupted = false;
volatile bool alertaActivada = false;
TaskHandle_t HandleTask1;
hw_timer_t *timerBlink = NULL;
WiFiClient espClient;
PubSubClient mqttClient(espClient);
/* ================= WIFI ================= */
void ConnectWiFi() {
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!");
}
/* ================= MQTT ================= */
void OnMqttReceived(char *topic, byte *payload, unsigned int length) {
String message = "";
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("MQTT [");
Serial.print(topic);
Serial.print("] -> ");
Serial.println(message);
if (strcmp(topic, "interfaz/input") == 0) {
if (message == "A") {
buttonA_released = true;
} else if (message == "B") {
buttonB_released = true;
} else if (message == "C") {
buttonC_released = true;
} else {
Serial.println("Payload incorrecto");
}
}
else if (strcmp(topic, "interfaz/alerta") == 0) {
if (message == "ON") {
alertaActivada = true;
} else if (message == "OFF") {
alertaActivada = false;
}
}
}
void InitMqtt() {
mqttClient.setServer(MQTT_BROKER_ADRESS, MQTT_PORT);
mqttClient.setCallback(OnMqttReceived);
}
void ConnectMqtt() {
while (!mqttClient.connected()) {
Serial.print("Connecting to MQTT...");
if (mqttClient.connect(MQTT_CLIENT_NAME, MQTT_USER, MQTT_PASS)) {
mqttClient.subscribe("interfaz/input");
mqttClient.subscribe("interfaz/alerta");
Serial.println(" OK");
} else {
Serial.print(" failed, rc=");
Serial.println(mqttClient.state());
delay(2000);
}
}
}
void HandleMqtt() {
if (!mqttClient.connected()) {
ConnectMqtt();
}
mqttClient.loop();
}
/* ================= ISR ================= */
void IRAM_ATTR timerBlink_int() {
timerBlink_interrupted = true;
}
void IRAM_ATTR buttonA_ISR() {
buttonA_released = true;
}
void IRAM_ATTR buttonB_ISR() {
buttonB_released = true;
}
void IRAM_ATTR buttonC_ISR() {
buttonC_released = true;
}
/* ================= FSM ================= */
void FSM(void *parameter) {
while (true) {
HandleMqtt(); // 🔥 MQTT siempre activo
switch (state) {
case DESARMADA:
if (buttonA_released) {
buttonA_released = false;
state = ARMADA;
timerStop(timerBlink);
digitalWrite(ledAzul, HIGH);
}
if (timerBlink_interrupted) {
timerBlink_interrupted = false;
digitalWrite(ledAzul, !digitalRead(ledAzul));
}
if (alertaActivada) {
state = ALERTA;
timerStart(timerBlink);
}
break;
case ARMADA:
if (buttonB_released) {
buttonB_released = false;
state = FUNCIONAMIENTO;
digitalWrite(ledVerde, HIGH);
digitalWrite(ledAzul, LOW);
}
if (buttonA_released) {
buttonA_released = false;
state = DESARMADA;
timerStart(timerBlink);
}
if (alertaActivada) {
state = ALERTA;
timerStart(timerBlink);
}
break;
case FUNCIONAMIENTO:
if (buttonB_released) {
buttonB_released = false;
state = ARMADA;
digitalWrite(ledAzul, HIGH);
}
if (alertaActivada) {
state = ALERTA;
timerStart(timerBlink);
}
break;
case ALERTA:
if (buttonC_released) {
buttonC_released = false;
alertaActivada = false;
state = DESARMADA;
}
if (timerBlink_interrupted) {
timerBlink_interrupted = false;
digitalWrite(ledAzul, !digitalRead(ledAzul));
digitalWrite(ledNaranja, !digitalRead(ledNaranja));
}
break;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
/* ================= SETUP / LOOP ================= */
void setup() {
Serial.begin(115200);
ConnectWiFi();
InitMqtt();
pinMode(buttonA, INPUT_PULLUP);
pinMode(buttonB, INPUT_PULLUP);
pinMode(buttonC, INPUT_PULLUP);
pinMode(ledAzul, OUTPUT);
pinMode(ledVerde, OUTPUT);
pinMode(ledNaranja, OUTPUT);
attachInterrupt(digitalPinToInterrupt(buttonA), buttonA_ISR, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonB), buttonB_ISR, FALLING);
attachInterrupt(digitalPinToInterrupt(buttonC), buttonC_ISR, FALLING);
timerBlink = timerBegin(1000000);
timerAttachInterrupt(timerBlink, &timerBlink_int);
timerAlarm(timerBlink, 250000, true, 0);
timerStart(timerBlink);
xTaskCreatePinnedToCore(
FSM,
"FSM",
4096,
NULL,
1,
&HandleTask1,
0
);
}
void loop() {
delay(10);
}
A
B
C