Skip to Content

CrowPanel de 4.2 pulgadas E-Paper con GxEPD2

CrowPanel de 4.2 pulgadas E-Paper con GxEPD2

En este blog te muestro cómo puedes usar la biblioteca GxEPD2 para dibujar en un CrowPanel de 4.2 pulgadas con pantalla de papel electrónico.

Los E-Papers CrowPanel de Elecrow vienen con un código de ejemplo que demuestra cómo dibujar en la pantalla. Sin embargo, la funcionalidad de ese código es bastante limitada. Sería mucho mejor si pudiéramos usar la más capaz GxEPD2 Libary. Desafortunadamente, a diciembre de 2024 no hay soporte directo para ninguna de las pantallas E-Paper CrowPanel en la biblioteca GxEPD2 (ver GxEPD2_display_selection_new_style.h).

Sin embargo, con un pequeño ajuste podemos hacer que la biblioteca GxEPD2 funcione en el CrowPanel de 4.2 pulgadas con pantalla E-Paper y en las siguientes secciones te mostraré cómo hacerlo.

Partes necesarias

Necesitarás un Display E-Paper CrowPanel. En este tutorial me centro en la versión de 4.2 pulgadas, que es la que deberías conseguir. Hay otros tamaños de pantalla y los ejemplos de código deberían funcionar en gran medida, pero tendrás que hacer cambios debido a la diferencia en resolución y controlador de pantalla.

CrowPanel E-Paper de 4.2 pulgadas

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.

Display E-Paper CrowPanel de 4.2 pulgadas

El Display E-Paper de 4.2 pulgadas de CrowPanel es una pantalla en blanco y negro, con una resolución de 400×300 píxeles. Viene como un módulo integrado que contiene un chip ESP32-S3, varios botones para controlar la pantalla y más. La siguiente imagen muestra el frente de la pantalla con tres botones de control al lado:

Front of CrowPanel 4.2-inch E-Paper Display
Frontal del Display E-Paper CrowPanel de 4.2 pulgadas (source)

Botones

Los botones MENU y EXIT son botones pulsadores simples, mientras que el interruptor rotatorio soporta funciones de Arriba, Abajo y Confirmar/OK. Los botones son totalmente programables. La siguiente tabla muestra qué pines GPIO están asignados a cada botón:

BotónGPIO
MENUIO2
Interruptor rotatorio AbajoIO4
Interruptor rotatorio ArribaIO6
Interruptor rotatorio CONFIO5
EXITIO1

Características

Además, el módulo de pantalla contiene una ranura para tarjeta TF, una interfaz para batería LiPo (SH1.0-2Pin) con capacidad de carga y una interfaz GPIO. La programación (y alimentación) se realiza vía un puerto USB-C.

Interna of CrowPanel 4.2-inch E-Paper Display
Interior del Display E-Paper CrowPanel de 4.2 pulgadas (source)

GPIO

Para GPIO están disponibles los siguientes pines: IO3; IO9; IO15; IO17; IO19; IO21; IO8; IO14; IO16; IO18; IO20; IO38 y el pinout del puerto GPIO se puede encontrar en la serigrafía pero también en la parte trasera del módulo:

Pinout of GPIO port
Pinout del puerto GPIO (source)

Reset y Boot

En la parte trasera del módulo están los botones Boot y Reset. Desafortunadamente, sobresalen del chasis y se presionan fácilmente por accidente al colocar el módulo sobre una mesa. Te sugiero que los recortes un poco (con unas pinzas) para evitar que eso suceda.

Back of CrowPanel 4.2-inch E-Paper Display
Parte trasera del Display E-Paper CrowPanel de 4.2 pulgadas (source)

Otros Displays E-Paper CrowPanel

El display de 4.2 pulgadas es uno de toda una serie de pantallas E-Paper similares pero con diferentes resoluciones, chips ESP32 y controladores. Consulta la tabla a continuación para un resumen:

