#include "CO2_Sense.h" #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include #include "nvs_flash.h" #include "lwip/err.h" #include "lwip/sys.h" #include "esp_wifi.h" #include "esp_log.h" #include "esp_vfs_fat.h" #include "mdns.h" #include "APlib.h" #include "HTTPServe.h" #include "ledController.h" #include "scd4x_i2c.h" #include "sensirion_i2c_hal.h" #include "scd4x_data.h" #define LED1_PIN CONFIG_LED_1_PIN #define LED2_PIN CONFIG_LED_2_PIN #define LED3_PIN CONFIG_LED_3_PIN #define LED_NUMBER 3 void app_main(void){ init_nvs(); nvs_handle_t nvs_handle; ESP_ERROR_CHECK(nvs_open("main", NVS_READWRITE, &nvs_handle)); configuration_data_t* conf = malloc(sizeof(configuration_data_t)); init_conf_from_nvs(conf, nvs_handle); // init LEDs driver init_led_driver(conf->leds, LED_NUMBER); // init server stuff if wifi enabled if(conf->wireless & C_WIFI_NEED_HTTP){ ESP_LOGI("main", "%i", conf->wireless); // init tcpip ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); // start avahi init_avahi(conf->hostname); // start httpd server init_http_server(conf); } // start wifi switch(conf->wireless){ case C_WIFI_MODE_AP: wifi_init_softap(conf->wifi_config); break; } // start sensor init_scd4x(); switch(conf->sensor->mode){ case SCD4X_NORMAL_MODE: ESP_ERROR_CHECK(scd4x_start_periodic_measurement()); ESP_LOGI("scd4x init","started in normal mode"); break; case SCD4X_LP_MODE: ESP_ERROR_CHECK(scd4x_start_low_power_periodic_measurement()); ESP_LOGI("scd4x init","started in low power mode"); break; } if(conf->sensor->mode & SCD4X_CAPTURE_ENABLED){ TaskHandle_t sensor_fetch_handle; xTaskCreate(fetch_sensor_task, "FETCH_SENSOR", 4096, conf, tskIDLE_PRIORITY, &sensor_fetch_handle); } while(1){ vTaskDelay(1000 / portTICK_PERIOD_MS); } } void fetch_sensor_task(void* pvParameters){ configuration_data_t* mainConf = (configuration_data_t*) pvParameters; scd4x_config_t* conf = mainConf->sensor; scd4x_data_t* measures = conf->measure; while(1){ if(conf->mode == SCD4X_SS_MODE) scd4x_measure_single_shot(); vTaskDelay(conf->delay * 1000 / portTICK_PERIOD_MS); uint16_t dataReady; scd4x_get_data_ready_status(&dataReady); if(!(dataReady & 0x07FF)) continue; int16_t error = scd4x_read_measurement(&measures->co2, &measures->temperature, &measures->humidity); if (error) ESP_LOGE("sensor fetch", "Error executing scd4x_read_measurement(): %i\n", error); update_led_status(mainConf->leds, LED_NUMBER, conf->measure->co2); ESP_LOGI("MAIN", "co2 : %u ppm, temp : %d m°C, hum : %d mRH", conf->measure->co2, conf->measure->temperature, conf->measure->humidity); } } void init_nvs(void){ esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); } void init_avahi(char* hostname){ ESP_LOGI("avahi", "hostname : %s", hostname); ESP_ERROR_CHECK(mdns_init()); ESP_ERROR_CHECK(mdns_hostname_set(hostname)); ESP_ERROR_CHECK(mdns_instance_name_set(hostname)); } void init_http_server(configuration_data_t* main_conf){ // mount http server fat partition const esp_vfs_fat_mount_config_t mount_config = { .max_files = 10, .format_if_mount_failed = false, .allocation_unit_size = CONFIG_WL_SECTOR_SIZE }; ESP_ERROR_CHECK(esp_vfs_fat_rawflash_mount("/http", "http", &mount_config)); // start http server HTTP_serve_config_t serv_config = { .mountpoint = "/http", .getUri = "/*", .postUri = "/*", .apiUri = "/api", }; ESP_ERROR_CHECK(start_server(serv_config, main_conf)); } void init_scd4x(){ sensirion_i2c_hal_init(0,1); scd4x_wake_up(); scd4x_stop_periodic_measurement(); scd4x_reinit(); }