Hello community,
This is my first post on this forum so I hope i will make everything correct and understandable.
I have a project using ESP32, freeRTOS, oled, touchbuttons...
Since this is my first hw and/or sw project (learning by doing), I learnt a lot during the previous couple of weeks but am still struggling with some issues. However, for most issues there is already a question asked and most likely a solution available online, hence why I haven't asked anything here yet.
But, as the saying goes "there's always a first time" so I will jump into it:
I have created a program with several tasks divided on both cores of the ESP32. For simplicity I have a code snippet with only 3 tasks to show my issue.
What happens in the code:
Loop:
includes a routine for buttonpress (touch detect) check. if the touchpad is activated, the program shall switch from task 1 to task 2 then task3 and than back to task 1 again.
While switching between the tasks, i would like to suspend the previous task before i go to the next one and with "xTaskNotify" i would like to call the new task.
Now for the strange part:
During boot up, in the setup section i call xTaskNotify for task1. This is executed perfectly and I am able to see "Task 1 entry" in the serial monitor.
Another touchbutton activation works well too. I suspend task1, send xTaskNotify and see "Task 2 entry" and the "for loop" i have included into this task. The same for task3 - so far so good.
But now the strange thing happens. If task3 is active at the moment and I would like to change to task1 again, this works without any issues, BUT if i want to change from task1 to task2 or from task2 to task3, with the same method as before - the program dives in directly into the "for loop" of the given task, without execution of the "Task x entry" part. I tried moving the if condition after the "for" part, moving the suspend command, adding vTaskDelay command... but nothing helped.
So to sum up, the first loop task1 -> task2 -> task3 works flawlesly, but after that, my task2 and task3 entries are not executed.
Can anyone suggest why or what I should be doing differently?
Thanks!
BR
RoB
uint8_t mode = 5, longtouchtime = 350, touchdebounce = 200, touch1begin =0, touch2begin = 0;
unsigned long touch1now = 0, touch1last = 0, touch1timer = 0, touch1longtime = 0;
bool touch1active = false, longtouchactive = false, relaisstate = false;
void task1( void *pvParameters );
void task3( void *pvParameters );
void task2( void *pvParameters );
TaskHandle_t xtask1 = NULL;
TaskHandle_t xtask2 = NULL;
TaskHandle_t xtask3 = NULL;
void setup() {
Serial.begin(115200);
Serial.println("Basic Demo - ESP32-Arduino-CAN");
touch1begin = touchRead(T3);
Serial.println(touch1begin);
xTaskCreatePinnedToCore(
task2
, "task2" // A name just for humans
, 1000 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 1 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, &xtask2
, 1);
xTaskCreatePinnedToCore(
task3
, "task3" // A name just for humans
, 2000 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 1 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, &xtask3
, 1);
xTaskCreate(task1, "task1", 2000, NULL, 1, &xtask1 );
//xTaskCreate(task2, "task2", 2000, NULL, 1, &xtask2 );
//xTaskCreate(task3, "task3", 2000, NULL, 1, &xtask3 );
vTaskSuspend(xtask2);
vTaskSuspend(xtask3);
xTaskNotifyGive( xtask1 );
}
void task1(void *pvParameters){
while(1){
if (ulTaskNotifyTake(pdTRUE, portMAX_DELAY) != 0){
Serial.println("task1 entry");
mode = 0;
}
vTaskSuspend(NULL);
}
}
void task2(void *pvParameters){
if (ulTaskNotifyTake(pdTRUE, portMAX_DELAY) != 0){
Serial.println("task 2 entry");
for(;;){
Serial.println("task 2 repeat");
vTaskDelay(pdMS_TO_TICKS( 200 ));
}
vTaskSuspend(NULL);
}
}
void task3(void *pvParameters){
if (ulTaskNotifyTake(pdTRUE, portMAX_DELAY) != 0){
Serial.println("task 3 entry");
for(;;){
Serial.println("task 3 repeat");
vTaskDelay(pdMS_TO_TICKS( 200 ));
}
vTaskSuspend(NULL);
}
}
void loop() {
if (touchRead(T3) < (touch1begin-5)){
touch1now = millis();
if((touch1now - touch1last) > touchdebounce) {
if ((touchRead(T3) < (touch1begin-5)) && touch1active == false && !longtouchactive) {
touch1longtime = millis();
touch1active = true;
Serial.println("Button pressed");
}
touch1last = millis();
}
} else if (touch1active == true && !(touchRead(T3) < (touch1begin-5))){
touch1active = false;
longtouchactive = false;
Serial.println("Button release");
if (mode !=4 || mode !=5){
if (mode == 0){
Serial.println(mode);
vTaskResume (xtask2);
xTaskNotifyGive( xtask2 );
mode=1;
}else if (mode == 1){
Serial.println(mode);
vTaskSuspend (xtask2);
vTaskResume (xtask3);
xTaskNotifyGive( xtask3 );
mode=2;
}else if (mode == 2){
Serial.println(mode);
vTaskSuspend (xtask3);
vTaskResume (xtask1);
xTaskNotifyGive( xtask1 );
}
}
}else if (longtouchactive == true && !(touchRead(T3) < (touch1begin-5))){
longtouchactive = false;
}
}