Tak jsem laboroval s knihovnou GxEPD2, ale s tou jsem se čistému zobrazení zatím nedopracoval.
Přešel jsem proto na vzorový kód výrobce a odtud vykradl ovládání displeje na základní úrovni a pomocí GFXcanvas1 display(800, 480); se mi již daří na displej psát černobíle bez zdlouhavého problikávání se super kontrastem. Mělo by dle vzoru fungovat i částečné překreslování a dokonce i zobrazení stupňů šedi, ale to zatím nepotřebuji. "Fast" vykreslování ve vzoru od výrobce mi nefungovalo. Používám DF Robot Beetle ESP32 C6.
Tady je zjednodušený vykuchaný kód od výrobce s jednoduchou testovací grafikou pro výše uvedenou desku a mé rozložení pinů. Snad to někomu pomůže, ani se neptejte kolik mě to stálo času :-)
#include
#include
#include
// PINY PRO BEETLE ESP32-C6
#define EPD_MOSI 4
#define EPD_CLK 5
#define EPD_CS 23
#define EPD_DC 22
#define EPD_RST 21
#define EPD_BUSY 7
#define EPD_WIDTH 480
#define EPD_HEIGHT 800
#define EPD_ARRAY EPD_WIDTH*EPD_HEIGHT/8
// Plátno podle orientace inicializace (X=800, Y=480)
GFXcanvas1 canvas(800, 480);
// --- NÍZKOÚROVŇOVÉ FUNKCE ---
void EPD_W21_WriteCMD(unsigned char command) {
digitalWrite(EPD_CS, LOW);
digitalWrite(EPD_DC, LOW);
SPI.transfer(command);
digitalWrite(EPD_CS, HIGH);
}
void EPD_W21_WriteDATA(unsigned char data) {
digitalWrite(EPD_CS, LOW);
digitalWrite(EPD_DC, HIGH);
SPI.transfer(data);
digitalWrite(EPD_CS, HIGH);
}
void Epaper_READBUSY(void) {
while (digitalRead(EPD_BUSY) == HIGH);
}
void EPD_Update(void) {
EPD_W21_WriteCMD(0x22);
EPD_W21_WriteDATA(0xF7);
EPD_W21_WriteCMD(0x20);
Epaper_READBUSY();
}
// --- TVŮJ FUNKČNÍ INIT (1:1 OPRAVENÝ) ---
void EPD_HW_Init(void) {
digitalWrite(EPD_RST, LOW); delay(10);
digitalWrite(EPD_RST, HIGH); delay(10);
Epaper_READBUSY();
EPD_W21_WriteCMD(0x12); // SWRESET
Epaper_READBUSY();
EPD_W21_WriteCMD(0x18);
EPD_W21_WriteDATA(0x80);
EPD_W21_WriteCMD(0x0C);
EPD_W21_WriteDATA(0xAE);
EPD_W21_WriteDATA(0xC7);
EPD_W21_WriteDATA(0xC3);
EPD_W21_WriteDATA(0xC0);
EPD_W21_WriteDATA(0x80);
EPD_W21_WriteCMD(0x01); // Driver output control
EPD_W21_WriteDATA((EPD_WIDTH - 1) % 256);
EPD_W21_WriteDATA((EPD_WIDTH - 1) / 256);
EPD_W21_WriteDATA(0x02);
EPD_W21_WriteCMD(0x3C); // BorderWaveform
EPD_W21_WriteDATA(0x01);
EPD_W21_WriteCMD(0x11); // Data entry mode
EPD_W21_WriteDATA(0x03);
EPD_W21_WriteCMD(0x44); // set Ram-X address start/end
EPD_W21_WriteDATA(0x00);
EPD_W21_WriteDATA(0x00);
EPD_W21_WriteDATA((EPD_HEIGHT - 1) % 256);
EPD_W21_WriteDATA((EPD_HEIGHT - 1) / 256);
EPD_W21_WriteCMD(0x45); // set Ram-Y address start/end
EPD_W21_WriteDATA(0x00);
EPD_W21_WriteDATA(0x00);
EPD_W21_WriteDATA((EPD_WIDTH - 1) % 256);
EPD_W21_WriteDATA((EPD_WIDTH - 1) / 256);
EPD_W21_WriteCMD(0x4E); // set RAM x address count to 0
EPD_W21_WriteDATA(0x00);
EPD_W21_WriteDATA(0x00);
EPD_W21_WriteCMD(0x4F); // set RAM y address count to 0
EPD_W21_WriteDATA(0x00);
EPD_W21_WriteDATA(0x00);
Epaper_READBUSY();
}
// Odeslání plátna do paměti (do 0x24)
void EPD_WhiteScreen_ALL(uint8_t* datas) {
unsigned int i;
EPD_W21_WriteCMD(0x24);
for (i = 0; i < EPD_ARRAY; i++) {
EPD_W21_WriteDATA(datas[i]);
}
EPD_Update();
}
// Rychlá bitová magie: otočí bity v bajtu (zrcadlo pro pixely)
uint8_t reverseByte(uint8_t b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) > 2 | (b & 0x33) > 1 | (b & 0x55) = 0; x--) {
// Přečteme původní bajt ze správného řádku
uint8_t origByte = buffer[y * 100 + x];
// Přetočíme bity v bajtu zrcadlově a pošleme do displeje
EPD_W21_WriteDATA(reverseByte(origByte));
}
}
EPD_Update();
}
void drawDashboard() {
// --- KRESLENÍ DASHBOARDU ---
canvas.setRotation(0); // Logické otočení na šířku (Adafruit GFX)
canvas.fillScreen(1); // Bílé pozadí
canvas.setTextColor(0); // Černý text
// 1. SEGMENTOVÁ BATERIE A VÝKON
int batX = 40, batY = 40, batW = 100, batH = 40;
canvas.drawRect(batX, batY, batW, batH, 0);
canvas.fillRect(batX + batW, batY + 10, 8, 20, 0);
// Plné segmenty baterie
canvas.fillRect(batX + 5, batY + 5, 20, 30, 0);
canvas.fillRect(batX + 28, batY + 5, 20, 30, 0);
canvas.fillRect(batX + 51, batY + 5, 20, 30, 0);
// Výkon v kW (žádná procenta)
canvas.setTextSize(4);
canvas.setCursor(batX + 130, batY + 5);
canvas.print("3.2 kW");
// 2. MĚŘÁKY ENERGIE
int gaugeX = 40, gaugeY = 160, gaugeW = 400, gaugeH = 30;
canvas.setTextSize(2);
canvas.setCursor(gaugeX, gaugeY - 25);
canvas.print("Solar (Generace)");
canvas.drawRect(gaugeX, gaugeY, gaugeW, gaugeH, 0);
canvas.fillRect(gaugeX, gaugeY, gaugeW * 0.8, gaugeH, 0); // 80% soláru
gaugeY += 90;
canvas.setCursor(gaugeX, gaugeY - 25);
canvas.print("Domacnost (Spotreba)");
canvas.drawRect(gaugeX, gaugeY, gaugeW, gaugeH, 0);
canvas.fillRect(gaugeX, gaugeY, gaugeW * 0.3, gaugeH, 0); // 30% dům
gaugeY += 90;
canvas.setCursor(gaugeX, gaugeY - 25);
canvas.print("Nabijeni auta");
canvas.drawRect(gaugeX, gaugeY, gaugeW, gaugeH, 0);
canvas.fillRect(gaugeX, gaugeY, gaugeW * 0.5, gaugeH, 0); // 50% auto
}
void EPD_DeepSleep(void) {
EPD_W21_WriteCMD(0x10);
EPD_W21_WriteDATA(0x01);
delay(100);
}
// --- HLAVNÍ PROGRAM ---
void setup() {
pinMode(EPD_BUSY, INPUT);
pinMode(EPD_RST, OUTPUT);
pinMode(EPD_DC, OUTPUT);
pinMode(EPD_CS, OUTPUT);
SPI.begin(EPD_CLK, -1, EPD_MOSI, EPD_CS);
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
drawDashboard();
EPD_HW_Init();
//EPD_DrawCanvas(canvas.getBuffer()); // Naše nová překlápěcí funkce
EPD_DrawCanvas();
EPD_DeepSleep();
}
void loop() {}