Skip to Content

Ecrã E-paper de 4 cores com ESP32

Ecrã E-paper de 4 cores com ESP32

Neste tutorial, vais aprender a usar o Waveshare 3-inch 4-color E-paper display com um ESP32.

O módulo de ecrã E-paper de 3 polegadas e 4 cores da Waveshare é um excelente hardware, mas o Demo software só tem exemplos para Arduino, STM32 e Raspberry. Portanto, se quiseres usar o ecrã com um ESP32, estás sem sorte.

Além disso, o exemplo do Arduino apenas mostra como exibir uma imagem estática pré-feita, não como criar e mostrar conteúdo dinamicamente, por exemplo, um relógio a funcionar ou uma estação meteorológica.

Seria ótimo se pudéssemos usar a biblioteca GxEPD2, mas em dezembro de 2024 ainda não tem driver para o E-paper de 3 polegadas e 4 cores. Por isso, implementei uma biblioteca simples (epd4c), que faz essencialmente o mesmo.

Neste tutorial, mostro-te como fazer o código de exemplo do Arduino funcionar com um ESP32, como criar conteúdo dinamicamente usando uma canvas e como usar a biblioteca epd4c.

Peças Necessárias

Estou a usar o ESP32 lite como microprocessador, porque é barato e tem interface para bateria. Como os ecrãs E-paper consomem muito pouca energia, são uma ótima escolha para projetos alimentados a bateria, e o ESP32 lite encaixa bem aqui. No entanto, qualquer outro ESP32 também funciona.

Obviamente, também vais precisar do módulo de ecrã E-paper de 3 polegadas e 4 cores listado abaixo. Testei o código com esse, mas deve funcionar também com o 2.13-inch 4-color E-Paper ou o 2.66-inch 4-color E-Paper. Contudo, não suporta ecrãs a 3 cores ou preto e branco.

Ecrã E-paper de 3 polegadas e 4 cores

ESP32 lite Lolin32

ESP32 lite

USB data cable

Cabo USB de Dados

Dupont wire set

Conjunto de Fios Dupont

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.

Ecrã E-paper de 3″ e 4 cores

O ecrã E-paper usado neste projeto é um módulo de 3 polegadas, com resolução de 400×168 pixels, 4 cores (branco, preto, vermelho, amarelo), tempo de atualização de 12 segundos (apenas atualização total suportada) e um controlador embutido com interface SPI.

Front and Back of 3" 4-color e-Paper display module
Frente e verso do módulo de ecrã E-paper de 3″ e 4 cores

Note que o módulo tem um pequeno jumper/chave na parte de trás para alternar entre SPI de 4 fios e SPI de 3 fios. Vamos usar o SPI de 4 fios por defeito aqui, por isso não precisas de alterar nada.

Back of display module with SPI-interface and controller
Parte de trás do módulo de ecrã com interface SPI e controlador

O módulo funciona a 3.3V ou 5V, tem uma corrente de sono muito baixa de 0.01µA e consome cerca de 60mW durante a atualização. Para mais informações sobre ecrãs E-paper em geral, vê o tutorial Interfacing Arduino To An E-ink Display.

Abaixo está o datasheet do ecrã e também vê o Waveshare manual:

Ligação do ecrã E-paper de 4 cores ao ESP32

Nesta secção vamos ligar o ecrã E-paper a um ESP32 lite. A imagem seguinte mostra toda a ligação entre o ESP32 e o ecrã para alimentação e interface SPI.

Connecting 4-color e-Paper to ESP32 lite via SPI
Ligação do ecrã E-paper de 4 cores ao ESP32 lite via SPI

Podes alimentar o ecrã com 3.3V ou 5V, mas o ESP32-lite só tem saída de 3.3V. Nota que tens de usar os pinos SPI hardware do microcontrolador. No caso do ESP32-lite, são os pinos 18 e 23. Abaixo está uma tabela com todas as ligações para conveniência.

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

Fazer o código de demonstração funcionar com ESP32

Se descarregares o Demo software para o ecrã E-paper da Waveshare, vais encontrar uma pasta dentro desse ficheiro zip chamada Arduino/epd3in0g. Lá dentro está um sketch chamado epd3in0g.ino que essencialmente produz a seguinte imagem no ecrã:

Demo image for 3" 4-color e-Paper
Imagem de demonstração para ecrã E-paper de 3″ e 4 cores

