#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// ===============================
// CONFIG WIFI
// ===============================
const char *SSID = "Wokwi-GUEST";
const char *PASSWORD = "";
// ===============================
// CONFIG MQTT
// ===============================
const char *BROKER_MQTT = "test.mosquitto.org";
const int BROKER_PORT = 1883;
const char *ID_MQTT = "esp32_001";
const char *TOPIC_PUBLISH_STATUS = "fiap/iot/led/status/esp32_001";
const char *TOPIC_SUBSCRIBE_CONTROL = "fiap/iot/led/control/esp32_001";
// ===============================
// PINOS
// ===============================
const int pinRed = 21;
const int pinGreen = 22;
const int pinBlue = 23;
const int buzzerPin = 13;
// ===============================
// ESTADOS
// ===============================
bool ledOn = false;
int currentColor = -1;
// Controle do buzzer (beep a cada 1s)
bool buzzerOn = false;
unsigned long lastBuzzTime = 0;
const unsigned long buzzInterval = 1000; // intervalo total entre beeps
const unsigned long buzzDuration = 250; // duração de cada beep
bool isBuzzingNow = false;
WiFiClient espClient;
PubSubClient client(espClient);
// ===============================
// ESTRUTURA DE CORES
// ===============================
struct LedColor {
uint8_t r, g, b;
const char *problema;
};
LedColor cores[] = {
{255, 0, 0, "Problema Mecânico"},
{0, 255, 0, "Documentação Pendente"},
{0, 0, 255, "Problema Elétrico"},
{255, 255, 0, "Problema Estético"},
{255, 50, 0, "Problema Segurança"},
{150, 0, 0, "Problemas Múltiplos"},
{130, 0, 255, "Motocicleta Pronta para Uso"}
};
// ===============================
// FUNÇÕES AUXILIARES
// ===============================
void setColor(uint8_t r, uint8_t g, uint8_t b) {
analogWrite(pinRed, r);
analogWrite(pinGreen, g);
analogWrite(pinBlue, b);
}
void startBuzz() {
buzzerOn = true;
lastBuzzTime = millis();
isBuzzingNow = true;
tone(buzzerPin, 2500);
}
void stopBuzz() {
noTone(buzzerPin);
isBuzzingNow = false;
}
void publishStatus() {
StaticJsonDocument<200> doc;
doc["id_tag"] = ID_MQTT;
doc["led_on"] = ledOn;
doc["color"] = currentColor;
doc["problema"] = (ledOn && currentColor >= 0 && currentColor < 7)
? cores[currentColor].problema
: "Desligado";
char buffer[256];
serializeJson(doc, buffer);
client.publish(TOPIC_PUBLISH_STATUS, buffer);
Serial.print("MQTT enviado: ");
Serial.println(buffer);
}
void updateLed() {
if (!ledOn || currentColor < 0) {
setColor(0, 0, 0);
buzzerOn = false;
stopBuzz();
publishStatus();
return;
}
LedColor c = cores[currentColor];
setColor(c.r, c.g, c.b);
buzzerOn = true; // ativa modo de beep contínuo
publishStatus();
}
// ===============================
// CALLBACK MQTT
// ===============================
void mqttCallback(char *topic, byte *payload, unsigned int length) {
Serial.print("Mensagem recebida no tópico: ");
Serial.println(topic);
char msg[length + 1];
memcpy(msg, payload, length);
msg[length] = '\0';
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, msg);
if (error) {
Serial.println("Erro ao decodificar JSON");
return;
}
bool newLedOn = doc["led_on"];
int newColor = doc["color"];
ledOn = newLedOn;
currentColor = newColor;
updateLed();
}
void reconnectMQTT() {
while (!client.connected()) {
Serial.print("Conectando ao MQTT...");
if (client.connect(ID_MQTT)) {
Serial.println("Conectado!");
client.subscribe(TOPIC_SUBSCRIBE_CONTROL);
} else {
Serial.print("Falhou, rc=");
Serial.println(client.state());
delay(5000);
}
}
}
// ===============================
// SETUP
// ===============================
void setup() {
Serial.begin(115200);
pinMode(pinRed, OUTPUT);
pinMode(pinGreen, OUTPUT);
pinMode(pinBlue, OUTPUT);
pinMode(buzzerPin, OUTPUT);
Serial.print("Conectando WiFi...");
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi conectado!");
client.setServer(BROKER_MQTT, BROKER_PORT);
client.setCallback(mqttCallback);
updateLed();
}
// ===============================
// LOOP PRINCIPAL
// ===============================
void loop() {
if (!client.connected()) reconnectMQTT();
client.loop();
unsigned long now = millis();
if (buzzerOn) {
if (isBuzzingNow && now - lastBuzzTime >= buzzDuration) {
// terminou o beep -> para som
stopBuzz();
lastBuzzTime = now;
} else if (!isBuzzingNow && now - lastBuzzTime >= (buzzInterval - buzzDuration)) {
// passou 1 segundo -> toca de novo
tone(buzzerPin, 2500);
isBuzzingNow = true;
lastBuzzTime = now;
}
}
}