EP-0133: Difference between revisions

From 52Pi Wiki
Jump to navigation Jump to search
Line 97: Line 97:


===Demo Code===
===Demo Code===
* Language C
Create a new file and name it: epaper.c, copy and paste following code:
<pre>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <wiringPi.h>
#include <wiringPiSPI.h>
#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;
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("test.png");
      process_file();
      // 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;
}
</pre>
* Save it and Compile it
<pre>
gcc -o epaper -lwiringPi -lpng epaper.c
sudo ./epaper
</pre>
==Keywords==
==Keywords==
* 2.13 inch E-paper (BRW), E-paper, EPD, e-ink, Electronic Ink, Electronics Ecosystem, display module.
* 2.13 inch E-paper (BRW), E-paper, EPD, e-ink, Electronic Ink, Electronics Ecosystem, display module.
==FAQ==
==FAQ==
To be continue...
To be continue...

Revision as of 19:08, 25 December 2020

2.13 inch E-paper (BRW)

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

  • 250×122 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

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

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.

此处应该有图接驳图

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
  • 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>

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

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("test.png");
      process_file();

      // 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

Keywords

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

FAQ

To be continue...