Multi thread behaviour
Posted: Sun Jan 15, 2023 12:05 pm
Hello all,
I'm trying to build a RGB LED Lamp using WS2812 leds.
Everything work well untill I decided to create multiple scenario to run led light driven by external push button.
My Idea was :
I think I need better knowledge of :
-1 ISR
- multi thread behaviour
- multi thread behaviour in ESP32
- suggestions.
This is my code :
I'm trying to build a RGB LED Lamp using WS2812 leds.
Everything work well untill I decided to create multiple scenario to run led light driven by external push button.
My Idea was :
- 0) Project with THREAD_MAIN to initialize everithing and start the THREAD_LED;
1) Power on the lamp with predefinite light scenario running on THREAD_LED defined by variable scenario_var=0;
2) push external button to change light scenario actions:- - first : delete ongoing THREAD_LED
- second : UPDATE scenario_var to change the next scenario to start
- third : start again THREAD_LED with updated passed variable
- - first : delete ongoing THREAD_LED
I think I need better knowledge of :
-1 ISR
- multi thread behaviour
- multi thread behaviour in ESP32
- suggestions.
This is my code :
Code: Select all
#include <stdio.h>
#include "driver/gpio.h" //useful to use GPIO pin
#include "freertos/FreeRTOS.h" //to use the FreeRTOS system
#include "freertos/task.h" //to call task functions
#include "freertos/semphr.h" //to use semaphores
#include "esp_heap_caps_init.h"
#include "esp_log.h"
#define TAG "MAIN"
#define STACK_SIZE 2048
#define ESP_INTR_FLAG_DEFAULT 0
#define CONFIG_BUTTON_PIN GPIO_NUM_0
#define CONFIG_LED_PIN GPIO_NUM_2
SemaphoreHandle_t xSemaphore = NULL; //Allocate semaphore variable
bool led_status = false; //create LED Flag
//----------------------------------------------------------------------
// task that will react to button clicks
void button_task(void* arg) {
// infinite loop
for(;;) {
// wait for the notification from the ISR
if(xSemaphoreTake(xSemaphore,portMAX_DELAY) == pdTRUE) {
printf("Button pressed!\n");
led_status = !led_status;
gpio_set_level(CONFIG_LED_PIN, led_status);
ESP_LOGI("ISR_TASK","free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
}
}
}
void second_task (void * pvParameter)
{
uint16_t counter = 0;
uint8_t passed_parameter = *((uint8_t*)pvParameter);
printf("received parameter value is %d\n",passed_parameter);
ESP_LOGI("SECOND_TASK","free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
while(1)
{
counter++;
printf("Counter Value %d\n",counter);
vTaskDelay(300);
}
}
//----------------------------------------------------------------------
// interrupt service routine, called when the button is pressed
//Interrupt handlers must be placed into IRAM Memory
void IRAM_ATTR button_isr_handler(void* arg) {
static uint8_t version=0;
TaskHandle_t xHandle = NULL;
xHandle = *((TaskHandle_t*)arg);
vTaskDelete( xHandle );
version++;
xTaskCreate( second_task, "actions_task", STACK_SIZE, (void *)&version, 10, &arg);
// notify the button task
//xSemaphoreGiveFromISR(xSemaphore, NULL);
}
void app_main(void)
{
ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
uint8_t mode_value=0;
static uint8_t ucParameterToPass=0; // parameter to be passed to the second task
TaskHandle_t xHandle = NULL;
xSemaphore = xSemaphoreCreateBinary(); //create the binary semaphore
ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
// configure button and led pins as GPIO pins
gpio_pad_select_gpio(CONFIG_BUTTON_PIN);
gpio_pad_select_gpio(CONFIG_LED_PIN);
ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
// set the correct direction
gpio_set_direction(CONFIG_BUTTON_PIN, GPIO_MODE_INPUT);
gpio_set_direction(CONFIG_LED_PIN, GPIO_MODE_OUTPUT);
ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
// // enable interrupt on falling (1->0) edge for button pin
gpio_set_intr_type(CONFIG_BUTTON_PIN, GPIO_INTR_NEGEDGE);
// ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
// // start the task that will handle the button
xTaskCreate(button_task, "button_task", 2048, (void *)&xHandle, 10, NULL);
// ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
// install ISR service with default configuration
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
// ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
// // attach the interrupt service routine
gpio_isr_handler_add(CONFIG_BUTTON_PIN, button_isr_handler, xHandle);
// ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
xTaskCreate( second_task, "actions_task", STACK_SIZE, (void *)&ucParameterToPass, 10, &xHandle);
configASSERT( xHandle );
}