Skip to Content

4-Farben E-Paper Display mit ESP32

4-Farben E-Paper Display mit ESP32

In diesem Tutorial lernst du, wie man das Waveshare 3-inch 4-color E-paper display mit einem ESP32 verwendet.

Das 3-Zoll 4-Farben E-Paper Display Modul von Waveshare ist ein schönes Stück Hardware, aber das Demo software bietet nur Beispiele für Arduino, STM32 und Raspberry. Wenn du also das Display mit einem ESP32 verwenden möchtest, hast du Pech gehabt.

Außerdem zeigt das Arduino-Beispiel nur, wie man ein vorgefertigtes, statisches Bild anzeigt, aber nicht, wie man dynamisch Inhalte erstellt und anzeigt, zum Beispiel eine laufende Uhr oder eine Wetterstation.

Es wäre schön, wenn wir die GxEPD2 Bibliothek verwenden könnten, aber Stand Dezember 2024 hat sie keinen Treiber für das 3-Zoll 4-Farben E-Paper. Deshalb habe ich eine einfache Bibliothek (epd4c) implementiert, die im Wesentlichen dasselbe macht.

In diesem Tutorial zeige ich dir, wie du den Arduino-Beispielcode mit einem ESP32 zum Laufen bringst, wie du dynamisch Inhalte mit einer Leinwand erstellst und wie du die epd4c-Bibliothek verwendest.

Benötigte Teile

Ich verwende den ESP32 lite als Mikroprozessor, weil er günstig ist und eine Batterie-Schnittstelle hat. Da E-Paper Displays sehr wenig Strom verbrauchen, sind sie eine großartige Wahl für batteriebetriebene Projekte, und der ESP32 lite passt hier gut rein. Allerdings funktioniert auch jeder andere ESP32.

Du brauchst natürlich auch das unten aufgeführte 3-Zoll 4-Farben E-Paper Display Modul. Ich habe den Code mit diesem getestet, aber er sollte auch mit dem 2.13-inch 4-color E-Paper oder dem 2.66-inch 4-color E-Paper funktionieren. Allerdings werden 3-Farben- oder Schwarz-Weiß-Displays nicht unterstützt.

3-Zoll 4-Farben E-Paper Display

ESP32 lite Lolin32

ESP32 lite

USB data cable

USB-Datenkabel

Dupont wire set

Dupont-Kabelset

Half_breadboard56a

Breadboard

Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.

3″ 4-Farben E-Paper Display

Das in diesem Projekt verwendete E-Paper Display ist ein 3-Zoll Display Modul mit 400×168 Pixel Auflösung, 4 Farben (weiß, schwarz, rot, gelb), einer Aktualisierungszeit von 12 Sekunden (nur Vollaktualisierung wird unterstützt) und einem eingebetteten Controller mit SPI-Schnittstelle.

Front and Back of 3" 4-color e-Paper display module
Vorder- und Rückseite des 3″ 4-Farben E-Paper Display Moduls

Beachte, dass das Modul auf der Rückseite einen kleinen Jumper-Pad/Schalter hat, um von 4-Draht SPI auf 3-Draht SPI umzuschalten. Wir verwenden hier den Standard 4-Draht SPI, also musst du dort nichts ändern.

Back of display module with SPI-interface and controller
Rückseite des Display-Moduls mit SPI-Schnittstelle und Controller

Das Display-Modul läuft mit 3,3V oder 5V, hat einen sehr niedrigen Schlafstrom von 0,01µA und verbraucht beim Aktualisieren nur etwa 60mW. Für mehr Informationen zu E-Paper Displays allgemein, schau dir das Interfacing Arduino To An E-ink Display Tutorial an.

Unten habe ich das Datenblatt für das Display verlinkt und siehe auch das Waveshare manual:

Anschluss des 4-Farben E-Paper Displays an ESP32

In diesem Abschnitt verbinden wir das E-Paper Display mit einem ESP32 lite. Das folgende Bild zeigt die komplette Verkabelung zwischen ESP32 und Display für Stromversorgung und SPI-Schnittstelle.

