Search code examples
c++carduinoesp32freertos

ESP32/FreeRTOS, how to stop currently running task when the new one was triggered (avoiding overlap)


I'm working on code to control 2 module relay regarding door access. I'm looking for the way to stop the currently running tasks, before running the new one (the same task). All I want is to avoid overlap.

void TaskOpenManRoom(void *parameter){
  Serial.println("Opening men room");
  digitalWrite(manRelay, LOW);
  vTaskDelay(6000 / portTICK_PERIOD_MS);
  digitalWrite(manRelay, HIGH);
  Serial.println("Closing men room");
  vTaskDelete(NULL);
};

xTaskCreate(
      TaskOpenManRoom,
      "TaskOpenManRoom",
      1000,
      (void *) &man,
      1,
      &TaskMen
    );

My goal is to extend the time when the door should be opened. So basically when the first task was triggered and then after some while the second one, the door should stay opened another 6000ms.

In mu current code, when the second task is called like in the middle of the first one, the door get closed because of first task calling digitalWrite(manRelay, HIGH);

I would appreciate the hint how I can kill the first task when the second been triggered.


Solution

  • Tasks are meant to be long-running, because they are relatively heavyweight. Don't start and end tasks for each user activity and don't delay them for extended periods of time.

    You don't need any task at all for your functionality, you just need a timer to perform the closing activity after 6000 ms. Then you can reset it whenever you need.

    TimerHandle_t closeManRoomTimer;
    
    void OpenManRoom() {
      xTimerReset(closeManRoomTimer, 100);    // <------ (re)arm the close timer
      Serial.println("Opening men room");
      digitalWrite(manRelay, LOW);
    };
    
    void CloseManRoom(TimerHandle_t) {
      Serial.println("Closing men room");
      digitalWrite(manRelay, HIGH);
    };
    
    // during program startup, setup a one-shot close timer
    closeManRoomTimer = xTimerCreate("closeManRoomTimer", pdMS_TO_TICKS(6000), pdFALSE, 0, &CloseManRoom);