#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_log.h"
static const char *TAG = "MAIN_APP";
#define BUTTON_GPIO GPIO_NUM_13
static QueueHandle_t my_queue = NULL;
// Обробник переривання (ISR) для кнопки
static void IRAM_ATTR button_isr_handler(void *arg) {
static int button_press_count = 0;
button_press_count++;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// Безпечна відправка даних у чергу з контексту переривання (ISR)
xQueueSendFromISR(my_queue, &button_press_count, &xHigherPriorityTaskWoken);
// Якщо задача-отримувач має вищий пріоритет, виконуємо перемикання контексту
if (xHigherPriorityTaskWoken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
// Задача, яка приймає дані з черги
void receiver_task(void *pvParameters) {
int received_value = 0;
while (1) {
// Очікуємо на дані з черги нескінченно
if (xQueueReceive(my_queue, &received_value, portMAX_DELAY) == pdPASS) {
ESP_LOGW(TAG, "---> Кнопку натиснуто! Лічильник: %d", received_value);
}
}
}
void app_main(void) {
ESP_LOGI(TAG, "Запуск програми...");
// 1. Створюємо чергу для повідомлень про натискання кнопки
my_queue = xQueueCreate(10, sizeof(int));
if (my_queue == NULL) {
ESP_LOGE(TAG, "Недостатньо пам'яті для створення черги!");
return;
}
// 2. Конфігурація GPIO пина D13 під кнопку
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << BUTTON_GPIO),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE, // Підтяжка до VCC, оскільки кнопка замыкає на GND
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_NEGEDGE // Спрацьовування при натисканні (High -> Low)
};
gpio_config(&io_conf);
// 3. Встановлення драйвера та обробника переривань
gpio_install_isr_service(0);
gpio_isr_handler_add(BUTTON_GPIO, button_isr_handler, NULL);
// 4. Створюємо задачу-отримувач на ядрі 1
xTaskCreatePinnedToCore(
receiver_task,
"receiver_task",
2048,
NULL,
10,
NULL,
1
);
ESP_LOGI(TAG, "Систему налаштовано. Натисніть кнопку на D13.");
}