CrowPanel E-Paper Displays
Displays E-Paper CrowPanel (source)

Para este tutorial usé el display de 4.2 pulgadas, pero la mayoría del código probablemente funcione para otros tamaños también. Sin embargo, tendrás que encontrar un controlador compatible en la biblioteca GxEPD2. Más sobre eso en la siguiente sección.

Biblioteca GxEPD2

La GxEPD2 Libary es una biblioteca para Arduino/ESP32 para pantallas E-Paper SPI. Como se mencionó antes, soporta muchas pantallas E-Paper diferentes pero hasta ahora no soporta directamente las pantallas E-Paper CrowPanel.

Sin embargo, comparada con el código demo que viene con las pantallas CrowPanel, la GxEPD2 Libary es preferible. Tiene más functions y mejor documentación, ya que deriva de la Adafruit-GFX-Library, y puede instalarse y usarse fácilmente.

Lo más importante es que puedes (re)usar código escrito con la GxEPD2 Libary en una amplia gama de pantallas E-Paper diferentes, sin tener que reescribirlo para pantallas específicas.

Subir código al display E-Paper CrowPanel

Subir código al módulo E-Paper vía Arduino IDE es fácil. Solo conecta el cable USB y selecciona la placa «ESP32S3 Dev Module»:

Selecting ESP32S3 Dev Module
Seleccionando ESP32S3 Dev Module

En «Tools» selecciona preferiblemente «Huge App» para el Partition Scheme y «OPI PSRAM» para la configuración de PSRAM. Aunque no es esencial para el código de este tutorial, parecen ser las configuraciones recomendadas.

Board settings for CrowPanel E-Paper display
Configuración de placa para display E-Paper CrowPanel

Código para usar la biblioteca GxEPD2 con el display E-Paper CrowPanel

En esta sección te muestro cómo hacer que la biblioteca GxEPD2 funcione con el display E-Paper CrowPanel. Hay dos pasos importantes. Primero, necesitamos encontrar un controlador GxEPD2 que tenga la misma resolución y soporte el mismo chip controlador que el display CrowPanel.

El display de 4.2 pulgadas usa el chip controlador SSD1683 y tiene una resolución de 400×300 píxeles. Si buscas en la lista de controladores soportados en GxEPD2_display_selection_new_style.h encontrarás dos coincidencias:

//#define GxEPD2_DRIVER_CLASS GxEPD2_420_GDEY042T81 // GDEY042T81 400x300, SSD1683 (no inking)
//#define GxEPD2_DRIVER_CLASS GxEPD2_420_GYE042A87  // GYE042A87, 400x300, SSD1683 (HINK-E042-A07-FPC-A1)  

Sin embargo, si pruebas estos controladores solo obtendrás una imagen muy tenue de lo que dibujes en la pantalla. Revisé más a fondo el demo code y resulta que también tienes que activar la alimentación para la pantalla. Esto se logra configurando la salida en GPIO7 a HIGH.

El siguiente ejemplo imprime el texto «Makerguides» en el centro del display E-Paper de 4.2 pulgadas. Échale un vistazo rápido y luego discutimos los detalles:

#include "GxEPD2_BW.h"

#define PWR 7
#define BUSY 48
#define RES 47
#define DC 46
#define CS 45

GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> epd(GxEPD2_420_GYE042A87(CS, DC, RES, BUSY));

void epdPower(int state) { 
  pinMode(PWR, OUTPUT);  
  digitalWrite(PWR, state);  
}

void epdInit() {  
  epd.init(115200, true, 50, false);
  epd.setRotation(0);
  epd.setTextColor(GxEPD_BLACK);
  epd.setTextSize(4);
  epd.setFullWindow();
}