Connecting 4-color e-Paper to ESP32 lite via SPI
Anschluss des 4-Farben E-Paper an ESP32 lite via SPI

Du kannst das Display mit 3,3V oder 5V versorgen, aber der ESP32-lite hat nur einen 3,3V Ausgang. Beachte, dass du die Hardware-SPI-Pins deines Mikrocontrollers verwenden musst. Beim ESP32-lite sind das die Pins 18 und 23. Unten eine Tabelle mit allen Verbindungen zur Übersicht.

E-Paper DisplayESP32 lite
CS/SS5
SCL/SCK 18
SDA/DIN/MOSI23
BUSY4
RES/RST16
DC17
VCC3.3V
GNDG

Demo-Code mit ESP32 zum Laufen bringen

Wenn du die demo software für das Waveshare E-Paper Display herunterlädst, findest du darin einen Ordner namens Arduino/epd3in0g. Darin befindet sich ein Sketch namens epd3in0g.ino, der im Wesentlichen folgendes Bild auf dem Display erzeugt:

Demo image for 3" 4-color e-Paper
Demo-Bild für 3″ 4-Farben E-Paper

Hier ist der gekürzte Ausschnitt des Beispielcodes, der das Bild erzeugt. Du siehst, dass er das Display-Objekt epd erstellt, initialisiert, die Bilddaten anzeigt und dann das Display in den Schlafmodus versetzt:

#include "epd3in0g.h"
#include "imagedata.h"

Epd epd;

void setup() {
  epd.Init();
  epd.Display(IMAGE_DATA);
  epd.Sleep();
}

void loop() { }

Dieser Code läuft nicht auf einem ESP32. Du kannst ihn aber zum Laufen bringen, indem du die unten aufgeführten Schritte befolgst (siehe auch dieses blog post für mehr Kontext):

  • Ändere const unsigned char zu unsigned char in imagedata.cpp und imagedata.h
  • Ändere #include <avr/pgmspace> zu #include <pgmspace> in imagedata.h
  • Ändere die Pin-Definitionen in epdif.h, um die Hardware-SPI-Pins des ESP32 zu verwenden
  • Füge SPI.endTransaction(); zur IfInit() Funktion in epdif.cpp

Hier sind die Pin-Definitionen, die du in epdif.h einfügen must:

#define RST_PIN         16
#define DC_PIN          17
#define CS_PIN          5
#define BUSY_PIN        4

und hier ist der Code in epdif.cpp, den du ändern musst,

int EpdIf::IfInit(void) {
    ...
    SPI.begin();
    SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
    return 0;
}

indem du eine Zeile hinzufügst (endTransaction()):

int EpdIf::IfInit(void) {
   ...
    SPI.begin();
    SPI.endTransaction(); // <== ADD THIS LINE
    SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
    return 0;
}

Mit diesen Änderungen sollte der Beispielcode funktionieren. Er ist jedoch weiterhin auf die Anzeige statischer Bilder beschränkt. Im nächsten Abschnitt zeige ich dir eine kleine Erweiterung, mit der du die Adafruit_GFX Grafikbibliothek verwenden kannst, um dynamisch Inhalte wie Text und Grafiken anzuzeigen.

Die Adafruit_GFX Bibliothek ist eine Grafikbibliothek, die eine gemeinsame Menge von graphics primitives (Text, Punkte, Linien, Kreise usw.) bereitstellt. Du kannst sie wie gewohnt über den Library Manager installieren. Nach der Installation sollte sie im Library Manager wie folgt erscheinen:


Adafruit_GFX in Library Manager
Adafruit_GFX im Library Manager

Die Adafruit_GFX Bibliothek hat das Konzept eines „canvas„, das es dir erlaubt, in einem Display-Puffer (=Leinwand) im Hintergrund zu zeichnen (ohne es anzuzeigen). Unten ein Codeausschnitt, der eine 8-Bit Tiefe Leinwand mit den Abmessungen des E-Paper Displays erstellt.

