EP-0133

From 52Pi Wiki
Jump to navigation Jump to search

2.13 inch E-paper (BRW)

Display 1 2.jpg

Descriptions

Electronic paper, also sometimes electronic ink(E-Ink) or electrophoretic display, are display devices that mimic the appearance of ordinary ink on paper.
Electrodes located above and below the capsules move up and down when a positive or negative electric field is applied, which makes the surface of the electronic paper display reflect a certain color.
The consumption of E-ink is very low during operation.
Once the data is refreshed on the screen, it can be kept for a long time without power consumption.
It is very suitable for displaying some specific information for a long time.
The only drawback may be the slow refresh speed.
The E-Ink provided by the product supports BRW three colors, B stands for black, R stands for red, and W stands for white, which can be refreshed on the screen through the picture file created in advance.

Features

  • High Contrast
  • Sunlight Readable
  • low-power performance attributes
  • Easy To Assemble

Specifications

Display 5.jpg


  • 122×250 pixels display
  • High contrast High reflectance
  • Ultra wide viewing angle Ultra low power consumption
  • Pure reflective mode
  • Bi-stable display
  • Commercial temperature range
  • Landscape portrait modes
  • Hard-coat antiglare display surface
  • Ultra Low current deep sleep mode
  • On chip display RAM
  • Waveform can stored in On-chip OTP or written by MCU
  • Serial peripheral interface available
  • On-chip oscillator
  • On-chip booster and regulator control for generating VCOM, Gate and Source driving voltage
  • I2C signal master interface to read external temperature sensor
  • Built-in temperature sensor
Display 6.jpg


Mechanical Specification

Parameter Specifications Unit Remark
Screen Size 2.13 Inch -
Display Resolution 122(H)×250(V) Pixel DPI:130
Active Area 23.705×48.55 mm -
Pixel Pitch 0.1942×0.1942 mm -
Pixel Configuration Square - -
Outline Dimension 29.2(H)×59.2 (V) ×1.0(D) mm -
Screen Weight 3.2±0.5 g -

Gallery

  • Product Outlook
Display 2.jpg
Display 3.jpg
Display 4.jpg

Package Includes

  • 1 x 2.13 inch E-paper (BRW)

How To Use

How To Assemble

  • Just connect the Hat board of the e-paper to the GPIO pins of the Raspberry Pi as shown below.
Display 7.jpg


How To Configure

  • Test Environment:
Item Details
Hardware Raspberry Pi 3B/3B+/4B/Zero/Zero W, 2.13 inch E-paper(BRW), 5V/3A USB-C power supply
OS Raspberry Pi OS
Distributor ID Raspbian
Description Raspbian GNU/Linux 10 (buster)
Release 10
Codename buster
Kernel Version 5.4.79-v7l+
Dependent library libpng-dev Version: 1.6.36-6
Dependent Third Part library wiringPi gpio version: 2.52

Pin Definitions

Physical Number GPIO Pin number in BCM Naming System Function Note
19 10 MOSI Master Output Slave Input
23 11 SCLK SPI Clock Pin
24 8 CE0 Chip Select
11 17 IO17 GPIO.0
18 24 IO24 GPIO.5
22 25 IO25 GPIO.6
1 - 3V3 3.3V Power
6/9/14/25/30/34/39 - GND Ground
  • Software configuration Steps

1. After assembling, boot up Raspberry Pi and login, make sure your Pi can access internet, and then open a terminal and typing:

sudo apt-get update
sudo apt-get -y install libpng-dev
sudo apt-get -y purge wiringpi
sudo hash -r
cd /tmp
wget https://project-downloads.drogon.net/wiringpi-latest.deb
sudo dpkg -i wiringpi-latest.deb
gpio -v

If the content shown in the figure appears in the terminal, the basic environment has been installed.

WiringPigpio2.52.jpg


Demo Code

  • Language C

Create a new file and name it: epaper.c, copy and paste following code:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <wiringPi.h>
#include <wiringPiSPI.h>      // Require wiringPi library 

#define PNG_DEBUG 3
#include <png.h>

#define RESET_PIN 0
#define DC_PIN 6
#define BUSY_PIN 5

int fd;
int x, y;

int width, height;
png_byte color_type;
png_byte bit_depth;

png_structp png_ptr;
png_infop info_ptr;
int number_of_passes;
png_bytep *row_pointers;

/* Declear functions */
void abort_(const char *s, ...);
void read_png_file(char *file_name);
void process_file(void);
void DEPG0213RWS800F13_Wait(void);
void DEPG0213RWS800F13_Command(uint8_t cmd);
void DEPG0213RWS800F13_Data(uint8_t data);
void DEPG0213RWS800F13_RedOn(void);
void DEPG0213RWS800F13_RedOff(void);
void DEPG0213RWS800F13_BlackOn(void);
void DEPG0213RWS800F13_BlackOff(void);
void DEPG0213RWS800F13_UpdateAndSleep(void);
void DEPG0213RWS800F13_Init(void);

