#include <Arduino.h>
#include <esp_task_wdt.h>
#include <esp_log.h>
const int ledVerde = 22;
const int ledVermelho = 5;
const int LDR_PIN = 34;
const int DO_PIN = 35;
hw_timer_t *timer1 = NULL;
hw_timer_t *timer2 = NULL;
const float GAMMA = 0.7;
const float RL10 = 50;
int valorAnterior = 0;
float lux = 0;
volatile int contadorCarrega = 0;
volatile int contadorIndicadorCarga = 0;
volatile int contadorMain = 0;
volatile bool flagCarrega = false;
volatile bool flagIndicadorCarga = false;
volatile bool flagWatchdog = false;
volatile bool isPiscar = false; // Controle do estado do LED (piscar ou ligado continuamente)
void IRAM_ATTR isrCarregar();
void IRAM_ATTR isr5Segundos();
void IRAM_ATTR isrWatchdog();
void taskCarregar(void *pvParameters);
void task5Segundos(void *pvParameters);
void taskWatchdog(void *pvParameters);
void piscaLedVerde();
void piscaLedVermelho();
void setup() {
Serial.begin(115200);
contadorCarrega = 69;
contadorIndicadorCarga = 69;
contadorMain = 69;
// Configuração dos pinos
pinMode(ledVerde, OUTPUT);
pinMode(ledVermelho, OUTPUT);
pinMode(LDR_PIN, INPUT);
pinMode(DO_PIN, INPUT);
// Configuração das interrupções
attachInterrupt(digitalPinToInterrupt(DO_PIN), isrCarregar, CHANGE);
esp_task_wdt_config_t wdt_config = {0};
wdt_config.timeout_ms = 60000;
wdt_config.trigger_panic = true;
if (!CONFIG_ESP_TASK_WDT_INIT) {
esp_task_wdt_init(&wdt_config); // Inicializa o Watchdog
} else {
esp_task_wdt_reconfigure(&wdt_config); // Reconfigura o Watchdog
}
Serial.print(esp_reset_reason());
// Criação das tarefas FreeRTOS
xTaskCreate(taskCarregar, "TaskCarregar", 2048, NULL, 1, NULL);
xTaskCreate(task5Segundos, "Task5Segundos", 2048, NULL, 1, NULL);
xTaskCreate(taskWatchdog, "TaskWatchdog", 2048, NULL, 2, NULL);
timer1 = timerBegin(1000000);
timerAttachInterrupt(timer1, &isr5Segundos);
timerAlarm(timer1, 5000000, true,0);
timer2 = timerBegin(1000000);
timerAttachInterrupt(timer2, &isrWatchdog);
timerAlarm(timer2, 7000000, true,0);
}
void loop() {
contadorMain++;
vTaskDelay(100 / portTICK_PERIOD_MS);
}
// Interrupção para monitorar o botão
void IRAM_ATTR isrCarregar() {
int analogValue = analogRead(LDR_PIN);
float voltage = analogValue / 4096.0 * 3.3;
float resistance = 2000 * voltage / (1 - voltage / 3.3);
lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
Serial.print("Luminosidade: ");
Serial.println(lux);
flagCarrega = digitalRead(DO_PIN);
isPiscar = false; // Interrompe o modo "piscar" ao pressionar o botão
}
// Interrupção para o temporizador
void IRAM_ATTR isr5Segundos() {
if (flagCarrega) {
flagIndicadorCarga = true;
isPiscar = true; // Ativa o modo "piscar"
}
}
// Interrupção para o Watchdog
void IRAM_ATTR isrWatchdog() {
flagWatchdog = true;
}
// Tarefa para gerenciar o estado do LED verde
void taskCarregar(void *pvParameters) {
while (true) {
if (flagCarrega && !isPiscar) { // Liga continuamente, exceto quando no modo "piscar"
digitalWrite(ledVerde, HIGH);
} else if (!flagCarrega) {
digitalWrite(ledVerde, LOW);
}
contadorCarrega++;
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
// Tarefa para gerenciar o piscar do LED verde
void task5Segundos(void *pvParameters) {
while (true) {
if (flagIndicadorCarga && isPiscar) {
flagIndicadorCarga = false; // Reseta a flag
contadorIndicadorCarga++;
Serial.println("Piscando LED Verde...");
piscaLedVerde();
}
contadorIndicadorCarga++;
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
// Tarefa para o Watchdog
void taskWatchdog(void *pvParameters) {
esp_task_wdt_add(NULL); // Adiciona a tarefa ao Watchdog
while (true) {
if (flagWatchdog) {
flagWatchdog = false;
Serial.println("contadorCarrega: " + String(contadorCarrega) + " contadorMain: " + String(contadorMain) + " contadorIndicadorCarga: " + String(contadorIndicadorCarga));
if (contadorCarrega >= 69 && ((contadorIndicadorCarga >= 69 && isPiscar == false) || (contadorIndicadorCarga >= 30 && isPiscar == true)) && contadorMain >= 69) {
contadorCarrega = 0;
contadorIndicadorCarga = 0;
contadorMain = 0;
Serial.println("Watchdog OK");
esp_task_wdt_reset();
} else {
Serial.println("Falha no Watchdog - Reiniciando ESP");
piscaLedVermelho();
esp_restart();
}
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
// Função para piscar o LED verde 5 vezes
void piscaLedVerde() {
for (int i = 0; i < 5; i++) {
digitalWrite(ledVerde, LOW);
vTaskDelay(200 / portTICK_PERIOD_MS);
digitalWrite(ledVerde, HIGH);
vTaskDelay(200 / portTICK_PERIOD_MS);
}
}
// Função para piscar o LED vermelho 5 vezes
void piscaLedVermelho() {
for (int i = 0; i < 5; i++) {
digitalWrite(ledVermelho, HIGH);
vTaskDelay(200 / portTICK_PERIOD_MS);
digitalWrite(ledVermelho, LOW);
vTaskDelay(200 / portTICK_PERIOD_MS);
}
}