#include "Adafruit_GFX.h"

GFXcanvas8 canvas(EPD_WIDTH, EPD_HEIGHT);

void setup() {
  canvas.setRotation(1);
  canvas.fillScreen(WHITE);
  canvas.fillCircle(200, 84, 60, RED);
}

Dann wird die Ausrichtung des Puffers/Displays gesetzt, der Display-Puffer mit Weiß gefüllt und ein roter Kreis gezeichnet. Da der Display-Puffer im Grunde ein Bild ist, wäre es schön, wenn wir den folgenden Code verwenden könnten, um die Zeichnung im Puffer auf dem E-Paper anzuzeigen:

 epd.Display(canvas.getBuffer());

Das 4-Farben E-Paper verwendet jedoch tatsächlich ein komprimiertes Bild, bei dem vier Pixel in ein Byte gepackt werden, um Speicher zu sparen. Da es nur vier Farben gibt, kann jede Farbe mit 2 Bits dargestellt werden:

FarbeBits
schwarz 00
weiß01
gelb 10
rot 11

Das bedeutet, wenn wir eine Folge von vier Pixeln mit den Farben schwarz, weiß, gelb und rot im Originalbild haben, können wir sie wie folgt in ein Byte komprimieren (00011011 = 0x1B):

Four pixels with 2-bit color codes
Vier Pixel mit 2-Bit Farbcode

Das musst du für alle 4-Pixel-Blöcke im Originalbild machen, um ein komprimiertes Bild zu erzeugen, das über epd.Display(image) auf dem E-Paper angezeigt werden kann. Die folgende compress() Funktion nimmt den Display-Puffer der Leinwand und komprimiert ihn wie beschrieben:

uint8_t* compress(GFXcanvas8& canvas) {
  uint8_t* buf = canvas.getBuffer();
  int n = canvas.width() * canvas.height();
  int ci = 0;
  for (int i = 0; i < n; i += 4) {
    uint8_t com = buf[i];
    com = (com << 2) | buf[i + 1];
    com = (com << 2) | buf[i + 2];
    com = (com << 2) | buf[i + 3];
    buf[ci++] = com;
  }
  return buf;
}

Beachte, dass der Display-Puffer wiederverwendet wird. Es wird also kein zusätzlicher Speicher für das komprimierte Bild benötigt, aber du kannst nach der Komprimierung nicht mehr auf der Leinwand zeichnen. Du müsstest sie zuerst löschen.

Mit der compress() Funktion kannst du dynamisch Inhalte erstellen und auf dem E-Paper anzeigen. Das Codegerüst sieht so aus:

Epd epd;
GFXcanvas8 canvas(EPD_WIDTH, EPD_HEIGHT);

void setup() {
  canvas.setRotation(1);
  canvas.fillScreen(WHITE);
  ...  // more graphics code

  epd.Init();
  epd.Display(compress(canvas));  // display compressed image
  epd.Sleep();
}

Hier ist ein komplettes Codebeispiel mit allem drin:

#include "Adafruit_GFX.h"
#include "epd3in0g.h"

Epd epd;
GFXcanvas8 canvas(EPD_WIDTH, EPD_HEIGHT);

uint8_t* compress(GFXcanvas8& canvas) {
  uint8_t* buf = canvas.getBuffer();
  int n = canvas.width() * canvas.height();
  int ci = 0;
  for (int i = 0; i < n; i += 4) {
    uint8_t com = buf[i];
    com = (com << 2) | buf[i + 1];
    com = (com << 2) | buf[i + 2];
    com = (com << 2) | buf[i + 3];
    buf[ci++] = com;
  }
  return buf;
}

void setup() {
  canvas.setRotation(1);
  canvas.fillScreen(red);
  canvas.fillCircle(200, 84, 50, yellow);
  canvas.setCursor(190, 80);
  canvas.setTextColor((black));
  canvas.print("Test");

  epd.Init();
  epd.Display(compress(canvas));
  epd.Sleep();
}

void loop() {
}