void abort_(const char *s, ...)
{
      va_list args;
      va_start(args, s);
      vfprintf(stderr, s, args);
      fprintf(stderr, "\n");
      va_end(args);
      abort();
}

void read_png_file(char *file_name)
{
      char header[8]; // 8 is the maximum size that can be checked

      /* open file and test for it being a png */
      FILE *fp = fopen(file_name, "rb");
      if (!fp)
            abort_("[read_png_file] File %s could not be opened for reading", file_name);
      fread(header, 1, 8, fp);
      if (png_sig_cmp(header, 0, 8))
            abort_("[read_png_file] File %s is not recognized as a PNG file", file_name);

      /* initialize stuff */
      png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

      if (!png_ptr)
            abort_("[read_png_file] png_create_read_struct failed");

      info_ptr = png_create_info_struct(png_ptr);
      if (!info_ptr)
            abort_("[read_png_file] png_create_info_struct failed");

      if (setjmp(png_jmpbuf(png_ptr)))
            abort_("[read_png_file] Error during init_io");

      png_init_io(png_ptr, fp);
      png_set_sig_bytes(png_ptr, 8);

      png_read_info(png_ptr, info_ptr);

      width = png_get_image_width(png_ptr, info_ptr);
      height = png_get_image_height(png_ptr, info_ptr);
      color_type = png_get_color_type(png_ptr, info_ptr);
      bit_depth = png_get_bit_depth(png_ptr, info_ptr);

      number_of_passes = png_set_interlace_handling(png_ptr);
      png_read_update_info(png_ptr, info_ptr);

      /* read file */
      if (setjmp(png_jmpbuf(png_ptr)))
            abort_("[read_png_file] Error during read_image");

      row_pointers = (png_bytep *)malloc(sizeof(png_bytep) * height);
      for (y = 0; y < height; y++)
            row_pointers[y] = (png_byte *)malloc(png_get_rowbytes(png_ptr, info_ptr));

      png_read_image(png_ptr, row_pointers);

      fclose(fp);
}

void process_file(void)
{
      uint16_t i;
      uint8_t tmp = 0;
      uint8_t rBuf[4000] = {0x00};
      uint8_t bBuf[4000] = {0x00};

      if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB)
            abort_("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGBA "
                   "(lacks the alpha channel)");
      for (y = 0; y < height; y++)
      {
            png_byte *row = row_pointers[y];
            for (x = 0; x < width; x++)
            {
                  png_byte *ptr = &(row[x * 3]);

                  // Extract the red color of the drawing board
                  if (ptr[0] == 237 && ptr[1] == 28 && ptr[2] == 36)
                  {
                        //     printf("Pixel at position [ %d - %d ] has Red Color.\n",x, y);
                        // We must first calculate which byte this pixel falls on
                        tmp = rBuf[16 * y + (15 - x / 8)];
                        rBuf[16 * y + (15 - x / 8)] = tmp | (1 << (x % 8));
                  }
                  // Extract the black color of the drawing board
                  else if (ptr[0] == 255 && ptr[1] == 255 && ptr[2] == 255)
                  {
                        //     printf("Pixel at position [ %d - %d ] has Black Color.\n",x, y);
                        // We must first calculate which byte this pixel falls on
                        tmp = bBuf[16 * y + (15 - x / 8)];
                        bBuf[16 * y + (15 - x / 8)] = tmp | (1 << (x % 8));
                  }
                  ptr[0] = 0;
                  ptr[1] = ptr[2];
            }
      }

      DEPG0213RWS800F13_Init();

      DEPG0213RWS800F13_Wait();
      DEPG0213RWS800F13_Command(0x26);
      for (i = 0; i < 4000; i++)
      {
            DEPG0213RWS800F13_Data(rBuf[i]);
      }
      DEPG0213RWS800F13_Wait();
      DEPG0213RWS800F13_Command(0x24);
      for (i = 0; i < 4000; i++)
      {
            DEPG0213RWS800F13_Data(bBuf[i]);
      }

      DEPG0213RWS800F13_UpdateAndSleep();
}

void DEPG0213RWS800F13_Wait(void)
{
      while (1)
      {
            if (digitalRead(BUSY_PIN) == 0)
                  break;
            usleep(5);
      }
      usleep(100);
}

void DEPG0213RWS800F13_Command(uint8_t cmd)
{
      digitalWrite(DC_PIN, 0);
      uint8_t buffer[1] = {cmd};
      wiringPiSPIDataRW(fd, buffer, 1);
}

void DEPG0213RWS800F13_Data(uint8_t data)
{
      digitalWrite(DC_PIN, 1);
      uint8_t buffer[1] = {data};
      wiringPiSPIDataRW(fd, buffer, 1);
}

void DEPG0213RWS800F13_RedOn(void)
{
      uint16_t i;
      DEPG0213RWS800F13_Wait();
      DEPG0213RWS800F13_Command(0x26);
      for (i = 0; i < 4000; i++)
      {
            DEPG0213RWS800F13_Data(0xFF);
      }
}