void setup() {
  epdPower(HIGH);
  epdInit();
  epd.fillScreen(GxEPD_WHITE);
  epd.drawRect(0, 0, 400, 300, GxEPD_BLACK);
  epd.setCursor(70, 130);
  epd.print("Makerguides");
  epd.display();
  epd.hibernate(); 
  epdPower(LOW);
}

void loop() {}

Incluir

Primero, incluimos la GxEPD2 Libary y como usamos un E-Paper en blanco y negro incluimos «GxEPD2_BW.h»:

#include "GxEPD2_BW.h"

Si aún no has instalado la GxEPD2 Libary, tendrás que hacerlo para que este código funcione. También necesitarás la biblioteca Adafruit_GFX. Solo install the libraries de la forma habitual. Después de la instalación deberían aparecer en el Library Manager así:

Adafruit_GFX and GxEPD2 libraries in Library Manager
Bibliotecas Adafruit_GFX y GxEPD2 en Library Manager

No necesitas ninguna de las demo code que vienen con las pantallas CrowPanel.

Definiciones de pines

Luego necesitamos definir los pines SPI que usa la pantalla para comunicarse con el ESP32.

#define PWR 7
#define BUSY 48
#define RES 47
#define DC 46
#define CS 45

Encontré estos pines mirando el Schematics of the CrowPanel 4.2-inch E-Paper display. Aquí está la sección relevante del esquema que describe la conexión al E-Paper:

Schematics of the CrowPanel 4.2-inch E-Paper display
Esquema del display E-Paper CrowPanel de 4.2 pulgadas (source)

Objeto Display

Como se mencionó antes, no hay soporte directo para el CrowPanel de 4.2 pulgadas en la GxEPD2 Libary. Por lo tanto, usamos una coincidencia cercana para crear el objeto epd que representa nuestro display E-Paper:

GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> epd(GxEPD2_420_GYE042A87(CS, DC, RES, BUSY));

Alternativamente, también puedes usar la clase GxEPD2_420_GDEY042T81. Ambas parecen funcionar, pero en el siguiente código usé la clase GxEPD2_420_GYE042A87.

Función epdPower

La función epdPower() es crítica y especial. Para otras pantallas E-Paper no la necesitas, pero para el CrowPanel sí. Configura GPIO7 en alto o bajo y por lo tanto habilita o deshabilita la pantalla E-Paper.

void epdPower(int state) { 
  pinMode(PWR, OUTPUT);  
  digitalWrite(PWR, state);  
}

Ten en cuenta que puedes desactivar la pantalla E-Paper (epdPower(LOW)) una vez que hayas dibujado en ella. Seguirá mostrando la imagen, incluso sin alimentación.

Función epdInit

La función epdInit() realiza la configuración inicial habitual para los gráficos, como la rotación de pantalla, color de texto, tamaño de texto y modo de refresco.

void epdInit() {  
  epd.init(115200, true, 50, false);
  epd.setRotation(0);
  epd.setTextColor(GxEPD_BLACK);
  epd.setTextSize(4);
  epd.setFullWindow();
}

Función setup

En la función setup(), encendemos la pantalla, llenamos la pantalla de blanco, dibujamos un marco, imprimimos el texto «Makerguides», lo mostramos y luego apagamos la pantalla nuevamente.

void setup() {
  epdPower(HIGH);
  epdInit();
  epd.fillScreen(GxEPD_WHITE);
  epd.drawRect(0, 0, 400, 300, GxEPD_BLACK);
  epd.setCursor(70, 130);
  epd.print("Makerguides");
  epd.display();
  epd.hibernate(); 
  epdPower(LOW);
}

Si subes y ejecutas este código deberías ver la siguiente salida en la pantalla E-Paper:

Salida de prueba en CrowPanel E-Paper de 4.2 pulgadas

Así que, con la adición de la función epdPower() puedes usar la GxEPD2 Libary como de costumbre para dibujar y escribir en el CrowPanel E-Paper de 4.2 pulgadas. En la siguiente sección probamos el refresco parcial.

