From 19d58e01e08b388f83262fba12451b73f76bff69 Mon Sep 17 00:00:00 2001 From: Northern Man Date: Sun, 23 Oct 2022 14:36:59 -0400 Subject: [PATCH] Defensive code for Heltec Display (#1296) Added to Heltec board display code logic to reduce corruption of messages on the display Two piece of defensive code were added - Only display messages to the display when operating on Core 1 ( Default Arduino ESP32 CONFIG_ARDUINO_RUNNING_CORE ) - Only display one character/string at a time In the event of failure, default to Serial output. PS SSD1306 driver similar issues https://github.com/ThingPulse/esp8266-oled-ssd1306/issues/326 https://github.com/ThingPulse/esp8266-oled-ssd1306/issues/352 --- main/ZboardHeltec.ino | 43 ++++++++++++++++++++++--------------------- main/config_HELTEC.h | 7 ++++++- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/main/ZboardHeltec.ino b/main/ZboardHeltec.ino index 37c8ac2..361685b 100644 --- a/main/ZboardHeltec.ino +++ b/main/ZboardHeltec.ino @@ -32,7 +32,8 @@ #if defined(ZboardHELTEC) # include "ArduinoLog.h" # include "config_HELTEC.h" -// # include "heltec.h" + +SemaphoreHandle_t semaphoreOLEDOperation; void logToLCD(bool display) { display ? Log.begin(LOG_LEVEL_LCD, &Oled) : Log.begin(LOG_LEVEL, &Serial); // Log on LCD following LOG_LEVEL_LCD @@ -125,6 +126,10 @@ OledSerial::OledSerial(int x) { void OledSerial::begin() { // Heltec.begin(); // User OMG serial support + + semaphoreOLEDOperation = xSemaphoreCreateBinary(); + xSemaphoreGive(semaphoreOLEDOperation); + display->init(); display->flipScreenVertically(); display->setFont(ArialMT_Plain_10); @@ -157,28 +162,24 @@ void OledSerial::fillScreen(OLEDDISPLAY_COLOR color) { display->fillRect(0, 0, OLED_WIDTH, OLED_HEIGHT); } -size_t OledSerial::write(uint8_t c) { - display->clear(); - display->setColor(WHITE); - display->setFont(ArialMT_Plain_10); - - display->write((char)c); - display->drawLogBuffer(0, 0); - display->display(); - return 1; -} - size_t OledSerial::write(const uint8_t* buffer, size_t size) { - display->clear(); - display->setColor(WHITE); - display->setFont(ArialMT_Plain_10); - while (size) { - display->write((char)*buffer++); - size--; + if (xPortGetCoreID() == CONFIG_ARDUINO_RUNNING_CORE) { + if (xSemaphoreTake(semaphoreOLEDOperation, pdMS_TO_TICKS(30000)) == pdTRUE) { + display->clear(); + display->setColor(WHITE); + display->setFont(ArialMT_Plain_10); + while (size) { + display->write((char)*buffer++); + size--; + } + display->drawLogBuffer(0, 0); + display->display(); + xSemaphoreGive(semaphoreOLEDOperation); + return size; + } } - display->drawLogBuffer(0, 0); - display->display(); - return size; + // Default to Serial output if the display is not available + return Serial.write(buffer, size); } /* diff --git a/main/config_HELTEC.h b/main/config_HELTEC.h index d9db1b6..1bb0b87 100644 --- a/main/config_HELTEC.h +++ b/main/config_HELTEC.h @@ -87,7 +87,12 @@ public: void fillScreen(OLEDDISPLAY_COLOR); // fillScreen display and set color - size_t write(uint8_t); + // This is a bit of lazy programmer simplifacation for the semapore and core detecting code. Not sure if it is truly space efficient. + + inline size_t write(uint8_t x) { + return write(&x, 1); + } + size_t write(const uint8_t* buffer, size_t size); inline size_t write(const char* buffer, size_t size) { return write((uint8_t*)buffer, size);