void DEPG0213RWS800F13_RedOff(void)
{
      uint16_t i;
      DEPG0213RWS800F13_Wait();
      DEPG0213RWS800F13_Command(0x26);
      for (i = 0; i < 4000; i++)
      {
            DEPG0213RWS800F13_Data(0x00);
      }
}

void DEPG0213RWS800F13_BlackOn(void)
{
      uint16_t i;

      DEPG0213RWS800F13_Wait();
      DEPG0213RWS800F13_Command(0x24);
      for (i = 0; i < 4000; i++)
      {
            DEPG0213RWS800F13_Data(0x00);
      }
}

void DEPG0213RWS800F13_BlackOff(void)
{
      uint16_t i;

      DEPG0213RWS800F13_Wait();
      DEPG0213RWS800F13_Command(0x24);
      for (i = 0; i < 4000; i++)
      {
            DEPG0213RWS800F13_Data(0xFF);
      }
}

void DEPG0213RWS800F13_UpdateAndSleep(void)
{
      DEPG0213RWS800F13_Command(0x20);
      DEPG0213RWS800F13_Wait();

      DEPG0213RWS800F13_Command(0x10);
      DEPG0213RWS800F13_Data(0x01);
      usleep(100 * 1000);
}

void DEPG0213RWS800F13_Init(void)
{
      usleep(10 * 1000);
      digitalWrite(RESET_PIN, 0);
      usleep(10 * 1000);
      digitalWrite(RESET_PIN, 1);
      usleep(10 * 1000);
      DEPG0213RWS800F13_Wait();
      DEPG0213RWS800F13_Command(0x12);
      DEPG0213RWS800F13_Wait();
}

int main()
{
      wiringPiSetup();
      // DC
      pinMode(DC_PIN, OUTPUT);
      // RST
      pinMode(RESET_PIN, OUTPUT);
      // BUSY
      pinMode(BUSY_PIN, INPUT);

      fd = wiringPiSPISetup(0, 500000);

      read_png_file("new.png");
      process_file();

      /* display testing code */
      printf("Preparing to paint all red\n");
      DEPG0213RWS800F13_Init();
      DEPG0213RWS800F13_RedOn();
      DEPG0213RWS800F13_BlackOff();
      DEPG0213RWS800F13_UpdateAndSleep();
       sleep(3);

      printf("Preparing to paint all black\n");
      DEPG0213RWS800F13_Init();
      DEPG0213RWS800F13_RedOff();
      DEPG0213RWS800F13_BlackOn();
      DEPG0213RWS800F13_UpdateAndSleep();
      sleep(3);

      printf("Preparing to paint all white\n");
      DEPG0213RWS800F13_Init();
      DEPG0213RWS800F13_RedOff();
      DEPG0213RWS800F13_BlackOff();
      DEPG0213RWS800F13_UpdateAndSleep();
      sleep(3);
      */

      return 0;
}
  • Save it and Compile it
gcc -o epaper -lwiringPi -lpng epaper.c
sudo ./epaper

  • Python
 Required: spidev, RPi.GPIO, PIL(Pillow) libraries in Python 
library Version
spidev 3.4
RPi.GPIO 0.7.0
Pillow 5.4.1
  • How to install libraries:
pip3 install pillow
pip3 install RPi.GPIO
pip3 install spidev
  • Demo code from GitHub:
cd ~
git clone https://github.com/geeekpi/epaper.git
cd epaper/
python3 eink2.13_demo.py

And the display will flash `red`, `black`, `white` and finally a picture.
NOTE: Please prepare the test.png picture in advance. The test.png in the code is just a sample picture and can be generated according to your needs. The format of the picture is recommended to use the PNG format, which can be generated by Microsoft's mspaint tool. The size of the picture:122x250 pixels.

How to create picture via MSPAINT tool

  • Press "windows icon" + "r" on the keyboard, and typing this command in the "run" window:
mspaint.exe
  • Click "File" and navigate to "properties" (or press ALT+E for short) and input the dimension as :128 x 250
Epaper-howto.jpg


Epaper-howto2.jpg


  • Draw the pattern you like on the canvas. It should be noted that only two colors can be used: red and black.
Epaper-howto3.jpg


  • Save it and upload it to Raspberry Pi and modify the demo code and replace the file name with it's name.
  • Execute the demo code and it will flash several times and the drawing will be on the screen.

Keywords

  • 2.13 inch E-paper (BRW), E-paper, EPD, e-ink, Electronic Ink, Electronics Ecosystem, display module.

FAQ

  • Is it possible to do a partial update?
 It can be partially updated, but after refreshing many times there will be ghosting, it is not recommended to partially updated, there is no demo program, you need to reconfigure the LUT according to the actual app, more detail can get from the PDF document: File:DEPG0213RWS800F13 V1.2 FINAL.pdf