Wenn du diesen Code hochlädst und ausführst, solltest du einen gelben Kreis auf rotem Hintergrund mit dem Text „Test“ darin sehen:

Output example for compress() function
Ausgabe-Beispiel für compress() Funktion

Obwohl der obige Code funktioniert, ist er etwas umständlich zu verwenden. Erstens musst du die Waveshare Demo-Code-Dateien (epd3in0g.h, epd3in0g.cpp, epdif.h, epdif.cpp) in jedem neuen Projekt, das das E-Paper Display nutzt, integrieren. Zweitens musst du die compress() Funktion jedes Mal neu implementieren.

Deshalb habe ich eine kleine Bibliothek namens epd4c erstellt, die all das vermeidet. Du musst sie nur installieren und kannst sie dann unabhängig vom Demo-Code verwenden. Im nächsten Abschnitt zeige ich dir, wie sie funktioniert.

Zeichnen auf 4-Farben E-Paper Display mit epd4c Bibliothek

Um die epd4c Library zu installieren, gehe zum epd4c_arduino_lib github repo und klicke auf den grünen „Code“ Button. Dann klicke auf „Download Zip“ wie unten gezeigt:

Download EPD4c Library library
EPD4c Bibliothek herunterladen

Dann gehe zu „Sketch" -> "Include Library" -> "Add .Zip Library..“ und wähle die „epd4c_arduino_lib-main.zip“ Datei aus, die du gerade heruntergeladen hast:

Adding TOF10120 library to sketch
EPD4c Bibliothek zum Sketch hinzufügen

Mit der epd4c Bibliothek (und der Adafruit_GFX Bibliothek) wird das Schreiben von Text und Zeichnen auf dem 4-Farben E-Paper viel einfacher.

Beispielcode

Hier ist ein Beispielcode. Er zeichnet eine Reihe farbiger Kreise zusammen mit einem zentrierten Text auf dem Bildschirm. Wie du siehst, ist keine separate Leinwand mehr nötig und du musst keinen der Waveshare Demo-Codes verwenden.

#include "epd4c.h"

#define RST_PIN 16
#define DC_PIN 17
#define CS_PIN 5
#define BUSY_PIN 4

#define EPD_WIDTH 168
#define EPD_HEIGHT 400

Epd4c epd(EPD_WIDTH, EPD_HEIGHT, RST_PIN, DC_PIN, CS_PIN, BUSY_PIN);

void setup() {
  epd.init();
  epd.setRotation(1);
  epd.fillScreen(WHITE);

  epd.fillCircle(200, 84, 60, RED);
  epd.fillCircle(200, 84, 50, YELLOW);
  epd.fillCircle(200, 84, 40, BLACK);
  epd.fillCircle(200, 84, 30, WHITE);

  epd.setCursor(190, 80);
  epd.setTextColor((BLACK));
  epd.print("Test");

  epd.display();
  epd.sleep();
}

void loop() {}

Lass uns den Code in seine Komponenten aufschlüsseln, um ihn besser zu verstehen.

Bibliothek Einbindung

Wir beginnen mit der Einbindung der epd4c Bibliothek zur Steuerung des E-Paper Displays, die eine Erweiterung der Adafruit_GFX canvas ist und daher alle graphics primitives der Adafruit_GFX Bibliothek unterstützt.

#include "epd4c.h"

Pin-Definitionen

Als nächstes definieren wir die Pins, die zur Verbindung des E-Paper Displays mit dem ESP32 verwendet werden. Beachte, dass die SPI-Pins nicht definiert werden können. Du musst die Standard-Hardware-SPI-Pins deines Mikrocontrollers verwenden und anschließen.

#define RST_PIN 16
#define DC_PIN 17
#define CS_PIN 5
#define BUSY_PIN 4

Display-Abmessungen

Wir definieren auch die Breite und Höhe des E-Paper Displays. Wie erwähnt, sollte der Code auch für andere 4-Farben E-Paper Displays mit anderen Abmessungen funktionieren, aber ich habe das nicht getestet.

