ESP32 FREERTOS сбой при использовании Adafruit ST7789 в задачах с включенным Wi-Fi

Я пытаюсь создать часы, используя дисплей ST7789 и DS3231 RTC. В этих часах я хочу использовать NTP, чтобы синхронизировать его и, возможно, использовать Wi-Fi для чего-то еще. Моя проблема началась, когда я попытался использовать задачи для разделения кода на части, управления приоритетами и поддержания кода цикла как можно более чистым. Когда я пытаюсь обновить отображаемый текст из задачи, ESP32 просто падает и перезагружается. Я очистил код, чтобы увидеть, где проблема, и я заметил, что проблема возникает, когда я подключаюсь к своему маршрутизатору, а затем я пытаюсь обновить текст на дисплее, но не терпит неудачи, если Wi-Fi не запущен или я обновляю текст вне задачи. Очищенный код, который я использую, это:

#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 (может подключаться контакту RST)

// 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**";

// Инициализация TFT-библиотеки Adafruit ST7789
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// функция настройки запускается один раз при нажатии кнопки сброс или питание
void setup() {
  
  // инициализация последовательной связи со скоростью 115200 бит в секунду:
  Serial.begin(115200);

  // Теперь установите две задачи для запуска независимо.
  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
  );

  // Подключение к Wi-Fi
   WiFi.begin(ssid, password);

  tft.init(240, 240, SPI_MODE2);    // Init ST7789 display 135x240 pixel
  tft.setRotation(3);
  drawBackground();
}

void loop() {
  
}

// Функция рисования фона дисплея
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);
}

// Функция обновления даты/времени
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);
  }
}

Если я комментирую функцию WiFi.begin или вызываю ее из цикла без создания задачи или просто перемещаю три строки в функцию цикла, она работает отлично.

#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);
  }
}

Я начинаю с FREERTOS и ESP32, и я не уверен, что делаю что-то не так... Я думал, что проблема была в RTC, но после того, как удалил код RTC и увидел, что это был Wi-Fi, я не уверен, в чем может быть проблема.

С наилучшими пожеланиями и благодарностью.

, 👍0

Обсуждение

ESP32 имеет встроенный RTC. Зачем тратить время на добавление внешнего?, @Majenko

Вы не первый, у кого возникли проблемы с использованием дисплея с кодом, работающим на том же ядре, что и Wi-Fi (ядро 0). Свяжите задачу с ядром 1., @Majenko

Здравствуйте @Majenko, у внутреннего RTC нет батареи, чтобы поддерживать часовой режим, даже когда нет энергии, и это настоящая причина. Также я читал, что внутренний RTC не так точен, как внешний. Я постараюсь связать его, спасибо!., @Daniel Carrasco Marín

Но если вы используете NTP в настоящее время, какое это имеет значение?, @Majenko

@Majenko Я также думаю о возможности потерять подключение к Интернету или не иметь его вообще. Также способ научиться делать что-то ;), @Daniel Carrasco Marín


1 ответ


Лучший ответ:

0

Прикрепить функцию к ядру не работало для меня, конечно, потому что init-код находится вне функции, поэтому я переместил init-код внутрь функции, из цикла:

#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 (может подключаться к первому контакту)

// Цвета
#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";

// Инициализация TFT-библиотеки Adafruit ST7789
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// функция настройки запускается один раз при нажатии кнопки reset или power board
void setup() {
  
  // инициализация последовательной связи со скоростью 115200 бит в секунду:
  Serial.begin(115200);

  xTaskCreatePinnedToCore(
    updateDateTime, /* Функция для реализации задачи */
    "updateDateTime", /* Имя задачи */
    1024, /* Размер стека в словах */
    NULL, /* Входной параметр задачи */
    3, /* Приоритет задачи */
    NULL, /* Дескриптор задачи. */
    0
  );

  // Подключение к Wi-Fi
   WiFi.begin(ssid, password);

  //tft.init(240, 240, SPI_MODE2);    // Init ST7789 display 135x240 pixel
//  tft.setRotation(3);
//  drawBackground();
}

void loop() {
}

// Функция рисования фона дисплея
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);
}

// Функция обновления даты/времени
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);
  }
}

Я сохранил эту функцию привязанной к ядру, чтобы избежать проблем, если ОСРВ решит позже запустить эту функцию на другом ядре. Мне приходится делать больше тестов, но, похоже, это работает.

С наилучшими пожеланиями.

,