Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement GxEPD2Out.h library to adapt menu with EPD2 displays #225

Open
wants to merge 3 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions CO2_Gadget_EINK.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ const GFXfont BigFont = NotoSans_Bold46pt7b;
int displayWidth = 250;
int displayHeight = 122;
uint16_t resetDuration = 2;
GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> display(GxEPD2_213_BN(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // DEPG0213BN https://s.click.aliexpress.com/e/_DDFb2gl
#define GxEPD2_DRIVER GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT>
GxEPD2_DRIVER display(GxEPD2_213_BN(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // DEPG0213BN https://s.click.aliexpress.com/e/_DDFb2gl
#endif
#ifdef EINKBOARDGDEM0213B74
#include <NotoSans_Bold46pt7b.h>
Expand All @@ -50,7 +51,8 @@ const GFXfont BigFont = NotoSans_Bold46pt7b;
int displayWidth = 250;
int displayHeight = 122;
uint16_t resetDuration = 2;
GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> display(GxEPD2_213_B74(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEM0213B74 https://s.click.aliexpress.com/e/_DDFb2gl
#define GxEPD2_DRIVER GxEPD2_BW<GxEPD2_213_B74, GxEPD2_213_B74::HEIGHT> // Ajusta esto a tu pantalla
GxEPD2_DRIVER display(GxEPD2_213_B74(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEM0213B74 https://s.click.aliexpress.com/e/_DDFb2gl
#endif
#ifdef EINKBOARDGDEW0213M21
#include <NotoSans_Bold38pt7b.h>
Expand All @@ -62,7 +64,8 @@ int displayHeight = 104;
uint16_t resetDuration = 2;
// GxEPD2_BW<GxEPD2_213_flex, GxEPD2_213_flex ::HEIGHT> display(GxEPD2_213_flex(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));
// GxEPD2_BW<GxEPD2_213_T5D, GxEPD2_213_T5D ::HEIGHT> display(GxEPD2_213_T5D(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY));
GxEPD2_BW<GxEPD2_213_M21, GxEPD2_213_M21 ::HEIGHT> display(GxEPD2_213_M21(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEW0213M21 104x212, SSD1608 (GDEW0213Z16LW) https://s.click.aliexpress.com/e/_DDFb2gl
#define GxEPD2_DRIVER GxEPD2_BW<GxEPD2_213_M21, GxEPD2_213_M21 ::HEIGHT>
GxEPD2_DRIVER display(GxEPD2_213_M21(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEW0213M21 104x212, SSD1608 (GDEW0213Z16LW) https://s.click.aliexpress.com/e/_DDFb2gl
#endif
#endif

Expand All @@ -85,7 +88,8 @@ uint16_t resetDuration = 2;
// #define EPD_DC 27
// #define EPD_RST 25
// #define EPD_BUSY 32
GxEPD2_BW<GxEPD2_290_T94, GxEPD2_290_T94::HEIGHT> display(GxEPD2_290_T94(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEM029T94
#define GxEPD2_DRIVER GxEPD2_BW<GxEPD2_290_T94, GxEPD2_290_T94::HEIGHT>
GxEPD2_DRIVER display(GxEPD2_290_T94(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEM029T94
// GxEPD2_BW<GxEPD2_290_T94_V2, GxEPD2_290_T94_V2::HEIGHT> display(GxEPD2_290_T94_V2(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEM029T94 V2 GDEM029T94 128x296, SSD1680, (FPC-7519 rev.b), Waveshare 2.9" V2 variant
// GxEPD2_BW<GxEPD2_290_BS, GxEPD2_290_BS::HEIGHT> display(GxEPD2_290_BS(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEM029T94 BS
// GxEPD2_BW<GxEPD2_290_GDEY029T94, GxEPD2_290_GDEY029T94::HEIGHT> display(GxEPD2_290_GDEY029T94(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEY029T94 128x296, SSD1680, (FPC-A005 20.06.15)
Expand All @@ -105,7 +109,8 @@ uint16_t resetDuration = 50;
#include "bootlogo.h" // Made with https://javl.github.io/image2cpp/
#include "icons.h"

GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT> display(GxEPD2_213_BN(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // DEPG0213BN https://s.click.aliexpress.com/e/_DDvVZ4N
#define GxEPD2_DRIVER GxEPD2_BW<GxEPD2_213_BN, GxEPD2_213_BN::HEIGHT>
GxEPD2_DRIVER display(GxEPD2_213_BN(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // DEPG0213BN https://s.click.aliexpress.com/e/_DDvVZ4N
#endif

#ifdef EINKBOARD_WEACT_GDEH0154D67
Expand All @@ -120,7 +125,8 @@ uint16_t resetDuration = 50;
#include "bootlogo.h" // Made with https://javl.github.io/image2cpp/
#include "icons.h"

GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT> display(GxEPD2_154_D67(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEH0154D67 200x200, SSD1681 https://s.click.aliexpress.com/e/_DDvVZ4N
#define GxEPD2_DRIVER GxEPD2_BW<GxEPD2_154_D67, GxEPD2_154_D67::HEIGHT>
GxEPD2_DRIVER display(GxEPD2_154_D67(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEH0154D67 200x200, SSD1681 https://s.click.aliexpress.com/e/_DDvVZ4N
#endif

#ifdef EINKBOARD_WEACT_GxEPD2_290_BS
Expand All @@ -135,7 +141,8 @@ uint16_t resetDuration = 50;
#include "bootlogo.h" // Made with https://javl.github.io/image2cpp/
#include "icons.h"

GxEPD2_BW<GxEPD2_290_BS, GxEPD2_290_BS::HEIGHT> display(GxEPD2_290_BS(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEM029C90 As WeAct Studio 2.9" 296x128 E-Ink Display
#define GxEPD2_DRIVER GxEPD2_BW<GxEPD2_290_BS, GxEPD2_290_BS::HEIGHT>
GxEPD2_DRIVER display(GxEPD2_290_BS(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // GDEM029C90 As WeAct Studio 2.9" 296x128 E-Ink Display
#endif

// Define a structure for the locations of elements
Expand Down
40 changes: 37 additions & 3 deletions CO2_Gadget_Menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#include <menuIO/TFT_eSPIOut.h>
#endif

#ifdef SUPPORT_EINK
#include <GxEPD2Out.h>
#endif

#ifdef SUPPORT_OLED
#include <menuIO/chainStream.h>
#include <menuIO/u8g2Out.h>
Expand Down Expand Up @@ -954,7 +958,36 @@ menuOut* outputs[]{&outSerial,&oledOut};//list of output devices
MENU_INPUTS(in,&serial);
#endif // SUPPORT_OLED

#if (!SUPPORT_OLED && !SUPPORT_TFT)
#ifdef SUPPORT_EINK
// define menu colors --------------------------------------------------------
const colorDef<uint8_t> colors[6] MEMMODE = {
// {{disabled normal, disabled selected}, {enabled normal, enabled selected, enabled editing}}
{{0, 1}, {1, 0, 0}}, // bgColor
{{1, 0}, {0, 1, 1}}, // fgColor
{{1, 0}, {0, 1, 1}}, // valColor
{{1, 0}, {0, 1, 1}}, // unitColor
{{0, 1}, {0, 0, 0}}, // cursorColor
{{1, 0}, {1, 0, 0}}, // titleColor
};

#define fontW 10
#define fontH 20
#define offsetX 1
#define offsetY -2
#define fontMarginX 2
#define fontMarginY 2

//define output device oled
idx_t gfx_tops[MAX_DEPTH];
PANELS(gfxPanels,{0, 0, displayWidth/fontW,displayHeight/fontH});
// Crear la instancia de salida para GxEPD2
Menu::GxEPD2Out<GxEPD2_DRIVER> displayOut(display, colors, gfx_tops, gfxPanels, fontW, fontH, offsetX, offsetY, fontMarginX, fontMarginY);

//define outputs controller
menuOut* outputs[]{&outSerial,&displayOut};//list of output devices
#endif // SUPPORT_EINK

#if (!SUPPORT_OLED && !SUPPORT_TFT && !SUPPORT_EINK)
menuOut* outputs[]{&outSerial};//No display, only serial output
#endif

Expand Down Expand Up @@ -1033,15 +1066,15 @@ result idle(menuOut &o, idleEvent e) {
setInMenu(false);
// nav.poll();

#if defined(SUPPORT_TFT) || defined(SUPPORT_OLED)
#if defined(SUPPORT_TFT) || defined(SUPPORT_OLED) || defined(SUPPORT_EINK)
displayShowValues(true);
#endif
break;
case idling:
#ifdef DEBUG_ARDUINOMENU
Serial.println("-->[MENU] Event iddling");
#endif
#if defined(SUPPORT_TFT) || defined(SUPPORT_OLED)
#if defined(SUPPORT_TFT) || defined(SUPPORT_OLED) || defined(SUPPORT_EINK)
displayShowValues(shouldRedrawDisplay);
shouldRedrawDisplay = false;
#endif
Expand Down Expand Up @@ -1113,6 +1146,7 @@ void menuLoopEINK() {
} else {
if (nav.changed(0)) {
nav.doOutput();
display.displayWindow(0, 0, display.width(), display.height()); // Refresh screen in partial mode
}
}
#endif
Expand Down
122 changes: 122 additions & 0 deletions GxEPD2Out.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/********************
May. 2024 Sergio Coscolín https://github.com/Coscolin
with special help from ChatGPT 4o

Based on U8GLibOut.h from Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
and TFT_eSPIOut.H from https://github.com/fa1ke5 (Jan. 2019)
Original from: https://github.com/christophepersoz

Adaptaded for GxEPD2 displays use
***/
#ifndef RSITE_ARDUINOP_MENU_GXEPD2
#define RSITE_ARDUINOP_MENU_GXEPD2
#include <GxEPD2.h>

#include "menuDefs.h"

namespace Menu {

template <typename GxEPD2_Type>
class GxEPD2Out : public gfxOut {
public:
int8_t offsetX = 0;
int8_t offsetY = 0;
GxEPD2_Type& gfx;
const colorDef<uint8_t> (&colors)[nColors];

GxEPD2Out(
GxEPD2_Type& gfx,
const colorDef<uint8_t> (&c)[nColors],
idx_t* t,
panelsList& p,
idx_t resX = 6,
idx_t resY = 9,
idx_t offsetX = 0,
idx_t offsetY = 0,
int fontMarginY = 1,
int fontMarginX = 1) : gfxOut(resX, resY, t, p, (styles)(menuOut::redraw | menuOut::rasterDraw)), gfx(gfx), colors(c) {
gfx.setTextWrap(false);
this->offsetX = offsetX;
this->offsetY = offsetY;
this->fontMarginY = fontMarginY;
this->fontMarginX = fontMarginX;
}

size_t write(uint8_t ch) override { return gfx.write(ch); }

inline uint8_t getColor(colorDefs color = bgColor, bool selected = false, status stat = enabledStatus, bool edit = false) const {
return memByte(&(stat == enabledStatus ? colors[color].enabled[selected + edit] : colors[color].disabled[selected]));
}

void setColor(colorDefs c, bool selected = false, status s = enabledStatus, bool edit = false) override {
if (c == titleColor) {
gfx.setTextColor(getColor(titleColor, selected, s, edit), getColor(titleColor, false, s, edit));
} else {
gfx.setTextColor(getColor(c, selected, s, edit), getColor(bgColor, selected, s, edit));
}
}

void clearLine(idx_t ln, idx_t panelNr = 0, colorDefs color = bgColor, bool selected = false, status stat = enabledStatus, bool edit = false) override {
const panel p = panels[panelNr];
setColor(color, selected, stat, edit);
gfx.fillRect(p.x * resX + offsetX, (p.y + ln) * resY + offsetY, maxX() * resX, resY, getColor(color, selected, stat, edit));
}

void clear() override {
setCursor(0, 0);
display.fillScreen(getColor(bgColor, false, enabledStatus, false));
setColor(fgColor);
panels.reset();
}

void clear(idx_t panelNr) override {
const panel p = panels[panelNr];
gfx.fillRect(p.x * resX + offsetX, p.y * resY + offsetY, p.w * resX, p.h * resY, getColor(bgColor, false, enabledStatus, false));
panels.nodes[panelNr] = NULL;
}

void box(idx_t panelNr, idx_t x, idx_t y, idx_t w = 1, idx_t h = 1, colorDefs c = bgColor, bool selected = false, status stat = enabledStatus, bool edit = false) override {
const panel p = panels[panelNr];
gfx.drawRect((p.x + x) * resX, (p.y + y) * resY, w * resX, h * resY, getColor(c, selected, stat, edit));
}

void rect(idx_t panelNr, idx_t x, idx_t y, idx_t w = 1, idx_t h = 1, colorDefs c = bgColor, bool selected = false, status stat = enabledStatus, bool edit = false) override {
const panel p = panels[panelNr];
gfx.fillRect((p.x + x) * resX, (p.y + y) * resY, w * resX, h * resY, getColor(c, selected, stat, edit));
}

void setCursor(idx_t x, idx_t y, idx_t panelNr = 0) override {
const panel p = panels[panelNr];
gfx.setCursor((p.x + x) * resX + fontMarginX + offsetX, (p.y + y + 1) * resY - fontMarginY + offsetY);
}

idx_t startCursor(navRoot& root, idx_t x, idx_t y, bool charEdit, idx_t panelNr) override {
if (charEdit) {
const panel p = panels[panelNr];
gfx.fillRect((p.x + x) * resX + offsetX + fontMarginX, (p.y + y) * resY + offsetY, resX, resY, getColor(fgColor, false, enabledStatus, false));
}
return 0;
}

idx_t editCursor(navRoot& root, idx_t x, idx_t y, bool editing, bool charEdit, idx_t panelNr = 0) override {
if (editing) {
const panel p = panels[panelNr];
_trace(Serial << "editCursor" << endl);
gfx.drawRect((x + p.x - 1) * resX + offsetX + fontMarginX - 1, (p.y + y) * resY + offsetY, resX + 1, resY, cursorColor);
}
return 0;
}

void drawCursor(idx_t ln, bool selected, status stat, bool edit = false, idx_t panelNr = 0) override {
const panel p = panels[panelNr];
gfx.drawRect(p.x * resX, (p.y + ln) * resY, maxX() * resX, resY, getColor(cursorColor, selected, enabledStatus, false));
}

idx_t printRaw(const char* at, idx_t len) override {
trace(Serial << "GxEPD2Out::printRaw" << endl);
trace(Serial << "[" << at << "]");
return print((__FlashStringHelper*)at);
}
};
} // namespace Menu
#endif // RSITE_ARDUINOP_MENU_GxEPD2
2 changes: 2 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,8 @@ build_flags =
${t5-board-eink_pins.build_flags}
-DSUPPORT_EINK
-DEINKBOARDGDEM0213B74
-DBTN_UP=39
-DBTN_DWN=19
-DUNITHOSTNAME="\"CO2-Gadget-GDEM0213B74"\"
-DFLAVOUR="\"GDEM0213B74"\"

Expand Down