From 3cdf2f9b4de9eaeb53f76ab5523f149dd20bc063 Mon Sep 17 00:00:00 2001 From: Florent de Lamotte Date: Tue, 2 Sep 2025 11:43:48 +0200 Subject: [PATCH 1/3] techo: display backlight behavior --- examples/companion_radio/ui-new/UITask.cpp | 8 ++++++++ src/helpers/ui/GxEPDDisplay.cpp | 5 +++-- variants/techo/platformio.ini | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index c751eaf5..f0f9ed1d 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -519,6 +519,14 @@ void UITask::loop() { c = handleLongPress(KEY_ENTER); } #endif +#if defined(DISP_BACKLIGHT) && defined(BACKLIGHT_BTN) + static int next_btn_check = 0; + if (millis() > next_btn_check) { + bool touch_state = digitalRead(PIN_BUTTON2); + digitalWrite(DISP_BACKLIGHT, !touch_state); + next_btn_check = millis() + 300; + } +#endif if (c != 0 && curr) { curr->handleInput(c); diff --git a/src/helpers/ui/GxEPDDisplay.cpp b/src/helpers/ui/GxEPDDisplay.cpp index ace25460..9ba7d074 100644 --- a/src/helpers/ui/GxEPDDisplay.cpp +++ b/src/helpers/ui/GxEPDDisplay.cpp @@ -19,6 +19,7 @@ bool GxEPDDisplay::begin() { display.fillScreen(GxEPD_WHITE); display.display(true); #if DISP_BACKLIGHT + digitalWrite(DISP_BACKLIGHT, LOW); pinMode(DISP_BACKLIGHT, OUTPUT); #endif _init = true; @@ -27,14 +28,14 @@ bool GxEPDDisplay::begin() { void GxEPDDisplay::turnOn() { if (!_init) begin(); -#if DISP_BACKLIGHT +#if defined(DISP_BACKLIGHT) && !defined(BACLIGHT_BTN) digitalWrite(DISP_BACKLIGHT, HIGH); #endif _isOn = true; } void GxEPDDisplay::turnOff() { -#if DISP_BACKLIGHT +#if defined(DISP_BACKLIGHT) && !defined(BACKLIGHT_BTN) digitalWrite(DISP_BACKLIGHT, LOW); #endif _isOn = false; diff --git a/variants/techo/platformio.ini b/variants/techo/platformio.ini index e5cfacd4..260be35f 100644 --- a/variants/techo/platformio.ini +++ b/variants/techo/platformio.ini @@ -78,6 +78,7 @@ build_flags = -D DISPLAY_CLASS=GxEPDDisplay -D OFFLINE_QUEUE_SIZE=256 -D UI_RECENT_LIST_SIZE=9 + -D BACKLIGHT_BTN=PIN_BUTTON2 ; -D MESH_PACKET_LOGGING=1 ; -D MESH_DEBUG=1 build_src_filter = ${LilyGo_Techo.build_src_filter} From cb3049e706201e300681981590feceeb5af02a91 Mon Sep 17 00:00:00 2001 From: Florent Date: Wed, 3 Sep 2025 17:22:11 +0200 Subject: [PATCH 2/3] cleanups (remove statics and typos) --- examples/companion_radio/ui-new/UITask.cpp | 33 +++++++++------------- examples/companion_radio/ui-new/UITask.h | 6 ++++ src/helpers/ui/GxEPDDisplay.cpp | 2 +- variants/techo/platformio.ini | 1 + 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index f0f9ed1d..a02b0288 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -419,38 +419,34 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i if (_display != NULL) { if (!_display->isOn()) _display->turnOn(); _auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer - _next_refresh = 0; // trigger refresh + _next_refresh = 100; // trigger refresh } } void UITask::userLedHandler() { #ifdef PIN_STATUS_LED - static int state = 0; - static int next_change = 0; - static int last_increment = 0; - int cur_time = millis(); - if (cur_time > next_change) { - if (state == 0) { - state = 1; + if (cur_time > next_led_change) { + if (led_state == 0) { + led_state = 1; if (_msgcount > 0) { - last_increment = LED_ON_MSG_MILLIS; + last_led_increment = LED_ON_MSG_MILLIS; } else { - last_increment = LED_ON_MILLIS; + last_led_increment = LED_ON_MILLIS; } - next_change = cur_time + last_increment; + next_led_change = cur_time + last_led_increment; } else { - state = 0; - next_change = cur_time + LED_CYCLE_MILLIS - last_increment; + led_state = 0; + next_led_change = cur_time + LED_CYCLE_MILLIS - last_led_increment; } - digitalWrite(PIN_STATUS_LED, state); + digitalWrite(PIN_STATUS_LED, led_state); } #endif } void UITask::setCurrScreen(UIScreen* c) { curr = c; - _next_refresh = 0; + _next_refresh = 100; } /* @@ -520,18 +516,17 @@ void UITask::loop() { } #endif #if defined(DISP_BACKLIGHT) && defined(BACKLIGHT_BTN) - static int next_btn_check = 0; - if (millis() > next_btn_check) { + if (millis() > next_backlight_btn_check) { bool touch_state = digitalRead(PIN_BUTTON2); digitalWrite(DISP_BACKLIGHT, !touch_state); - next_btn_check = millis() + 300; + next_backlight_btn_check = millis() + 300; } #endif if (c != 0 && curr) { curr->handleInput(c); _auto_off = millis() + AUTO_OFF_MILLIS; // extend auto-off timer - _next_refresh = 0; // trigger refresh + _next_refresh = 100; // trigger refresh } userLedHandler(); diff --git a/examples/companion_radio/ui-new/UITask.h b/examples/companion_radio/ui-new/UITask.h index f9e01550..3a27e55f 100644 --- a/examples/companion_radio/ui-new/UITask.h +++ b/examples/companion_radio/ui-new/UITask.h @@ -26,6 +26,12 @@ class UITask : public AbstractUITask { unsigned long _alert_expiry; int _msgcount; unsigned long ui_started_at, next_batt_chck; + int next_backlight_btn_check = 0; +#ifdef PIN_STATUS_LED + int led_state = 0; + int next_led_change = 0; + int last_led_increment = 0; +#endif UIScreen* splash; UIScreen* home; diff --git a/src/helpers/ui/GxEPDDisplay.cpp b/src/helpers/ui/GxEPDDisplay.cpp index 9ba7d074..49022d74 100644 --- a/src/helpers/ui/GxEPDDisplay.cpp +++ b/src/helpers/ui/GxEPDDisplay.cpp @@ -28,7 +28,7 @@ bool GxEPDDisplay::begin() { void GxEPDDisplay::turnOn() { if (!_init) begin(); -#if defined(DISP_BACKLIGHT) && !defined(BACLIGHT_BTN) +#if defined(DISP_BACKLIGHT) && !defined(BACKLIGHT_BTN) digitalWrite(DISP_BACKLIGHT, HIGH); #endif _isOn = true; diff --git a/variants/techo/platformio.ini b/variants/techo/platformio.ini index 260be35f..f748fdfe 100644 --- a/variants/techo/platformio.ini +++ b/variants/techo/platformio.ini @@ -92,3 +92,4 @@ lib_deps = ${LilyGo_Techo.lib_deps} densaugeo/base64 @ ~1.4.0 zinggjm/GxEPD2 @ 1.6.2 + bakercp/CRC32 @ ^2.0.0 From 9f97edcb21f01fb126bd94f55a1215d965c41999 Mon Sep 17 00:00:00 2001 From: Florent Date: Wed, 3 Sep 2025 18:17:37 +0200 Subject: [PATCH 3/3] gxepd: use a crc to track damage ! --- examples/companion_radio/ui-new/UITask.cpp | 10 ++++++++- src/helpers/ui/GxEPDDisplay.cpp | 26 +++++++++++++++++++++- src/helpers/ui/GxEPDDisplay.h | 3 +++ variants/techo/platformio.ini | 3 ++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index a02b0288..8ca5c950 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -3,7 +3,9 @@ #include "../MyMesh.h" #include "target.h" -#define AUTO_OFF_MILLIS 15000 // 15 seconds +#ifndef AUTO_OFF_MILLIS + #define AUTO_OFF_MILLIS 15000 // 15 seconds +#endif #define BOOT_SCREEN_MILLIS 3000 // 3 seconds #ifdef PIN_STATUS_LED @@ -321,7 +323,11 @@ public: display.setColor(DisplayDriver::LIGHT); display.printWordWrap(p->msg, display.width()); +#if AUTO_OFF_MILLIS==0 // probably e-ink + return 10000; // 10 s +#else return 1000; // next render after 1000 ms +#endif } bool handleInput(char c) override { @@ -556,9 +562,11 @@ void UITask::loop() { } _display->endFrame(); } +#if AUTO_OFF_MILLIS > 0 if (millis() > _auto_off) { _display->turnOff(); } +#endif } #ifdef AUTO_SHUTDOWN_MILLIVOLTS diff --git a/src/helpers/ui/GxEPDDisplay.cpp b/src/helpers/ui/GxEPDDisplay.cpp index 49022d74..98b34eaa 100644 --- a/src/helpers/ui/GxEPDDisplay.cpp +++ b/src/helpers/ui/GxEPDDisplay.cpp @@ -44,14 +44,17 @@ void GxEPDDisplay::turnOff() { void GxEPDDisplay::clear() { display.fillScreen(GxEPD_WHITE); display.setTextColor(GxEPD_BLACK); + display_crc.reset(); } void GxEPDDisplay::startFrame(Color bkg) { display.fillScreen(GxEPD_WHITE); display.setTextColor(_curr_color = GxEPD_BLACK); + display_crc.reset(); } void GxEPDDisplay::setTextSize(int sz) { + display_crc.update(sz); switch(sz) { case 1: // Small display.setFont(&FreeSans9pt7b); @@ -69,6 +72,7 @@ void GxEPDDisplay::setTextSize(int sz) { } void GxEPDDisplay::setColor(Color c) { + display_crc.update (c); // colours need to be inverted for epaper displays if (c == DARK) { display.setTextColor(_curr_color = GxEPD_WHITE); @@ -78,22 +82,38 @@ void GxEPDDisplay::setColor(Color c) { } void GxEPDDisplay::setCursor(int x, int y) { + display_crc.update(x); + display_crc.update(y); display.setCursor(x*SCALE_X, (y+10)*SCALE_Y); } void GxEPDDisplay::print(const char* str) { + display_crc.update(str, strlen(str)); display.print(str); } void GxEPDDisplay::fillRect(int x, int y, int w, int h) { + display_crc.update(x); + display_crc.update(y); + display_crc.update(w); + display_crc.update(h); display.fillRect(x*SCALE_X, y*SCALE_Y, w*SCALE_X, h*SCALE_Y, _curr_color); } void GxEPDDisplay::drawRect(int x, int y, int w, int h) { + display_crc.update(x); + display_crc.update(y); + display_crc.update(w); + display_crc.update(h); display.drawRect(x*SCALE_X, y*SCALE_Y, w*SCALE_X, h*SCALE_Y, _curr_color); } void GxEPDDisplay::drawXbm(int x, int y, const uint8_t* bits, int w, int h) { + display_crc.update(x); + display_crc.update(y); + display_crc.update(w); + display_crc.update(h); + display_crc.update(bits, w * h / 8); // Calculate the base position in display coordinates uint16_t startX = x * SCALE_X; uint16_t startY = y * SCALE_Y; @@ -137,5 +157,9 @@ uint16_t GxEPDDisplay::getTextWidth(const char* str) { } void GxEPDDisplay::endFrame() { - display.display(true); + uint32_t crc = display_crc.finalize(); + if (crc != last_display_crc_value) { + display.display(true); + last_display_crc_value = crc; + } } diff --git a/src/helpers/ui/GxEPDDisplay.h b/src/helpers/ui/GxEPDDisplay.h index 49746dee..9acf3ac2 100644 --- a/src/helpers/ui/GxEPDDisplay.h +++ b/src/helpers/ui/GxEPDDisplay.h @@ -17,6 +17,7 @@ #define GxEPD2_DRIVER_CLASS GxEPD2_150_BN // DEPG0150BN 200x200, SSD1681, (FPC8101), TTGO T5 V2.4.1 #include // 1.54" b/w +#include #include "DisplayDriver.h" @@ -29,6 +30,8 @@ class GxEPDDisplay : public DisplayDriver { bool _init = false; bool _isOn = false; uint16_t _curr_color; + CRC32 display_crc; + int last_display_crc_value = 0; public: // there is a margin in y... diff --git a/variants/techo/platformio.ini b/variants/techo/platformio.ini index f748fdfe..812baa78 100644 --- a/variants/techo/platformio.ini +++ b/variants/techo/platformio.ini @@ -74,11 +74,12 @@ build_flags = -D MAX_CONTACTS=100 -D MAX_GROUP_CHANNELS=8 -D BLE_PIN_CODE=123456 - -D BLE_DEBUG_LOGGING=1 +; -D BLE_DEBUG_LOGGING=1 -D DISPLAY_CLASS=GxEPDDisplay -D OFFLINE_QUEUE_SIZE=256 -D UI_RECENT_LIST_SIZE=9 -D BACKLIGHT_BTN=PIN_BUTTON2 + -D AUTO_OFF_MILLIS=0 ; -D MESH_PACKET_LOGGING=1 ; -D MESH_DEBUG=1 build_src_filter = ${LilyGo_Techo.build_src_filter}