2026-09-25 16:33:06 +02:00
|
|
|
#include <stdio.h>
|
2026-09-11 10:19:50 +02:00
|
|
|
#include <freertos/FreeRTOS.h>
|
|
|
|
|
#include <freertos/task.h>
|
|
|
|
|
#include <esp_system.h>
|
2026-09-25 16:33:06 +02:00
|
|
|
#include <esp_timer.h>
|
2026-10-05 19:28:37 +02:00
|
|
|
#include <esp_log.h>
|
2026-09-11 10:19:50 +02:00
|
|
|
|
|
|
|
|
#include "nvs_flash.h"
|
|
|
|
|
#include "esp_http_server.h"
|
2026-10-05 19:28:37 +02:00
|
|
|
#include "i2cdev.h"
|
2026-09-11 10:19:50 +02:00
|
|
|
|
|
|
|
|
#include "ygg_http_server.h"
|
|
|
|
|
#include "ygg_http_routes.h"
|
|
|
|
|
#include "ygg_wifi.h"
|
|
|
|
|
#include "ygg_http_server.h"
|
|
|
|
|
#include "ygg_bmp280.h"
|
2026-09-13 18:14:19 +02:00
|
|
|
#include "ygg_http_req.h"
|
2026-09-15 20:51:07 +02:00
|
|
|
#include "ygg_state.h"
|
2026-09-25 16:21:37 +02:00
|
|
|
#include "ygg_sh1106.h"
|
2026-10-05 19:28:37 +02:00
|
|
|
#include "ygg_lock.h"
|
2026-09-25 16:21:37 +02:00
|
|
|
#include "lvgl.h"
|
2026-09-11 10:19:50 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
static const char *TAG = "thermo_sensor";
|
2026-09-25 16:21:37 +02:00
|
|
|
static lv_display_t *sh_display = NULL;
|
|
|
|
|
static lv_obj_t *label = NULL;
|
2026-09-11 10:19:50 +02:00
|
|
|
bmp280_t dev_bmp_280;
|
|
|
|
|
|
2026-09-25 16:33:06 +02:00
|
|
|
void lvgl_task(void *pvParameters) {
|
|
|
|
|
while (1) {
|
2026-10-05 19:28:37 +02:00
|
|
|
if (ygg_lvgl_lock_take(pdMS_TO_TICKS(100))) {
|
|
|
|
|
lv_timer_handler();
|
|
|
|
|
ygg_lvgl_lock_give();
|
|
|
|
|
}
|
2026-09-25 16:33:06 +02:00
|
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void sensor_task(void *pvParameters) {
|
2026-09-20 18:24:09 +02:00
|
|
|
// Wait 1s, to avoid corrupted first sensor readout
|
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
2026-09-11 10:19:50 +02:00
|
|
|
while (1) {
|
2026-10-05 19:28:37 +02:00
|
|
|
esp_err_t err = ygg_bmp280_read_sensor(&dev_bmp_280);
|
2026-09-25 16:33:06 +02:00
|
|
|
// Najpierw OLED, potem (blokujący) HTTP — żeby ekran
|
|
|
|
|
// odświeżył się nawet gdy serwer nie odpowiada.
|
2026-10-05 19:28:37 +02:00
|
|
|
// 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.
|
2026-09-25 16:46:30 +02:00
|
|
|
char buf[256];
|
2026-10-05 19:28:37 +02:00
|
|
|
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));
|
2026-09-11 10:19:50 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void app_main()
|
|
|
|
|
{
|
2026-09-17 19:49:23 +02:00
|
|
|
// 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
|
2026-09-11 10:19:50 +02:00
|
|
|
esp_err_t ret = nvs_flash_init();
|
2026-09-17 19:49:23 +02:00
|
|
|
|
2026-09-18 14:20:49 +02:00
|
|
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
|
|
|
|
|
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
2026-09-17 19:49:23 +02:00
|
|
|
// ESP_ERR_NVS_NEW_VERSION_FOUND - NVS header page is
|
|
|
|
|
// stored in newer version (newer IDF) than version
|
|
|
|
|
// it is used by this application
|
2026-09-11 10:19:50 +02:00
|
|
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
2026-09-17 19:49:23 +02:00
|
|
|
ESP_ERROR_CHECK(nvs_flash_init());
|
2026-09-11 10:19:50 +02:00
|
|
|
}
|
2026-09-17 19:49:23 +02:00
|
|
|
|
|
|
|
|
ygg_wifi_init_sta();
|
2026-09-11 10:19:50 +02:00
|
|
|
|
|
|
|
|
httpd_handle_t server = ygg_start_webserver();
|
|
|
|
|
httpd_register_uri_handler(server, &ygg_temp_uri);
|
2026-09-11 13:34:55 +02:00
|
|
|
httpd_register_uri_handler(server, &ygg_press_uri);
|
|
|
|
|
httpd_register_uri_handler(server, &ygg_hum_uri);
|
2026-09-11 10:19:50 +02:00
|
|
|
|
2026-10-05 19:28:37 +02:00
|
|
|
// 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());
|
|
|
|
|
|
2026-09-25 16:21:37 +02:00
|
|
|
sh_display = ygg_sh1106_init();
|
2026-09-25 16:33:06 +02:00
|
|
|
|
2026-09-25 16:21:37 +02:00
|
|
|
lv_obj_t *scr = lv_display_get_screen_active(sh_display);
|
|
|
|
|
label = lv_label_create(scr);
|
2026-09-30 15:46:21 +02:00
|
|
|
ygg_set_display_label(sh_display, label, "PLEASE WAIT...");
|
2026-09-25 16:21:37 +02:00
|
|
|
|
2026-09-11 10:19:50 +02:00
|
|
|
ygg_bmp280_init(&dev_bmp_280);
|
2026-09-30 15:46:21 +02:00
|
|
|
|
2026-09-25 16:33:06 +02:00
|
|
|
xTaskCreatePinnedToCore(lvgl_task, "lvgl", 4096, NULL, 4, NULL, APP_CPU_NUM);
|
|
|
|
|
xTaskCreatePinnedToCore(sensor_task, "bmp280_test", 8192, NULL, 5, NULL, APP_CPU_NUM);
|
2026-09-11 10:19:50 +02:00
|
|
|
}
|
|
|
|
|
|