EP-0133: Difference between revisions
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.
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...