From 1dc66037ad61908bd70ecb54b825c9a7660c0196 Mon Sep 17 00:00:00 2001 From: Stephan Enderlein Date: Sat, 15 Jul 2023 20:53:15 +0200 Subject: [PATCH] -add mono display "Wemos OLED shield 64x48" - remove senseless "display type" check (copy&paste from first display) - reorder displays --- src/.vscode/settings.json | 5 +- src/plugins/Display/Display.h | 11 +- src/plugins/Display/Display_Mono_128X32.h | 2 - src/plugins/Display/Display_Mono_128X64.h | 5 +- src/plugins/Display/Display_Mono_64X48.h | 131 ++++++++++++++++++++++ src/plugins/Display/Display_Mono_84X48.h | 9 +- src/web/html/setup.html | 2 +- 7 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 src/plugins/Display/Display_Mono_64X48.h diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json index 58a2c3c7..e61851fb 100644 --- a/src/.vscode/settings.json +++ b/src/.vscode/settings.json @@ -8,7 +8,7 @@ "files.eol": "\n", "files.trimTrailingWhitespace": true, "diffEditor.ignoreTrimWhitespace": true, - "files.autoSave": "afterDelay", + "files.autoSave": "off", "editor.tabSize": 4, "editor.insertSpaces": true, // `editor.tabSize` and `editor.insertSpaces` will be detected based on the file contents. @@ -79,7 +79,8 @@ "mutex": "cpp", "ranges": "cpp", "stop_token": "cpp", - "thread": "cpp" + "thread": "cpp", + "variant": "cpp" }, "cmake.configureOnOpen": false, "editor.formatOnSave": false, diff --git a/src/plugins/Display/Display.h b/src/plugins/Display/Display.h index ba187c7d..fee4e35e 100644 --- a/src/plugins/Display/Display.h +++ b/src/plugins/Display/Display.h @@ -10,6 +10,7 @@ #include "Display_Mono_128X32.h" #include "Display_Mono_128X64.h" #include "Display_Mono_84X48.h" +#include "Display_Mono_64X48.h" #include "Display_ePaper.h" template @@ -30,9 +31,8 @@ class Display { if ((0 < mCfg->type) && (mCfg->type < 10)) { switch (mCfg->type) { + case 1: // fall-through case 2: - case 1: - default: mMono = new DisplayMono128X64(); break; case 3: @@ -41,6 +41,13 @@ class Display { case 4: mMono = new DisplayMono128X32(); break; + case 5: + mMono = new DisplayMono64X48(); + break; + + default: + mMono = new DisplayMono128X64(); + break; } mMono->config(mCfg->pwrSaveAtIvOffline, mCfg->pxShift, mCfg->contrast); mMono->init(mCfg->type, mCfg->rot, mCfg->disp_cs, mCfg->disp_dc, 0xff, mCfg->disp_clk, mCfg->disp_data, mUtcTs, mVersion); diff --git a/src/plugins/Display/Display_Mono_128X32.h b/src/plugins/Display/Display_Mono_128X32.h index 9d5ade7e..e9e09d28 100644 --- a/src/plugins/Display/Display_Mono_128X32.h +++ b/src/plugins/Display/Display_Mono_128X32.h @@ -21,8 +21,6 @@ class DisplayMono128X32 : public DisplayMono { void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char *version) { - if((0 == type) || (type > 4)) - return; u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0); mType = type; diff --git a/src/plugins/Display/Display_Mono_128X64.h b/src/plugins/Display/Display_Mono_128X64.h index 3d4f91ee..a828816c 100644 --- a/src/plugins/Display/Display_Mono_128X64.h +++ b/src/plugins/Display/Display_Mono_128X64.h @@ -19,8 +19,6 @@ class DisplayMono128X64 : public DisplayMono { } void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char *version) { - if((0 == type) || (type > 4)) - return; u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0); mType = type; @@ -65,8 +63,7 @@ class DisplayMono128X64 : public DisplayMono { mDisplay->clearBuffer(); // set Contrast of the Display to raise the lifetime - if (3 != mType) - mDisplay->setContrast(mLuminance); + mDisplay->setContrast(mLuminance); if ((totalPower > 0) && (isprod > 0)) { mTimeout = DISP_DEFAULT_TIMEOUT; diff --git a/src/plugins/Display/Display_Mono_64X48.h b/src/plugins/Display/Display_Mono_64X48.h new file mode 100644 index 00000000..5c3a95f4 --- /dev/null +++ b/src/plugins/Display/Display_Mono_64X48.h @@ -0,0 +1,131 @@ +//----------------------------------------------------------------------------- +// 2023 Ahoy, https://ahoydtu.de +// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed +//----------------------------------------------------------------------------- + +#pragma once +#include "Display_Mono.h" + +class DisplayMono64X48 : public DisplayMono { + public: + DisplayMono64X48() : DisplayMono() { + mEnPowerSafe = true; + mEnScreenSaver = true; + mLuminance = 50; + mExtra = 0; + mDispY = 0; + mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds) + mUtcTs = NULL; + mType = 0; + } + + void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char *version) { + + u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0); + mType = type; + + // Wemos OLed Shield is not defined in u8 lib -> use nearest compatible + mDisplay = new U8G2_SSD1306_64X48_ER_F_HW_I2C(rot, reset, clock, data); + + mUtcTs = utcTs; + + mDisplay->begin(); + calcLinePositions(); + + mDisplay->clearBuffer(); + mDisplay->setContrast(mLuminance); + + printText("AHOY!", 0); + printText("ahoydtu.de", 2); + printText(version, 3); + mDisplay->sendBuffer(); + } + + void config(bool enPowerSafe, bool enScreenSaver, uint8_t lum) { + mEnPowerSafe = enPowerSafe; + mEnScreenSaver = enScreenSaver; + mLuminance = lum; + } + + void loop(void) { + if (mEnPowerSafe) { + if (mTimeout != 0) + mTimeout--; + } + } + + void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { + mDisplay->clearBuffer(); + + // set Contrast of the Display to raise the lifetime + mDisplay->setContrast(mLuminance); + + if ((totalPower > 0) && (isprod > 0)) { + mTimeout = DISP_DEFAULT_TIMEOUT; + mDisplay->setPowerSave(false); + + if (totalPower > 999) + snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%2.2f kW", (totalPower / 1000)); + else + snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%3.0f W", totalPower); + + printText(mFmtText, 0); + } else { + printText("offline", 0); + // check if it's time to enter power saving mode + if (mTimeout == 0) + mDisplay->setPowerSave(mEnPowerSafe); + } + + snprintf(mFmtText, DISP_FMT_TEXT_LEN, "today: %4.0f Wh", totalYieldDay); + printText(mFmtText, 1); + + snprintf(mFmtText, DISP_FMT_TEXT_LEN, "total: %.1f kWh", totalYieldTotal); + printText(mFmtText, 2); + + IPAddress ip = WiFi.localIP(); + if (!(mExtra % 10) && (ip)) + printText(ip.toString().c_str(), 3); + else if (!(mExtra % 5)) { + snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%d Inverter on", isprod); + printText(mFmtText, 3); + } else if (NULL != mUtcTs) + printText(ah::getTimeStr(gTimezone.toLocal(*mUtcTs)).c_str(), 3); + + mDisplay->sendBuffer(); + + mExtra = 1; + } + + private: + void calcLinePositions() { + uint8_t yOff = 0; + for (uint8_t i = 0; i < 4; i++) { + setFont(i); + yOff += (mDisplay->getMaxCharHeight()); + mLineYOffsets[i] = yOff; + } + } + + inline void setFont(uint8_t line) { + switch (line) { + case 0: + mDisplay->setFont(u8g2_font_logisoso16_tr); + break; + case 3: + mDisplay->setFont(u8g2_font_5x8_tr); + break; + default: + mDisplay->setFont(u8g2_font_5x8_tr); + break; + } + } + + void printText(const char *text, uint8_t line) { + uint8_t dispX = (line == 0) ? 10 : 5; + setFont(line); + + dispX += (mEnScreenSaver) ? (mExtra % 7) : 0; + mDisplay->drawStr(dispX, mLineYOffsets[line], text); + } +}; diff --git a/src/plugins/Display/Display_Mono_84X48.h b/src/plugins/Display/Display_Mono_84X48.h index 82aa83fa..e527ec23 100644 --- a/src/plugins/Display/Display_Mono_84X48.h +++ b/src/plugins/Display/Display_Mono_84X48.h @@ -20,8 +20,6 @@ class DisplayMono84X48 : public DisplayMono { } void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char *version) { - if((0 == type) || (type > 4)) - return; u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0); mType = type; @@ -33,8 +31,8 @@ class DisplayMono84X48 : public DisplayMono { calcLinePositions(); mDisplay->clearBuffer(); - if (3 != mType) - mDisplay->setContrast(mLuminance); + mDisplay->setContrast(mLuminance); + printText("AHOY!", 0); printText("ahoydtu.de", 2); printText(version, 3); @@ -58,8 +56,7 @@ class DisplayMono84X48 : public DisplayMono { mDisplay->clearBuffer(); // set Contrast of the Display to raise the lifetime - if (3 != mType) - mDisplay->setContrast(mLuminance); + mDisplay->setContrast(mLuminance); if ((totalPower > 0) && (isprod > 0)) { mTimeout = DISP_DEFAULT_TIMEOUT; diff --git a/src/web/html/setup.html b/src/web/html/setup.html index c0f7cf83..a57b9e83 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -805,7 +805,7 @@ ); } - var opts = [[0, "None"], [1, "SSD1306 0.96\" 128X64"], [2, "SH1106 1.3\""], [3, "Nokia5110"], [4, "SSD1306 0.91\" 128X32"]]; + var opts = [[0, "None"], [5, "SSD1306 0.66\" 64X48"], [4, "SSD1306 0.91\" 128X32"], [1, "SSD1306 0.96\" 128X64"], [2, "SH1106 1.3\""], [3, "Nokia5110"]]; if("ESP32" == type) opts.push([10, "ePaper"]); var dispType = sel("disp_typ", opts, obj["disp_typ"]);