implement handlers and tasks
This commit is contained in:
parent
1b279474c6
commit
d8e42372b1
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@ build/
|
|||||||
sdkconfig
|
sdkconfig
|
||||||
sdkconfig.old
|
sdkconfig.old
|
||||||
main/frontend.h
|
main/frontend.h
|
||||||
|
managed_components/
|
||||||
|
|||||||
21
dependencies.lock
Normal file
21
dependencies.lock
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
dependencies:
|
||||||
|
espressif/cjson:
|
||||||
|
component_hash: e788323270d90738662d66fffa910bfe1fba019bba087f01557e70c40485b469
|
||||||
|
dependencies:
|
||||||
|
- name: idf
|
||||||
|
require: private
|
||||||
|
version: '>=5.0'
|
||||||
|
source:
|
||||||
|
registry_url: https://components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.7.19~2
|
||||||
|
idf:
|
||||||
|
source:
|
||||||
|
type: idf
|
||||||
|
version: 6.2.0
|
||||||
|
direct_dependencies:
|
||||||
|
- espressif/cjson
|
||||||
|
- idf
|
||||||
|
manifest_hash: 626fd43651c3fd7f446de49c6321e4d29d1ea2ce423ef88701f30386e340d0f8
|
||||||
|
target: esp32
|
||||||
|
version: 3.0.0
|
||||||
@ -1,3 +1,3 @@
|
|||||||
idf_component_register(SRCS "main.c"
|
idf_component_register(SRCS "main.c"
|
||||||
PRIV_REQUIRES esp_wifi esp_http_server nvs_flash esp_driver_gpio esp_adc
|
PRIV_REQUIRES esp_wifi esp_http_server nvs_flash esp_driver_gpio esp_adc cjson
|
||||||
INCLUDE_DIRS ".")
|
INCLUDE_DIRS ".")
|
||||||
|
|||||||
17
main/idf_component.yml
Normal file
17
main/idf_component.yml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
## IDF Component Manager Manifest File
|
||||||
|
dependencies:
|
||||||
|
## Required IDF version
|
||||||
|
idf:
|
||||||
|
version: '>=4.1.0'
|
||||||
|
# # Put list of dependencies here
|
||||||
|
# # For components maintained by Espressif:
|
||||||
|
# component: "~1.0.0"
|
||||||
|
# # For 3rd party components:
|
||||||
|
# username/component: ">=1.0.0,<2.0.0"
|
||||||
|
# username2/component2:
|
||||||
|
# version: "~1.0.0"
|
||||||
|
# # For transient dependencies `public` flag can be set.
|
||||||
|
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||||
|
# # All dependencies of `main` are public by default.
|
||||||
|
# public: true
|
||||||
|
espressif/cjson: '*'
|
||||||
410
main/main.c
410
main/main.c
@ -21,6 +21,7 @@
|
|||||||
#include "esp_adc/adc_cali.h"
|
#include "esp_adc/adc_cali.h"
|
||||||
#include "esp_adc/adc_cali_scheme.h"
|
#include "esp_adc/adc_cali_scheme.h"
|
||||||
#include "frontend.h"
|
#include "frontend.h"
|
||||||
|
#include <cJSON.h>
|
||||||
|
|
||||||
// ==================== НАСТРОЙКИ ТОЧКИ ДОСТУПА ====================
|
// ==================== НАСТРОЙКИ ТОЧКИ ДОСТУПА ====================
|
||||||
#define AP_SSID "ESP32_Hotspot" // Имя Wi-Fi сети
|
#define AP_SSID "ESP32_Hotspot" // Имя Wi-Fi сети
|
||||||
@ -28,6 +29,7 @@
|
|||||||
#define AP_MAX_CONN 4 // Максимум клиентов
|
#define AP_MAX_CONN 4 // Максимум клиентов
|
||||||
#define AP_CHANNEL 6 // Wi-Fi канал
|
#define AP_CHANNEL 6 // Wi-Fi канал
|
||||||
|
|
||||||
|
#define PUMP_PIN 2
|
||||||
|
|
||||||
#define ADC_CHAN0 ADC_CHANNEL_4
|
#define ADC_CHAN0 ADC_CHANNEL_4
|
||||||
#define ADC_CHAN1 ADC_CHANNEL_5
|
#define ADC_CHAN1 ADC_CHANNEL_5
|
||||||
@ -37,6 +39,11 @@ static adc_oneshot_unit_handle_t adc_handle;
|
|||||||
static adc_cali_handle_t cali_handle;
|
static adc_cali_handle_t cali_handle;
|
||||||
static bool is_calibrated = false;
|
static bool is_calibrated = false;
|
||||||
|
|
||||||
|
static int g_threshold_low = 0;
|
||||||
|
static int g_threshold_up = 0;
|
||||||
|
|
||||||
|
static int g_current_pressure = 0;
|
||||||
|
|
||||||
|
|
||||||
// ==================== ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ====================
|
// ==================== ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ====================
|
||||||
static const char *TAG = "ESP32_AP_SERVER";
|
static const char *TAG = "ESP32_AP_SERVER";
|
||||||
@ -80,6 +87,17 @@ esp_err_t adc_init(void)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pump_init(void) {
|
||||||
|
gpio_config_t io_conf = {
|
||||||
|
.pin_bit_mask = (1ULL << PUMP_PIN),
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
|
.pull_down_en = 1,
|
||||||
|
.pull_up_en = 0,
|
||||||
|
};
|
||||||
|
gpio_config(&io_conf);
|
||||||
|
}
|
||||||
|
|
||||||
int adc_read_raw(uint8_t channel)
|
int adc_read_raw(uint8_t channel)
|
||||||
{
|
{
|
||||||
int raw_value = 0;
|
int raw_value = 0;
|
||||||
@ -102,8 +120,7 @@ int adc_read_raw(uint8_t channel)
|
|||||||
return raw_value;
|
return raw_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int adc_read_voltage(uint8_t channel)
|
int adc_read_voltage(uint8_t channel) {
|
||||||
{
|
|
||||||
int raw_value = adc_read_raw(channel);
|
int raw_value = adc_read_raw(channel);
|
||||||
if (raw_value < 0) return -1;
|
if (raw_value < 0) return -1;
|
||||||
|
|
||||||
@ -122,11 +139,7 @@ int adc_read_voltage(uint8_t channel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ==================== ОБРАБОТЧИКИ HTTP ЗАПРОСОВ ====================
|
static esp_err_t root_get_handler(httpd_req_t *req) {
|
||||||
|
|
||||||
// Обработчик главной страницы
|
|
||||||
static esp_err_t root_get_handler(httpd_req_t *req)
|
|
||||||
{
|
|
||||||
const char* response =
|
const char* response =
|
||||||
"<!DOCTYPE html>"
|
"<!DOCTYPE html>"
|
||||||
"<html>"
|
"<html>"
|
||||||
@ -261,47 +274,11 @@ static esp_err_t root_get_handler(httpd_req_t *req)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Управление GPIO
|
static esp_err_t current_pressure_handler(httpd_req_t *req) {
|
||||||
static esp_err_t gpio_handler(httpd_req_t *req)
|
int sensor_value = g_current_pressure;
|
||||||
{
|
|
||||||
char param[10];
|
|
||||||
char state_str[10];
|
|
||||||
|
|
||||||
// Получаем параметр state из URL
|
|
||||||
if (httpd_req_get_url_query_str(req, param, sizeof(param)) == ESP_OK) {
|
|
||||||
if (httpd_query_key_value(param, "state", state_str, sizeof(state_str)) == ESP_OK) {
|
|
||||||
int state = atoi(state_str);
|
|
||||||
|
|
||||||
// Настройка GPIO2 (встроенный LED на многих ESP32)
|
|
||||||
gpio_config_t io_conf = {
|
|
||||||
.pin_bit_mask = (1ULL << 2),
|
|
||||||
.mode = GPIO_MODE_OUTPUT,
|
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
|
||||||
.pull_down_en = 0,
|
|
||||||
.pull_up_en = 0,
|
|
||||||
};
|
|
||||||
gpio_config(&io_conf);
|
|
||||||
gpio_set_level(2, state);
|
|
||||||
|
|
||||||
char response[100];
|
|
||||||
snprintf(response, sizeof(response), "{\"status\":\"%s\"}", state ? "on" : "off");
|
|
||||||
httpd_resp_set_type(req, "application/json");
|
|
||||||
httpd_resp_send(req, response, strlen(response));
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Missing state parameter");
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Имитация датчика
|
|
||||||
static esp_err_t sensor_handler(httpd_req_t *req) {
|
|
||||||
int volt0 = adc_read_voltage(0);
|
|
||||||
int sensor_value = volt0;
|
|
||||||
char response[100];
|
char response[100];
|
||||||
snprintf(response, sizeof(response),
|
snprintf(response, sizeof(response),
|
||||||
"{\"value\":%d,\"message\":\"Случайное значение датчика\"}",
|
"{\"value\":%d}",
|
||||||
sensor_value);
|
sensor_value);
|
||||||
|
|
||||||
httpd_resp_set_type(req, "application/json");
|
httpd_resp_set_type(req, "application/json");
|
||||||
@ -309,23 +286,189 @@ static esp_err_t sensor_handler(httpd_req_t *req) {
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Статистика системы
|
static esp_err_t save_thresholds_handler(httpd_req_t *req) {
|
||||||
static esp_err_t stats_handler(httpd_req_t *req)
|
char response[100];
|
||||||
{
|
char *content = NULL;
|
||||||
char response[200];
|
size_t content_len = req->content_len;
|
||||||
snprintf(response, sizeof(response),
|
|
||||||
"{\"free_heap\":%lu,\"uptime\":%d}",
|
// Проверка длины содержимого
|
||||||
esp_get_free_heap_size(),
|
if (content_len > 512) { // Ограничение размера для безопасности
|
||||||
(int)(xTaskGetTickCount() * portTICK_PERIOD_MS / 1000));
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Content too large");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Выделение памяти под содержимое запроса
|
||||||
|
content = malloc(content_len + 1);
|
||||||
|
if (!content) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Memory allocation failed");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Чтение тела запроса
|
||||||
|
int ret = httpd_req_recv(req, content, content_len);
|
||||||
|
if (ret <= 0) {
|
||||||
|
free(content);
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Failed to receive data");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
content[content_len] = '\0'; // Null-terminator
|
||||||
|
|
||||||
|
// Парсинг JSON
|
||||||
|
cJSON *json = cJSON_Parse(content);
|
||||||
|
free(content);
|
||||||
|
|
||||||
|
if (!json) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Извлечение параметров low и up
|
||||||
|
cJSON *low_item = cJSON_GetObjectItem(json, "low");
|
||||||
|
cJSON *up_item = cJSON_GetObjectItem(json, "up");
|
||||||
|
|
||||||
|
int low_value = 0;
|
||||||
|
int up_value = 0;
|
||||||
|
bool valid = true;
|
||||||
|
|
||||||
|
if (cJSON_IsNumber(low_item)) {
|
||||||
|
low_value = low_item->valueint;
|
||||||
|
} else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cJSON_IsNumber(up_item)) {
|
||||||
|
up_value = up_item->valueint;
|
||||||
|
} else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Missing or invalid 'low' or 'up' parameters");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка значений (опционально)
|
||||||
|
if (low_value >= up_value) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Low value must be less than up value");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvs_handle_t my_handle;
|
||||||
|
esp_err_t err;
|
||||||
|
|
||||||
|
// 1. Открываем раздел "nvs" и пространство имен "storage" на запись/чтение
|
||||||
|
err = nvs_open("storage", NVS_READWRITE, &my_handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE("TAG", "Error opening NVS");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nvs_set_i32(my_handle, "treshhold_low", low_value);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
|
err = nvs_set_i32(my_handle, "treshhold_up", up_value);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
|
// 4. Сохраняем изменения во flash
|
||||||
|
err = nvs_commit(my_handle);
|
||||||
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
|
// 5. Закрываем хендл
|
||||||
|
nvs_close(my_handle);
|
||||||
|
|
||||||
|
// Формирование успешного ответа
|
||||||
|
snprintf(response, sizeof(response), "{\"success\":true,\"low\":%d,\"up\":%d}", low_value, up_value);
|
||||||
|
|
||||||
httpd_resp_set_type(req, "application/json");
|
httpd_resp_set_type(req, "application/json");
|
||||||
httpd_resp_send(req, response, strlen(response));
|
httpd_resp_send(req, response, strlen(response));
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== ИНИЦИАЛИЗАЦИЯ ТОЧКИ ДОСТУПА ====================
|
static esp_err_t set_thresholds_handler(httpd_req_t *req) {
|
||||||
void wifi_init_softap(void)
|
char response[100];
|
||||||
{
|
char *content = NULL;
|
||||||
|
size_t content_len = req->content_len;
|
||||||
|
|
||||||
|
// Проверка длины содержимого
|
||||||
|
if (content_len > 512) { // Ограничение размера для безопасности
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Content too large");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Выделение памяти под содержимое запроса
|
||||||
|
content = malloc(content_len + 1);
|
||||||
|
if (!content) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Memory allocation failed");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Чтение тела запроса
|
||||||
|
int ret = httpd_req_recv(req, content, content_len);
|
||||||
|
if (ret <= 0) {
|
||||||
|
free(content);
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Failed to receive data");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
content[content_len] = '\0'; // Null-terminator
|
||||||
|
|
||||||
|
// Парсинг JSON
|
||||||
|
cJSON *json = cJSON_Parse(content);
|
||||||
|
free(content);
|
||||||
|
|
||||||
|
if (!json) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Извлечение параметров low и up
|
||||||
|
cJSON *low_item = cJSON_GetObjectItem(json, "low");
|
||||||
|
cJSON *up_item = cJSON_GetObjectItem(json, "up");
|
||||||
|
|
||||||
|
int low_value = 0;
|
||||||
|
int up_value = 0;
|
||||||
|
bool valid = true;
|
||||||
|
|
||||||
|
if (cJSON_IsNumber(low_item)) {
|
||||||
|
low_value = low_item->valueint;
|
||||||
|
} else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cJSON_IsNumber(up_item)) {
|
||||||
|
up_value = up_item->valueint;
|
||||||
|
} else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON_Delete(json);
|
||||||
|
|
||||||
|
if (!valid) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Missing or invalid 'low' or 'up' parameters");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка значений (опционально)
|
||||||
|
if (low_value >= up_value) {
|
||||||
|
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Low value must be less than up value");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_threshold_low = low_value;
|
||||||
|
g_threshold_up = up_value;
|
||||||
|
|
||||||
|
// Формирование успешного ответа
|
||||||
|
snprintf(response, sizeof(response), "{\"success\":true,\"low\":%d,\"up\":%d}", low_value, up_value);
|
||||||
|
|
||||||
|
httpd_resp_set_type(req, "application/json");
|
||||||
|
httpd_resp_send(req, response, strlen(response));
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wifi_init_softap(void) {
|
||||||
// Инициализация сетевого интерфейса
|
// Инициализация сетевого интерфейса
|
||||||
ESP_ERROR_CHECK(esp_netif_init());
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||||
@ -347,7 +490,6 @@ void wifi_init_softap(void)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Если пароль не задан - открытая сеть
|
|
||||||
if (strlen(AP_PASS) == 0) {
|
if (strlen(AP_PASS) == 0) {
|
||||||
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
|
||||||
}
|
}
|
||||||
@ -364,56 +506,39 @@ void wifi_init_softap(void)
|
|||||||
ESP_LOGI(TAG, "=========================================");
|
ESP_LOGI(TAG, "=========================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
// void setup_adc() {
|
static void disablePump(void) {
|
||||||
// // Настройка разрешения (9-12 бит)
|
gpio_set_level(PUMP_PIN, false);
|
||||||
// adc1_config_width(ADC_WIDTH_BIT_12);
|
}
|
||||||
//
|
|
||||||
// // Настройка аттенюации (диапазон входного напряжения)
|
|
||||||
// adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// int read_mid_pressure(void) {
|
|
||||||
// int N = 5;
|
|
||||||
// int pause = 20;
|
|
||||||
//
|
|
||||||
// int sum = 0;
|
|
||||||
// for (int i = 0; i < N; i++) {
|
|
||||||
// sum += adc1_get_raw(ADC1_CHANNEL_0);
|
|
||||||
// vTaskDelay(pdMS_TO_TICKS(pause));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return sum /= N;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// static void pressure_control_task(void *pvParameters) {
|
static void enablePump(void) {
|
||||||
// gpio_config_t io_conf = {
|
gpio_set_level(PUMP_PIN, true);
|
||||||
// .pin_bit_mask = (1ULL << 2),
|
}
|
||||||
// .mode = GPIO_MODE_OUTPUT,
|
|
||||||
// .intr_type = GPIO_INTR_DISABLE,
|
|
||||||
// .pull_down_en = 1,
|
|
||||||
// .pull_up_en = 0,
|
|
||||||
// };
|
|
||||||
// gpio_config(&io_conf);
|
|
||||||
//
|
|
||||||
// while(1) {
|
|
||||||
// int low_treshhold_pressure = atomic_load(&low_treshhold);
|
|
||||||
// int up_treshhold_pressure = atomic_load(&up_treshhold);
|
|
||||||
//
|
|
||||||
// int pressure = read_mid_pressure();
|
|
||||||
//
|
|
||||||
// if (pressure < low_treshhold_pressure) {
|
|
||||||
// gpio_set_level(2, 1);
|
|
||||||
// } else if (pressure >= up_treshhold_pressure) {
|
|
||||||
// gpio_set_level(2, 0);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// vTaskDelay(pdMS_TO_TICKS(400));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ==================== ЗАДАЧА HTTP СЕРВЕРА ====================
|
static void vPumpControllTask(void *pvParameters) {
|
||||||
static void http_server_task(void *pvParameters)
|
while (1) {
|
||||||
{
|
int current_pressure = g_current_pressure;
|
||||||
|
int low_treshhold = g_threshold_low;
|
||||||
|
int up_treshhold = g_threshold_up;
|
||||||
|
|
||||||
|
if (current_pressure < low_treshhold) {
|
||||||
|
enablePump();
|
||||||
|
} else if (current_pressure >= up_treshhold) {
|
||||||
|
disablePump();
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vReadSensorTask(void *pvParameters) {
|
||||||
|
while (1) {
|
||||||
|
g_current_pressure = adc_read_voltage(0);
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vHttpServerTask(void *pvParameters) {
|
||||||
httpd_handle_t server = NULL;
|
httpd_handle_t server = NULL;
|
||||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||||
config.max_uri_handlers = 10;
|
config.max_uri_handlers = 10;
|
||||||
@ -432,35 +557,29 @@ static void http_server_task(void *pvParameters)
|
|||||||
};
|
};
|
||||||
httpd_register_uri_handler(server, &root);
|
httpd_register_uri_handler(server, &root);
|
||||||
|
|
||||||
httpd_uri_t gpio = {
|
httpd_uri_t pressure = {
|
||||||
.uri = "/gpio",
|
.uri = "/pressure",
|
||||||
.method = HTTP_GET,
|
.method = HTTP_GET,
|
||||||
.handler = gpio_handler,
|
.handler = current_pressure_handler,
|
||||||
.user_ctx = NULL
|
.user_ctx = NULL
|
||||||
};
|
};
|
||||||
httpd_register_uri_handler(server, &gpio);
|
httpd_register_uri_handler(server, &pressure);
|
||||||
|
|
||||||
httpd_uri_t sensor = {
|
httpd_uri_t set_thresholds = {
|
||||||
.uri = "/sensor",
|
.uri = "/thresholds",
|
||||||
.method = HTTP_GET,
|
.method = HTTP_POST,
|
||||||
.handler = sensor_handler,
|
.handler = set_thresholds_handler,
|
||||||
.user_ctx = NULL
|
.user_ctx = NULL
|
||||||
};
|
};
|
||||||
httpd_register_uri_handler(server, &sensor);
|
httpd_register_uri_handler(server, &set_thresholds);
|
||||||
|
|
||||||
httpd_uri_t stats = {
|
httpd_uri_t save_thresholds = {
|
||||||
.uri = "/stats",
|
.uri = "/persist_thresholds",
|
||||||
.method = HTTP_GET,
|
.method = HTTP_POST,
|
||||||
.handler = stats_handler,
|
.handler = save_thresholds_handler,
|
||||||
.user_ctx = NULL
|
.user_ctx = NULL
|
||||||
};
|
};
|
||||||
httpd_register_uri_handler(server, &stats);
|
httpd_register_uri_handler(server, &save_thresholds);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "📝 Зарегистрированы обработчики:");
|
|
||||||
ESP_LOGI(TAG, " - GET / (главная страница)");
|
|
||||||
ESP_LOGI(TAG, " - GET /gpio (управление LED)");
|
|
||||||
ESP_LOGI(TAG, " - GET /sensor (чтение датчика)");
|
|
||||||
ESP_LOGI(TAG, " - GET /stats (статистика)");
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "❌ Ошибка запуска HTTP сервера");
|
ESP_LOGE(TAG, "❌ Ошибка запуска HTTP сервера");
|
||||||
}
|
}
|
||||||
@ -470,10 +589,7 @@ static void http_server_task(void *pvParameters)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== ГЛАВНАЯ ФУНКЦИЯ ====================
|
void app_main(void) {
|
||||||
void app_main(void)
|
|
||||||
{
|
|
||||||
// Инициализация NVS
|
|
||||||
esp_err_t ret = nvs_flash_init();
|
esp_err_t ret = nvs_flash_init();
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
@ -481,29 +597,50 @@ void app_main(void)
|
|||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(ret);
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
nvs_handle_t my_handle;
|
||||||
|
esp_err_t err;
|
||||||
|
// 1. Открываем раздел "nvs" и пространство имен "storage" на запись/чтение
|
||||||
|
err = nvs_open("storage", NVS_READWRITE, &my_handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE("TAG", "Error opening NVS");
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nvs_get_i32(my_handle, "treshhold_low", &g_threshold_low);
|
||||||
|
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||||
|
g_threshold_low = 0;
|
||||||
|
} else {
|
||||||
|
ESP_ERROR_CHECK(err); // Обработка других ошибок
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nvs_get_i32(my_handle, "treshhold_low", &g_threshold_up);
|
||||||
|
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||||
|
g_threshold_up = 1;
|
||||||
|
} else {
|
||||||
|
ESP_ERROR_CHECK(err); // Обработка других ошибок
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
adc_init();
|
adc_init();
|
||||||
|
pump_init();
|
||||||
|
|
||||||
ESP_LOGI(TAG, "=========================================");
|
ESP_LOGI(TAG, "=========================================");
|
||||||
ESP_LOGI(TAG, "ESP32 Точка Доступа + HTTP Сервер");
|
ESP_LOGI(TAG, "ESP32 Точка Доступа + HTTP Сервер");
|
||||||
ESP_LOGI(TAG, "=========================================");
|
ESP_LOGI(TAG, "=========================================");
|
||||||
|
|
||||||
|
|
||||||
// Инициализация точки доступа
|
|
||||||
wifi_init_softap();
|
wifi_init_softap();
|
||||||
|
|
||||||
// Небольшая задержка для стабилизации
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
|
||||||
// Создание задачи HTTP сервера
|
xTaskCreate(vHttpServerTask, "http_server", 8192, NULL, 5, NULL);
|
||||||
xTaskCreate(http_server_task, "http_server", 8192, NULL, 5, NULL);
|
xTaskCreate(vPumpControllTask, "pump_controll", 8192, NULL, 5, NULL);
|
||||||
|
xTaskCreate(vReadSensorTask, "read_sensor", 8192, NULL, 5, NULL);
|
||||||
|
|
||||||
// Демонстрационная задача для имитации датчика
|
|
||||||
ESP_LOGI(TAG, "✅ Система готова к работе");
|
ESP_LOGI(TAG, "✅ Система готова к работе");
|
||||||
ESP_LOGI(TAG, "📱 Подключитесь к Wi-Fi: %s", AP_SSID);
|
ESP_LOGI(TAG, "📱 Подключитесь к Wi-Fi: %s", AP_SSID);
|
||||||
ESP_LOGI(TAG, "🌐 Откройте браузер: http://192.168.4.1");
|
ESP_LOGI(TAG, "🌐 Откройте браузер: http://192.168.4.1");
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// Вывод информации о подключенных клиентах каждые 10 секунд
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(10000));
|
vTaskDelay(pdMS_TO_TICKS(10000));
|
||||||
|
|
||||||
wifi_sta_list_t sta_list;
|
wifi_sta_list_t sta_list;
|
||||||
@ -511,7 +648,6 @@ void app_main(void)
|
|||||||
esp_wifi_ap_get_sta_list(&sta_list);
|
esp_wifi_ap_get_sta_list(&sta_list);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "📊 Подключено клиентов: %d", sta_list.num);
|
ESP_LOGI(TAG, "📊 Подключено клиентов: %d", sta_list.num);
|
||||||
ESP_LOGI(TAG, "💾 Свободно памяти: %d байт", esp_get_free_heap_size());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
5
partitions.csv
Normal file
5
partitions.csv
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# ESP-IDF Partition Table
|
||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
phy_init, data, phy, 0xf000, 0x1000,
|
||||||
|
factory, app, factory, 0x10000, 1M,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user