Bodmer / TFT_eSPI

Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
Other
3.65k stars 1.05k forks source link

Support for RTOS #1506

Closed Stallone888 closed 2 years ago

Stallone888 commented 2 years ago

I have been using old UCGlib for controlling displays but after I have seen this library I want to switch to it. It works super fast and super nice on ESP32 boards, but issue I found is that it does not support RTOS, or use of threads and cores for ESP32. It just won't work and compile. The setup I use on my last project is 3 task operation: TaskHandle_t Task1; //Sensors - Core 1 TaskHandle_t Task2; //Display - Core 0 TaskHandle_t Task3; //Web - Core 0 All task are managed by RTOS of Arduino ESP32 project and I have no problem in programing easy to understand and use code. Is there a way to make things work for this kind of operations or will it ever be a support for RTOS?

Bodmer commented 2 years ago

An Arduino sketch normally runs on core 1 and I suspect that if you keep the display funcions on core 1 then it will work.

I have experiemented with tasks and have found things work OK, see example here.

Stallone888 commented 2 years ago

The problem is with display flickering, when I use RTOS, and cores display resets itself after 10-15 seconds. I will put code here:

`//GLOBAL VARIABLES: int screen_rotation = 2;

TaskHandle_t Task1; TaskHandle_t Task2;

//Display

include // Graphics and font library for ST7735 driver chip

include

TFT_eSPI tft = TFT_eSPI();

// MENU: uint8_t draw_state = 0; void draw(void) { switch(draw_state) { case 0: PrviEkran(draw_state&7); break; //case 1: DrugiEkran(draw_state&7); break; //case 2: TreciEkran(draw_state&7); break; //case 3: CetvrtiEkran(draw_state&7); break; //case 4: PetiEkran(draw_state&7); break; } }

//SETUP----------------------------------------------------------------

void setup() {

tft.init(); tft.setRotation(screen_rotation); tft.fillScreen(TFT_BLACK); tft.setSwapBytes(true); Serial.begin(9600);

//CORES: xTaskCreatePinnedToCore( Task1code, / Task function. / "Task1", / name of task. / 10000, / Stack size of task / NULL, / parameter of the task / 1, / priority of the task / &Task1, / Task handle to keep track of created task / 0); / pin task to core 0 /
delay(500);

//create a task that will be executed in the Task2code() function, with priority 1 and executed on core 1 xTaskCreatePinnedToCore( Task2code, / Task function. / "Task2", / name of task. / 10000, / Stack size of task / NULL, / parameter of the task / 1, / priority of the task / &Task2, / Task handle to keep track of created task / 1); / pin task to core 1 / delay(500);

}

//KOD PROGRAMA: Display

void Task1code( void * pvParameters ){ for(;;){

  TFT_eSPI tft_task1 = TFT_eSPI();
  tft_task1.init();
  delay(100);

while(1) { draw_state = 0; draw(); while(1) yield(); // We must yield() to stop a watchdog timeout.
}

} }

//KOD PROGRAMA: Senzori

void Task2code( void * pvParameters ){

for(;;){

} }

void PrviEkran(uint8_t a) {

        tft.setTextColor(TFT_GREEN);
        tft.setCursor (20, 20);
        tft.print("Prvi ekran");    

}

void loop() {

}`

Can this be the case with using RTOS and cores, or my bad programming skills?

Bodmer commented 2 years ago

You are instantiating two copies of the library so this will cause resource conflicts. You ust either use handshake semaphores to prevent both cores simultaneously trying to access the TFT or just run the TFT library on core 1.

I suggest you avoid RTOS tasks.