#define EPD_WIDTH 168
#define EPD_HEIGHT 400

Display-Objekt Erstellung

Hier erstellen wir eine Instanz der Epd4c Klasse und übergeben die Display-Abmessungen und Pin-Definitionen als Parameter. Dieses Objekt wird im gesamten Programm zur Steuerung des Displays verwendet.

Epd4c epd(EPD_WIDTH, EPD_HEIGHT, RST_PIN, DC_PIN, CS_PIN, BUSY_PIN);

Setup-Funktion

In der setup() Funktion initialisieren wir das E-Paper Display und konfigurieren seine Einstellungen. Hier setzen wir die Display-Rotation, füllen den Bildschirm mit weißer Farbe und zeichnen mehrere überlappende Kreise in verschiedenen Farben und Größen.

void setup() {
  epd.init();
  epd.setRotation(1);
  epd.fillScreen(WHITE);

  epd.fillCircle(200, 84, 60, RED);
  epd.fillCircle(200, 84, 50, YELLOW);
  epd.fillCircle(200, 84, 40, BLACK);
  epd.fillCircle(200, 84, 30, WHITE);

  epd.setCursor(190, 80);
  epd.setTextColor((BLACK));
  epd.print("Test");

  epd.display();
  epd.sleep();
}

Die Ausgabe auf dem E-Paper Display sieht wie folgt aus

Output on 3" 4-color E-paper Display
Ausgabe auf 3″ 4-Farben E-Paper Display

wobei

  • epd.init(); das Display initialisiert.
  • epd.setRotation(1); setzt die Ausrichtung des Displays.
  • epd.fillScreen(WHITE); füllt den gesamten Bildschirm mit weißer Farbe.
  • Die fillCircle() Funktionen zeichnen Kreise mit unterschiedlichen Radien und Farben an den angegebenen Koordinaten (200, 84).
  • epd.setCursor(190, 80); setzt die Position für den zu druckenden Text.
  • epd.setTextColor((BLACK)); setzt die Textfarbe auf schwarz.
  • epd.print("Test"); gibt den Text „Test“ auf dem Display aus.
  • epd.display(); aktualisiert das Display mit den gezeichneten Grafiken
  • epd.sleep(); versetzt das Display in den Schlafmodus, um Strom zu sparen.

Loop-Funktion

Die loop() Funktion ist in diesem Beispiel leer, was bedeutet, dass das Programm nach der Einrichtung keine weiteren Aktionen ausführt. Das Display bleibt im Schlafmodus und zeigt das Bild weiterhin an, auch wenn der ESP32 ausgeschaltet ist.

void loop() {}

Wenn du den Inhalt kontinuierlich aktualisieren möchtest, z.B. um eine laufende Uhr anzuzeigen, würdest du den Grafikcode in die loop-Funktion setzen. Siehe die Digital Clock on e-Paper Display oder die Weather Station on e-Paper Display Tutorials für Beispiele.

Und das war’s!

Fazit

In diesem Tutorial hast du gelernt, wie man das 3-Zoll 4-Farben E-Paper Display von Waveshare mit einem ESP32 steuert.

Ich habe dir gezeigt, wie du den Arduino Demo-Code änderst, damit er mit einem ESP32 funktioniert. Wir haben auch die Adafruit_GFX canvas verwendet, um dynamisch Inhalte für das E-Paper Display zu erstellen. Und schließlich habe ich dir die epd4c Bibliothek vorgestellt.

Die epd4c Bibliothek macht im Wesentlichen dasselbe wie die GxEPD2 Bibliothek, aber leider unterstützt letztere derzeit nicht das 3-Zoll 4-Farben E-Paper Display von Waveshare. Das hätte ich bevorzugt. Ich hätte die GxEPD2 Bibliothek erweitern können, war aber zu faul und habe stattdessen den Waveshare Demo-Code aufgeräumt und erweitert, um die epd4c Bibliothek zu erstellen.

Wenn du Fragen hast, kannst du sie gerne im Kommentarbereich stellen.

Viel Spaß beim Tüfteln ; )