Refresco parcial en display E-Paper CrowPanel

En el código anterior realizamos un refresco completo del contenido del E-Paper. Este refresco completo es ocasionalmente necesario para eliminar imágenes residuales, pero es lento (varios segundos) y causa mucho parpadeo en la pantalla.

Para la mayoría de las aplicaciones quieres actualizar solo una parte de la pantalla, sin parpadeo y mucho más rápido. Por ejemplo, para mostrar los dígitos de un reloj en marcha. Un refresco parcial te permite hacer eso. Para más detalles, echa un vistazo al tutorial Partial Refresh of e-Paper Display.

El siguiente código es esencialmente el mismo que se usa en ese tutorial. Primero realiza un refresco completo para limpiar la pantalla e imprime el texto «msec:». Luego realiza continuamente un refresco parcial y actualiza los milisegundos en curso. A continuación hay una captura de pantalla de la salida en la pantalla:

Display output for full- and partial refresh
Salida en pantalla para refresco completo y parcial

Aquí está el código completo para esta prueba. La única diferencia con el del tutorial Partial Refresh of e-Paper Display es que necesitamos usar la función epdPower() nuevamente para encender la pantalla. Y por supuesto el controlador de pantalla es diferente.

#include "GxEPD2_BW.h"

#define PWR 7
#define BUSY 48
#define RES 47
#define DC 46
#define CS 45

GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> epd(GxEPD2_420_GYE042A87(CS, DC, RES, BUSY));

void epdPower(int state) { 
  pinMode(PWR, OUTPUT);  
  digitalWrite(PWR, state);  
}

void drawFull(const void* pv) {
  epd.setFullWindow();
  epd.setCursor(40, 60);
  epd.print("msec: ");
}

void drawPartial(const void* pv) {
  uint16_t x = 120, y = 50, w = 130, h = 34;
  epd.setPartialWindow(x, y, w, h);
  epd.setCursor(x + 30, y + 10);
  epd.print(millis());
  epd.drawRect(x, y, w, h, GxEPD_BLACK);
}

void setup() {
  epdPower(HIGH);
  epd.init(115200, true, 50, false);
  epd.setRotation(0);
  epd.setTextSize(2);
  epd.setTextColor(GxEPD_BLACK);
  epd.drawPaged(drawFull, 0);  
}

void loop() {
  epd.drawPaged(drawPartial, 0);
  epd.hibernate();
}

Si subes y ejecutas este código deberías ver la siguiente salida. Ten en cuenta que los milisegundos se actualizan en menos de 0.5 segundos y que casi no hay parpadeo (solo un poco alrededor del marco):

Partial refresh on CrowPanel 4.2-inch E-Paper
Refresco parcial en CrowPanel E-Paper de 4.2 pulgadas

Así que, el refresco completo y parcial funcionan bien en el CrowPanel E-Paper de 4.2 pulgadas con el controlador GxEPD2 elegido GxEPD2_420_GYE042A87.

En la siguiente y última sección, te mostraré cómo usar el refresco parcial y los botones del display CrowPanel para implementar un menú simple que controle tres LEDs.

Controlando GPIO vía menú en display E-Paper CrowPanel

Una de las demos para el display CrowPanel muestra un menú simple con ítems que pueden activarse o desactivarse mediante pulsaciones de botones.

Aquí vamos a construir algo similar. Pero usaremos la biblioteca GxEPD2 y nuestros botones controlarán tres LEDs. La captura de pantalla a continuación muestra cómo se verá el menú:

Menú de selección de LED en display CrowPanel

Podremos navegar el menú con los botones arriba y abajo del interruptor rotatorio y seleccionar un ítem con el botón de confirmación. Si un ítem está seleccionado, se encenderá un LED del color correspondiente conectado al GPIO, por ejemplo, seleccionar «Red» encenderá un LED rojo:

Red LED selected in Menu
LED rojo seleccionado en el menú