Aqui está o trecho reduzido desse código de exemplo que produz a imagem. Podes ver que cria o objeto do ecrã epd, inicializa-o, mostra os dados da imagem e depois coloca o ecrã em modo de sono:

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

Epd epd;

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

void loop() { }

Este código não funciona num ESP32. No entanto, podes fazê-lo funcionar seguindo os passos abaixo (vê este blog post para mais contexto):

  • Muda const unsigned char para unsigned char em imagedata.cpp e imagedata.h
  • Muda #include <avr/pgmspace> para #include <pgmspace> em imagedata.h
  • Muda as definições dos pinos em epdif.h para usar os pinos SPI hardware do ESP32
  • Adiciona SPI.endTransaction(); à função IfInit() em epdif.cpp

Aqui estão as definições dos pinos que precisas de usar em epdif.h:

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

e aqui está o código em epdif.cpp que tens de mudar de

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

para este código adicionando uma linha (endTransaction):

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

Com essas alterações, o código de exemplo deve funcionar. No entanto, ainda está limitado à exibição de imagens estáticas. Na próxima secção, mostro-te uma pequena adição que permite usar a biblioteca gráfica Adafruit_GFX para mostrar conteúdo dinamicamente, como texto e gráficos.

Desenhar no ecrã E-paper de 4 cores usando a canvas Adafruit_GFX

A biblioteca Adafruit_GFX é uma biblioteca gráfica que fornece um conjunto comum de graphics primitives (texto, pontos, linhas, círculos, etc.). Basta instalá-la via Library Manager como de costume. Após a instalação, deve aparecer no Library Manager assim:


Adafruit_GFX in Library Manager
Adafruit_GFX no Library Manager

A biblioteca Adafruit_GFX tem o conceito de “canvas” que te permite desenhar num buffer do ecrã (=canvas) em segundo plano (sem mostrar). Abaixo está um trecho de código que cria uma canvas de 8 bits de profundidade com as dimensões do ecrã E-paper.

#include "Adafruit_GFX.h"

GFXcanvas8 canvas(EPD_WIDTH, EPD_HEIGHT);

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

Depois define a orientação do buffer/ecrã, preenche o buffer com branco e desenha um círculo vermelho. Como o buffer é essencialmente uma imagem, seria ótimo se pudéssemos usar o seguinte código para mostrar o desenho no buffer no E-paper:

 epd.Display(canvas.getBuffer());

No entanto, o E-paper de 4 cores usa uma imagem comprimida, onde quatro pixels são comprimidos num byte para poupar memória. Como só há quatro cores, cada cor pode ser representada por 2 bits:

CorBits
preto 00
branco01
amarelo 10
vermelho 11

O que significa que, se tivermos uma sequência de quatro pixels com as cores preto, branco, amarelo e vermelho na imagem original, podemos comprimi-la num byte (00011011 = 0x1B) assim:

Four pixels with 2-bit color codes
Quatro pixels com códigos de cor de 2 bits

Tens de fazer isto para todos os blocos de 4 pixels na imagem original para criar uma imagem comprimida que pode ser mostrada no E-paper via epd.Display(image). A seguinte função compress() pega no buffer do canvas e comprime-o como descrito:

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;
}

Note que reutiliza o buffer do ecrã. Portanto, não é necessária memória adicional para a imagem comprimida, mas não podes desenhar na canvas depois de comprimida. Terás de a limpar primeiro.

Com a função compress() podes criar conteúdo dinamicamente e mostrar no E-paper. A estrutura do código é esta:

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();
}

Aqui está um exemplo completo com tudo incluído:

#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() {
}

Se carregares e executares este código, deverás ver um círculo amarelo num fundo vermelho com o texto “Test” no meio:

Output example for compress() function
Exemplo de saída para a função compress()

Embora o código acima funcione, é um pouco complicado de usar. Primeiro, tens de integrar os ficheiros do código de demonstração da Waveshare (epd3in0g.h, epd3in0g.cpp, epdif.h, epdif.cpp) em cada novo projeto que use o ecrã E-paper. Segundo, tens de reimplementar a função compress() cada vez.

Por isso, criei uma pequena biblioteca chamada epd4c, que evita tudo isso. Só tens de a instalar e depois podes usá-la independentemente do código de demonstração. Na próxima secção, mostro como funciona.

Desenhar no ecrã E-paper de 4 cores usando a biblioteca epd4c

Para instalar a epd4c Library, vai ao epd4c_arduino_lib github repo e clica no botão verde “Code“. Depois clica em “Download Zip” como mostrado abaixo:

