Skip to content

Commit

Permalink
Defensive code for Heltec Display (#1296)
Browse files Browse the repository at this point in the history
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

ThingPulse/esp8266-oled-ssd1306#326
ThingPulse/esp8266-oled-ssd1306#352
  • Loading branch information
NorthernMan54 authored Oct 23, 2022
1 parent 941b1e1 commit 19d58e0
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 22 deletions.
43 changes: 22 additions & 21 deletions main/ZboardHeltec.ino
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

/*
Expand Down
7 changes: 6 additions & 1 deletion main/config_HELTEC.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ class OledSerial : public Stream {

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);
Expand Down

0 comments on commit 19d58e0

Please sign in to comment.