1.说明
当我们在DIY实验时,经常需要用到显示屏。keyes 电子墨水屏模块上带有一个2.13寸的显示屏,显示颜色为黑白色,分辨率为250*122。模块通过SPI通讯,可动态显示图案。模块上带有2个拨码开关,P1拨码开关用于调节显示亮度,拨打到“0.47”时,显示更亮;拨打到“3”时,显示更暗。P2拨码开关用于调节供电电压,拨打到“5VIN”时,供电电压为5V;拨打到“3.3VIN”时,供电电压为3.3V。
为了方便你使用,我们还提供显示屏模块和arduino单片机、树莓派搭配使用的详细方法。同时,为了方便将模块固定在其他设备上,模块自带2个直径为3mm的定位孔。
特别注意:测试时,我们使用的是1.8.9版本的IDE软件测试,如果使用其他版本IDE,
代码可能出现不兼容现象。
2.技术参数
工作电压: DC 3.3或5V(拨码开关控制)
工作电流:100mA
最大功率:0.8W
显示屏颜色:黑白色
显示屏大小:2.13寸
显示屏分辨率:250*122
接口类型:间距为2.54mm的8pin排针
工作温度范围:-20℃到+60℃
定位孔大小:直径3mm
尺寸:79*40*7mm
重量:9.6g
环保属性:ROHS
3.接线方法
UNO板连接方法
树莓派连接方法
4.测试代码
Arduino代码
#include”Ap_29demo.h”
//IO settings
int BUSY_Pin = 8;
int RES_Pin = 9;
int DC_Pin = 10;
int CS_Pin = 11;
int SCK_Pin = 12;
int SDI_Pin = 13;
#define EPD_W21_MOSI_0 digitalWrite(SDI_Pin,LOW)
#define EPD_W21_MOSI_1 digitalWrite(SDI_Pin,HIGH)
#define EPD_W21_CLK_0 digitalWrite(SCK_Pin,LOW)
#define EPD_W21_CLK_1 digitalWrite(SCK_Pin,HIGH)
#define EPD_W21_CS_0 digitalWrite(CS_Pin,LOW)
#define EPD_W21_CS_1 digitalWrite(CS_Pin,HIGH)
#define EPD_W21_DC_0 digitalWrite(DC_Pin,LOW)
#define EPD_W21_DC_1 digitalWrite(DC_Pin,HIGH)
#define EPD_W21_RST_0 digitalWrite(RES_Pin,LOW)
#define EPD_W21_RST_1 digitalWrite(RES_Pin,HIGH)
#define isEPD_W21_BUSY digitalRead(BUSY_Pin)
//250*122///////////////////////////////////////
#define MONOMSB_MODE 1
#define MONOLSB_MODE 2
#define RED_MODE 3
#define MAX_LINE_BYTES 16// =128/8
#define MAX_COLUMN_BYTES 250
#define ALLSCREEN_GRAGHBYTES 4000
////////FUNCTION//////
void driver_delay_us(unsigned int xus);
void driver_delay_xms(unsigned long xms);
void DELAY_S(unsigned int delaytime);
void SPI_Delay(unsigned char xrate);
void SPI_Write(unsigned char value);
void Epaper_Write_Command(unsigned char command);
void Epaper_Write_Data(unsigned char command);
//EPD
void Epaper_READBUSY(void);
void SPI_Write(u8 TxData);
void Epaper_Write_Command(u8 cmd);
void Epaper_Write_Data(u8 data);
void EPD_HW_Init(void); //Electronic paper initialization
void EPD_Part_Init(void); //Local refresh initialization
void EPD_Part_Update(void);
void EPD_Update(void);
void EPD_WhiteScreen_Black(void);
void EPD_WhiteScreen_White(void);
void EPD_DeepSleep(void);
//Display
void EPD_WhiteScreen_ALL(const unsigned char * datas);
void EPD_SetRAMValue_BaseMap(const unsigned char * datas);
void EPD_Dis_Part(unsigned int x_start,unsigned int y_start,const unsigned char * datas,unsigned int PART_COLUMN,unsigned int PART_LINE);
void setup() {
pinMode(BUSY_Pin, INPUT);
pinMode(RES_Pin, OUTPUT);
pinMode(DC_Pin, OUTPUT);
pinMode(CS_Pin, OUTPUT);
pinMode(SCK_Pin, OUTPUT);
pinMode(SDI_Pin, OUTPUT);
}
void loop() {
unsigned char fen_L,fen_H,miao_L,miao_H;
//////////////////////Partial refresh digital presentation//////////////////////////////////////
EPD_HW_Init(); //Electronic paper initialization
EPD_WhiteScreen_ALL(gImage_1); //Refresh the picture in full screen
delay(100);
EPD_SetRAMValue_BaseMap(gImage_basemap); //Partial refresh background color,Brush map is a must, please do not delete
delay(100);
////////////////////////////////////////////////////////////////////////
}
///////////////////EXTERNAL FUNCTION////////////////////////////////////////////////////////////////////////
/////////////////////delay//////////////////////////////////////
void driver_delay_us(unsigned int xus) //1us
{
for(;xus>1;xus–);
}
void driver_delay_xms(unsigned long xms) //1ms
{
unsigned long i = 0 , j=0;
for(j=0;j<xms;j++)
{
for(i=0; i<256; i++);
}
}
void DELAY_S(unsigned int delaytime)
{
int i,j,k;
for(i=0;i<delaytime;i++)
{
for(j=0;j<4000;j++)
{
for(k=0;k<222;k++);
}
}
}
//////////////////////SPI///////////////////////////////////
void SPI_Delay(unsigned char xrate)
{
unsigned char i;
while(xrate)
{
for(i=0;i<2;i++);
xrate–;
}
}
void SPI_Write(unsigned char value)
{
unsigned char i;
SPI_Delay(1);
for(i=0; i<8; i++)
{
EPD_W21_CLK_0;
SPI_Delay(1);
if(value & 0x80)
EPD_W21_MOSI_1;
else
EPD_W21_MOSI_0;
value = (value << 1);
SPI_Delay(1);
driver_delay_us(1);
EPD_W21_CLK_1;
SPI_Delay(1);
}
}
void Epaper_Write_Command(unsigned char command)
{
SPI_Delay(1);
EPD_W21_CS_0;
EPD_W21_DC_0; // command write
SPI_Write(command);
EPD_W21_CS_1;
}
void Epaper_Write_Data(unsigned char command)
{
SPI_Delay(1);
EPD_W21_CS_0;
EPD_W21_DC_1; // command write
SPI_Write(command);
EPD_W21_CS_1;
}
/////////////////EPD settings Functions/////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
void EPD_HW_Init(void)
{
EPD_W21_RST_0;
delay(1);
EPD_W21_RST_1; //hard reset
delay(1);
Epaper_READBUSY();
Epaper_Write_Command(0x12); //SWRESET
Epaper_READBUSY();
Epaper_Write_Command(0x01); //Driver output control
Epaper_Write_Data(0xF9);
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x00);
Epaper_Write_Command(0x11); //data entry mode
Epaper_Write_Data(0x01);
Epaper_Write_Command(0x44); //set Ram-X address start/end position
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x0F); //0x0F–>(15+1)*8=128
Epaper_Write_Command(0x45); //set Ram-Y address start/end position
Epaper_Write_Data(0xF9); //0xF9–>(249+1)=250
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x00);
Epaper_Write_Data(0x00);
Epaper_Write_Command(0x3C); //BorderWavefrom
Epaper_Write_Data(0x01);
Epaper_Write_Command(0x18);
Epaper_Write_Data(0x80);
Epaper_Write_Command(0x4E); // set RAM x address count to 0;
Epaper_Write_Data(0x00);
Epaper_Write_Command(0x4F); // set RAM y address count to 0X199;
Epaper_Write_Data(0xF9);
Epaper_Write_Data(0x00);
Epaper_READBUSY();
}
//////////////////////////////All screen update////////////////////////////////////////////
void EPD_WhiteScreen_ALL(const unsigned char * datas)
{
unsigned int i;
Epaper_Write_Command(0x24); //write RAM for black(0)/white (1)
for(i=0;i<ALLSCREEN_GRAGHBYTES;i++)
{
Epaper_Write_Data(pgm_read_byte(&datas[i]));
}
EPD_Update();
}
/////////////////////////////////////////////////////////////////////////////////////////
void EPD_Update(void)
{
Epaper_Write_Command(0x22);
Epaper_Write_Data(0xF7);
Epaper_Write_Command(0x20);
Epaper_READBUSY();
}
void EPD_Part_Update(void)
{
Epaper_Write_Command(0x22);
Epaper_Write_Data(0xFF);
Epaper_Write_Command(0x20);
Epaper_READBUSY();
}
void EPD_DeepSleep(void)
{
Epaper_Write_Command(0x10); //enter deep sleep
Epaper_Write_Data(0x01);
delay(100);
}
void Epaper_READBUSY(void)
{
while(1)
{ //=1 BUSY
if(isEPD_W21_BUSY==0) break;
}
}
///////////////////////////Part update//////////////////////////////////////////////
void EPD_SetRAMValue_BaseMap( const unsigned char * datas)
{
unsigned int i;
const unsigned char *datas_flag;
datas_flag=datas;
Epaper_Write_Command(0x24); //Write Black and White image to RAM
for(i=0;i<ALLSCREEN_GRAGHBYTES;i++)
{
Epaper_Write_Data(pgm_read_byte(&datas[i]));
}
datas=datas_flag;
Epaper_Write_Command(0x26); //Write Black and White image to RAM
for(i=0;i<ALLSCREEN_GRAGHBYTES;i++)
{
Epaper_Write_Data(pgm_read_byte(&datas[i]));
}
EPD_Update();
}
void EPD_Dis_Part(unsigned int x_start,unsigned int y_start,const unsigned char * datas,unsigned int PART_COLUMN,unsigned int PART_LINE)
{
unsigned int i;
unsigned int x_end,y_start1,y_start2,y_end1,y_end2;
x_start=x_start/8;//
x_end=x_start+PART_LINE/8-1;
y_start1=0;
y_start2=y_start;
if(y_start>=256)
{
y_start1=y_start2/256;
y_start2=y_start2%256;
}
y_end1=0;
y_end2=y_start+PART_COLUMN-1;
if(y_end2>=256)
{
y_end1=y_end2/256;
y_end2=y_end2%256;
}
Epaper_Write_Command(0x44); // set RAM x address start/end, in page 35
Epaper_Write_Data(x_start); // RAM x address start at 00h;
Epaper_Write_Data(x_end); // RAM x address end at 0fh(15+1)*8->128
Epaper_Write_Command(0x45); // set RAM y address start/end, in page 35
Epaper_Write_Data(y_start2); // RAM y address start at 0127h;
Epaper_Write_Data(y_start1); // RAM y address start at 0127h;
Epaper_Write_Data(y_end2); // RAM y address end at 00h;
Epaper_Write_Data(y_end1); // ????=0
Epaper_Write_Command(0x4E); // set RAM x address count to 0;
Epaper_Write_Data(x_start);
Epaper_Write_Command(0x4F); // set RAM y address count to 0X127;
Epaper_Write_Data(y_start2);
Epaper_Write_Data(y_start1);
Epaper_Write_Command(0x24); //Write Black and White image to RAM
for(i=0;i<PART_COLUMN*PART_LINE/8;i++)
{
Epaper_Write_Data(pgm_read_byte(&datas[i]));
}
EPD_Part_Update();
}
/////////////////////////////////Single display////////////////////////////////////////////////
void EPD_WhiteScreen_Black(void)
{
unsigned int i,k;
Epaper_Write_Command(0x24); //write RAM for black(0)/white (1)
for(k=0;k<250;k++)
{
for(i=0;i<16;i++)
{
Epaper_Write_Data(0x00);
}
}
EPD_Update();
}
void EPD_WhiteScreen_White(void)
{
unsigned int i,k;
Epaper_Write_Command(0x24); //write RAM for black(0)/white (1)
for(k=0;k<250;k++)
{
for(i=0;i<16;i++)
{
Epaper_Write_Data(0xff);
}
}
EPD_Update();
}
树莓派代码(main.c)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include “epd1in54.h”
#include “epdpaint.h”
#include “imagedata.h”
#define COLORED 0
#define UNCOLORED 1
//Tips//
/*When the electronic paper is refreshed in full screen, the picture flicker is a normal phenomenon, and the main function is to clear the display afterimage in the previous picture.
When the local refresh is performed, the screen does not flash.*/
/*When you need to transplant the driver, you only need to change the corresponding IO. The BUSY pin is the input mode and the others are the output mode. */
int main(void)
{
time_t now;
struct tm* timenow;
Epd epd;
if (epd.Init(lut_full_update) != 0) {
printf(“e-Paper init failed\n”);
return -1;
}
//Full screen refresh
epd.EPD_HW_Init(); //Electronic paper initialization
epd.EPD_WhiteScreen_ALL(gImage_1); //Refresh the picture in full screen
//epd.DelayMs(500);
//////////////////////Partial refresh digital presentation//////////////////////////////////////
epd.EPD_HW_Init(); //Electronic paper initialization
epd.EPD_SetRAMValue_BaseMap(gImage_2); //Partial refresh background color
epd.EPD_HW_Init(); //Electronic paper initialization
epd.EPD_SetRAMValue_BaseMap(gImage_3); //Partial refresh background color
epd.EPD_HW_Init(); //Electronic paper initialization
epd.EPD_Dis_Part(0,32,gImage_num1,32,32); //x,y,DATA,Resolution 32*32
epd.EPD_Dis_Part(0,32,gImage_num2,32,32); //x,y,DATA,Resolution 32*32
epd.EPD_Dis_Part(0,32,gImage_num3,32,32); //x,y,DATA,Resolution 32*32
//epd.DelayMs(500);
//all white
epd.EPD_HW_Init(); //Electronic paper initialization
epd.EPD_WhiteScreen_ALL(gImage_white); //Refresh the picture in full screen
epd.Sleep(); //EPD_sleep,Sleep instruction is necessary, please do not delete!!!
while(1);
}
5.arduino代码设置方法
- 设置时,我们需要安装Image2Lcd取模软件,安装后,利用注册码注册。
- 利用画图软件,画出你需要的图案,导出设置为黑白色,像素设置为250*122。
- 打开取模软件,设置如下图。
4.点击打开,选择你导出的图案,如下图。
正显(白底黑字),则“颜色反转”打钩;负显(黑底白字)则不需要打钩。
5.点击 ,即可生成对应的C语言代码,如下图。
6.将生成的C语言代码,复制到代码中的const unsigned char gImage_basemap[4000] PROGMEM或者const unsigned char gImage_1[4000] PROGMEM位置,如下图。
6.树莓派设置方法
- 按照树莓派接线方法,将模块接到树莓派上(我的是树莓派4B)
- 打开树莓派终端,输入以下指令进入配置界面,开启SPI接口功能。
sudo raspi-config
Interfacing Options -> SPI -> Yes
然后重启树莓派。
sudo reboot
3.在树莓派系统中建立KE0159文件夹,并将树莓派代码全部复制到KE0159文件夹中。
D、进入树莓派终端,执行以下指令,显示屏上回显示对应图片。
cd KE0159
make clean
make
ls
sudo ./epd
按Ctrl+C退出测试程序。
4.我们可以在main.c文件中设置显示内容。
5.当在main.c设置显示内容后,在imagedata.cpp中设置图像代码
设置方法和前面介绍的方法一样。
6.在imagedata.h中要特别注明设置图片名称。
7.测试结果
按照接线图接线,上传测试代码成功,上电后,显示屏会循环显示各种图案。
(此时拨码开关1拨打到“0.47”,拨码开关2拨打到“5VIN”)
8.相关资料链接
https://pan.baidu.com/s/1M4lVwg85N2IRPdVrWIhfmg
提取码:hlop