#include #include #include "esp_rom_sys.h" #include "esp_task_wdt.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "nvs_flash.h" #include "esp_system.h" #include "esp_log.h" #include "esp_wifi.h" #include "esp_event.h" #include "esp_netif.h" #include "esp_spiffs.h" #include "esp_sntp.h" #include "wifi_config_portal.h" #include "mqtt_handler.h" #include "led_driver.h" #include "esp_random.h" #include "eeprom_virtual.h" #include "eeprom_tls.h" typedef struct { int total_creditos; int total_saidas; } contadores_t; static const char *TAG = "APP"; static uint32_t segundos = 0; static bool wifi_ready = false; // === Contador simples de debug === void segundos_task(void *pv) { while (1) { vTaskDelay(pdMS_TO_TICKS(1000)); segundos++; // ESP_LOGI("TIMER", "⏱ %lu segundos", segundos); } } uint32_t get_segundos(void) { return segundos; } // === Task de LEDs === void led_task(void *pv) { bool tem_creditos = false; while (1) { if (wifi_ready && tem_creditos) { uint16_t target = esp_random() % LED_COUNT; led_spin_to(target, 2, 12, 80); tem_creditos = false; } else if (wifi_ready) { led_idle_animation(); } else { vTaskDelay(pdMS_TO_TICKS(100)); // espera Wi-Fi } vTaskDelay(pdMS_TO_TICKS(50)); } } // === Callback quando Wi-Fi e IP estão prontos === static void on_wifi_connected(void) { wifi_ready = true; ESP_LOGI(TAG, "✅ Wi-Fi conectado, IP obtido — iniciando MQTT e LEDs..."); mqtt_handler_start(); ESP_LOGI(TAG, "🕒 Inicializando SNTP..."); esp_sntp_setoperatingmode(SNTP_OPMODE_POLL); esp_sntp_setservername(0, "pool.ntp.org"); esp_sntp_init(); ESP_LOGI(TAG, "💡 Inicializando LEDs..."); led_init(); } #include "esp_rom_sys.h" void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { esp_rom_printf("\n🧨 Stack overflow em %s!\n", pcTaskName); // NÃO reinicia aqui — isso bloqueia o WiFi event task e causa WDT // apenas marca para reiniciar depois esp_task_wdt_reset(); vTaskDelay(pdMS_TO_TICKS(1000)); esp_restart(); } // === Função principal === void app_main(void) { // ---------- EEPROM ---------- eeprom_virtual_init(); contadores_t contadores = {100, 25}; eeprom_virtual_write_bin("contadores", &contadores, sizeof(contadores)); ESP_LOGI("EEPROM", "💾 Gravado: total_creditos=%d, total_saidas=%d", contadores.total_creditos, contadores.total_saidas); contadores_t lidos = {0}; size_t len = sizeof(lidos); if (eeprom_virtual_read_bin("contadores", &lidos, &len) == ESP_OK) { ESP_LOGI("EEPROM", "📖 Lido: total_creditos=%d, total_saidas=%d", lidos.total_creditos, lidos.total_saidas); } else { ESP_LOGW("EEPROM", "⚠️ Falha ao ler dados!"); } // ---------- NVS ---------- ESP_ERROR_CHECK(nvs_flash_init()); // ---------- LOG ---------- esp_log_level_set("wifi", ESP_LOG_WARN); // ---------- SPIFFS ---------- ESP_LOGI(TAG, "🔧 Montando SPIFFS..."); esp_vfs_spiffs_conf_t spiffs_conf = { .base_path = "/spiffs", .partition_label = "storage", .max_files = 5, .format_if_mount_failed = true }; esp_err_t ret = esp_vfs_spiffs_register(&spiffs_conf); if (ret != ESP_OK) { ESP_LOGE(TAG, "❌ Falha ao montar SPIFFS (%s)", esp_err_to_name(ret)); } else { size_t total = 0, used = 0; esp_spiffs_info(spiffs_conf.partition_label, &total, &used); ESP_LOGI(TAG, "📦 SPIFFS OK: total=%d bytes, usado=%d", total, used); } // ---------- Wi-Fi ---------- wifi_config_t cfg; bool have_creds = false; if (esp_wifi_get_config(WIFI_IF_STA, &cfg) == ESP_OK) { if (strlen((char *)cfg.sta.ssid) > 0) { ESP_LOGI(TAG, "📂 Credenciais encontradas no NVS: SSID=%s", cfg.sta.ssid); have_creds = true; } } wifi_config_portal_init(on_wifi_connected, have_creds); // ---------- Tasks ---------- xTaskCreate(segundos_task, "segundos_task", 12288, NULL, 5, NULL); xTaskCreate(led_task, "led_task", 12288, NULL, 5, NULL); // ---------- Loop principal (livre) ---------- while (1) { if (wifi_ready) { mqtt_handler_loop(); // mantém MQTT ativo } vTaskDelay(pdMS_TO_TICKS(100)); } }