//Autor: Fábio Henrique Cabrini
//Resumo: Esse programa possibilita ligar e desligar o led onboard, além de mandar o status para o Broker MQTT possibilitando o Helix saber
//se o led está ligado ou desligado.
//Revisões:
//Rev1: 26-08-2023 Código portado para o ESP32 e para realizar a leitura de luminosidade e publicar o valor em um tópico aprorpiado do broker
//Autor Rev1: Lucas Demetrius Augusto
//Rev2: 28-08-2023 Ajustes para o funcionamento no FIWARE Descomplicado
//Autor Rev2: Fábio Henrique Cabrini
//Rev3: 1-11-2023 Refinamento do código e ajustes para o funcionamento no FIWARE Descomplicado
//Autor Rev3: Fábio Henrique Cabrini
#include <WiFi.h>
#include <PubSubClient.h>
// Configurações - variáveis editáveis
const char* default_SSID = "Wokwi-GUEST"; // Nome da rede Wi-Fi
const char* default_PASSWORD = ""; // Senha da rede Wi-Fi
const char* default_BROKER_MQTT = "46.17.108.131"; // IP do Broker MQTT
const int default_BROKER_PORT = 1883; // Porta do Broker MQTT
const char* default_TOPICO_SUBSCRIBE = "/TEF/Flux060/cmd"; // Tópico MQTT de escuta
const char* default_TOPICO_PUBLISH_1 = "/TEF/Flux060/attrs"; // Tópico MQTT de envio de informações para Broker
const char* default_TOPICO_PUBLISH_2 = "/TEF/Flux060/attrs/1"; // Tópico MQTT de envio de informações para Broker
const char* default_ID_MQTT = "fiware_flux_060"; // ID MQTT
const int default_D4 = 2; // Pino do LED onboard
// Declaração da variável para o prefixo do tópico
const char* topicPrefix = "flux060";
// Variáveis para configurações editáveis
char* SSID = const_cast<char*>(default_SSID);
char* PASSWORD = const_cast<char*>(default_PASSWORD);
char* BROKER_MQTT = const_cast<char*>(default_BROKER_MQTT);
int BROKER_PORT = default_BROKER_PORT;
char* TOPICO_SUBSCRIBE = const_cast<char*>(default_TOPICO_SUBSCRIBE);
char* TOPICO_PUBLISH_1 = const_cast<char*>(default_TOPICO_PUBLISH_1);
char* TOPICO_PUBLISH_2 = const_cast<char*>(default_TOPICO_PUBLISH_2);
char* ID_MQTT = const_cast<char*>(default_ID_MQTT);
int D4 = default_D4;
#define FS300A_PULSE 508 // PULSE / LITRO
#define FS300A_FLOW_RATE 60 // LITRO / MINUTO
const float factor = 60.0F / 508.0F; // FS300A_FLOW_RATE / FS300A_PULSE
#define interruptPin 5
volatile uint16_t pulse; // Variável que será incrementada na interrupção
uint16_t count; // Variável para armazenar o valor atual de pulse
float frequency; // Frequência calculada a partir de count
float flowRate; // Taxa de fluxo calculada a partir da frequência
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; // Mutex para garantir acesso seguro a pulse
WiFiClient espClient;
PubSubClient MQTT(espClient);
char EstadoSaida = '0';
void initSerial() {
Serial.begin(115200);
}
void initWiFi() {
delay(10);
Serial.println("------Conexao WI-FI------");
Serial.print("Conectando-se na rede: ");
Serial.println(SSID);
Serial.println("Aguarde");
reconectWiFi();
}
void initMQTT() {
MQTT.setServer(BROKER_MQTT, BROKER_PORT);
MQTT.setCallback(mqtt_callback);
}
void IRAM_ATTR FlowInterrupt() {
portENTER_CRITICAL_ISR(&mux); // Entra em uma seção crítica de interrupção
pulse++; // Incrementa a variável pulse de maneira segura
portEXIT_CRITICAL_ISR(&mux); // Sai da seção crítica de interrupção
}
void setup() {
InitOutput();
initSerial();
initWiFi();
initMQTT();
delay(5000);
MQTT.publish(TOPICO_PUBLISH_1, "s|on");
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), FlowInterrupt, CHANGE); // Configura a interrupção no pino
}
void loop() {
VerificaConexoesWiFIEMQTT();
EnviaEstadoOutputMQTT();
Frequency();
MQTT.loop();
}
void reconectWiFi() {
if (WiFi.status() == WL_CONNECTED)
return;
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.println("Conectado com sucesso na rede ");
Serial.print(SSID);
Serial.println("IP obtido: ");
Serial.println(WiFi.localIP());
// Garantir que o LED inicie desligado
digitalWrite(D4, LOW);
}
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
String msg;
for (int i = 0; i < length; i++) {
char c = (char)payload[i];
msg += c;
}
Serial.print("- Mensagem recebida: ");
Serial.println(msg);
// Forma o padrão de tópico para comparação
String onTopic = String(topicPrefix) + "@on|";
String offTopic = String(topicPrefix) + "@off|";
// Compara com o tópico recebido
if (msg.equals(onTopic)) {
digitalWrite(D4, HIGH);
EstadoSaida = '1';
}
if (msg.equals(offTopic)) {
digitalWrite(D4, LOW);
EstadoSaida = '0';
}
}
void VerificaConexoesWiFIEMQTT() {
if (!MQTT.connected())
reconnectMQTT();
reconectWiFi();
}
void EnviaEstadoOutputMQTT() {
if (EstadoSaida == '1') {
MQTT.publish(TOPICO_PUBLISH_1, "s|on");
Serial.println("- Led Ligado");
}
if (EstadoSaida == '0') {
MQTT.publish(TOPICO_PUBLISH_1, "s|off");
Serial.println("- Led Desligado");
}
Serial.println("- Estado do LED onboard enviado ao broker!");
delay(1000);
}
void InitOutput() {
pinMode(D4, OUTPUT);
digitalWrite(D4, HIGH);
boolean toggle = false;
for (int i = 0; i <= 10; i++) {
toggle = !toggle;
digitalWrite(D4, toggle);
delay(200);
}
}
void reconnectMQTT() {
while (!MQTT.connected()) {
Serial.print("* Tentando se conectar ao Broker MQTT: ");
Serial.println(BROKER_MQTT);
if (MQTT.connect(ID_MQTT)) {
Serial.println("Conectado com sucesso ao broker MQTT!");
MQTT.subscribe(TOPICO_SUBSCRIBE);
} else {
Serial.println("Falha ao reconectar no broker.");
Serial.println("Haverá nova tentativa de conexão em 2s");
delay(2000);
}
}
}
void Frequency() {
static unsigned long startTime;
if (micros() - startTime < 1000000UL ) return; // Intervalo de 1000 milissegundos (1 segundo)
startTime = micros();
portENTER_CRITICAL(&mux); // Entra em uma seção crítica
count = pulse; // Salva o valor atual de pulse e zera pulse
pulse = 0;
portEXIT_CRITICAL(&mux); // Sai da seção crítica
frequency = count / 2.0f; // Calcula a frequência
flowRate = frequency * factor; // Calcula a taxa de fluxo
PlotInfo(); // Exibe as informações no Serial Monitor
String mensagem = String(flowRate);
Serial.println(mensagem.c_str());
MQTT.publish(TOPICO_PUBLISH_2, mensagem.c_str());
}
void PlotInfo() {
Serial.print("Freq.:= " + String(frequency, 2) + " Hz");
Serial.println(", FLow:= " + String(flowRate, 3) + " L/min");
}