From a6fd3ef599a2859594864823e158474b0815a346 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Mon, 23 Feb 2026 15:34:10 +0100 Subject: [PATCH 1/3] System page with N2K device list by improved patching feature and patch --- lib/obp60task/PageSystem.cpp | 102 ++++++++++++++++++++--- lib/obp60task/extra_task.py | 22 +++-- lib/obp60task/patches/01-nmea2000.patch | 103 ++++++++++++++++++++++++ 3 files changed, 210 insertions(+), 17 deletions(-) create mode 100644 lib/obp60task/patches/01-nmea2000.patch diff --git a/lib/obp60task/PageSystem.cpp b/lib/obp60task/PageSystem.cpp index 92af7b2..a8b3ee4 100644 --- a/lib/obp60task/PageSystem.cpp +++ b/lib/obp60task/PageSystem.cpp @@ -15,6 +15,7 @@ #include "images/logo64.xbm" #include #include "qrcode.h" +#include #ifdef BOARD_OBP40S3 #include "dirent.h" @@ -40,6 +41,7 @@ private: String rtc_module; String gps_module; String env_module; + String flashLED; String batt_sensor; String solar_sensor; @@ -50,6 +52,17 @@ private: char mode = 'N'; // (N)ormal, (S)ettings, (D)evice list, (C)ard +#ifdef PATCH_N2K + struct device { + uint64_t NAME; + uint8_t id; + char hex_name[17]; + uint16_t manuf_code; + const char *model; + }; + std::vector devicelist; +#endif + public: PageSystem(CommonData &common){ commonData = &common; @@ -76,6 +89,7 @@ public: rot_sensor = common.config->getString(common.config->useRotSensor); homelat = common.config->getString(common.config->homeLAT).toDouble(); homelon = common.config->getString(common.config->homeLON).toDouble(); + flashLED = common.config->getString(common.config->flashLED); } void setupKeys() { @@ -168,19 +182,43 @@ public: } } + void displayNew(PageData &pageData) { +#ifdef BOARD_OBP60S3 + // Clear optical warning + if (flashLED == "Limit Violation") { + setBlinkingLED(false); + setFlashLED(false); + } +#endif + +#ifdef PATCH_N2K + // load current device list + tN2kDeviceList *pDevList = pageData.api->getN2kDeviceList(); + // TODO check if changed + if (pDevList->ReadResetIsListUpdated()) { + // only reload if changed + devicelist.clear(); + for (uint8_t i = 0; i <= 252; i++) { + const tNMEA2000::tDevice *d = pDevList->FindDeviceBySource(i); + if (d == nullptr) { + continue; + } + device dev; + dev.id = i; + dev.NAME = d->GetName(); + snprintf(dev.hex_name, sizeof(dev.hex_name), "%08X%08X", (uint32_t)(dev.NAME >> 32), (uint32_t)(dev.NAME & 0xFFFFFFFF)); + dev.manuf_code = d->GetManufacturerCode(); + dev.model = d->GetModelID(); + devicelist.push_back(dev); + } + } +#endif + }; + int displayPage(PageData &pageData){ GwConfigHandler *config = commonData->config; GwLog *logger = commonData->logger; - // Get config data - String flashLED = config->getString(config->flashLED); - - // Optical warning by limit violation (unused) - if(String(flashLED) == "Limit Violation"){ - setBlinkingLED(false); - setFlashLED(false); - } - // Logging boat values logger->logDebug(GwLog::LOG, "Drawing at PageSystem, Mode=%c", mode); @@ -461,12 +499,54 @@ public: getdisplay().print("NMEA2000 device list"); getdisplay().setFont(&Ubuntu_Bold8pt8b); - getdisplay().setCursor(20, 80); + getdisplay().setCursor(20, 70); getdisplay().print("RxD: "); getdisplay().print(String(commonData->status.n2kRx)); - getdisplay().setCursor(20, 100); + getdisplay().setCursor(120, 70); getdisplay().print("TxD: "); getdisplay().print(String(commonData->status.n2kTx)); + +#ifdef PATCH_N2K + x0 = 20; + y0 = 100; + + getdisplay().setFont(&Ubuntu_Bold10pt8b); + getdisplay().setCursor(x0, y0); + getdisplay().print("ID"); + getdisplay().setCursor(x0 + 50, y0); + getdisplay().print("Model"); + getdisplay().setCursor(x0 + 250, y0); + getdisplay().print("Manuf."); + getdisplay().drawLine(18, y0 + 4, 360 , y0 + 4 , commonData->fgcolor); + + getdisplay().setFont(&Ubuntu_Bold8pt8b); + y0 = 120; + uint8_t n_dev = 0; + for (const device& item : devicelist) { + if (n_dev > 8) { + break; + } + getdisplay().setCursor(x0, y0 + n_dev * 20); + getdisplay().print(item.id); + getdisplay().setCursor(x0 + 50, y0 + n_dev * 20); + getdisplay().print(item.model); + getdisplay().setCursor(x0 + 250, y0 + n_dev * 20); + getdisplay().print(item.manuf_code); + n_dev++; + } + getdisplay().setCursor(x0, y0 + (n_dev + 1) * 20); + if (n_dev == 0) { + getdisplay().printf("no devices found on bus"); + + } else { + getdisplay().drawLine(18, y0 + n_dev * 20, 360 , y0 + n_dev * 20, commonData->fgcolor); + getdisplay().printf("%d devices of %d in total", n_dev, devicelist.size()); + } +#else + getdisplay().setCursor(20, 100); + getdisplay().print("NMEA2000 not exposed to obp60 task"); +#endif + } // Update display diff --git a/lib/obp60task/extra_task.py b/lib/obp60task/extra_task.py index 66ee3b1..dfc8257 100644 --- a/lib/obp60task/extra_task.py +++ b/lib/obp60task/extra_task.py @@ -2,6 +2,14 @@ import subprocess +def cleanup_patches(source, target, env): + for p in patchfiles: + patch = os.path.join(patchdir, p) + print(f"removing {patch}") + res = subprocess.run(["git", "apply", "-R", patch], capture_output=True, text=True) + if res.returncode != 0: + print(res.stderr) + patching = False epdtype = "unknown" @@ -46,11 +54,13 @@ if patching: print("patchdir not found, no patches applied") else: patchfiles = [f for f in os.listdir(patchdir)] - for p in patchfiles: - patch = os.path.join(patchdir, p) - print(f"applying {patch}") - res = subprocess.run(["git", "apply", patch], capture_output=True, text=True) - if res.returncode != 0: - print(res.stderr) + if len(patchfiles) > 0: + for p in patchfiles: + patch = os.path.join(patchdir, p) + print(f"applying {patch}") + res = subprocess.run(["git", "apply", patch], capture_output=True, text=True) + if res.returncode != 0: + print(res.stderr) + env.AddPostAction("$PROGPATH", cleanup_patches) else: print("no patches found") diff --git a/lib/obp60task/patches/01-nmea2000.patch b/lib/obp60task/patches/01-nmea2000.patch new file mode 100644 index 0000000..3d50bea --- /dev/null +++ b/lib/obp60task/patches/01-nmea2000.patch @@ -0,0 +1,103 @@ +diff --git a/lib/api/GwApi.h b/lib/api/GwApi.h +index 88f9690..9663a65 100644 +--- a/lib/api/GwApi.h ++++ b/lib/api/GwApi.h +@@ -2,6 +2,8 @@ + #define _GWAPI_H + #include "GwMessage.h" + #include "N2kMsg.h" ++#include "Nmea2kTwai.h" ++#include "N2kDeviceList.h" + #include "NMEA0183Msg.h" + #include "GWConfig.h" + #include "GwBoatData.h" +@@ -222,6 +224,8 @@ class GwApi{ + * accessing boat data must only be executed from within the main thread + * you need to use the request pattern as shown in GwExampleTask.cpp + */ ++ virtual Nmea2kTwai *getNMEA2000()=0; ++ virtual tN2kDeviceList *getN2kDeviceList()=0; + virtual GwBoatData *getBoatData()=0; + virtual ~GwApi(){} + }; +diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h +index 604c356..2fe4496 100644 +--- a/lib/obp60task/OBP60Extensions.h ++++ b/lib/obp60task/OBP60Extensions.h +@@ -15,6 +15,9 @@ + #define MOUNT_POINT "/sdcard" + #endif + ++// Patches to apply to gateway code ++#define PATCH_N2K ++ + // FRAM address reservations 32kB: 0x0000 - 0x7FFF + // 0x0000 - 0x03ff: single variables + #define FRAM_PAGE_NO 0x0002 +diff --git a/lib/usercode/GwUserCode.cpp b/lib/usercode/GwUserCode.cpp +index 1b007f8..90087d4 100644 +--- a/lib/usercode/GwUserCode.cpp ++++ b/lib/usercode/GwUserCode.cpp +@@ -216,6 +216,14 @@ public: + { + return api->getLogger(); + } ++ virtual Nmea2kTwai *getNMEA2000() ++ { ++ return api->getNMEA2000(); ++ } ++ virtual tN2kDeviceList *getN2kDeviceList() ++ { ++ return api->getN2kDeviceList(); ++ } + virtual GwBoatData *getBoatData() + { + return api->getBoatData(); +@@ -428,4 +436,4 @@ void GwUserCode::handleWebRequest(const String &url,AsyncWebServerRequest *req){ + } + LOG_DEBUG(GwLog::DEBUG,"no task found for web request %s[%s]",url.c_str(),tname.c_str()); + req->send(404, "text/plain", "not found"); +-} +\ No newline at end of file ++} +diff --git a/src/main.cpp b/src/main.cpp +index 44c715f..fdb0366 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -100,6 +100,7 @@ GwLog logger(LOGLEVEL,NULL); + GwConfigHandler config(&logger); + + #include "Nmea2kTwai.h" ++#include + static const unsigned long CAN_RECOVERY_PERIOD=3000; //ms + static const unsigned long NMEA2000_HEARTBEAT_INTERVAL=5000; + class Nmea2kTwaiLog : public Nmea2kTwai{ +@@ -126,6 +127,7 @@ class Nmea2kTwaiLog : public Nmea2kTwai{ + #endif + + Nmea2kTwai &NMEA2000=*(new Nmea2kTwaiLog((gpio_num_t)ESP32_CAN_TX_PIN,(gpio_num_t)ESP32_CAN_RX_PIN,CAN_RECOVERY_PERIOD,&logger)); ++tN2kDeviceList *pN2kDeviceList; + + #ifdef GWBUTTON_PIN + bool fixedApPass=false; +@@ -333,6 +335,12 @@ public: + status.n2kTx=countNMEA2KOut.getGlobal(); + channels.fillStatus(status); + } ++ virtual Nmea2kTwai *getNMEA2000(){ ++ return &NMEA2000; ++ } ++ virtual tN2kDeviceList *getN2kDeviceList(){ ++ return pN2kDeviceList; ++ } + virtual GwBoatData *getBoatData(){ + return &boatData; + } +@@ -935,6 +943,7 @@ void setup() { + NMEA2000.SetMsgHandler([](const tN2kMsg &n2kMsg){ + handleN2kMessage(n2kMsg,N2K_CHANNEL_ID); + }); ++ pN2kDeviceList = new tN2kDeviceList(&NMEA2000); + NMEA2000.Open(); + logger.logDebug(GwLog::LOG,"starting addon tasks"); + logger.flush(); From 97fcebdcb7e50264a4ceb4df4e92521edf980d8e Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Mon, 23 Feb 2026 18:56:20 +0100 Subject: [PATCH 2/3] Added format "formatXdr:A:rd" to formatter (see #159) --- lib/obp60task/OBP60Formatter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/obp60task/OBP60Formatter.cpp b/lib/obp60task/OBP60Formatter.cpp index 9b42102..ad40372 100644 --- a/lib/obp60task/OBP60Formatter.cpp +++ b/lib/obp60task/OBP60Formatter.cpp @@ -835,7 +835,7 @@ FormattedData formatValue(GwApi::BoatValue *value, CommonData &commondata, bool result.cvalue = dplace; } //######################################################## - else if (value->getFormat() == "formatXdr:A:D"){ + else if ((value->getFormat() == "formatXdr:A:D") || ((value->getFormat() == "formatXdr:A:rd"))){ double angle = 0; if (usesimudata == false) { angle = value->value; From aea401589d793e0e4919195f09340ad071951d68 Mon Sep 17 00:00:00 2001 From: Norbert Walter Date: Fri, 27 Feb 2026 21:33:23 +0000 Subject: [PATCH 3/3] Add 4 inch TFT display ST7796 --- lib/obp60task/OBP60Extensions.cpp | 48 ++++++++++- lib/obp60task/OBP60Extensions.h | 117 +++++++++++++++++++++++++++ lib/obp60task/OBP60QRWiFi.h | 2 +- lib/obp60task/OBPcharts.cpp | 10 ++- lib/obp60task/PageAutopilot.cpp | 2 +- lib/obp60task/PageBME280.cpp | 2 +- lib/obp60task/PageBattery.cpp | 2 +- lib/obp60task/PageBattery2.cpp | 2 +- lib/obp60task/PageClock.cpp | 12 +-- lib/obp60task/PageCompass.cpp | 2 +- lib/obp60task/PageDST810.cpp | 2 +- lib/obp60task/PageDigitalOut.cpp | 2 +- lib/obp60task/PageFluid.cpp | 2 +- lib/obp60task/PageFourValues.cpp | 2 +- lib/obp60task/PageFourValues2.cpp | 2 +- lib/obp60task/PageGenerator.cpp | 2 +- lib/obp60task/PageKeelPosition.cpp | 4 +- lib/obp60task/PageNavigation.cpp | 2 +- lib/obp60task/PageOneValue.cpp | 2 +- lib/obp60task/PageRollPitch.cpp | 4 +- lib/obp60task/PageRudderPosition.cpp | 4 +- lib/obp60task/PageSixValues.cpp | 2 +- lib/obp60task/PageSkyView.cpp | 10 +-- lib/obp60task/PageSolar.cpp | 2 +- lib/obp60task/PageSystem.cpp | 4 +- lib/obp60task/PageThreeValues.cpp | 2 +- lib/obp60task/PageTwoValues.cpp | 2 +- lib/obp60task/PageVoltage.cpp | 2 +- lib/obp60task/PageWhite.cpp | 2 +- lib/obp60task/PageWind.cpp | 2 +- lib/obp60task/PageWindPlot.cpp | 2 +- lib/obp60task/PageWindRose.cpp | 4 +- lib/obp60task/PageWindRoseFlex.cpp | 4 +- lib/obp60task/PageXTETrack.cpp | 12 +-- lib/obp60task/obp60task.cpp | 72 +++++++++++------ lib/obp60task/platformio.ini | 8 +- 36 files changed, 272 insertions(+), 85 deletions(-) diff --git a/lib/obp60task/OBP60Extensions.cpp b/lib/obp60task/OBP60Extensions.cpp index 3b3ee88..6dbcf05 100644 --- a/lib/obp60task/OBP60Extensions.cpp +++ b/lib/obp60task/OBP60Extensions.cpp @@ -56,6 +56,12 @@ GxEPD2_BW display(GxEPD2_4 GxEPD2_BW & getdisplay(){return display;} #endif +#ifdef DISPLAY_ST7796 +// only instantiate; class defined in header +static LGFX display; +LGFX & getdisplay(){return display;} +#endif + // Horter I2C moduls PCF8574 pcf8574_Modul1(PCF8574_I2C_ADDR1); // First digital IO modul PCF8574 from Horter @@ -251,8 +257,10 @@ void deepSleep(CommonData &common){ getdisplay().setFont(&Ubuntu_Bold8pt8b); getdisplay().setCursor(65, 175); getdisplay().print("To wake up press key and wait 5s"); - getdisplay().nextPage(); // Update display contents + displayNextPage(); // Update display contents + #ifndef DISPLAY_ST7796 getdisplay().powerOff(); // Display power off + #endif setPortPin(OBP_POWER_50, false); // Power off ePaper display // Stop system esp_deep_sleep_start(); // Deep Sleep with weakup via touch pin @@ -276,8 +284,10 @@ void deepSleep(CommonData &common){ getdisplay().setFont(&Ubuntu_Bold8pt8b); getdisplay().setCursor(65, 175); getdisplay().print("To wake up press wheel and wait 5s"); - getdisplay().nextPage(); // Partial update + displayNextPage(); // Partial update + #ifndef DISPLAY_ST7796 getdisplay().powerOff(); // Display power off + #endif setPortPin(OBP_POWER_EPD, false); // Power off ePaper display setPortPin(OBP_POWER_SD, false); // Power off SD card // Stop system @@ -479,7 +489,13 @@ std::vector wordwrap(String &line, uint16_t maxwidth) { void drawTextCenter(int16_t cx, int16_t cy, String text) { int16_t x1, y1; uint16_t w, h; +#ifdef DISPLAY_ST7796 + // LovyanGFX doesn't expose getTextBounds; use width/height helpers + w = getdisplay().textWidth(text); + h = getdisplay().fontHeight(); +#else getdisplay().getTextBounds(text, 0, 150, &x1, &y1, &w, &h); +#endif getdisplay().setCursor(cx - w / 2, cy + h / 2); getdisplay().print(text); } @@ -490,7 +506,12 @@ void drawButtonCenter(int16_t cx, int16_t cy, int8_t sx, int8_t sy, String text, uint16_t w, h; uint16_t color; +#ifdef DISPLAY_ST7796 + w = getdisplay().textWidth(text); + h = getdisplay().fontHeight(); +#else getdisplay().getTextBounds(text, cx, cy, &x1, &y1, &w, &h); // Find text center +#endif getdisplay().setCursor(cx - w/2, cy + h/2); // Set cursor to center //getdisplay().drawPixel(cx, cy, fg); // Debug pixel for center position if (inverted) { @@ -509,7 +530,12 @@ void drawButtonCenter(int16_t cx, int16_t cy, int8_t sx, int8_t sy, String text, void drawTextRalign(int16_t x, int16_t y, String text) { int16_t x1, y1; uint16_t w, h; +#ifdef DISPLAY_ST7796 + w = getdisplay().textWidth(text); + h = getdisplay().fontHeight(); +#else getdisplay().getTextBounds(text, 0, 150, &x1, &y1, &w, &h); +#endif getdisplay().setCursor(x - w - 1, y); // '-1' required since some strings wrap around w/o it getdisplay().print(text); } @@ -1000,7 +1026,14 @@ void displayRudderPosition(int rudderPosition, uint8_t rangeDeg, uint16_t cx, ui String lbl = String(angle); int16_t bx, by; uint16_t bw, bh; - getdisplay().getTextBounds(lbl, 0, 0, &bx, &by, &bw, &bh); + #ifdef DISPLAY_ST7796 + // LovyanGFX: compute width/height manually + bw = getdisplay().textWidth(lbl); + bh = getdisplay().fontHeight(); + bx = 0; by = 0; + #else + getdisplay().getTextBounds(lbl, 0, 0, &bx, &by, &bw, &bh); + #endif int16_t tx = xpos - bw/2; int16_t ty = top + h + bh + 5; // A little spacing getdisplay().setCursor(tx, ty); @@ -1019,9 +1052,16 @@ void doImageRequest(GwApi *api, int *pageno, const PageStruct pages[MAX_PAGE_NUM logger->logDebug(GwLog::LOG,"handle image request [%s]: %s", imgformat, filename); - uint8_t *fb = getdisplay().getBuffer(); // EPD framebuffer + uint8_t *fb = nullptr; // EPD framebuffer std::vector imageBuffer; // image in webserver transferbuffer String mimetype; + #ifndef DISPLAY_ST7796 + fb = getdisplay().getBuffer(); // available only for EPD + #endif + if (!fb) { + request->send(500, "text/plain", "screenshot not available"); + return; + } if (imgformat == "gif") { // GIF is commpressed with LZW, so small diff --git a/lib/obp60task/OBP60Extensions.h b/lib/obp60task/OBP60Extensions.h index 41e3717..47767f3 100644 --- a/lib/obp60task/OBP60Extensions.h +++ b/lib/obp60task/OBP60Extensions.h @@ -9,6 +9,10 @@ #include // I2C FRAM #include +#ifdef DISPLAY_ST7796 +#include // TFT LCD lib for ST7796 +#endif + #ifdef BOARD_OBP40S3 #include "esp_vfs_fat.h" #include "sdmmc_cmd.h" @@ -74,11 +78,124 @@ GxEPD2_BW & getdisplay(); GxEPD2_BW & getdisplay(); #endif +#ifdef DISPLAY_ST7796 +// LovyanGFX based display wrapper for ST7796 +class LGFX : public lgfx::LGFX_Device { +public: + lgfx::Bus_SPI _bus_instance; + lgfx::Light_PWM _light_instance; + + LGFX(void) { + { + auto cfg = _bus_instance.config(); + cfg.spi_host = SPI2_HOST; + cfg.spi_mode = 0; + cfg.freq_write = 80000000; + cfg.freq_read = 16000000; + cfg.pin_sclk = OBP_SPI_CLK; + cfg.pin_mosi = OBP_SPI_DIN; + cfg.pin_miso = -1; + cfg.pin_dc = OBP_SPI_DC; + _bus_instance.config(cfg); + _panel_instance.setBus(&_bus_instance); + } + { + auto cfg = _panel_instance.config(); + cfg.pin_cs = OBP_SPI_CS; + cfg.pin_rst = OBP_SPI_RST; + cfg.pin_busy = -1; + cfg.panel_width = 480; + cfg.panel_height = 320; + cfg.offset_x = 0; + cfg.offset_y = 0; + cfg.offset_rotation = 0; + cfg.dummy_read_pixel = 8; + cfg.dummy_read_bits = 1; + cfg.memory_width = 480; + cfg.memory_height = 320; + // cfg.pwm_control not available in this LovyanGFX version + cfg.invert = false; + cfg.rgb_order = false; + cfg.dlen_16bit = false; + cfg.bus_shared = true; + _panel_instance.config(cfg); + } + { + auto cfg = _light_instance.config(); + cfg.pin_bl = -1; + _light_instance.config(cfg); + _panel_instance.setLight(&_light_instance); + } + setPanel(&_panel_instance); + } + + // compatibility helpers -------------------------------------------------- + // Adafruit GFX fonts support: ignore on TFT, use base on E-Ink + void setFont(const GFXfont *font) { (void)font; } + // E-Ink interface compatibility + void setFullWindow() { /* no-op on TFT */ } + +private: + lgfx::Panel_ST7796 _panel_instance; +}; + +LGFX & getdisplay(); +#endif + // Page display return values #define PAGE_OK 0 // all ok, do nothing #define PAGE_UPDATE 1 // page wants display to update #define PAGE_HIBERNATE 2 // page wants displey to hibernate +// Display wrapper functions for E-Ink/TFT compatibility +inline void displayFirstPage() { + #ifdef DISPLAY_ST7796 + // TFT LCD doesn't need firstPage() + #else + getdisplay().firstPage(); + #endif +} + +inline void displayNextPage() { + #ifdef DISPLAY_ST7796 + // TFT LCD doesn't need nextPage() for refresh + #else + getdisplay().nextPage(); + #endif +} + +inline void displaySetPartialWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { + #ifdef DISPLAY_ST7796 + // TFT LCD doesn't use partial windows + (void)x; (void)y; (void)w; (void)h; + #else + getdisplay().setPartialWindow(x, y, w, h); + #endif +} + +inline void displaySetFullWindow() { + #ifdef DISPLAY_ST7796 + // TFT LCD doesn't need setFullWindow() + #else + getdisplay().setFullWindow(); + #endif +} + +// replacement for getTextBounds that works with both EPD and ST7796 +inline void displayGetTextBounds(const String &txt, int16_t x, int16_t y, + int16_t *x0, int16_t *y0, + uint16_t *w, uint16_t *h) { +#ifdef DISPLAY_ST7796 + // LovyanGFX doesn't expose getTextBounds; compute via helpers + *w = getdisplay().textWidth(txt); + *h = getdisplay().fontHeight(); + if (x0) *x0 = 0; + if (y0) *y0 = 0; +#else + getdisplay().getTextBounds(txt, x, y, x0, y0, w, h); +#endif +} + void fillPoly4(const std::vector& p4, uint16_t color); void drawPoly(const std::vector& points, uint16_t color); diff --git a/lib/obp60task/OBP60QRWiFi.h b/lib/obp60task/OBP60QRWiFi.h index d3f5248..d2139ed 100644 --- a/lib/obp60task/OBP60QRWiFi.h +++ b/lib/obp60task/OBP60QRWiFi.h @@ -39,7 +39,7 @@ void qrWiFi(String ssid, String passwd, uint16_t fgcolor, uint16_t bgcolor){ getdisplay().setTextColor(fgcolor); getdisplay().setCursor(140, 285); getdisplay().print("WiFi"); - getdisplay().nextPage(); // Full Refresh + displayNextPage(); // Full Refresh } #endif diff --git a/lib/obp60task/OBPcharts.cpp b/lib/obp60task/OBPcharts.cpp index 8ae38ec..b245972 100644 --- a/lib/obp60task/OBPcharts.cpp +++ b/lib/obp60task/OBPcharts.cpp @@ -28,8 +28,14 @@ Chart::Chart(RingBuffer& dataBuf, double dfltRng, CommonData& common, fgColor = commonData->fgcolor; bgColor = commonData->bgcolor; - dWidth = getdisplay().width(); - dHeight = getdisplay().height(); + // display dimensions (avoid calling width()/height() on incomplete LGFX type) + #ifdef DISPLAY_ST7796 + dWidth = 480; + dHeight = 320; + #else + dWidth = getdisplay().width(); + dHeight = getdisplay().height(); + #endif dataBuf.getMetaData(dbName, dbFormat); dbMIN_VAL = dataBuf.getMinVal(); diff --git a/lib/obp60task/PageAutopilot.cpp b/lib/obp60task/PageAutopilot.cpp index ecfc62e..b57c159 100644 --- a/lib/obp60task/PageAutopilot.cpp +++ b/lib/obp60task/PageAutopilot.cpp @@ -117,7 +117,7 @@ class PageAutopilot : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); /* // Horizontal line 2 pix top & bottom diff --git a/lib/obp60task/PageBME280.cpp b/lib/obp60task/PageBME280.cpp index 540d5c5..e54b629 100644 --- a/lib/obp60task/PageBME280.cpp +++ b/lib/obp60task/PageBME280.cpp @@ -105,7 +105,7 @@ class PageBME280 : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageBattery.cpp b/lib/obp60task/PageBattery.cpp index 463b848..e53f12f 100644 --- a/lib/obp60task/PageBattery.cpp +++ b/lib/obp60task/PageBattery.cpp @@ -158,7 +158,7 @@ class PageBattery : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // Show average settings getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageBattery2.cpp b/lib/obp60task/PageBattery2.cpp index b0b712b..05ae52e 100644 --- a/lib/obp60task/PageBattery2.cpp +++ b/lib/obp60task/PageBattery2.cpp @@ -184,7 +184,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageClock.cpp b/lib/obp60task/PageClock.cpp index 3c5a63f..4ff6783 100644 --- a/lib/obp60task/PageClock.cpp +++ b/lib/obp60task/PageClock.cpp @@ -375,7 +375,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); @@ -442,8 +442,8 @@ public: uint16_t wDigit, hDigit; uint16_t wColon, hColon; - getdisplay().getTextBounds("00", 0, 0, &x0, &y0, &wDigit, &hDigit); - getdisplay().getTextBounds(":", 0, 0, &x0, &y0, &wColon, &hColon); +displayGetTextBounds("00", 0, 0, &x0, &y0, &wDigit, &hDigit); +displayGetTextBounds(":", 0, 0, &x0, &y0, &wColon, &hColon); uint16_t totalWidth = 3 * wDigit + 2 * wColon; @@ -453,7 +453,7 @@ public: // Draw time string centered int16_t x1b, y1b; uint16_t wb, hb; - getdisplay().getTextBounds(timeStr, 0, 0, &x1b, &y1b, &wb, &hb); + displayGetTextBounds(timeStr, 0, 0, &x1b, &y1b, &wb, &hb); int16_t textX = (static_cast(getdisplay().width()) - static_cast(wb)) / 2; int16_t textY = centerY + hb / 2; @@ -520,7 +520,7 @@ public: int16_t x1b, y1b; uint16_t wb, hb; - getdisplay().getTextBounds(timeStr, 0, 0, &x1b, &y1b, &wb, &hb); + displayGetTextBounds(timeStr, 0, 0, &x1b, &y1b, &wb, &hb); int16_t x = (static_cast(getdisplay().width()) - static_cast(wb)) / 2; int16_t y = 150 + hb / 2; @@ -665,7 +665,7 @@ public: // Print text centered on position x, y int16_t x1c, y1c; // Return values of getTextBounds uint16_t wc, hc; // Return values of getTextBounds - getdisplay().getTextBounds(ii, int(x), int(y), &x1c, &y1c, &wc, &hc); // Calc width of new string + displayGetTextBounds(ii, int(x), int(y), &x1c, &y1c, &wc, &hc); // Calc width of new string getdisplay().setCursor(x - wc / 2, y + hc / 2); if (i % 90 == 0) { getdisplay().setFont(&Ubuntu_Bold12pt8b); diff --git a/lib/obp60task/PageCompass.cpp b/lib/obp60task/PageCompass.cpp index 12281e9..f5e14b5 100644 --- a/lib/obp60task/PageCompass.cpp +++ b/lib/obp60task/PageCompass.cpp @@ -109,7 +109,7 @@ class PageCompass : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); // Horizontal line 2 pix top & bottom diff --git a/lib/obp60task/PageDST810.cpp b/lib/obp60task/PageDST810.cpp index 2ac7494..93021c2 100644 --- a/lib/obp60task/PageDST810.cpp +++ b/lib/obp60task/PageDST810.cpp @@ -91,7 +91,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageDigitalOut.cpp b/lib/obp60task/PageDigitalOut.cpp index 464a069..1919785 100644 --- a/lib/obp60task/PageDigitalOut.cpp +++ b/lib/obp60task/PageDigitalOut.cpp @@ -106,7 +106,7 @@ bool button5 = false; //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); getdisplay().setFont(&Ubuntu_Bold12pt8b); // Write text diff --git a/lib/obp60task/PageFluid.cpp b/lib/obp60task/PageFluid.cpp index f844d87..f17038a 100644 --- a/lib/obp60task/PageFluid.cpp +++ b/lib/obp60task/PageFluid.cpp @@ -138,7 +138,7 @@ class PageFluid : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageFourValues.cpp b/lib/obp60task/PageFourValues.cpp index cb9de68..5797f55 100644 --- a/lib/obp60task/PageFourValues.cpp +++ b/lib/obp60task/PageFourValues.cpp @@ -91,7 +91,7 @@ class PageFourValues : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageFourValues2.cpp b/lib/obp60task/PageFourValues2.cpp index 730e14b..63b0045 100644 --- a/lib/obp60task/PageFourValues2.cpp +++ b/lib/obp60task/PageFourValues2.cpp @@ -91,7 +91,7 @@ class PageFourValues2 : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageGenerator.cpp b/lib/obp60task/PageGenerator.cpp index 201b647..05550cb 100644 --- a/lib/obp60task/PageGenerator.cpp +++ b/lib/obp60task/PageGenerator.cpp @@ -83,7 +83,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageKeelPosition.cpp b/lib/obp60task/PageKeelPosition.cpp index dd86611..ddb47aa 100644 --- a/lib/obp60task/PageKeelPosition.cpp +++ b/lib/obp60task/PageKeelPosition.cpp @@ -68,7 +68,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update //******************************************************************************************* @@ -105,7 +105,7 @@ public: // Print text centered on position x, y int16_t x1, y1; // Return values of getTextBounds uint16_t w, h; // Return values of getTextBounds - getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string + displayGetTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string getdisplay().setCursor(x-w/2, y+h/2); if(i % 30 == 0){ getdisplay().setFont(&Ubuntu_Bold8pt8b); diff --git a/lib/obp60task/PageNavigation.cpp b/lib/obp60task/PageNavigation.cpp index bd4adf1..92d6789 100644 --- a/lib/obp60task/PageNavigation.cpp +++ b/lib/obp60task/PageNavigation.cpp @@ -371,7 +371,7 @@ bool showValues = false; // Show values HDT, SOG, DBT in navigation map // ############### Draw Navigation Map ################ // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); // If a network connection to URL then load the navigation map diff --git a/lib/obp60task/PageOneValue.cpp b/lib/obp60task/PageOneValue.cpp index 78cc6e6..dd3eb1b 100644 --- a/lib/obp60task/PageOneValue.cpp +++ b/lib/obp60task/PageOneValue.cpp @@ -276,7 +276,7 @@ public: // Draw page //*********************************************************** - getdisplay().setPartialWindow(0, 0, width, height); // Set partial update + displaySetPartialWindow(0, 0, width, height); // Set partial update if (pageMode == VALUE || dataHstryBuf == nullptr) { // show only data value; ignore other pageMode options if no chart supported boat data history buffer is available diff --git a/lib/obp60task/PageRollPitch.cpp b/lib/obp60task/PageRollPitch.cpp index 3cc9277..59c79dc 100644 --- a/lib/obp60task/PageRollPitch.cpp +++ b/lib/obp60task/PageRollPitch.cpp @@ -116,7 +116,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); @@ -194,7 +194,7 @@ public: // Print text centered on position x, y int16_t x1, y1; // Return values of getTextBounds uint16_t w, h; // Return values of getTextBounds - getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string + displayGetTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string getdisplay().setCursor(x-w/2, y+h/2); if(i % 20 == 0){ getdisplay().setFont(&Ubuntu_Bold8pt8b); diff --git a/lib/obp60task/PageRudderPosition.cpp b/lib/obp60task/PageRudderPosition.cpp index 6a8695f..a09f4e6 100644 --- a/lib/obp60task/PageRudderPosition.cpp +++ b/lib/obp60task/PageRudderPosition.cpp @@ -72,7 +72,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update //******************************************************************************************* @@ -110,7 +110,7 @@ public: // Print text centered on position x, y int16_t x1, y1; // Return values of getTextBounds uint16_t w, h; // Return values of getTextBounds - getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string + displayGetTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string getdisplay().setCursor(x-w/2, y+h/2); if(i % 30 == 0){ getdisplay().setFont(&Ubuntu_Bold8pt8b); diff --git a/lib/obp60task/PageSixValues.cpp b/lib/obp60task/PageSixValues.cpp index b75f307..8d89167 100644 --- a/lib/obp60task/PageSixValues.cpp +++ b/lib/obp60task/PageSixValues.cpp @@ -75,7 +75,7 @@ class PageSixValues : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); for (int i = 0; i < ( HowManyValues / 2 ); i++){ diff --git a/lib/obp60task/PageSkyView.cpp b/lib/obp60task/PageSkyView.cpp index 9d80a85..a9bf8ef 100644 --- a/lib/obp60task/PageSkyView.cpp +++ b/lib/obp60task/PageSkyView.cpp @@ -73,7 +73,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // current position getdisplay().setFont(&Ubuntu_Bold8pt8b); @@ -105,19 +105,19 @@ public: uint16_t w, h; getdisplay().setFont(&Ubuntu_Bold12pt8b); - getdisplay().getTextBounds("N", 0, 150, &x1, &y1, &w, &h); + displayGetTextBounds("N", 0, 150, &x1, &y1, &w, &h); getdisplay().setCursor(c.x - w / 2, c.y - r + h + 3); getdisplay().print("N"); - getdisplay().getTextBounds("S", 0, 150, &x1, &y1, &w, &h); + displayGetTextBounds("S", 0, 150, &x1, &y1, &w, &h); getdisplay().setCursor(c.x - w / 2, c.y + r - 3); getdisplay().print("S"); - getdisplay().getTextBounds("E", 0, 150, &x1, &y1, &w, &h); + displayGetTextBounds("E", 0, 150, &x1, &y1, &w, &h); getdisplay().setCursor(c.x + r - w - 3, c.y + h / 2); getdisplay().print("E"); - getdisplay().getTextBounds("W", 0, 150, &x1, &y1, &w, &h); + displayGetTextBounds("W", 0, 150, &x1, &y1, &w, &h); getdisplay().setCursor(c.x - r + 3 , c.y + h / 2); getdisplay().print("W"); diff --git a/lib/obp60task/PageSolar.cpp b/lib/obp60task/PageSolar.cpp index 2a19bb9..e06b95e 100644 --- a/lib/obp60task/PageSolar.cpp +++ b/lib/obp60task/PageSolar.cpp @@ -82,7 +82,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageSystem.cpp b/lib/obp60task/PageSystem.cpp index a8b3ee4..223bf81 100644 --- a/lib/obp60task/PageSystem.cpp +++ b/lib/obp60task/PageSystem.cpp @@ -229,7 +229,7 @@ public: uint16_t y0 = 48; // data table starts here // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update if (mode == 'N') { @@ -550,7 +550,7 @@ public: } // Update display - getdisplay().nextPage(); // Partial update (fast) + displayNextPage(); // Partial update (fast) return PAGE_OK; }; }; diff --git a/lib/obp60task/PageThreeValues.cpp b/lib/obp60task/PageThreeValues.cpp index 7c5324f..404015b 100644 --- a/lib/obp60task/PageThreeValues.cpp +++ b/lib/obp60task/PageThreeValues.cpp @@ -80,7 +80,7 @@ class PageThreeValues : public Page //*********************************************************** /// Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // ############### Value 1 ################ diff --git a/lib/obp60task/PageTwoValues.cpp b/lib/obp60task/PageTwoValues.cpp index 5990656..4c10c00 100644 --- a/lib/obp60task/PageTwoValues.cpp +++ b/lib/obp60task/PageTwoValues.cpp @@ -283,7 +283,7 @@ public: // Draw page //*********************************************************** - getdisplay().setPartialWindow(0, 0, width, height); // Set partial update + displaySetPartialWindow(0, 0, width, height); // Set partial update if (pageMode == VALUES || (dataHstryBuf[0] == nullptr && dataHstryBuf[1] == nullptr)) { // show only data value; ignore other pageMode options if no chart supported boat data history buffer is available diff --git a/lib/obp60task/PageVoltage.cpp b/lib/obp60task/PageVoltage.cpp index 6681b5e..adf3d28 100644 --- a/lib/obp60task/PageVoltage.cpp +++ b/lib/obp60task/PageVoltage.cpp @@ -193,7 +193,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update if (mode == 'D') { // Display mode digital diff --git a/lib/obp60task/PageWhite.cpp b/lib/obp60task/PageWhite.cpp index 4791400..bfdb9d8 100644 --- a/lib/obp60task/PageWhite.cpp +++ b/lib/obp60task/PageWhite.cpp @@ -63,7 +63,7 @@ public: if (mode == 'W') { getdisplay().setFullWindow(); } else { - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update } if (mode == 'L') { diff --git a/lib/obp60task/PageWind.cpp b/lib/obp60task/PageWind.cpp index 242a365..084651b 100644 --- a/lib/obp60task/PageWind.cpp +++ b/lib/obp60task/PageWind.cpp @@ -358,7 +358,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); diff --git a/lib/obp60task/PageWindPlot.cpp b/lib/obp60task/PageWindPlot.cpp index da948c2..c9ff5d5 100644 --- a/lib/obp60task/PageWindPlot.cpp +++ b/lib/obp60task/PageWindPlot.cpp @@ -221,7 +221,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, width, height); // Set partial update + displaySetPartialWindow(0, 0, width, height); // Set partial update getdisplay().setTextColor(commonData->fgcolor); if (chrtMode == DIRECTION) { diff --git a/lib/obp60task/PageWindRose.cpp b/lib/obp60task/PageWindRose.cpp index 427e64b..75f9ab1 100644 --- a/lib/obp60task/PageWindRose.cpp +++ b/lib/obp60task/PageWindRose.cpp @@ -140,7 +140,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); @@ -260,7 +260,7 @@ public: // Print text centered on position x, y int16_t x1, y1; // Return values of getTextBounds uint16_t w, h; // Return values of getTextBounds - getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string + displayGetTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string getdisplay().setCursor(x-w/2, y+h/2); if(i % 30 == 0){ getdisplay().setFont(&Ubuntu_Bold8pt8b); diff --git a/lib/obp60task/PageWindRoseFlex.cpp b/lib/obp60task/PageWindRoseFlex.cpp index d3526e0..2b71328 100644 --- a/lib/obp60task/PageWindRoseFlex.cpp +++ b/lib/obp60task/PageWindRoseFlex.cpp @@ -200,7 +200,7 @@ public: //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); @@ -314,7 +314,7 @@ public: // Print text centered on position x, y int16_t x1, y1; // Return values of getTextBounds uint16_t w, h; // Return values of getTextBounds - getdisplay().getTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string + displayGetTextBounds(ii, int(x), int(y), &x1, &y1, &w, &h); // Calc width of new string getdisplay().setCursor(x-w/2, y+h/2); if(i % 30 == 0){ getdisplay().setFont(&Ubuntu_Bold8pt8b); diff --git a/lib/obp60task/PageXTETrack.cpp b/lib/obp60task/PageXTETrack.cpp index 0b513df..ce404a9 100644 --- a/lib/obp60task/PageXTETrack.cpp +++ b/lib/obp60task/PageXTETrack.cpp @@ -89,7 +89,7 @@ class PageXTETrack : public Page //*********************************************************** // Set display in partial refresh mode - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().setTextColor(commonData->fgcolor); @@ -112,25 +112,25 @@ class PageXTETrack : public Page GwApi::BoatValue *bv_xte = pageData.values[0]; // XTE String sval_xte = formatValue(bv_xte, *commonData).svalue; - getdisplay().getTextBounds(sval_xte, 0, 0, &x, &y, &w, &h); + displayGetTextBounds(sval_xte, 0, 0, &x, &y, &w, &h); getdisplay().setCursor(160-w, 170); getdisplay().print(sval_xte); GwApi::BoatValue *bv_cog = pageData.values[1]; // COG String sval_cog = formatValue(bv_cog, *commonData).svalue; - getdisplay().getTextBounds(sval_cog, 0, 0, &x, &y, &w, &h); + displayGetTextBounds(sval_cog, 0, 0, &x, &y, &w, &h); getdisplay().setCursor(360-w, 170); getdisplay().print(sval_cog); GwApi::BoatValue *bv_dtw = pageData.values[2]; // DTW String sval_dtw = formatValue(bv_dtw, *commonData).svalue; - getdisplay().getTextBounds(sval_dtw, 0, 0, &x, &y, &w, &h); + displayGetTextBounds(sval_dtw, 0, 0, &x, &y, &w, &h); getdisplay().setCursor(160-w, 257); getdisplay().print(sval_dtw); GwApi::BoatValue *bv_btw = pageData.values[3]; // BTW String sval_btw = formatValue(bv_btw, *commonData).svalue; - getdisplay().getTextBounds(sval_btw, 0, 0, &x, &y, &w, &h); + displayGetTextBounds(sval_btw, 0, 0, &x, &y, &w, &h); getdisplay().setCursor(360-w, 257); getdisplay().print(sval_btw); @@ -149,7 +149,7 @@ class PageXTETrack : public Page } getdisplay().setFont(&Ubuntu_Bold10pt8b); - getdisplay().getTextBounds(sval_wpname, 0, 150, &x, &y, &w, &h); + displayGetTextBounds(sval_wpname, 0, 150, &x, &y, &w, &h); // TODO if text don't fix use smaller font size. // if smallest size does not fit use 2 lines // last resort: clip with ellipsis diff --git a/lib/obp60task/obp60task.cpp b/lib/obp60task/obp60task.cpp index 84bc572..93fbf9b 100644 --- a/lib/obp60task/obp60task.cpp +++ b/lib/obp60task/obp60task.cpp @@ -284,8 +284,10 @@ void underVoltageError(CommonData &common) { getdisplay().setFont(&Ubuntu_Bold8pt8b); getdisplay().setCursor(65, 175); getdisplay().print("Charge battery and restart system"); - getdisplay().nextPage(); // Partial update + displayNextPage(); // Partial update + #ifndef DISPLAY_ST7796 getdisplay().powerOff(); // Display power off + #endif setPortPin(OBP_POWER_EPD, false); // Power off ePaper display setPortPin(OBP_POWER_SD, false); // Power off SD card #else @@ -295,7 +297,7 @@ void underVoltageError(CommonData &common) { buzzer(TONE4, 20); // Buzzer tone 4kHz 20ms setPortPin(OBP_POWER_50, false); // Power rail 5.0V Off // Shutdown EInk display - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().fillScreen(common.bgcolor);// Clear screen getdisplay().setTextColor(common.fgcolor); getdisplay().setFont(&Ubuntu_Bold20pt8b); @@ -304,8 +306,10 @@ void underVoltageError(CommonData &common) { getdisplay().setFont(&Ubuntu_Bold8pt8b); getdisplay().setCursor(65, 175); getdisplay().print("To wake up repower system"); - getdisplay().nextPage(); // Partial update + displayNextPage(); // Partial update + #ifndef DISPLAY_ST7796 getdisplay().powerOff(); // Display power off + #endif #endif while (true) { esp_deep_sleep_start(); // Deep Sleep without wakeup. Wakeup only after power cycle (restart). @@ -375,36 +379,38 @@ void OBP60Task(GwApi *api){ #ifdef DISPLAY_GDEY042T81 getdisplay().init(115200, true, 2, false); // Init for Waveshare boards with "clever" reset circuit, 2ms reset pulse + #elif defined DISPLAY_ST7796 + getdisplay().init(); // Init for ST7796 TFT LCD #else getdisplay().init(115200); // Init for normal displays #endif getdisplay().setRotation(0); // Set display orientation (horizontal) - getdisplay().setFullWindow(); // Set full Refresh - getdisplay().firstPage(); // set first page + displaySetFullWindow(); // Set full Refresh (E-Ink only) + displayFirstPage(); // set first page getdisplay().fillScreen(commonData.bgcolor); getdisplay().setTextColor(commonData.fgcolor); - getdisplay().nextPage(); // Full Refresh - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displayNextPage(); // Full Refresh + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update (E-Ink only) getdisplay().fillScreen(commonData.bgcolor); - getdisplay().nextPage(); // Fast Refresh - getdisplay().nextPage(); // Fast Refresh + displayNextPage(); // Fast Refresh + displayNextPage(); // Fast Refresh if(String(displaymode) == "Logo + QR Code" || String(displaymode) == "Logo"){ getdisplay().fillScreen(commonData.bgcolor); getdisplay().drawBitmap(0, 0, gImage_Logo_OBP_400x300_sw, getdisplay().width(), getdisplay().height(), commonData.fgcolor); // Draw start logo - getdisplay().nextPage(); // Fast Refresh - getdisplay().nextPage(); // Fast Refresh + displayNextPage(); // Fast Refresh + displayNextPage(); // Fast Refresh delay(SHOW_TIME); // Logo show time if(String(displaymode) == "Logo + QR Code"){ getdisplay().fillScreen(commonData.bgcolor); qrWiFi(systemname, wifipass, commonData.fgcolor, commonData.bgcolor); // Show QR code for WiFi connection - getdisplay().nextPage(); // Fast Refresh - getdisplay().nextPage(); // Fast Refresh + displayNextPage(); // Fast Refresh + displayNextPage(); // Fast Refresh delay(SHOW_TIME); // QR code show time } getdisplay().fillScreen(commonData.bgcolor); - getdisplay().nextPage(); // Fast Refresh - getdisplay().nextPage(); // Fast Refresh + displayNextPage(); // Fast Refresh + displayNextPage(); // Fast Refresh } // Init pages @@ -722,9 +728,12 @@ void OBP60Task(GwApi *api){ if(millis() > starttime4 + 8000 && delayedDisplayUpdate == true){ starttime1 = millis(); starttime2 = millis(); - getdisplay().setFullWindow(); // Set full update + displaySetFullWindow(); // Set full update + #ifdef DISPLAY_ST7796 + // TFT LCD doesn't need refresh operations + #else if(fastrefresh == "true"){ - getdisplay().nextPage(); // Full update + displayNextPage(); // Full update } else{ getdisplay().fillScreen(commonData.fgcolor); // Clear display @@ -734,13 +743,14 @@ void OBP60Task(GwApi *api){ #else getdisplay().init(115200); // Init for normal displays #endif - getdisplay().firstPage(); // Full update - getdisplay().nextPage(); // Full update + displayFirstPage(); // Full update + displayNextPage(); // Full update // getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // getdisplay().fillScreen(commonData.bgcolor); // Clear display // getdisplay().nextPage(); // Partial update // getdisplay().nextPage(); // Partial update } + #endif delayedDisplayUpdate = false; } @@ -750,9 +760,12 @@ void OBP60Task(GwApi *api){ starttime1 = millis(); starttime2 = millis(); LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh first 5 min"); - getdisplay().setFullWindow(); // Set full update + displaySetFullWindow(); // Set full update + #ifdef DISPLAY_ST7796 + // TFT LCD doesn't need refresh operations + #else if(fastrefresh == "true"){ - getdisplay().nextPage(); // Full update + displayNextPage(); // Full update } else{ getdisplay().fillScreen(commonData.fgcolor); // Clear display @@ -762,19 +775,23 @@ void OBP60Task(GwApi *api){ #else getdisplay().init(115200); // Init for normal displays #endif - getdisplay().firstPage(); // Full update - getdisplay().nextPage(); // Full update + displayFirstPage(); // Full update + displayNextPage(); // Full update // getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update // getdisplay().fillScreen(commonData.bgcolor); // Clear display // getdisplay().nextPage(); // Partial update // getdisplay().nextPage(); // Partial update } + #endif } // Subtask E-Ink full refresh if(millis() > starttime2 + fullrefreshtime * 60 * 1000){ starttime2 = millis(); LOG_DEBUG(GwLog::DEBUG,"E-Ink full refresh"); + #ifdef DISPLAY_ST7796 + // TFT LCD: no special refresh + #else getdisplay().setFullWindow(); // Set full update if(fastrefresh == "true"){ getdisplay().nextPage(); // Full update @@ -794,6 +811,7 @@ void OBP60Task(GwApi *api){ // getdisplay().nextPage(); // Partial update // getdisplay().nextPage(); // Partial update } + #endif } // Refresh display data, default all 1s @@ -842,13 +860,13 @@ void OBP60Task(GwApi *api){ if (currentPage == NULL){ LOG_DEBUG(GwLog::ERROR,"page number %d not found", pageNumber); // Error handling for missing page - getdisplay().setPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update + displaySetPartialWindow(0, 0, getdisplay().width(), getdisplay().height()); // Set partial update getdisplay().fillScreen(commonData.bgcolor); // Clear display getdisplay().drawXBitmap(200 - unknown_width / 2, 150 - unknown_height / 2, unknown_bits, unknown_width, unknown_height, commonData.fgcolor); getdisplay().setCursor(140, 250); getdisplay().setFont(&Atari16px); getdisplay().print("Here be dragons!"); - getdisplay().nextPage(); // Partial update (fast) + displayNextPage(); // Partial update (fast) } else{ if (lastPage != pageNumber){ @@ -871,10 +889,12 @@ void OBP60Task(GwApi *api){ displayAlarm(commonData); } if (ret & PAGE_UPDATE) { - getdisplay().nextPage(); // Partial update (fast) + displayNextPage(); // Partial update (fast) } if (ret & PAGE_HIBERNATE) { + #ifndef DISPLAY_ST7796 getdisplay().hibernate(); + #endif } } diff --git a/lib/obp60task/platformio.ini b/lib/obp60task/platformio.ini index 03a5463..970869f 100644 --- a/lib/obp60task/platformio.ini +++ b/lib/obp60task/platformio.ini @@ -45,6 +45,7 @@ lib_deps = milesburton/DallasTemperature@3.11.0 signetica/SunRise@2.0.2 adafruit/Adafruit FRAM I2C@2.0.3 + lovyan03/LovyanGFX@^1.2.19 build_flags= #https://thingpulse.com/usb-settings-for-logging-with-the-esp32-s3-in-platformio/?srsltid=AfmBOopGskbkr4GoeVkNlFaZXe_zXkLceKF6Rn-tmoXABCeAR2vWsdHL # -D CORE_DEBUG_LEVEL=1 #Debug level for CPU core via CDC (serial device) @@ -54,9 +55,10 @@ build_flags= # -D HARDWARE_V20 #OBP60 hardware revision V2.0 -D HARDWARE_V21 #OBP60 hardware revision V2.1 # -D DISPLAY_GDEW042T2 #old E-Ink display from GoodDisplay (Waveshare), R10 0.47 ohm - very good - -D DISPLAY_GDEY042T81 #new E-Ink display from GoodDisplay (Waveshare), R10 2.2 ohm - good (contast lost by shunshine) +# -D DISPLAY_GDEY042T81 #new E-Ink display from GoodDisplay (Waveshare), R10 2.2 ohm - good (contast lost by shunshine) # -D DISPLAY_GYE042A87 #alternativ E-Ink display from Genyo Optical, R10 2.2 ohm - medium # -D DISPLAY_SE0420NQ04 #alternativ E-Ink display from SID Technology, R10 2.2 ohm - bad (burn in effects) + -D DISPLAY_ST7796 #ST7796 TFT LCD display (480x320 color display) # -D DISPLAY_ZJY400300-042CAAMFGN #alternativ E-Ink display from ZZE Technology, R10 2.2 ohm - very good # -D ENABLE_PATCHES #enable patching of gateway code ${env.build_flags} @@ -101,11 +103,13 @@ lib_deps = milesburton/DallasTemperature@3.11.0 signetica/SunRise@2.0.2 adafruit/Adafruit FRAM I2C@2.0.3 + lovyan03/LovyanGFX@^1.2.19 build_flags= -D DISABLE_DIAGNOSTIC_OUTPUT #Disable diagnostic output for GxEPD2 lib -D BOARD_OBP40S3 #Board OBP40 with ESP32S3 -D HARDWARE_V10 #OBP40 hardware revision V1.0 SKU:DIE07300S V1.1 (CrowPanel 4.2) - -D DISPLAY_GDEY042T81 #new E-Ink display from Good Display (Waveshare), R10 2.2 ohm - good (contast lost by shunshine) +# -D DISPLAY_GDEY042T81 #new E-Ink display from Good Display (Waveshare), R10 2.2 ohm - good (contast lost by shunshine) + -D DISPLAY_ST7796 #ST7796 TFT LCD display (480x320 color display) #-D DISPLAY_ZJY400300-042CAAMFGN #alternativ E-Ink display from ZZE Technology, R10 2.2 ohm - very good -D LIPO_ACCU_1200 #Hardware extension, LiPo accu 3,7V 1200mAh -D VOLTAGE_SENSOR #Hardware extension, LiPo voltage sensor with two resistors