Diagrama de conexiones

El diagrama de conexiones a continuación muestra cómo conectar los tres LEDs al puerto GPIO del display CrowPanel. El cátodo de cada LED está conectado a tierra (GND). El ánodo del LED rojo está conectado a GPIO3, el LED verde a GPIO9 y el azul a GPIO15. Usé una resistencia limitadora de corriente de 220Ω para cada LED:

Connecting three LEDs to CrowPanel Display
Conexión de tres LEDs al display CrowPanel

Código para navegar el menú y controlar los LEDs

A continuación encontrarás el código para navegar el menú, seleccionar y deseleccionar ítems y controlar los LEDs correspondientemente:

#include "GxEPD2_BW.h"
#include <Fonts/FreeMonoBold24pt7b.h>

#define PWR 7
#define BUSY 48
#define RES 47
#define DC 46
#define CS 45
#define W 400
#define H 300

#define HOME_KEY 2
#define EXIT_KEY 1
#define PREV_KEY 6
#define NEXT_KEY 4
#define OK_KEY 5

int cursor = 0;
const int xoff = 70;
const int n_items = 3;
const char* items[] = { "Red", "Green", "Blue" };
const int pins[] = { 3, 9, 15 };
bool states[] = { false, false, false };
const int ypos[] = { 100, 100 + 60, 100 + 2 * 60 };

GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> epd(GxEPD2_420_GYE042A87(CS, DC, RES, BUSY));


void epdPower(int state) { 
  pinMode(PWR, OUTPUT);  
  digitalWrite(PWR, state);  
}

void drawCursor() {
  int16_t s = 12;
  int16_t x0 = xoff - s;
  int16_t y0 = ypos[cursor] - 12;
  int16_t x1 = x0 - s;
  int16_t y1 = y0 - s;
  int16_t x2 = x0 - s;
  int16_t y2 = y0 + s;
  epd.fillTriangle(x0, y0, x1, y1, x2, y2, GxEPD_BLACK);
}

void updateCursor(const void* pv) {
  epd.setPartialWindow(0, 0, xoff, 300);
  drawCursor();
}

void drawItem(int index) {
  int16_t xb, yb;
  uint16_t wb, hb;
  epd.setCursor(xoff + 5, ypos[index]);
  epd.getTextBounds(items[index], xoff + 5, ypos[index], &xb, &yb, &wb, &hb);
  if (states[index]) {
    epd.setTextColor(GxEPD_WHITE);
    epd.fillRect(xb - 5, yb - 3, W - 2 * xoff, hb + 6, GxEPD_BLACK);
  } else {
    epd.setTextColor(GxEPD_BLACK);
    epd.fillRect(xb - 5, yb - 3, W - 2 * xoff, hb + 6, GxEPD_WHITE);
  }
  epd.print(items[index]);
}

void updateItems(const void* pv) {
  epd.setPartialWindow(xoff, 0, W - xoff, 300);
  drawItems();
}

void drawItems() {
  for (int i = 0; i < n_items; i++) {
    drawItem(i);
  }
}

void initEPD() {
  epdPower(HIGH);
  epd.init(115200, true, 50, false);
  epd.setRotation(0);
  epd.setTextColor(GxEPD_BLACK);
  epd.setFont(&FreeMonoBold24pt7b);
  epd.setFullWindow();
  epd.fillScreen(GxEPD_WHITE);
}

void initButtons() {
  pinMode(HOME_KEY, INPUT);
  pinMode(EXIT_KEY, INPUT);
  pinMode(PREV_KEY, INPUT);
  pinMode(NEXT_KEY, INPUT);
  pinMode(OK_KEY, INPUT);
}

void initPins() {
  for (int i = 0; i < n_items; i++) {
      pinMode(pins[i], OUTPUT);
  }    
}

void setup() {
  initEPD();
  initButtons();
  initPins();
  drawItems();
  drawCursor();
  epd.display();
}

