// (using task allocate & free) dynamically when button is pressed
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "sdkconfig.h"
#include <inttypes.h>
#define LED 32
#define LED2 12
#define Push_Button 27
TaskHandle_t led_task_handle = NULL; // Handle for the LED task (pin 32)
TaskHandle_t manage_task_handle = NULL; // Handle for the task managing the button and LED toggling
static const char* TAG = "APP";
// Task to blink LED at pin 32
void blink_led_task(void *pvParameters)
{
while (1) {
gpio_set_level(LED, 1); // Turn on LED
vTaskDelay(100 / portTICK_PERIOD_MS); // Delay 100ms
gpio_set_level(LED, 0); // Turn off LED
vTaskDelay(100 / portTICK_PERIOD_MS); // Delay 100ms
}
}
// ISR handler for button press
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
BaseType_t higher_priority_task_woken = pdFALSE;
// Notify the main task (manage_task_handle) from the ISR
vTaskNotifyGiveFromISR(manage_task_handle, &higher_priority_task_woken);
if (higher_priority_task_woken) {
portYIELD_FROM_ISR();
}
}
// Task to handle button press and manage LED task creation and deletion
void manage_led_task(void *pvParameters)
{
while (1) {
// Wait for notification from ISR (button press)
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// Log the notification reception
ESP_LOGI(TAG, "Button pressed!");
// Debounce: simple delay to avoid multiple triggers
vTaskDelay(200 / portTICK_PERIOD_MS);
// Check if the LED task is running
if (led_task_handle == NULL) {
// If no task, create a new one dynamically
// ESP_LOGI(TAG, "Creating LED task (pin 32).");
printf("Creating LED task (pin 32).\n");
xTaskCreate(blink_led_task, "LED Task", 2048, NULL, 1, &led_task_handle);
} else {
// If the task exists, delete it to free memory
// ESP_LOGI(TAG, "Deleting LED task (pin 32).");
printf("Deleting LED task (pin 32).\n");
vTaskDelete(led_task_handle);
led_task_handle = NULL; // Set handle to NULL after deletion
}
}
}
// Task to blink LED2 at pin 12 (blinking every 300ms)
void blink_led2_task(void *pvParameters)
{
while (1) {
gpio_set_level(LED2, 1); // Turn on LED2
vTaskDelay(300 / portTICK_PERIOD_MS); // Delay 300ms
gpio_set_level(LED2, 0); // Turn off LED2
vTaskDelay(300 / portTICK_PERIOD_MS); // Delay 300ms
}
}
void app_main(void)
{
// Initialize LED2 pin (pin 12)
gpio_reset_pin(LED2);
gpio_set_direction(LED2, GPIO_MODE_OUTPUT);
// Initialize LED pin (pin 32)
gpio_reset_pin(LED);
gpio_set_direction(LED, GPIO_MODE_OUTPUT);
// Initialize Push_Button pin (pin 27)
gpio_reset_pin(Push_Button);
gpio_set_direction(Push_Button, GPIO_MODE_INPUT);
gpio_pullup_en(Push_Button); // Enable pull-up resistor
// Configure interrupt for the button (rising edge)
gpio_set_intr_type(Push_Button, GPIO_INTR_POSEDGE);
// Install the ISR service and attach the handler
gpio_install_isr_service(0);
gpio_isr_handler_add(Push_Button, gpio_isr_handler, NULL);
// Get a handle to the current task (used for notification)
manage_task_handle = xTaskGetCurrentTaskHandle();
// Create the task to manage the button press and LED task
xTaskCreate(manage_led_task, "Manage LED Task", 2048, NULL, 1, &manage_task_handle);
// Create the task to blink LED2 on pin 12 (blinks every 300ms)
xTaskCreate(blink_led2_task, "LED2 Task", 2048, NULL, 1, NULL);
ESP_LOGI(TAG, "Setup complete.");
}
// // (using Task Suspend) secondary task blink when button is pressed
// #include <stdio.h>
// #include "freertos/FreeRTOS.h"
// #include "freertos/task.h"
// #include "freertos/semphr.h"
// #include "driver/gpio.h"
// #include "esp_log.h"
// #include "sdkconfig.h"
// #include <inttypes.h>
// #define LED 32
// #define LED2 12
// #define Push_Button 27
// TaskHandle_t led_task_handle = NULL; // Handle for the LED task (pin 32)
// TaskHandle_t manage_task_handle = NULL; // Handle for the task managing the button and LED toggling
// static const char* TAG = "APP";
// // Task to blink LED at pin 32
// void blink_led_task(void *pvParameters)
// {
// while (1) {
// gpio_set_level(LED, 1); // Turn on LED
// vTaskDelay(100 / portTICK_PERIOD_MS); // Delay 100ms
// gpio_set_level(LED, 0); // Turn off LED
// vTaskDelay(100 / portTICK_PERIOD_MS); // Delay 100ms
// }
// }
// // ISR handler for button press
// static void IRAM_ATTR gpio_isr_handler(void* arg)
// {
// BaseType_t higher_priority_task_woken = pdFALSE;
// // Notify the main task (manage_task_handle) from the ISR
// vTaskNotifyGiveFromISR(manage_task_handle, &higher_priority_task_woken);
// if (higher_priority_task_woken) {
// portYIELD_FROM_ISR();
// }
// }
// // Task to handle button press and manage LED blinking task
// void manage_led_task(void *pvParameters)
// {
// while (1) {
// // Wait for notification from ISR (button press)
// ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
// // Log the notification reception
// ESP_LOGI(TAG, "Button pressed!");
// // Debounce: simple delay to avoid multiple triggers
// vTaskDelay(200 / portTICK_PERIOD_MS);
// // Toggle the LED task based on its current state (running or suspended)
// if (eTaskGetState(led_task_handle) == eSuspended) {
// // If the task is suspended, resume it
// vTaskResume(led_task_handle);
// ESP_LOGI(TAG, "LED task (pin 32) resumed.");
// } else {
// // If the task is running, suspend it
// vTaskSuspend(led_task_handle);
// ESP_LOGI(TAG, "LED task (pin 32) suspended.");
// }
// }
// }
// // Task to blink LED2 at pin 12 (blinking every 300ms)
// void blink_led2_task(void *pvParameters)
// {
// while (1) {
// gpio_set_level(LED2, 1); // Turn on LED2
// vTaskDelay(300 / portTICK_PERIOD_MS); // Delay 300ms
// gpio_set_level(LED2, 0); // Turn off LED2
// vTaskDelay(300 / portTICK_PERIOD_MS); // Delay 300ms
// }
// }
// void app_main(void)
// {
// // Initialize LED2 pin (pin 12)
// gpio_reset_pin(LED2);
// gpio_set_direction(LED2, GPIO_MODE_OUTPUT);
// // Initialize LED pin (pin 32)
// gpio_reset_pin(LED);
// gpio_set_direction(LED, GPIO_MODE_OUTPUT);
// // Initialize Push_Button pin (pin 27)
// gpio_reset_pin(Push_Button);
// gpio_set_direction(Push_Button, GPIO_MODE_INPUT);
// gpio_pullup_en(Push_Button); // Enable pull-up resistor
// // Configure interrupt for the button (rising edge)
// gpio_set_intr_type(Push_Button, GPIO_INTR_POSEDGE);
// // Install the ISR service and attach the handler
// gpio_install_isr_service(0);
// gpio_isr_handler_add(Push_Button, gpio_isr_handler, NULL);
// // Get a handle to the current task (used for notification)
// manage_task_handle = xTaskGetCurrentTaskHandle();
// // Create the task to manage the button press and LED task
// xTaskCreate(manage_led_task, "Manage LED Task", 2048, NULL, 1, &manage_task_handle);
// // Create the task to blink LED2 on pin 12 (blinks every 300ms)
// xTaskCreate(blink_led2_task, "LED2 Task", 2048, NULL, 1, NULL);
// // Create the task to blink LED at pin 32 (initially suspended)
// xTaskCreate(blink_led_task, "LED Task", 2048, NULL, 1, &led_task_handle);
// vTaskSuspend(led_task_handle); // Suspend the LED task initially
// ESP_LOGI(TAG, "Setup complete.");
// }
// stack overflowed as soon as I pressed the button
// #include <stdio.h>
// #include "freertos/FreeRTOS.h"
// #include "freertos/task.h"
// #include "driver/gpio.h"
// #include "esp_log.h"
// #include "sdkconfig.h"
// #include <inttypes.h>
// #define LED 32
// #define LED2 12
// #define Push_Button 27
// bool task_running = false; // Tracks if the LED (pin 32) task is running
// TaskHandle_t led_task_handle = NULL; // Task handle for the dynamically spawned task
// // Task to blink LED at pin 32 (blinking every 100ms)
// void blink_led_task(void *pvParameters)
// {
// while (1) {
// gpio_set_level(LED, 1); // Turn on LED
// vTaskDelay(100 / portTICK_PERIOD_MS); // Delay 100ms
// gpio_set_level(LED, 0); // Turn off LED
// vTaskDelay(100 / portTICK_PERIOD_MS); // Delay 100ms
// }
// }
// // ISR handler for the button press
// static void IRAM_ATTR gpio_isr_handler(void* arg)
// {
// if (task_running) {
// // Button pressed again, delete the task to save memory
// if (led_task_handle != NULL) {
// vTaskDelete(led_task_handle); // Delete the task
// led_task_handle = NULL; // Clear the task handle
// }
// task_running = false; // Mark task as not running
// printf("LED task (pin 32) stopped.\n");
// } else {
// // Button pressed, spawn the task to blink LED at pin 32
// xTaskCreate(blink_led_task, "LED Task", 2048, NULL, 1, &led_task_handle);
// task_running = true; // Mark task as running
// printf("LED task (pin 32) started.\n");
// }
// }
// // Task to blink LED2 at pin 12 (blinking every 300ms)
// void blink_led2_task(void *pvParameters)
// {
// while (1) {
// gpio_set_level(LED2, 1); // Turn on LED2
// vTaskDelay(300 / portTICK_PERIOD_MS); // Delay 300ms
// gpio_set_level(LED2, 0); // Turn off LED2
// vTaskDelay(300 / portTICK_PERIOD_MS); // Delay 300ms
// }
// }
// void app_main(void)
// {
// // Initialize LED2 pin
// gpio_reset_pin(LED2);
// gpio_set_direction(LED2, GPIO_MODE_OUTPUT);
// // Initialize LED pin (pin 32)
// gpio_reset_pin(LED);
// gpio_set_direction(LED, GPIO_MODE_OUTPUT);
// // Initialize Push_Button pin (pin 27)
// gpio_reset_pin(Push_Button);
// gpio_set_direction(Push_Button, GPIO_MODE_INPUT);
// gpio_pullup_en(Push_Button); // Enable pull-up resistor
// // Configure interrupt for the button (rising edge)
// gpio_set_intr_type(Push_Button, GPIO_INTR_POSEDGE);
// // Install the ISR service and attach the handler
// gpio_install_isr_service(0);
// gpio_isr_handler_add(Push_Button, gpio_isr_handler, NULL);
// // Create the task to blink LED2 on pin 12
// xTaskCreate(blink_led2_task, "LED2 Task", 2048, NULL, 1, NULL);
// }
// a bit of multitasking
// #include <stdio.h>
// #include "freertos/FreeRTOS.h"
// #include "freertos/task.h"
// #include "driver/gpio.h"
// #include "esp_log.h"
// #include "sdkconfig.h"
// #include <inttypes.h>
// #define LED 32
// #define LED2 12
// #define Push_Button 27
// bool gpio_value = false; // This tracks the state of the LED (true = ON, false = OFF)
// // Task 1: Will print "task 1 executing each 100ms" every 100ms
// void task1(void *pvParameters)
// {
// while (1) {
// printf("task 1 executing each 100ms\n");
// vTaskDelay(100 / portTICK_PERIOD_MS); // Delay 100ms
// }
// }
// // Task 2: Will print "task 2 executing each 300ms" every 300ms
// void task2(void *pvParameters)
// {
// while (1) {
// printf("task 2 executing each 300ms\n");
// vTaskDelay(300 / portTICK_PERIOD_MS); // Delay 300ms
// }
// }
// static void IRAM_ATTR gpio_isr_handler(void* arg)
// {
// /* Disable the Interrupt */
// gpio_intr_disable(Push_Button); // Disable the interrupt on the push button
// gpio_isr_handler_remove(Push_Button); // Remove the interrupt service routine on the push button
// /* Button is pressed. Toggle the LED */
// gpio_value = !gpio_value; // Toggle the LED state
// gpio_set_level(LED, gpio_value); // Update the LED based on the new state
// /* Re-enable the Interrupt */
// gpio_isr_handler_add(Push_Button, gpio_isr_handler, NULL); // Re-enable the interrupt service routine on the push button
// gpio_intr_enable(Push_Button); // Re-enable the interrupt on the push button
// }
// void app_main(void)
// {
// /* Reset the pins */
// gpio_reset_pin(LED); // Reset the LED pin
// gpio_reset_pin(Push_Button); // Reset the PushButton pin
// /* Set the GPIOs to Output and Input modes */
// gpio_set_direction(LED, GPIO_MODE_OUTPUT); // Set the GPIO mode of the LED as output
// gpio_set_direction(Push_Button, GPIO_MODE_INPUT); // Set the GPIO mode of the push button as input
// /* Enable pull-up for Input pin */
// gpio_pullup_en(Push_Button); // Enable pull-up resistor on push button pin
// gpio_pulldown_dis(Push_Button); // Disable pull-down resistor
// /* Configure rising edge detection interrupt for Input pin */
// gpio_set_intr_type(Push_Button, GPIO_INTR_POSEDGE); // Set the interrupt to trigger on rising edge
// /* Install and attach ISR to the GPIO interrupt */
// gpio_install_isr_service(0); // Install ISR service
// gpio_isr_handler_add(Push_Button, gpio_isr_handler, NULL); // Attach ISR handler to the push button pin
// /* Create two new FreeRTOS tasks */
// xTaskCreate(task1, "Task 1", 2048, NULL, 1, NULL); // Create Task 1 with 100ms execution
// xTaskCreate(task2, "Task 2", 2048, NULL, 1, NULL); // Create Task 2 with 300ms execution
// /* Main loop for the LED control */
// while (1)
// {
// if (gpio_value)
// {
// printf("ON \n");
// }
// else
// {
// printf("OFF \n");
// }
// vTaskDelay(100 / portTICK_PERIOD_MS); // Delay to avoid too frequent logging
// }
// }
// old code of single interrupt button, led
// #include <stdio.h>
// #include "freertos/FreeRTOS.h"
// #include "freertos/task.h"
// #include "driver/gpio.h"
// #include "esp_log.h"
// #include "sdkconfig.h"
// #include <inttypes.h>
// #define LED 32
// #define Push_Button 27
// bool gpio_value = false; // This tracks the state of the LED (true = ON, false = OFF)
// static void IRAM_ATTR gpio_isr_handler(void* arg)
// {
// /*
// GOOD to DO - Implement the debouncing algorithm
// to eliminate the Spurious interrupt trigger. (already done)
// */
// /* Disable the Interrupt */
// gpio_intr_disable(Push_Button); // Disable the interrupt on the push button
// gpio_isr_handler_remove(Push_Button); // Remove the interrupt service routine on the push button
// /* Button is pressed. Toggle the LED */
// gpio_value = !gpio_value; // Toggle the LED state
// gpio_set_level(LED, gpio_value); // Update the LED based on the new state
// /* Re-enable the Interrupt */
// gpio_isr_handler_add(Push_Button, gpio_isr_handler, NULL); // Re-enable the interrupt service routine on the push button
// gpio_intr_enable(Push_Button); // Re-enable the interrupt on the push button
// }
// void app_main(void)
// {
// /* Reset the pins */
// gpio_reset_pin(LED); // Reset the LED pin
// gpio_reset_pin(Push_Button); // Reset the PushButton pin
// /* Set the GPIOs to Output and Input modes */
// gpio_set_direction(LED, GPIO_MODE_OUTPUT); // Set the GPIO mode of the LED as output
// gpio_set_direction(Push_Button, GPIO_MODE_INPUT); // Set the GPIO mode of the push button as input
// /* Enable pull-up for Input pin */
// gpio_pullup_en(Push_Button); // Enable pull-up resistor on push button pin
// gpio_pulldown_dis(Push_Button); // Disable pull-down resistor
// /* Configure rising edge detection interrupt for Input pin */
// gpio_set_intr_type(Push_Button, GPIO_INTR_POSEDGE); // Set the interrupt to trigger on rising edge
// /* Install and attach ISR to the GPIO interrupt */
// gpio_install_isr_service(0); // Install ISR service
// gpio_isr_handler_add(Push_Button, gpio_isr_handler, NULL); // Attach ISR handler to the push button pin
// while (1)
// {
// if (gpio_value)
// {
// printf("ON \n");
// }
// else
// {
// printf("OFF \n");
// }
// vTaskDelay(100 / portTICK_PERIOD_MS); // Delay to avoid too frequent logging
// }
// }