↩ Alle projecten en sketches This page in English
ESP32 · e-paper · SPI

2.13 inch e-paper display: NTP-klok met ESP32

2.13 inch e-paper display aangesloten op een ESP32
2.13 inch e-paper op Amazon — de code werkt ongewijzigd ook op de LILYGO TTGO T5

Een e-paper display heeft geen stroom nodig om het beeld te behouden — ideaal voor een klokje dat gewoon blijft "staan", ook zonder voeding.

Wat heb je nodig?

2.13 inch e-paper-display + ESP32

Voordeel van een e-paper display is dat het geen stroom vereist om info op het scherm te tonen. Enkel een klein beetje om gegevens op het display te wijzigen. Wat je erop zet, blijft er permanent op staan, ook zonder enige stroom. Nadeel is een tragere update dan de tft-spi displays (daarom werden de seconden weggelaten), en je moet opletten hoe je het scherm "ververst" om geen hevige flicker te krijgen. De gebruikte bibliotheek heeft geen functie "drawCentreString", we moeten zelf een functie voorzien voor een string die we gecentreerd willen weergeven.

Verbindingen:

ESP32 ---> 2.13 inch e-paper
============================
G4   --------> BUSY
G16  --------> RST
G17  --------> DC
G5   --------> CS
G18  --------> CLK
G23  --------> DIN
GND  --------> GND
3V3  --------> VCC

Sketch:

#include <GxEPD.h>
#include <GxDEPG0213BN/GxDEPG0213BN.h>  // 2.13" black/white 128x250 px
#include <WiFiManager.h>                // https://github.com/tzapu/WiFiManager/
#include <esp_sntp.h>                   // ESP32 core
#include <Fonts/FreeSansBold24pt7b.h>
#include <Fonts/FreeSansBold18pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.h>
#include <GxIO/GxIO.h>

char days[7][10] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
int previousMinute;

GxIO_Class io(SPI, /*CS=5*/ SS, /*DC=*/17, /*RST=*/16);  // 17 & 16 = arbitrary choice
GxEPD_Class display(io, /*RST=*/16, /*BUSY=*/4);         // 16 & 4 = arbitrary choice
struct tm tInfo;                                         // https://cplusplus.com/reference/ctime/tm/
WiFiManager myWiFi;  

void setup() {
  display.init();
  display.setRotation(1);                          // landscape
  display.setTextColor(GxEPD_BLACK, GxEPD_WHITE);  // GxEPD_BLACK = 0x0000, GxEPD_WHITE = 0xFFFF
  myWiFi.setAPCallback(noConnection);              // on screen instructions for wifi connection
  myWiFi.autoConnect("E-PAPER-ESP32");             // will also reconnect after connection was lost
  sntp_set_sync_interval(4 * 60 * 60 * 1000UL);    // sntp sync every 4 hr
  configTzTime("CET-1CEST,M3.5.0,M10.5.0/3", "be.pool.ntp.org");
  display.fillScreen(GxEPD_WHITE);
  display.update();  // fully updating the display causes flicker for 2 seconds
}

void loop() {
  char hourMin[6], theDate[11];
  getLocalTime(&tInfo);
  if (previousMinute != tInfo.tm_min) {                      // update display only when minute changes
    strftime(hourMin, sizeof(hourMin), "%R", &tInfo);        // https://cplusplus.com/reference/ctime/strftime
    strftime(theDate, sizeof(theDate), "%d-%m-%G", &tInfo);  // this display is too slow to show the seconds
    display.fillScreen(GxEPD_WHITE);
    showCentered(39, hourMin);
    showCentered(84, days[tInfo.tm_wday]);
    showCentered(126, theDate);
    previousMinute = tInfo.tm_min;
    display.updateWindow(66, 0, 116, 41, true);  // partial update time (= no flicker)
    display.updateWindow(0, 50, 250, 78, true);  // partial update date
    display.powerDown();
  }
}

void showCentered(byte myHeight, const char* myText) {
  display.setTextColor(GxEPD_WHITE);
  display.setFont(strlen(myText) > 9 ? &FreeSansBold18pt7b : &FreeSansBold24pt7b);  // date = smaller font
  display.setCursor(0, myHeight);
  display.print(myText);
  display.setTextColor(GxEPD_BLACK);
  display.setCursor((display.width() - display.getCursorX()) / 2, myHeight);
  display.print(myText);
}

void noConnection(WiFiManager* myWiFi) {
  display.fillScreen(GxEPD_WHITE);
  display.setFont(&FreeSansBold9pt7b);
  display.setTextSize(1);
  showNoConnection(18, F("WiFi: no connection."));
  showNoConnection(35, F("Connect to hotspot:"));
  showNoConnection(52, F("E-PAPER-ESP32 and open"));
  showNoConnection(69, F("a browser at address"));
  showNoConnection(86, F("192.168.4.1"));
  showNoConnection(103, F("to enter network name"));
  showNoConnection(120, F("and password"));
  display.update();
}

void showNoConnection(byte top, const __FlashStringHelper* tekst) {
  display.setCursor(0, top);  // allows for 7 lines on a 128 px height display
  display.print(tekst);       // println without setCursor = interline of text is too large
}
Partiële refresh = geen flicker display.updateWindow() ververst enkel het gewijzigde gebied van het scherm in plaats van het volledige display — daardoor geen zichtbare flicker bij elke minuutwissel. Een volledige display.update(), zoals bij het opstarten, veroorzaakt wél een korte flicker van ~2 seconden.

Meer displays met de ESP8266 / ESP32

Benieuwd naar andere displays? Bekijk het volledige overzicht met o.a. TM1637, SSD1306, SH1106, ST7735, ST7789 en geïntegreerde displays zoals de Lilygo T-Display en de Waveshare ESP32-S3.