void loop() {
  if (!digitalRead(PREV_KEY)) {
    cursor = --cursor < 0 ? n_items - 1 : cursor;
    epd.drawPaged(updateCursor, 0);
  }
  if (!digitalRead(NEXT_KEY)) {
    cursor = ++cursor >= n_items ? 0 : cursor;
    epd.drawPaged(updateCursor, 0);
  }
  if (!digitalRead(OK_KEY)) {
    states[cursor] = !states[cursor];
    epd.drawPaged(updateItems, 0);
    digitalWrite(pins[cursor], states[cursor] ? HIGH : LOW);
  }
  if (!digitalRead(HOME_KEY)) {
    cursor = 0;
    epd.drawPaged(updateCursor, 0);
  }  
  if (!digitalRead(EXIT_KEY)) {
    for (int i = 0; i < n_items; i++) {
      states[i] = false;
      digitalWrite(pins[i], LOW);  
    }      
    epd.drawPaged(updateItems, 0);
  }
  delay(100);
}

Vamos a desglosar el código en sus componentes para una mejor comprensión.

Librerías y constantes

Comenzamos incluyendo las librerías necesarias para el display E-Paper y fonts. Las constantes definen los pines usados para la pantalla y botones, así como las dimensiones del display.

#include "GxEPD2_BW.h"
#include <Fonts/FreeMonoBold24pt7b.h>

#define PWR 7
#define BUSY 48
#define RES 47
#define DC 46
#define CS 45
#define W 400
#define H 300

Definiciones de botones

Definimos los pines para los botones que se usarán para navegar el menú. Cada botón tiene una función específica: HOME, EXIT, PREV, NEXT y OK.

#define HOME_KEY 2
#define EXIT_KEY 1
#define PREV_KEY 6
#define NEXT_KEY 4
#define OK_KEY 5

Variables

Se declaran varias variables para manejar el estado del menú. cursor lleva el seguimiento de la selección actual, items contiene los nombres de los LEDs, y states rastrea si cada LED está encendido o apagado. ypos especifica dónde están ubicados los ítems del menú en la pantalla.

int cursor = 0;
const char* items[] = { "Red", "Green", "Blue" };
const int pins[] = { 3, 9, 15 };
bool states[] = { false, false, false };
const int ypos[] = { 100, 160, 220 };

Objeto display E-Paper

Como antes, el objeto display E-Paper se crea usando la clase GxEPD2_BW. Esto configura la pantalla con los pines especificados. Si tienes un display E-Paper CrowPanel diferente, tendrás que cambiar esta línea.

GxEPD2_BW<GxEPD2_420_GYE042A87, GxEPD2_420_GYE042A87::HEIGHT> epd(GxEPD2_420_GYE042A87(CS, DC, RES, BUSY));

Función de control de energía

La función epdPower() controla la alimentación del display E-Paper. Configura el pin de energía como salida y escribe el estado especificado (HIGH o LOW).

void epdPower(int state) { 
  pinMode(PWR, OUTPUT);  
  digitalWrite(PWR, state);  
}

Función para dibujar cursor

La función drawCursor() representa visualmente la selección actual en el menú dibujando un triángulo en la posición correspondiente.

void drawCursor() {
  int16_t s = 12;
  int16_t x0 = xoff - s;
  int16_t y0 = ypos[cursor] - 12;
  epd.fillTriangle(x0, y0, x1, y1, x2, y2, GxEPD_BLACK);
}

Ten en cuenta que la función updateCursor() realiza un refresco parcial y solo actualiza la sección de la pantalla donde se muestra el cursor. Se llamará cuando se presionen los botones Arriba o Abajo, por ejemplo.

void updateCursor(const void* pv) {
  epd.setPartialWindow(0, 0, xoff, 300);
  drawCursor();
}

Función para dibujar ítems