Download EPD4c Library library
Descarregar biblioteca EPD4c

Depois vai a “Sketch" -> "Include Library" -> "Add .Zip Library..” e seleciona o ficheiro “epd4c_arduino_lib-main.zip” que acabaste de descarregar:

Adding TOF10120 library to sketch
Adicionar biblioteca EPD4c ao sketch

Com a biblioteca epd4c (e a biblioteca Adafruit_GFX), escrever texto e desenhar no ecrã E-paper de 4 cores fica muito mais fácil.

Código de exemplo

Aqui está um código de exemplo. Desenha uma série de círculos coloridos junto com um texto centrado no ecrã. Como podes ver, já não é necessário um canvas separado nem usar o código de demonstração da Waveshare.

#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() {}

Vamos decompor o código em componentes para melhor compreensão.

Inclusão da Biblioteca

Começamos por incluir a biblioteca epd4c para controlar o ecrã E-paper, que é uma extensão da biblioteca Adafruit_GFX canvas, e por isso suporta todas as graphics primitives da biblioteca Adafruit_GFX.

#include "epd4c.h"

Definições dos Pinos

De seguida, definimos os pinos usados para ligar o ecrã E-paper ao ESP32. Nota que os pinos SPI não podem ser definidos. Tens de usar e ligar aos pinos SPI hardware por defeito do teu microcontrolador.

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

Dimensões do Ecrã

Também definimos a largura e altura do ecrã E-paper. Como mencionado, o código deve funcionar para outros ecrãs E-paper de 4 cores, com dimensões diferentes, mas não testei isso.

#define EPD_WIDTH 168
#define EPD_HEIGHT 400

Criação do Objeto do Ecrã

Aqui, criamos uma instância da classe Epd4c, passando as dimensões do ecrã e as definições dos pinos como parâmetros. Este objeto será usado para controlar o ecrã durante o programa.

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

Função Setup

Na função setup(), inicializamos o ecrã E-paper e configuramos as suas definições. Aqui definimos a rotação do ecrã, preenchemos o ecrã com branco e desenhamos vários círculos sobrepostos de cores e tamanhos diferentes.

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();
}

A saída no ecrã E-paper será a seguinte

Output on 3" 4-color E-paper Display
Saída no ecrã E-paper de 3″ e 4 cores

onde

  • epd.init(); inicializa o ecrã.
  • epd.setRotation(1); define a orientação do ecrã.
  • epd.fillScreen(WHITE); preenche todo o ecrã com cor branca.
  • As funções fillCircle() desenham círculos de vários raios e cores nas coordenadas especificadas (200, 84).
  • epd.setCursor(190, 80); define a posição para o texto a imprimir.
  • epd.setTextColor((BLACK)); define a cor do texto para preto.
  • epd.print("Test"); imprime o texto “Test” no ecrã.
  • epd.display(); atualiza o ecrã com os gráficos desenhados
  • epd.sleep(); coloca o ecrã em modo de sono para poupar energia.

Função Loop

A função loop() está vazia neste exemplo, o que significa que, uma vez concluído o setup, o programa não executa mais ações. O ecrã permanecerá em modo de sono e continuará a mostrar a imagem, mesmo quando o ESP32 estiver desligado.

void loop() {}

Se quiseres atualizar o conteúdo continuamente, por exemplo, para mostrar um relógio a funcionar, colocarias o código gráfico na função loop. Vê os tutoriais Digital Clock on e-Paper Display ou Weather Station on e-Paper Display para exemplos.

E é tudo!

Conclusões

Neste tutorial aprendeste a controlar o ecrã E-paper de 3 polegadas e 4 cores da Waveshare com um ESP32.

Mostrei-te como alterar o código de demonstração do Arduino para funcionar com um ESP32. Também usamos a Adafruit_GFX canvas para criar conteúdo dinamicamente para o ecrã E-paper. E finalmente, apresentei-te a biblioteca epd4c.

A biblioteca epd4c faz essencialmente o mesmo que a biblioteca GxEPD2, mas infelizmente esta última atualmente não suporta o ecrã E-paper de 3 polegadas e 4 cores da Waveshare. Eu preferia que suportasse. Poderia ter estendido a biblioteca GxEPD2, mas fui preguiçoso e simplesmente limpei e estendi o código de demonstração da Waveshare para criar a biblioteca epd4c.

Se tiveres alguma dúvida, não hesites em deixar nos comentários.

Boas experiências a criar ; )