I am trying to create a clock using a ST7789 display and a DS3231 RTC. In this clock I want to use NTP to keep it synced and maybe use the WiFi to anything else. My problem started when I have tried to use tasks to split the code into pieces, manage priorities and to keep the loop code as clean as possible. When I try to update the display text from a task the ESP32 just crash and reboots. I have cleaned the code to see where is the problem and I have noticed that the problem comes when I connect to my Router and then I try to update the text in the display, but doesn't fail if the WiFi is not started or I update the text outside the task. The cleaned code I am using is this:
#include <WiFi.h>
#include <Adafruit_ST7789.h>
#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif
#define TFT_MOSI 23 // SDA Pin on ESP32
#define TFT_SCLK 18 // SCL Pin on ESP32
#define TFT_CS 15 // Chip select control pin
#define TFT_DC 2 // Data Command control pin
#define TFT_RST 4 // Reset pin (could connect to RST pin)
// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)
#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
static const char* ssid = "WIFI_SSID";
static const char* password = "**REDACTED**";
// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 115200 bits per second:
Serial.begin(115200);
// Now set up two tasks to run independently.
xTaskCreate(
updateDateTime,
"updateDateTime", // A name just for humans
1024, // This stack size can be checked & adjusted by reading the Stack Highwater
NULL,
3, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
NULL
);
// Connecting to Wifi
WiFi.begin(ssid, password);
tft.init(240, 240, SPI_MODE2); // Init ST7789 display 135x240 pixel
tft.setRotation(3);
drawBackground();
}
void loop() {
}
// Function to draw the display background
void drawBackground() {
tft.fillScreen(0xFFFFFF);
tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);
tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}
// Function to update the date/time
void updateDateTime( void * pvParameters ) {
for( ;; ) {
//tft.init(240, 240, SPI_MODE2);
tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
tft.setCursor(6, 4);
tft.println("MIE");
delay(100);
}
}
If I comment the WiFi.begin function or I call the function from loop without create a task or just move the three lines to loop function, it works perfectly.
#include <WiFi.h>
#include <Adafruit_ST7789.h>
#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif
#define TFT_MOSI 23 // SDA Pin on ESP32
#define TFT_SCLK 18 // SCL Pin on ESP32
#define TFT_CS 15 // Chip select control pin
#define TFT_DC 2 // Data Command control pin
#define TFT_RST 4 // Reset pin (could connect to RST pin)
// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)
#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
static const char* ssid = "WIFI_SSID";
static const char* password = "**REDACTED**";
// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 115200 bits per second:
Serial.begin(115200);
// Connecting to Wifi
WiFi.begin(ssid, password);
tft.init(240, 240, SPI_MODE2); // Init ST7789 display 135x240 pixel
tft.setRotation(3);
drawBackground();
}
void loop() {
void * test;
updateDateTime(test);
}
// Function to draw the display background
void drawBackground() {
tft.fillScreen(0xFFFFFF);
tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);
tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}
// Function to update the date/time
void updateDateTime( void * pvParameters ) {
for( ;; ) {
//tft.init(240, 240, SPI_MODE2);
tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
tft.setCursor(6, 4);
tft.println("MIE");
delay(100);
}
}
I am starting with FREERTOS and ESP32, and I am not sure what I am doing wrong... I have thougth that the problem was the RTC but after remove the RTC code and see that was the WiFi, I am not sure what can be the problem.
Best regards and thanks.
-
The ESP32 has a built in RTC. Why waste time adding an external one as well?Majenko– Majenko04/23/2021 10:31:42Commented Apr 23, 2021 at 10:31
-
1You're not the first to have problems using a display with code running on the same core as the WiFi (core 0). Bind the task to core 1.Majenko– Majenko04/23/2021 10:35:36Commented Apr 23, 2021 at 10:35
-
Hello @Majenko, the internal RTC doesn't have battery to keep the hour even when the energy is gone, and that's the real reason. Also I have read that the internal RTC is not as precise as an external. I'll try to bind it, Thanks!.Daniel Carrasco Marín– Daniel Carrasco Marín04/23/2021 14:02:07Commented Apr 23, 2021 at 14:02
-
But if you're using NTP for the time, what does any of that matter?Majenko– Majenko04/23/2021 14:36:01Commented Apr 23, 2021 at 14:36
-
@Majenko I am also thinking in the posibility of loose the internet connection or doesn't have it at all. Also a way to learn doing things ;)Daniel Carrasco Marín– Daniel Carrasco Marín04/23/2021 15:16:01Commented Apr 23, 2021 at 15:16
1 Answer 1
To pin the function to a core was not working for me surely because the init code is outside the function, so I have moved the init code to inside the function, out of the loop:
#include <WiFi.h>
#include <Adafruit_ST7789.h>
#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif
#define TFT_MOSI 23 // SDA Pin on ESP32
#define TFT_SCLK 18 // SCL Pin on ESP32
#define TFT_CS 15 // Chip select control pin
#define TFT_DC 2 // Data Command control pin
#define TFT_RST 4 // Reset pin (could connect to RST pin)
// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)
#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
static const char* ssid = "MOVISTAR_F6112";
static const char* password = "C89qlqMifsjDMWhbdsJQ";
// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 115200 bits per second:
Serial.begin(115200);
xTaskCreatePinnedToCore(
updateDateTime, /* Function to implement the task */
"updateDateTime", /* Name of the task */
1024, /* Stack size in words */
NULL, /* Task input parameter */
3, /* Priority of the task */
NULL, /* Task handle. */
0
);
// Connecting to Wifi
WiFi.begin(ssid, password);
//tft.init(240, 240, SPI_MODE2); // Init ST7789 display 135x240 pixel
// tft.setRotation(3);
// drawBackground();
}
void loop() {
}
// Function to draw the display background
void drawBackground() {
tft.fillScreen(0xFFFFFF);
tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);
tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}
// Function to update the date/time
void updateDateTime( void * pvParameters ) {
tft.init(240, 240, SPI_MODE2);
tft.setRotation(3);
drawBackground();
for( ;; ) {
//tft.init(240, 240, SPI_MODE2);
tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
tft.setCursor(6, 4);
tft.println("MIE");
delay(100);
}
}
I have kept the function pinned to a core to avoid problems if RTOS decides to run the function on another core later. I have to do more tests, but seems to works.
Best regards.