La función drawItem() muestra un ítem en el menú. Verifica el estado del LED y cambia el fondo a negro si un ítem está seleccionado.

void drawItem(int index) {
  epd.setCursor(xoff + 5, ypos[index]);
  if (states[index]) {
    epd.setTextColor(GxEPD_WHITE);
    epd.fillRect(...);
  } else {
    epd.setTextColor(GxEPD_BLACK);
    epd.fillRect(...);
  }
  epd.print(items[index]);
}

Para dibujar todos los ítems del menú se usa la función drawItems():

void drawItems() {
  for (int i = 0; i < n_items; i++) {
    drawItem(i);
  }
}

Y el estado de todos los ítems se actualiza realizando un refresco parcial de la pantalla, donde están ubicados los ítems del menú:

void updateItems(const void* pv) {
  epd.setPartialWindow(xoff, 0, W - xoff, 300);
  drawItems();
}

Funciones de inicialización

Se definen varias funciones de inicialización: initEPD() inicializa el display E-Paper, initButtons() configura los pines de los botones como entradas, y initPins() configura los pines de los LEDs como salidas.

void initEPD() {
  epdPower(HIGH);
  ...
}

void initButtons() {
  pinMode(HOME_KEY, INPUT);
  ...
}

void initPins() {
  for (int i = 0; i < n_items; i++) {
      pinMode(pins[i], OUTPUT);
  }    
}

Función setup

La función setup() se llama una vez cuando inicia el programa. Inicializa el display E-Paper, los botones y los pines de los LEDs, y dibuja los ítems iniciales y el cursor en la pantalla.

void setup() {
  initEPD();
  initButtons();
  initPins();
  drawItems();
  drawCursor();
  epd.display();
}

Función loop

La función loop() se ejecuta continuamente. Verifica el estado de los botones y actualiza la posición del cursor o alterna el estado de los LEDs según la entrada del usuario. La pantalla se actualiza usando un redibujado paginado con refresco parcial.

void loop() {
  if (!digitalRead(PREV_KEY)) {
    ...
  }
  if (!digitalRead(NEXT_KEY)) {
    ...
  }
  if (!digitalRead(OK_KEY)) {
    ...
  }
  if (!digitalRead(HOME_KEY)) {
    ...
  }  
  if (!digitalRead(EXIT_KEY)) {
    ...
  }
  delay(100);
}

El botón PREV_KEY mueve el cursor un ítem hacia arriba y el NEXT_KEY lo mueve un ítem hacia abajo. Si se llega al final o al principio del menú, el cursor se envuelve.

Con el botón OK_KEY puedes alternar el estado de un ítem. El botón HOME_KEY mueve el cursor al primer ítem del menú y el botón EXIT_KEY deselecciona todos los ítems.

Demostración del código

En resumen, este código proporciona una interfaz de usuario en un display E-Paper para controlar tres LEDs. El usuario puede navegar por las opciones y alternar los LEDs encendidos o apagados usando botones físicos. El siguiente video corto muestra cómo se ve esto:

Controlando LEDs con menú en display E-Paper

Conclusiones

En este tutorial aprendiste cómo usar la biblioteca GxEPD2 para dibujar y escribir en un Display E-Paper CrowPanel de 4.2 pulgadas.

Si necesitas más información de fondo sobre pantallas E-Paper, echa un vistazo al Interfacing Arduino with E-ink Display y al tutorial Partial Refresh of e-Paper Display.

Además, si buscas otras aplicaciones, los tutoriales Weather Station on e-Paper Display, Temperature Plotter on e-Paper Display, Digital Clock on e-Paper Display y Analog Clock on e-Paper Display pueden ser de interés.

Si tienes alguna pregunta, no dudes en preguntar en la sección de comentarios. ¡Feliz bricolaje ; )

Enlaces

A continuación algunos enlaces sobre el Display E-Paper CrowPanel de 4.2 pulgadas que encontré útiles al escribir este tutorial: