#include #include #include #include #include #include #include "nvs_flash.h" #include "esp_http_server.h" #include "i2cdev.h" #include "ygg_http_server.h" #include "ygg_http_routes.h" #include "ygg_wifi.h" #include "ygg_http_server.h" #include "ygg_bmp280.h" #include "ygg_http_req.h" #include "ygg_state.h" #include "ygg_sh1106.h" #include "ygg_lock.h" #include "lvgl.h" static const char *TAG = "thermo_sensor"; static lv_display_t *sh_display = NULL; static lv_obj_t *label = NULL; bmp280_t dev_bmp_280; void lvgl_task(void *pvParameters) { while (1) { if (ygg_lvgl_lock_take(pdMS_TO_TICKS(100))) { lv_timer_handler(); ygg_lvgl_lock_give(); } vTaskDelay(pdMS_TO_TICKS(10)); } } void sensor_task(void *pvParameters) { // Wait 1s, to avoid corrupted first sensor readout vTaskDelay(pdMS_TO_TICKS(1000)); while (1) { esp_err_t err = ygg_bmp280_read_sensor(&dev_bmp_280); // Najpierw OLED, potem (blokujący) HTTP — żeby ekran // odświeżył się nawet gdy serwer nie odpowiada. // ygg_bmp280_read_sensor() aktualizuje CURR_READOUT TYLKO przy // sukcesie, więc przy błędzie pokazujemy ostatnie dobre + ERR // i NIE wysyłamy śmieci do bazy. char buf[256]; if (err == ESP_OK) { snprintf(buf, sizeof(buf), "Temp: %.1f C\nHumid: %.1f %%\nPress: %.1f hPa", CURR_READOUT.temperature, CURR_READOUT.humidity, CURR_READOUT.pressure / 100.); ygg_set_display_label(sh_display, label, buf); ygg_send_sensor_readouts(BASE_URL, SENSOR_NAME, CURR_READOUT); } else { snprintf(buf, sizeof(buf), "SENSOR ERR\nTemp: %.1f C\nHumid: %.1f %%\nPress: %.1f hPa", CURR_READOUT.temperature, CURR_READOUT.humidity, CURR_READOUT.pressure / 100.); ygg_set_display_label(sh_display, label, buf); ESP_LOGW(TAG, "skipping HTTP POST, keeping last good readout"); } vTaskDelay(pdMS_TO_TICKS(60 * 1000)); } } void app_main() { // NVS - Non-Volatile Storage, this memory stays untouched // after power off. It is key value memory stored // in separate partition of flash. It takes about 20kB. // Here it is not used directly. It is required by WiFi // driver to store SSID and password. // NVS is organized into pages. Single page is one flash // sector - typically 4096B esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { // ESP_ERR_NVS_NEW_VERSION_FOUND - NVS header page is // stored in newer version (newer IDF) than version // it is used by this application ESP_ERROR_CHECK(nvs_flash_erase()); ESP_ERROR_CHECK(nvs_flash_init()); } ygg_wifi_init_sta(); httpd_handle_t server = ygg_start_webserver(); httpd_register_uri_handler(server, &ygg_temp_uri); httpd_register_uri_handler(server, &ygg_press_uri); httpd_register_uri_handler(server, &ygg_hum_uri); // Jedna centralna inicjalizacja: mutexy + magistrala I2C. // Wcześniej i2cdev_init() był wołany w obu ygg_*_init() + bus był // tworzony przez dummy-device OLED, co mieszało. ygg_lock_init(); ESP_ERROR_CHECK(i2cdev_init()); sh_display = ygg_sh1106_init(); lv_obj_t *scr = lv_display_get_screen_active(sh_display); label = lv_label_create(scr); ygg_set_display_label(sh_display, label, "PLEASE WAIT..."); ygg_bmp280_init(&dev_bmp_280); xTaskCreatePinnedToCore(lvgl_task, "lvgl", 4096, NULL, 4, NULL, APP_CPU_NUM); xTaskCreatePinnedToCore(sensor_task, "bmp280_test", 8192, NULL, 5, NULL, APP_CPU_NUM); }