2.13inch e-Paper HAT

2.13inch e-Paper
2.13inch e-Paper
2.13inch e-Paper HAT
{{{name2}}}
{{{name3}}}
基本信息
分类: 树莓派模块
{{{userDefinedInfo1}}}: {{{userdefinedvalue1}}}
{{{userDefinedInfo2}}}: {{{userdefinedvalue2}}}
{{{userDefinedInfo3}}}: {{{userdefinedvalue3}}}
品牌: Waveshare
功能简介
特性 树莓派2.13英寸墨水屏 可局部刷新
分辨率 250x122
显示颜色 黑、白
' 无特性,不解释
' 无特性,不解释
接口 RPi SPI
相关产品
1.54inch e-Paper Module

1.54inch e-Paper Module (B)
1.54inch e-Paper Module (C)
2.13inch e-Paper HAT
2.13inch e-Paper HAT (B)
2.13inch e-Paper HAT (C)
2.13inch e-Paper HAT (D)
2.7inch e-Paper HAT
2.7inch e-Paper HAT (B)
2.9inch e-Paper Module
2.9inch e-Paper Module (B)
2.9inch e-Paper Module (C)
2.9inch e-Paper HAT (D)
4.2inch e-Paper Module
4.2inch e-Paper Module (B)
4.2inch e-Paper Module (C)
4.3inch e-Paper UART Module
5.83inch e-Paper HAT
5.83inch e-Paper HAT (B)
5.83inch e-Paper HAT (C)
6inch e-Paper HAT
6inch HD e-Paper HAT
6inch HD Touch e-Paper HAT
7.5inch e-Paper HAT
7.5inch e-Paper HAT (B)
7.5inch e-Paper HAT (C)
7.5inch HD e-Paper HAT
7.5inch HD e-Paper HAT (B)
7.8inch e-Paper HAT
9.7inch e-Paper HAT
10.3inch e-Paper HAT (D)

♦ {{{Product2}}}
♦ {{{Product3}}}
♦ {{{Product4}}}
♦ {{{Product5}}}
♦ {{{Product6}}}

目录

版本说明

由于芯片升级,2.13inch e-Paper 将升级为2.13inch e-Paper v2版本。新老程序无法兼容。v2版本与老版本对比,除了芯片和驱动程序之外,其他外观和功能都兼容。如果您是老客户,需要再次采购新屏幕的话,注意更新程序。如果您是第一次采购,并且拿到的是新款屏幕,直接使用新版程序即可。新版屏幕的标签上带有v2的后缀。请注意区分

特点

  • 尺寸: 2.13 inch
  • 外形尺寸(裸屏):59.2mm × 29.2mm × 1.05mm
  • 外形尺寸(驱动板):65mmx30.2mm
  • 显示尺寸:48.55mm × 23.71mm
  • 工作电压:3.3V/5V
  • 通信接口:SPI
  • 点距:0.194* 0.194
  • 分辨率:250*122
  • 显示颜色:黑、白
  • 灰度等级:2
  • 局部刷新 :0.3s
  • 全局刷新 :2s
  • 刷新功耗 : 26.4mW(typ.)
  • 待机功耗 :<=0.017mW

【备注】: 刷新时间:刷新时间为实验测试数据,实际刷新时间会有误差,以实际效果为准。全局刷新过程中会有闪烁效果,这个是正常现象
功耗:功耗数据为实验测试数据,实际功耗由于驱动板的存在和实际使用情况的不同,会有一定误差,以实际效果为准

SPI 通信时序

E-paper-spi-timing.jpg

由于墨水屏只需要显示,这里将从机发,主机收的数据线(MISO)隐藏。
CS:从机片选,当CS为低电平的时候,芯片使能
DC:数据/命令控制引脚,当DC=0时写入命令;DC=1时写入数据
SCLK: SPI通信时钟
SDIN:SPI通信主机发送,从机接收
时序:CPHL=0, CPOL=0 (SPI0)
【备注】具体关于SPI通信的相关信息,可以自行网上搜索资料了解

墨水屏刷新原理

像素与字节的关系

对于黑白图片,我们可以规定,如果如果是黑色我们定义成0,如果是白色就定义成1,那么有了表示颜色的方式:
白色:□,对应1
黑色:■:对应0

  • 一个点在图形上一般称之为像素点(pixel),而颜色不是1就是0,也就是1个位就可以标识颜色:1Pixel = 1bit,那么一个字节里面就包含了8个像素点。
  • 以16个像素点为例,我们假设前8个像素点为黑,后8个像素点为白色,那么可以这么认为,像素点1-16,对应这0位到15位,0表示黑色,1表示白色:

E-paper hardware work 1.png
对于计算机而言,它的数据存储方式是高位在前,低位在后,且一个字节只有8个位,因此会有一点改变:
E-paper hardware work 2.png
这样只需要2个字节即可表示16个像素点了。

硬件连接

连接树莓派的时候,如果是驱动板带有40pin排座的,可以直接插到树莓派的40PIN排针上去,注意对好引脚。如果是选择用8PIN排线连接的话,请参考下方的引脚对应表格
对于1.02inch e-paper Module使用的是排针,需要对照以下表格连线

树莓派连接引脚对应关系
e-Paper Raspberry Pi
BCM2835编码 Board物理引脚序号
VCC 3.3V 3.3V
GND GND GND
DIN MOSI 19
CLK SCLK 23
CS CE0 24
DC 25 22
RST 17 11
BUSY 24 18

以7.5inch HD e-Paper (B)连接至e-paper Driver HAT为例,直接插在树莓派上即可:
7.5inch e-Paper(B)800-480 1.jpg

开启SPI接口

  • 打开树莓派终端,输入以下指令进入配置界面
sudo raspi-config
选择Interfacing Options -> SPI -> Yes 开启SPI接口

RPI open spi.png
然后重启树莓派:

sudo reboot

请确保SPI没有被其他的设备占用,你可以在/boot/config.txt中间检查

安装库

  • 安装BCM2835, 打开树莓派终端,并运行以下指令
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.60.tar.gz
tar zxvf bcm2835-1.60.tar.gz 
cd bcm2835-1.60/
sudo ./configure && sudo make && sudo make check && sudo make install
# 更多的可以参考官网:http://www.airspayce.com/mikem/bcm2835/
  • 安装wiringPi
sudo apt-get install wiringpi
#对于树莓派2019年5月之后的系统(早于之前的可不用执行),可能需要进行升级:
wget https://project-downloads.drogon.net/wiringpi-latest.deb
sudo dpkg -i wiringpi-latest.deb
gpio -v
# 运行gpio -v会出现2.52版本,如果没有出现说明安装出错
  • 安装Python函数库
#python2
sudo apt-get update
sudo apt-get install python-pip
sudo apt-get install python-pil
sudo apt-get install python-numpy
sudo pip install RPi.GPIO
sudo pip install spidev
#python3
sudo apt-get update
sudo apt-get install python3-pip
sudo apt-get install python3-pil
sudo apt-get install python3-numpy
sudo pip3 install RPi.GPIO
sudo pip3 install spidev

下载测试程序

打开树莓派终端,执行:

sudo git clone https://github.com/waveshare/e-Paper
cd e-Paper/RaspberryPi\&JetsonNano/

运行测试程序

以下命令请在RaspberryPi&JetsonNano下执行,否则不在索引不到目录;

C语言

  • 打开main.c选择对应尺寸的屏幕
cd c
sudo nano examples/main.c 

如果你使用的是2.7inch e-paper,那么就去掉EPD_2IN7_test()函数前面的//,然后按ctrl+c,然后按Y键并回车保存并退出,具体如下:
E-paper rpi change main.png
可以查看到所有的屏幕尺寸的测试程序,按照尺寸分类:
1.02寸(128×80):
EPD_1in02d_test():对应1.02inch e-paper测试程序;

1.54寸(1.54inch e-paper c:152×152,其他:200×200):
EPD_1in54_test(): 对应1.54inch e-paper V1(黑)版本测试程序,购买日期早于2019-11-22为V1版本,目前已停产;
EPD_1in54_V2_test():对应1.54inch e-paper V2(黑)版本测试程序,购买日期晚于2019-11-22为V2版本,目前出货版本,背面贴有V2标识;
EPD_1in54b_test(): 对应1.54inch e-paper B(黑)测试程序;
EPD_1in54c_test(): 对应1.54inch e-paper C(黑)测试程序;

2.7寸(264×176):
EPD_2in7_test(): 对应2.7inch e-paper(黑)测试程序;
EPD_2in7b_test(): 对应2.7inch e-paper B(黑)测试程序;

2.9寸(296×128):
EPD_2in9_test(): 对应2.9inch e-paper(黑)测试程序;
EPD_2in9bc_test(): 对应2.9inch e-paper B(黑)和2.9inch e-paper C(黑)测试程序;
EPD_2in9d_test(): 对应2.9inch e-paper D(黑)测试程序;

2.13寸(2.13inch e-Paper:250×122,其他:212×104):
EPD_2in13_test(): 对应2.13inch e-paper V1(黑)版本测试程序,购买日期早于2019-05-15为V1版本,目前已停产;
EPD_2in13_V2_test():对应2.13inch e-paper V2(黑)版本测试程序,购买日期晚于2019-05-15为V2版本,目前出货版本,背面贴有V2标识;
EPD_2in13bc_test():对应2.13inch e-paper B(黑)和2.13inch e-paper C(黑)测试程序;
EPD_2in13d_test(): 对应2.13inch e-paper D(黑)测试程序;

4.2寸(400×300):
EPD_4in2_test(): 对应4.2inch e-paper(黑)测试程序;
EPD_4in2bc_test(): 对应4.2inch e-paper B(黑)测试程序;

5.83寸(600×448):
EPD_5in83_test(): 对应5.83inch e-paper(黑)测试程序;
EPD_5in83bc_test(): 对应5.83inch e-paper B(黑)和5.83inch e-paper C(黑)测试程序;

7.5寸(V1:640×384,V2:800×480):
EPD_7in5_test(): 对应7.5inch e-paper(黑)测试程序,购买日期早于2019-12-07为V1版本,目前已停产;
EPD_7in5bc_test(): 对应7.5inch e-paper B(黑)和7.5inch e-paper C(黑)测试程序,7.5inch e-paper B购买日期早于2019-12-07为V1版本,目前已停产,7.5inch e-paper C正常供货;
EPD_7in5_V2_test(): 对应7.5inch e-paper V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前出货版本,背面贴有V2标识;
EPD_7in5bc_V2_test():对应7.5inch e-paper B V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前7.5inch e-paper B出货版本,背面贴有V2标识;

  • 重新编译,编译过程可能需要几秒
返回c目录下,运行以下指令
make clean
make
sudo ./epd

python

  • 进入python程序目录,并运行指令ls -al
cd python/examples
ls -al

E-paper rpi change python1.png
可以查看到所有的屏幕尺寸的测试程序,按照尺寸分类:
1.02寸(128×80):
epd_1in02_test.py:对应1.02inch e-paper测试程序;

1.54寸(1.54inch e-paper c:152×152,其他:200×200):
epd_1in54_test.py: 对应1.54inch e-paper V1(黑)版本测试程序,购买日期早于2019-11-22为V1版本,目前已停产;
epd_1in54_V2_test.py:对应1.54inch e-paper V2(黑)版本测试程序,购买日期晚于2019-11-22为V2版本,目前出货版本,背面贴有V2标识;
epd_1in54b_test.py: 对应1.54inch e-paper B(黑)测试程序;
epd_1in54c_test.py: 对应1.54inch e-paper C(黑)测试程序;

2.7寸(264×176):
EPD_2in7_test(): 对应2.7inch e-paper(黑)测试程序;
EPD_2in7b_test(): 对应2.7inch e-paper B(黑)测试程序;

2.9寸(296×128):
epd_2in9_test.py: 对应2.9inch e-paper(黑)测试程序;
epd_2in9bc_test.py: 对应2.9inch e-paper B(黑)和2.9inch e-paper C(黑)测试程序;
epd_2in9d_test.py: 对应2.9inch e-paper D(黑)测试程序;

2.13寸(2.13inch e-Paper:250×122,其他:212×104):
epd_2in13_test.py: 对应2.13inch e-paper V1(黑)版本测试程序,购买日期早于2019-05-15为V1版本,目前已停产;
epd_2in13_V2_test.py:对应2.13inch e-paper V2(黑)版本测试程序,购买日期晚于2019-05-15为V2版本,目前出货版本,背面贴有V2标识;
epd_2in13bc_test.py:对应2.13inch e-paper B(黑)和2.13inch e-paper C(黑)测试程序;
epd_2in13d_test.py: 对应2.13inch e-paper D(黑)测试程序;

4.2寸(400×300):
epd_4in2_test.py: 对应4.2inch e-paper(黑)测试程序;
epd_4in2bc_test.py: 对应4.2inch e-paper B(黑)测试程序;

5.83寸(600×448):
epd_5in83_test.py: 对应5.83inch e-paper(黑)测试程序;
epd_5in83bc_test.py: 对应5.83inch e-paper B(黑)和5.83inch e-paper C(黑)测试程序;

7.5寸(V1:640×384,V2:800×480):
epd_7in5_test.py: 对应7.5inch e-paper(黑)测试程序,购买日期早于2019-12-07为V1版本,目前已停产;
epd_7in5bc_test.py: 对应7.5inch e-paper B(黑)和7.5inch e-paper C(黑)测试程序,7.5inch e-paper B购买日期早于2019-12-07为V1版本,目前已停产,7.5inch e-paper C正常供货;
epd_7in5_V2_test.py: 对应7.5inch e-paper V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前出货版本,背面贴有V2标识;
epd_7in5b_V2_test.py:对应7.5inch e-paper B V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前7.5inch e-paper B出货版本,背面贴有V2标识;

  • 运行对应屏幕的程序即可,程序支持python2/3,以1.54 V2为例子
# python2
sudo python2.7 epd_1in54_V2_test.py
# python3
sudo python3 epd_1in54_V2_test.py

API详解(请选读c或python部分)

RaspberryPi与Jetson nano共用一套程序,因为他们都是嵌入式系统,兼容性比较强。
程序分为底层硬件接口、中间层墨水屏驱动、上层应用;

C

底层硬件接口

我们进行了底层的封装,由于硬件平台不一样,内部的实现是不一样的,如果需要了解内部实现可以去对应的目录中查看
在DEV_Config.c(.h)可以看到很多定义,在目录:RaspberryPi&JetsonNano\c\lib\Config

C语言使用了2种方式进行驱动:分别是BCM2835库、WiringPi库
默认使用WiringPi库进行操作,如果你需要使用BCM2835来驱动的话,可以打开RaspberryPi&JetsonNano\c\Makefile,修改13-14行,如下:
E-paper Driver HAT RPI Makefile.png
  • 数据类型:
#define UBYTE   uint8_t
#define UWORD   uint16_t
#define UDOUBLE uint32_t
  • 模块初始化与退出的处理:
void DEV_Module_Init(void);
void DEV_Module_Exit(void);
注意:
1.这里是处理使用墨水屏前与使用完之后一些GPIO的处理。
2.对于PCB带有Rev2.1的,DEV_Module_Exit()之后整个模块会进入低功耗,经过测试这个功耗基本为0;
  • GPIO读写:
void DEV_Digital_Write(UWORD Pin, UBYTE Value);
UBYTE DEV_Digital_Read(UWORD Pin);
  • SPI写数据
void DEV_SPI_WriteByte(UBYTE Value);

中间层墨水屏驱动

e-paper驱动代码文件,在目录:RaspberryPi&JetsonNano\c\lib\e-Paper
如下图:
E-paper Driver HAT RPI epd.png
打开.h可以看到如下的函数

  • 墨水屏初始化,再屏幕开始工作时和退出睡眠模式之后调用
//1.54inch e-Paper、1.54inch e-Paper V2、2.13inch e-Paper、2.13inch e-Paper  V2、2.13inch e-Paper (D)、2.9inch e-Paper、2.9inch e-Paper (D)
void EPD_xxx_Init(UBYTE Mode); // Mode = 0 全局刷新初始化、Mode = 1 局部刷新初始化
//其他型号
void EPD_xxx_Init(void);

其中xxx表示,墨水屏型号。如是是2.13D,全屏初始化那么是EPD_2IN13D_Init(0),局部刷新初始化EPD_2IN13D_Init(1);如果是1.54 V2,那么EPD_1IN54_V2_Init();如果是7.5B,那就是EPD_7IN5BC_Init(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

  • 清屏,把墨水屏刷成白色
void EPD_xxx_Clear(void); 

其中xxx表示,墨水屏型号。如是是2.13D,那么是EPD_2IN9D_Clear();如果是7.5B,那就是EPD_7IN5_Clear(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

  • 传输一帧的图片数据并打开显示
//黑白双色墨水屏
void EPD_xxx_Display(UBYTE *Image);
//黑白红或黑白黄墨水屏
void EPD_xxx_Display(const UBYTE *blackimage, const UBYTE *ryimage);

需要注意以下的几个是特例:

//对于2.13inch e-paper (D)、2.9inch e-paper (D)两款柔性屏幕,局部刷新
void EPD_2IN13D_DisplayPart(UBYTE *Image);
void EPD_2IN9D_DisplayPart(UBYTE *Image);
//对于1.54inch e-paper V2、2.13inch e-paper V2由于控制芯片升级,对于局部刷新,需要调用EPD_xxx_DisplayPartBaseImage显示静态的背景图片,也就是以这个图片为基础进行局部刷新,然后调用动态的EPD_xxx_DisplayPart()
void EPD_1IN54_V2_DisplayPartBaseImage(UBYTE *Image);
void EPD_1IN54_V2_DisplayPart(UBYTE *Image);
void EPD_2IN13_V2_DisplayPart(UBYTE *Image);
void EPD_2IN13_V2_DisplayPartBaseImage(UBYTE *Image);
  • 进入睡眠模式
void EPD_xxx_Sleep(void);

注意进入了睡眠模式,只有两个方式能够重新工作:第一种硬件复位,第二种重新调用初始化函数
其中xxx表示,墨水屏型号。如是是2.13D,那么是EPD_2IN13D_Sleep();如果是7.5B,那就是EPD_7IN5BC_Sleep(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

上层应用

对于屏幕而言,如果需要进行画图、显示中英文字符、显示图片等怎么办,这些都是上层应用做的。这有很多小伙伴有问到一些图形的处理,我们这里提供了一些基本的功能 在如下的目录中可以找到GUI,在目录:RaspberryPi&JetsonNano\c\lib\GUI\GUI_Paint.c(.h)
E-paper Driver HAT GUI.png
在如下目录下是GUI依赖的字符字体,在目录:RaspberryPi&JetsonNano\c\lib\Fonts
E-paper Driver HAT Fonts.png

  • 新建图像属性:新建一个图像属性,这个属性包括图像缓存的名称、宽度、高度、翻转角度、颜色
void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color)
参数:
 	image : 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
 	Width : 图像缓存的宽度;
 	Height: 图像缓存的高度;
 	Rotate:图像的翻转的角度
 	Color :图像的初始颜色;
  • 选择图像缓存:选择图像缓存,选择的目的是你可以创建多个图像属性,图像缓存可以存在多个,你可以选择你所创建的每一张图像
void Paint_SelectImage(UBYTE *image)
参数:
 	image: 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
  • 图像旋转:设置选择好的图像的旋转角度,最好使用在Paint_SelectImage()后,可以选择旋转0、90、180、270
void Paint_SetRotate(UWORD Rotate)
参数:
 	Rotate: 图像选择角度,可以选择ROTATE_0、ROTATE_90、ROTATE_180、ROTATE_270分别对应0、90、180、270度
【说明】不同选择角度下,坐标对应起始像素点不同,这里以1.54B为例,四张图,按顺序为0°, 90°, 180°, 270°。仅做为参考
SPI-epaper-C-0.png SPI-epaper-C-90.png SPI-epaper-C-180.pngSPI-epaper-C-270.png
  • 图像镜像翻转:设置选择好的图像的镜像翻转,可以选择不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像。
void Paint_SetMirroring(UBYTE mirror)
参数:
 	mirror: 图像的镜像方式,可以选择MIRROR_NONE、MIRROR_HORIZONTAL、MIRROR_VERTICAL、MIRROR_ORIGIN分别对应不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像
  • 设置点在缓存中显示位置和颜色:这里是GUI最核心的一个函数、处理点在缓存中显示位置和颜色;
void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color)
参数:
 	Xpoint: 点在图像缓存中X位置
 	Ypoint: 点在图像缓存中Y位置
 	Color : 点显示的颜色
  • 图像缓存填充颜色:把图像缓存填充为某颜色,一般作为屏幕刷白的作用
void Paint_Clear(UWORD Color)
参数:
 	Color: 填充的颜色
  • 图像缓存部分窗口填充颜色:把图像缓存的某部分窗口填充为某颜色,一般作为窗口刷白的作用,常用于时间的显示,刷白上一秒
void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color)
参数:
 	Xstart: 窗口的X起点坐标
 	Ystart: 窗口的Y起点坐标
 	Xend: 窗口的X终点坐标
 	Yend: 窗口的Y终点坐标
 	Color: 填充的颜色
  • 画点:在图像缓存中,在(Xpoint, Ypoint)上画点,可以选择颜色,点的大小,点的风格
void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style)
参数:
 	Xpoint: 点的X坐标
 	Ypoint: 点的Y坐标
 	Color: 填充的颜色
 	Dot_Pixel: 点的大小,提供默认的8种大小点
 	 	 typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  , 	 	// 3 X 3
 	 	 	 DOT_PIXEL_4X4  , 	 	// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Dot_Style: 点的风格,大小扩充方式是以点为中心扩大还是以点为左下角往右上扩大
 	 	typedef enum {
 	 	   DOT_FILL_AROUND  = 1,		
 	 	   DOT_FILL_RIGHTUP,
 	 	} DOT_STYLE;
  • 画线:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画线,可以选择颜色,线的宽度,线的风格
void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, LINE_STYLE Line_Style , LINE_STYLE Line_Style)
参数:
 	Xstart: 线的X起点坐标
 	Ystart: 线的Y起点坐标
 	Xend: 线的X终点坐标
 	Yend: 线的Y终点坐标
 	Color: 填充的颜色
 	Line_width: 线的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	 Line_Style: 线的风格,选择线是以直线连接还是以虚线的方式连接
 	 	typedef enum {
 	 	 	 LINE_STYLE_SOLID = 0,
 	 	 	 LINE_STYLE_DOTTED,
 	 	} LINE_STYLE;
  • 画矩形:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画一个矩形,可以选择颜色,线的宽度,是否填充矩形内部
void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
 	Xstart: 矩形的X起点坐标
 	Ystart: 矩形的Y起点坐标
 	Xend: 矩形的X终点坐标
 	Yend: 矩形的Y终点坐标
 	Color: 填充的颜色
 	Line_width: 矩形四边的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Draw_Fill: 填充,是否填充矩形的内部
 	 	typedef enum {
 	 	 	 DRAW_FILL_EMPTY = 0,
 	 	 	 DRAW_FILL_FULL,
 	 	} DRAW_FILL;
  • 画圆:在图像缓存中,以 (X_Center Y_Center) 为圆心,画一个半径为Radius的圆,可以选择颜色,线的宽度,是否填充圆内部
void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
 	X_Center: 圆心的X坐标
 	Y_Center: 圆心的Y坐标
 	Radius:圆的半径
 	Color: 填充的颜色
 	Line_width: 圆弧的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Draw_Fill: 填充,是否填充圆的内部
 	 	typedef enum {
 	 	 	 DRAW_FILL_EMPTY = 0,
 	 	 	 DRAW_FILL_FULL,
 	 	} DRAW_FILL;
  • 写Ascii字符:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一个Ascii字符,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawChar(UWORD Xstart, UWORD Ystart, const char Ascii_Char, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	Ascii_Char:Ascii字符
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写英文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串英文字符,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pString:字符串,字符串是一个指针
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写中文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串中文字符,可以选择GB2312编码字符字库、字体前景色、字体背景色;
void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, cFONT* font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pString:字符串,字符串是一个指针
 	Font: GB2312编码字符字库,在Fonts文件夹中提供了以下字体:
 	 	font12CN:ascii字符字体11*21,中文字体16*21
 	 	font24CN:ascii字符字体24*41,中文字体32*41
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写数字:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串数字,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, int32_t Nummber, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	Nummber:显示的数字,这里使用的是32位长的int型保存,可以最大显示到2147483647
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 显示时间:在图像缓存中,在 (Xstart Ystart) 为左顶点,显示一段时间,可以选择Ascii码可视字符字库、字体前景色、字体背景色;这里是方便测试局部刷新而写的,因为局部刷新需要的时间为0.3S,整体显示少于1S加上数据的传输,可以做到1S刷新一次
void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pTime:显示的时间,这里定义好了一个时间的结构体,只要把时分秒各位数传给参数;
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写图片:把一个位图写入图像缓存中
void Paint_DrawBitMap(const unsigned char* image_buffer)
参数:
 	image_buffer: 图像数据的缓存中的首地址
  • 读取本地的bmp图片并写到缓存中

对于Jetson Nano, Raspberry Pi这些Linux操作系统的,可以读写图片
对于Raspberry Pi和Jetson Nano,在目录:RaspberryPi&JetsonNano\c\lib\GUI\GUI_BMPfile.c(.h)

UBYTE GUI_ReadBmp(const char *path, UWORD Xstart, UWORD Ystart)
参数:
	path:BMP图片的相对路径
 	Xstart: 图片的左顶点X坐标,一般默认传0
 	Ystart: 图片的左顶点Y坐标,一般默认传0

用户测试代码

前三个章节介绍了经典的linux三层代码结构,这里稍微讲解一下用户测试代码
对于Raspberry Pi和Jetson Nano,在目录:RaspberryPi&JetsonNano\c\examples,为全部的测试代码,在本目录下的main.c中可以多个屏蔽;
E-Paper Shield c test.png
如果需要运行7.5inch e-paper测试程序,你需要把42行的屏蔽去掉

// EPD_7in5_test();

改成

EPD_7in5_test();

在linux命令模式下重新执行如下:

make clean
make
sudo ./epd

Python(适用于Jetson Nano\Raspberry Pi)

适用于python2.7和python3
对于python而言他的调用没有C复杂
Raspberry Pi和Jetson Nano:RaspberryPi&JetsonNano\python\lib\
E-paper Driver python lib.png

epdconfig.py

  • 模块初始化与退出的处理:
def module_init()
def module_exit()
 注意:
 1.这里是处理使用墨水屏前与使用完之后一些GPIO的处理。
 2.对于PCB带有Rev2.1的,module_exit()之后整个模块会进入低功耗,经过测试这个功耗基本为0;
  • GPIO读写:
def  digital_write(pin, value)
def  digital_read(pin)
  • SPI写数据
def spi_writebyte(data)

epdxxx.py(xxx表示尺寸,若是2.13inch e-paper,则为epd2in13.py,依此类推)

  • 墨水屏初始化,再屏幕开始工作时和退出睡眠模式之后调用
对于1.54inch e-Paper、1.54inch e-Paper V2、2.13inch e-Paper、2.13inch e-Paper  V2、2.13inch e-Paper (D)、2.9inch e-Paper、2.9inch e-Paper (D)
def init(self, update) # 选择lut_full_update或lut_partial_update
其他型号
def init(self)
  • 清屏,把墨水屏刷成白色
def Clear(self)
def Clear(self, color) # 对于某几个屏幕需要调用这个
  • 把图片转换成数组
def getbuffer(self, image)
  • 传输一帧的图片数据并打开显示
黑白双色墨水屏
def display(self, image)
黑白红或黑白黄墨水屏
def display(self, blackimage, redimage)

需要注意以下的几个是特例:<br />
对于2.13inch e-paper (D)、2.9inch e-paper (D)两款柔性屏幕,局部刷新
def DisplayPartial(self, image)

对于1.54inch e-paper V2、2.13inch e-paper V2由于控制芯片升级,对于局部刷新,需要调用displayPartBaseImage()显示静态的背景图片,也就是以这个图片为基础进行局部刷新,然后调用动态的displayPart()
def displayPartBaseImage(self, image)
def displayPart(self, image)
  • 进入睡眠模式
def sleep(self)

epd_xxx_test.py(xxx表示尺寸,若是2.13inch e-paper,则为epd_2in13_test.py,依此类推)

python在如下目录:
Raspberry Pi和Jetson Nano:RaspberryPi&JetsonNano\python\examples\
E-paper Driver python examples.png
如果你的python版本是python2,且需要运行7.5inch e-paper测试程序,在linux命令模式下重新执行如下:

sudo python epd_7in5_test.py

如果你的python版本是python3,且需要运行7.5inch e-paper测试程序,在linux命令模式下重新执行如下:

sudo python3 epd_7in5_test.py

关于旋转设置

如果在python程序中你需要设置屏幕旋转,可以通过语句blackimage = blackimage.transpose(Image.ROTATE_270)设置。

blackimage = blackimage.transpose(Image.ROTATE_270) 
redimage = redimage.transpose(Image.ROTATE_270)
#支持ROTATE_90, ROTATE_180, ROTATE_270三个参数
旋转效果,以1.54B为例, 按顺序分别为0°, 90°,180°, 270°
SPI-epaper-Python-0.pngSPI-epaper-Python-90.pngSPI-epaper-Python-180.pngSPI-epaper-Python-270.png

画图GUI

由于python有一个image库pil官方库链接,他十分的强大,不需要像C从逻辑层出发编写代码,可以直接引用image库进行图像处理,以下将以1.54inch e-paper为例,对程序中使用了的进行简要说明

  • 需要使用image库,需要安装库
sudo apt-get install python3-pil  安装库

然后导入库

from PIL import Image,ImageDraw,ImageFont

其中Image为基本库、ImageDraw为画图功能、ImageFont为文字

  • 定义一个图像缓存,以方便在图片上进行画图、写字等功能
image = Image.new('1', (epd.width, epd.height), 255)  # 255: clear the frame

第一个参数定义图片的颜色深度,定义为1说明是2位图,第二个参数是一个元组,定义好图片的宽度和高度,第三个参数是定义缓存的默认颜色,0为黑色,255为白色。

  • 创建一个基于image的画图对象,所有的画图操作都在这个对象上
draw = ImageDraw.Draw(image)
  • 画框
draw.rectangle((0, 10, 200, 34), fill = 0)

第一个参数为一个4个元素的元组,(0,10)矩形左上角坐标值,(200,34)为矩形右下角坐标值,fill=0表示内部填充黑色。

  • 画线
draw.line((16, 60, 56, 60), fill = 0)

第一个参数为一个4个元素的元组,以(16,60)为起始点,(200,34)为终止点,画一条直线,fill=0表示线为黑色。

  • 画圆
draw.arc((90, 60, 150, 120), 0, 360, fill = 0)

在正方形内画一个内切圆,第一个参数为一个4个元素的元组,以(90,60)为正方形的左上角顶点,(150,120)为正方形右下角顶点,规定矩形框的水平中位线为0度角,角度顺时针变大,第二个参数表示开始角度,第三个参数标识结束角度,fill=0线为黑色
如果不是正方形,画出来的就是椭圆,这个实际上是圆弧的绘制。

除了arc可以话圆之外,还有chord可以画实心圆

draw.chord((90, 130, 150, 190), 0, 360, fill = 0)

实质是弦的绘制,第一个参数指定弦的圆外切矩形,第二、三两个参数分别是弦的起始和终止角度, 第四个参数是填充颜色,将弦从0度到360度连接并填充就变成了填充的圆了。

  • 写字符

写字符往往需要写不同大小的字符,需要导入ImageFont模块,并实例化:

font = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 24)

为了丰富字体库,这里使用的是windows目录下的字符文件,如果是其他的ttc结尾的字符文件也是支持的。

写英文字符直接使用即可,写中文,由于编码是GB2312所以需要在前面加个u:

draw.text((8, 12), 'hello world', font = font, fill = 255)
draw.text((8, 36), u'微雪电子', font = font, fill = 0)

第一个参数为一个2个元素的元组,以(8,12)为左顶点,字体为font,点,fill为字体颜色,第一句fill=255所以看上去是不会显示的,第二句显示微雪电子。

  • 读取本地图片
image = Image.open(os.path.join(picdir, '1in54.bmp'))

参数为图片路径。

  • 其他功能

python的image库十分强大,如果需要实现其他的更多功能,可以上官网学习http://effbot.org/imagingbook pil,官方的是英文的,如果感觉对你不友好,当然我们国内也有很多的优秀的博客都有讲解。

Jetson nano程序使用的是模拟SPI,所以刷新速度会相对较慢一些

硬件连接

Jetson Nano的40PIN引脚是兼容树莓派的40PIN引脚的,并且提供了一个Jetson.GPIO库跟树莓派的RPI.GPIO 库的API是一致的,所以这里连接的序号跟树莓派的是一样的

Jetson nano连接引脚对应关系
e-Paper Jetson Nano Developer Kit
BCM2835编码 Board物理引脚序号
VCC 3.3V 3.3V
GND GND GND
DIN 10(SPI0_MOSI) 19
CLK 11(SPI0_SCK 23
CS 8(SPI0_CS0) 24
DC 25 22
RST 17 11
BUSY 24 18

软件设置

安装函数库

  • 打开终端界面,输入以下指令安装相应的函数库
sudo apt-get update
sudo apt-get install python3-pip
sudo pip3 install Jetson.GPIO
sudo groupadd -f -r gpio
sudo usermod -a -G gpio your_user_name
sudo cp /opt/nvidia/jetson-gpio/etc/99-gpio.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger

【注意】your_user_name 是你使用的用户名,比如说 waveshare

  • 安装I2C
sudo apt-get install python-smbus
  • 安装图像处理库:
sudo apt-get install python3-pil
sudo apt-get install python3-numpy

下载测试程序

打开linux终端,执行:

sudo git clone https://github.com/waveshare/e-Paper
cd e-Paper/RaspberryPi\&JetsonNano/

运行测试程序

以下命令请在RaspberryPi&JetsonNano下执行,否则不在索引不到目录;

C语言

  • 打开main.c选择对应尺寸的屏幕
cd c
sudo nano examples/main.c 

如果你使用的是2.7inch e-paper,那么就去掉EPD_2IN7_test()函数前面的//,然后按ctrl+c,然后按Y键并回车保存并退出,具体如下:
E-paper rpi change main.png
可以查看到所有的屏幕尺寸的测试程序,按照尺寸分类:
1.02寸(128×80):
EPD_1in02d_test():对应1.02inch e-paper测试程序;

1.54寸(1.54inch e-paper c:152×152,其他:200×200):
EPD_1in54_test(): 对应1.54inch e-paper V1(黑)版本测试程序,购买日期早于2019-11-22为V1版本,目前已停产;
EPD_1in54_V2_test():对应1.54inch e-paper V2(黑)版本测试程序,购买日期晚于2019-11-22为V2版本,目前出货版本,背面贴有V2标识;
EPD_1in54b_test(): 对应1.54inch e-paper B(黑)测试程序;
EPD_1in54c_test(): 对应1.54inch e-paper C(黑)测试程序;

2.7寸(264×176):
EPD_2in7_test(): 对应2.7inch e-paper(黑)测试程序;
EPD_2in7b_test(): 对应2.7inch e-paper B(黑)测试程序;

2.9寸(296×128):
EPD_2in9_test(): 对应2.9inch e-paper(黑)测试程序;
EPD_2in9bc_test(): 对应2.9inch e-paper B(黑)和2.9inch e-paper C(黑)测试程序;
EPD_2in9d_test(): 对应2.9inch e-paper D(黑)测试程序;

2.13寸(2.13inch e-Paper:250×122,其他:212×104):
EPD_2in13_test(): 对应2.13inch e-paper V1(黑)版本测试程序,购买日期早于2019-05-15为V1版本,目前已停产;
EPD_2in13_V2_test():对应2.13inch e-paper V2(黑)版本测试程序,购买日期晚于2019-05-15为V2版本,目前出货版本,背面贴有V2标识;
EPD_2in13bc_test():对应2.13inch e-paper B(黑)和2.13inch e-paper C(黑)测试程序;
EPD_2in13d_test(): 对应2.13inch e-paper D(黑)测试程序;

4.2寸(400×300):
EPD_4in2_test(): 对应4.2inch e-paper(黑)测试程序;
EPD_4in2bc_test(): 对应4.2inch e-paper B(黑)测试程序;

5.83寸(600×448):
EPD_5in83_test(): 对应5.83inch e-paper(黑)测试程序;
EPD_5in83bc_test(): 对应5.83inch e-paper B(黑)和5.83inch e-paper C(黑)测试程序;

7.5寸(V1:640×384,V2:800×480):
EPD_7in5_test(): 对应7.5inch e-paper(黑)测试程序,购买日期早于2019-12-07为V1版本,目前已停产;
EPD_7in5bc_test(): 对应7.5inch e-paper B(黑)和7.5inch e-paper C(黑)测试程序,7.5inch e-paper B购买日期早于2019-12-07为V1版本,目前已停产,7.5inch e-paper C正常供货;
EPD_7in5_V2_test(): 对应7.5inch e-paper V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前出货版本,背面贴有V2标识;
EPD_7in5bc_V2_test():对应7.5inch e-paper B V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前7.5inch e-paper B出货版本,背面贴有V2标识;

  • 重新编译,编译过程可能需要几秒
make clean
make
sudo ./epd

python

  • 进入python程序目录,并运行指令ls -al
cd python/examples
ls -al

E-paper rpi change python1.png
可以查看到所有的屏幕尺寸的测试程序,按照尺寸分类:
1.02寸(128×80):
epd_1in02_test.py:对应1.02inch e-paper测试程序;

1.54寸(1.54inch e-paper c:152×152,其他:200×200):
epd_1in54_test.py: 对应1.54inch e-paper V1(黑)版本测试程序,购买日期早于2019-11-22为V1版本,目前已停产;
epd_1in54_V2_test.py:对应1.54inch e-paper V2(黑)版本测试程序,购买日期晚于2019-11-22为V2版本,目前出货版本,背面贴有V2标识;
epd_1in54b_test.py: 对应1.54inch e-paper B(黑)测试程序;
epd_1in54c_test.py: 对应1.54inch e-paper C(黑)测试程序;

2.7寸(264×176):
EPD_2in7_test(): 对应2.7inch e-paper(黑)测试程序;
EPD_2in7b_test(): 对应2.7inch e-paper B(黑)测试程序;

2.9寸(296×128):
epd_2in9_test.py: 对应2.9inch e-paper(黑)测试程序;
epd_2in9bc_test.py: 对应2.9inch e-paper B(黑)和2.9inch e-paper C(黑)测试程序;
epd_2in9d_test.py: 对应2.9inch e-paper D(黑)测试程序;

2.13寸(2.13inch e-Paper:250×122,其他:212×104):
epd_2in13_test.py: 对应2.13inch e-paper V1(黑)版本测试程序,购买日期早于2019-05-15为V1版本,目前已停产;
epd_2in13_V2_test.py:对应2.13inch e-paper V2(黑)版本测试程序,购买日期晚于2019-05-15为V2版本,目前出货版本,背面贴有V2标识;
epd_2in13bc_test.py:对应2.13inch e-paper B(黑)和2.13inch e-paper C(黑)测试程序;
epd_2in13d_test.py: 对应2.13inch e-paper D(黑)测试程序;

4.2寸(400×300):
epd_4in2_test.py: 对应4.2inch e-paper(黑)测试程序;
epd_4in2bc_test.py: 对应4.2inch e-paper B(黑)测试程序;

5.83寸(600×448):
epd_5in83_test.py: 对应5.83inch e-paper(黑)测试程序;
epd_5in83bc_test.py: 对应5.83inch e-paper B(黑)和5.83inch e-paper C(黑)测试程序;

7.5寸(V1:640×384,V2:800×480):
epd_7in5_test.py: 对应7.5inch e-paper(黑)测试程序,购买日期早于2019-12-07为V1版本,目前已停产;
epd_7in5bc_test.py: 对应7.5inch e-paper B(黑)和7.5inch e-paper C(黑)测试程序,7.5inch e-paper B购买日期早于2019-12-07为V1版本,目前已停产,7.5inch e-paper C正常供货;
epd_7in5_V2_test.py: 对应7.5inch e-paper V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前出货版本,背面贴有V2标识;
epd_7in5b_V2_test.py:对应7.5inch e-paper B V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前7.5inch e-paper B出货版本,背面贴有V2标识;

  • 运行对应屏幕的程序即可,程序支持python2/3,以1.54 V2为例子
# python2
sudo python2.7 epd_1in54_V2_test.py
# python3
sudo python3 epd_1in54_V2_test.py

程序详解

RaspberryPi与Jetson nano共用一套程序,因为他们都是嵌入式系统,兼容性比较强。
程序分为底层硬件接口、中间层墨水屏驱动、上层应用;

C

底层硬件接口

我们进行了底层的封装,由于硬件平台不一样,内部的实现是不一样的,如果需要了解内部实现可以去对应的目录中查看
在DEV_Config.c(.h)可以看到很多定义,在目录:RaspberryPi&JetsonNano\c\lib\Config

C语言使用了2种方式进行驱动:分别是BCM2835库、WiringPi库
默认使用WiringPi库进行操作,如果你需要使用BCM2835来驱动的话,可以打开RaspberryPi&JetsonNano\c\Makefile,修改13-14行,如下:
E-paper Driver HAT RPI Makefile.png
  • 数据类型:
#define UBYTE   uint8_t
#define UWORD   uint16_t
#define UDOUBLE uint32_t
  • 模块初始化与退出的处理:
void DEV_Module_Init(void);
void DEV_Module_Exit(void);
注意:
1.这里是处理使用墨水屏前与使用完之后一些GPIO的处理。
2.对于PCB带有Rev2.1的,DEV_Module_Exit()之后整个模块会进入低功耗,经过测试这个功耗基本为0;
  • GPIO读写:
void DEV_Digital_Write(UWORD Pin, UBYTE Value);
UBYTE DEV_Digital_Read(UWORD Pin);
  • SPI写数据
void DEV_SPI_WriteByte(UBYTE Value);

中间层墨水屏驱动

e-paper驱动代码文件,在目录:RaspberryPi&JetsonNano\c\lib\e-Paper
如下图:
E-paper Driver HAT RPI epd.png
打开.h可以看到如下的函数

  • 墨水屏初始化,再屏幕开始工作时和退出睡眠模式之后调用
//1.54inch e-Paper、1.54inch e-Paper V2、2.13inch e-Paper、2.13inch e-Paper  V2、2.13inch e-Paper (D)、2.9inch e-Paper、2.9inch e-Paper (D)
void EPD_xxx_Init(UBYTE Mode); // Mode = 0 全局刷新初始化、Mode = 1 局部刷新初始化
//其他型号
void EPD_xxx_Init(void);

其中xxx表示,墨水屏型号。如是是2.13D,全屏初始化那么是EPD_2IN13D_Init(0),局部刷新初始化EPD_2IN13D_Init(1);如果是1.54 V2,那么EPD_1IN54_V2_Init();如果是7.5B,那就是EPD_7IN5BC_Init(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

  • 清屏,把墨水屏刷成白色
void EPD_xxx_Clear(void); 

其中xxx表示,墨水屏型号。如是是2.13D,那么是EPD_2IN9D_Clear();如果是7.5B,那就是EPD_7IN5_Clear(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

  • 传输一帧的图片数据并打开显示
//黑白双色墨水屏
void EPD_xxx_Display(UBYTE *Image);
//黑白红或黑白黄墨水屏
void EPD_xxx_Display(const UBYTE *blackimage, const UBYTE *ryimage);

需要注意以下的几个是特例:

//对于2.13inch e-paper (D)、2.9inch e-paper (D)两款柔性屏幕,局部刷新
void EPD_2IN13D_DisplayPart(UBYTE *Image);
void EPD_2IN9D_DisplayPart(UBYTE *Image);
//对于1.54inch e-paper V2、2.13inch e-paper V2由于控制芯片升级,对于局部刷新,需要调用EPD_xxx_DisplayPartBaseImage显示静态的背景图片,也就是以这个图片为基础进行局部刷新,然后调用动态的EPD_xxx_DisplayPart()
void EPD_1IN54_V2_DisplayPartBaseImage(UBYTE *Image);
void EPD_1IN54_V2_DisplayPart(UBYTE *Image);
void EPD_2IN13_V2_DisplayPart(UBYTE *Image);
void EPD_2IN13_V2_DisplayPartBaseImage(UBYTE *Image);
  • 进入睡眠模式
void EPD_xxx_Sleep(void);

注意进入了睡眠模式,只有两个方式能够重新工作:第一种硬件复位,第二种重新调用初始化函数
其中xxx表示,墨水屏型号。如是是2.13D,那么是EPD_2IN13D_Sleep();如果是7.5B,那就是EPD_7IN5BC_Sleep(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

上层应用

对于屏幕而言,如果需要进行画图、显示中英文字符、显示图片等怎么办,这些都是上层应用做的。这有很多小伙伴有问到一些图形的处理,我们这里提供了一些基本的功能 在如下的目录中可以找到GUI,在目录:RaspberryPi&JetsonNano\c\lib\GUI\GUI_Paint.c(.h)
E-paper Driver HAT GUI.png
在如下目录下是GUI依赖的字符字体,在目录:RaspberryPi&JetsonNano\c\lib\Fonts
E-paper Driver HAT Fonts.png

  • 新建图像属性:新建一个图像属性,这个属性包括图像缓存的名称、宽度、高度、翻转角度、颜色
void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color)
参数:
 	image : 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
 	Width : 图像缓存的宽度;
 	Height: 图像缓存的高度;
 	Rotate:图像的翻转的角度
 	Color :图像的初始颜色;
  • 选择图像缓存:选择图像缓存,选择的目的是你可以创建多个图像属性,图像缓存可以存在多个,你可以选择你所创建的每一张图像
void Paint_SelectImage(UBYTE *image)
参数:
 	image: 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
  • 图像旋转:设置选择好的图像的旋转角度,最好使用在Paint_SelectImage()后,可以选择旋转0、90、180、270
void Paint_SetRotate(UWORD Rotate)
参数:
 	Rotate: 图像选择角度,可以选择ROTATE_0、ROTATE_90、ROTATE_180、ROTATE_270分别对应0、90、180、270度
【说明】不同选择角度下,坐标对应起始像素点不同,这里以1.54B为例,四张图,按顺序为0°, 90°, 180°, 270°。仅做为参考
SPI-epaper-C-0.png SPI-epaper-C-90.png SPI-epaper-C-180.pngSPI-epaper-C-270.png
  • 图像镜像翻转:设置选择好的图像的镜像翻转,可以选择不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像。
void Paint_SetMirroring(UBYTE mirror)
参数:
 	mirror: 图像的镜像方式,可以选择MIRROR_NONE、MIRROR_HORIZONTAL、MIRROR_VERTICAL、MIRROR_ORIGIN分别对应不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像
  • 设置点在缓存中显示位置和颜色:这里是GUI最核心的一个函数、处理点在缓存中显示位置和颜色;
void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color)
参数:
 	Xpoint: 点在图像缓存中X位置
 	Ypoint: 点在图像缓存中Y位置
 	Color : 点显示的颜色
  • 图像缓存填充颜色:把图像缓存填充为某颜色,一般作为屏幕刷白的作用
void Paint_Clear(UWORD Color)
参数:
 	Color: 填充的颜色
  • 图像缓存部分窗口填充颜色:把图像缓存的某部分窗口填充为某颜色,一般作为窗口刷白的作用,常用于时间的显示,刷白上一秒
void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color)
参数:
 	Xstart: 窗口的X起点坐标
 	Ystart: 窗口的Y起点坐标
 	Xend: 窗口的X终点坐标
 	Yend: 窗口的Y终点坐标
 	Color: 填充的颜色
  • 画点:在图像缓存中,在(Xpoint, Ypoint)上画点,可以选择颜色,点的大小,点的风格
void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style)
参数:
 	Xpoint: 点的X坐标
 	Ypoint: 点的Y坐标
 	Color: 填充的颜色
 	Dot_Pixel: 点的大小,提供默认的8种大小点
 	 	 typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  , 	 	// 3 X 3
 	 	 	 DOT_PIXEL_4X4  , 	 	// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Dot_Style: 点的风格,大小扩充方式是以点为中心扩大还是以点为左下角往右上扩大
 	 	typedef enum {
 	 	   DOT_FILL_AROUND  = 1,		
 	 	   DOT_FILL_RIGHTUP,
 	 	} DOT_STYLE;
  • 画线:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画线,可以选择颜色,线的宽度,线的风格
void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, LINE_STYLE Line_Style , LINE_STYLE Line_Style)
参数:
 	Xstart: 线的X起点坐标
 	Ystart: 线的Y起点坐标
 	Xend: 线的X终点坐标
 	Yend: 线的Y终点坐标
 	Color: 填充的颜色
 	Line_width: 线的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	 Line_Style: 线的风格,选择线是以直线连接还是以虚线的方式连接
 	 	typedef enum {
 	 	 	 LINE_STYLE_SOLID = 0,
 	 	 	 LINE_STYLE_DOTTED,
 	 	} LINE_STYLE;
  • 画矩形:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画一个矩形,可以选择颜色,线的宽度,是否填充矩形内部
void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
 	Xstart: 矩形的X起点坐标
 	Ystart: 矩形的Y起点坐标
 	Xend: 矩形的X终点坐标
 	Yend: 矩形的Y终点坐标
 	Color: 填充的颜色
 	Line_width: 矩形四边的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Draw_Fill: 填充,是否填充矩形的内部
 	 	typedef enum {
 	 	 	 DRAW_FILL_EMPTY = 0,
 	 	 	 DRAW_FILL_FULL,
 	 	} DRAW_FILL;
  • 画圆:在图像缓存中,以 (X_Center Y_Center) 为圆心,画一个半径为Radius的圆,可以选择颜色,线的宽度,是否填充圆内部
void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
 	X_Center: 圆心的X坐标
 	Y_Center: 圆心的Y坐标
 	Radius:圆的半径
 	Color: 填充的颜色
 	Line_width: 圆弧的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Draw_Fill: 填充,是否填充圆的内部
 	 	typedef enum {
 	 	 	 DRAW_FILL_EMPTY = 0,
 	 	 	 DRAW_FILL_FULL,
 	 	} DRAW_FILL;
  • 写Ascii字符:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一个Ascii字符,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawChar(UWORD Xstart, UWORD Ystart, const char Ascii_Char, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	Ascii_Char:Ascii字符
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写英文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串英文字符,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pString:字符串,字符串是一个指针
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写中文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串中文字符,可以选择GB2312编码字符字库、字体前景色、字体背景色;
void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, cFONT* font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pString:字符串,字符串是一个指针
 	Font: GB2312编码字符字库,在Fonts文件夹中提供了以下字体:
 	 	font12CN:ascii字符字体11*21,中文字体16*21
 	 	font24CN:ascii字符字体24*41,中文字体32*41
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写数字:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串数字,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, int32_t Nummber, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	Nummber:显示的数字,这里使用的是32位长的int型保存,可以最大显示到2147483647
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 显示时间:在图像缓存中,在 (Xstart Ystart) 为左顶点,显示一段时间,可以选择Ascii码可视字符字库、字体前景色、字体背景色;这里是方便测试局部刷新而写的,因为局部刷新需要的时间为0.3S,整体显示少于1S加上数据的传输,可以做到1S刷新一次
void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pTime:显示的时间,这里定义好了一个时间的结构体,只要把时分秒各位数传给参数;
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写图片:把一个位图写入图像缓存中
void Paint_DrawBitMap(const unsigned char* image_buffer)
参数:
 	image_buffer: 图像数据的缓存中的首地址
  • 读取本地的bmp图片并写到缓存中

对于Jetson Nano, Raspberry Pi这些Linux操作系统的,可以读写图片
对于Raspberry Pi和Jetson Nano,在目录:RaspberryPi&JetsonNano\c\lib\GUI\GUI_BMPfile.c(.h)

UBYTE GUI_ReadBmp(const char *path, UWORD Xstart, UWORD Ystart)
参数:
	path:BMP图片的相对路径
 	Xstart: 图片的左顶点X坐标,一般默认传0
 	Ystart: 图片的左顶点Y坐标,一般默认传0

用户测试代码

前三个章节介绍了经典的linux三层代码结构,这里稍微讲解一下用户测试代码
对于Raspberry Pi和Jetson Nano,在目录:RaspberryPi&JetsonNano\c\examples,为全部的测试代码,在本目录下的main.c中可以多个屏蔽;
E-Paper Shield c test.png
如果需要运行7.5inch e-paper测试程序,你需要把42行的屏蔽去掉

// EPD_7in5_test();

改成

EPD_7in5_test();

在linux命令模式下重新执行如下:

make clean
make
sudo ./epd

Python(适用于Jetson Nano\Raspberry Pi)

适用于python2.7和python3
对于python而言他的调用没有C复杂
Raspberry Pi和Jetson Nano:RaspberryPi&JetsonNano\python\lib\
E-paper Driver python lib.png

epdconfig.py

  • 模块初始化与退出的处理:
def module_init()
def module_exit()
 注意:
 1.这里是处理使用墨水屏前与使用完之后一些GPIO的处理。
 2.对于PCB带有Rev2.1的,module_exit()之后整个模块会进入低功耗,经过测试这个功耗基本为0;
  • GPIO读写:
def  digital_write(pin, value)
def  digital_read(pin)
  • SPI写数据
def spi_writebyte(data)

epdxxx.py(xxx表示尺寸,若是2.13inch e-paper,则为epd2in13.py,依此类推)

  • 墨水屏初始化,再屏幕开始工作时和退出睡眠模式之后调用
对于1.54inch e-Paper、1.54inch e-Paper V2、2.13inch e-Paper、2.13inch e-Paper  V2、2.13inch e-Paper (D)、2.9inch e-Paper、2.9inch e-Paper (D)
def init(self, update) # 选择lut_full_update或lut_partial_update
其他型号
def init(self)
  • 清屏,把墨水屏刷成白色
def Clear(self)
def Clear(self, color) # 对于某几个屏幕需要调用这个
  • 把图片转换成数组
def getbuffer(self, image)
  • 传输一帧的图片数据并打开显示
黑白双色墨水屏
def display(self, image)
黑白红或黑白黄墨水屏
def display(self, blackimage, redimage)

需要注意以下的几个是特例:<br />
对于2.13inch e-paper (D)、2.9inch e-paper (D)两款柔性屏幕,局部刷新
def DisplayPartial(self, image)

对于1.54inch e-paper V2、2.13inch e-paper V2由于控制芯片升级,对于局部刷新,需要调用displayPartBaseImage()显示静态的背景图片,也就是以这个图片为基础进行局部刷新,然后调用动态的displayPart()
def displayPartBaseImage(self, image)
def displayPart(self, image)
  • 进入睡眠模式
def sleep(self)

epd_xxx_test.py(xxx表示尺寸,若是2.13inch e-paper,则为epd_2in13_test.py,依此类推)

python在如下目录:
Raspberry Pi和Jetson Nano:RaspberryPi&JetsonNano\python\examples\
E-paper Driver python examples.png
如果你的python版本是python2,且需要运行7.5inch e-paper测试程序,在linux命令模式下重新执行如下:

sudo python epd_7in5_test.py

如果你的python版本是python3,且需要运行7.5inch e-paper测试程序,在linux命令模式下重新执行如下:

sudo python3 epd_7in5_test.py

关于旋转设置

如果在python程序中你需要设置屏幕旋转,可以通过语句blackimage = blackimage.transpose(Image.ROTATE_270)设置。

blackimage = blackimage.transpose(Image.ROTATE_270) 
redimage = redimage.transpose(Image.ROTATE_270)
#支持ROTATE_90, ROTATE_180, ROTATE_270三个参数
旋转效果,以1.54B为例, 按顺序分别为0°, 90°,180°, 270°
SPI-epaper-Python-0.pngSPI-epaper-Python-90.pngSPI-epaper-Python-180.pngSPI-epaper-Python-270.png

画图GUI

由于python有一个image库pil官方库链接,他十分的强大,不需要像C从逻辑层出发编写代码,可以直接引用image库进行图像处理,以下将以1.54inch e-paper为例,对程序中使用了的进行简要说明

  • 需要使用image库,需要安装库
sudo apt-get install python3-pil  安装库

然后导入库

from PIL import Image,ImageDraw,ImageFont

其中Image为基本库、ImageDraw为画图功能、ImageFont为文字

  • 定义一个图像缓存,以方便在图片上进行画图、写字等功能
image = Image.new('1', (epd.width, epd.height), 255)  # 255: clear the frame

第一个参数定义图片的颜色深度,定义为1说明是2位图,第二个参数是一个元组,定义好图片的宽度和高度,第三个参数是定义缓存的默认颜色,0为黑色,255为白色。

  • 创建一个基于image的画图对象,所有的画图操作都在这个对象上
draw = ImageDraw.Draw(image)
  • 画框
draw.rectangle((0, 10, 200, 34), fill = 0)

第一个参数为一个4个元素的元组,(0,10)矩形左上角坐标值,(200,34)为矩形右下角坐标值,fill=0表示内部填充黑色。

  • 画线
draw.line((16, 60, 56, 60), fill = 0)

第一个参数为一个4个元素的元组,以(16,60)为起始点,(200,34)为终止点,画一条直线,fill=0表示线为黑色。

  • 画圆
draw.arc((90, 60, 150, 120), 0, 360, fill = 0)

在正方形内画一个内切圆,第一个参数为一个4个元素的元组,以(90,60)为正方形的左上角顶点,(150,120)为正方形右下角顶点,规定矩形框的水平中位线为0度角,角度顺时针变大,第二个参数表示开始角度,第三个参数标识结束角度,fill=0线为黑色
如果不是正方形,画出来的就是椭圆,这个实际上是圆弧的绘制。

除了arc可以话圆之外,还有chord可以画实心圆

draw.chord((90, 130, 150, 190), 0, 360, fill = 0)

实质是弦的绘制,第一个参数指定弦的圆外切矩形,第二、三两个参数分别是弦的起始和终止角度, 第四个参数是填充颜色,将弦从0度到360度连接并填充就变成了填充的圆了。

  • 写字符

写字符往往需要写不同大小的字符,需要导入ImageFont模块,并实例化:

font = ImageFont.truetype(os.path.join(picdir, 'Font.ttc'), 24)

为了丰富字体库,这里使用的是windows目录下的字符文件,如果是其他的ttc结尾的字符文件也是支持的。

写英文字符直接使用即可,写中文,由于编码是GB2312所以需要在前面加个u:

draw.text((8, 12), 'hello world', font = font, fill = 255)
draw.text((8, 36), u'微雪电子', font = font, fill = 0)

第一个参数为一个2个元素的元组,以(8,12)为左顶点,字体为font,点,fill为字体颜色,第一句fill=255所以看上去是不会显示的,第二句显示微雪电子。

  • 读取本地图片
image = Image.open(os.path.join(picdir, '1in54.bmp'))

参数为图片路径。

  • 其他功能

python的image库十分强大,如果需要实现其他的更多功能,可以上官网学习http://effbot.org/imagingbook pil,官方的是英文的,如果感觉对你不友好,当然我们国内也有很多的优秀的博客都有讲解。

STM32

硬件连接

我们提供的例程是基于STM32F103ZET6的,提供的连接方式也是对应的STM32F103ZET6的引脚,如果有需要移植程序,请按实际引脚连接

STM32F103ZET连接引脚对应关系
e-Paper STM32
Vcc 3.3V
GND GND
DIN PA7
CLK PA5
CS PA4
DC PA2
RST PA1
BUSY PA3

以我们的open103Z为例,连接如下图:
E-paper driver hat to stm32 connet.png
如果你的是STM32F103RBT6可以参考E-Paper Shield

软件说明

例程是基于HAL库进行开发的。 下载程序,找到STM32程序文件目录,打开STM32\STM32-F103ZET6\MDK-ARM目录下的epd-demo.uvprojx,即可看到程序。
E-paper stm32 code1.png

打开main.c,可以看到所有的测试程序,把对应的屏幕的测试程序前面的注释去掉,重新编译下载即可。
E-paper stm32 code2.png

可以查看到所有的屏幕尺寸的测试程序,按照尺寸分类:
1.02寸(128×80):
EPD_1in02d_test():对应1.02inch e-paper测试程序;

1.54寸(1.54inch e-paper c:152×152,其他:200×200):
EPD_1in54_test(): 对应1.54inch e-paper V1(黑)版本测试程序,购买日期早于2019-11-22为V1版本,目前已停产;
EPD_1in54_V2_test():对应1.54inch e-paper V2(黑)版本测试程序,购买日期晚于2019-11-22为V2版本,目前出货版本,背面贴有V2标识;
EPD_1in54b_test(): 对应1.54inch e-paper B(黑)测试程序;
EPD_1in54c_test(): 对应1.54inch e-paper C(黑)测试程序;

2.7寸(264×176):
EPD_2in7_test(): 对应2.7inch e-paper(黑)测试程序;
EPD_2in7b_test(): 对应2.7inch e-paper B(黑)测试程序;

2.9寸(296×128):
EPD_2in9_test(): 对应2.9inch e-paper(黑)测试程序;
EPD_2in9bc_test(): 对应2.9inch e-paper B(黑)和2.9inch e-paper C(黑)测试程序;
EPD_2in9d_test(): 对应2.9inch e-paper D(黑)测试程序;

2.13寸(2.13inch e-Paper:250×122,其他:212×104):
EPD_2in13_test(): 对应2.13inch e-paper V1(黑)版本测试程序,购买日期早于2019-05-15为V1版本,目前已停产;
EPD_2in13_V2_test():对应2.13inch e-paper V2(黑)版本测试程序,购买日期晚于2019-05-15为V2版本,目前出货版本,背面贴有V2标识;
EPD_2in13bc_test():对应2.13inch e-paper B(黑)和2.13inch e-paper C(黑)测试程序;
EPD_2in13d_test(): 对应2.13inch e-paper D(黑)测试程序;

4.2寸(400×300):
EPD_4in2_test(): 对应4.2inch e-paper(黑)测试程序;
EPD_4in2bc_test(): 对应4.2inch e-paper B(黑)测试程序;

5.83寸(600×448):
EPD_5in83_test(): 对应5.83inch e-paper(黑)测试程序;
EPD_5in83bc_test(): 对应5.83inch e-paper B(黑)和5.83inch e-paper C(黑)测试程序;

7.5寸(V1:640×384,V2:800×480):
EPD_7in5_test(): 对应7.5inch e-paper(黑)测试程序,购买日期早于2019-12-07为V1版本,目前已停产;
EPD_7in5bc_test(): 对应7.5inch e-paper B(黑)和7.5inch e-paper C(黑)测试程序,7.5inch e-paper B购买日期早于2019-12-07为V1版本,目前已停产,7.5inch e-paper C正常供货;
EPD_7in5_V2_test(): 对应7.5inch e-paper V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前出货版本,背面贴有V2标识;
EPD_7in5bc_V2_test():对应7.5inch e-paper B V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前7.5inch e-paper B出货版本,背面贴有V2标识;

程序说明

底层硬件接口

我们进行了底层的封装,由于硬件平台不一样,内部的实现是不一样的,如果需要了解内部实现可以去对应的目录中查看
在DEV_Config.c(.h)可以看到很多定义,在目录:\STM32\STM32-F103ZET6\User\Config

  • 数据类型:
#define UBYTE   uint8_t
#define UWORD   uint16_t
#define UDOUBLE uint32_t
  • 模块初始化与退出的处理:
void DEV_Module_Init(void);
void DEV_Module_Exit(void);
注意:
1.这里是处理使用墨水屏前与使用完之后一些GPIO的处理。
2.对于PCB带有Rev2.1的,DEV_Module_Exit()之后整个模块会进入低功耗,经过测试这个功耗基本为0;
  • GPIO读写:
void DEV_Digital_Write(UWORD Pin, UBYTE Value);
UBYTE DEV_Digital_Read(UWORD Pin);
  • SPI写数据
void DEV_SPI_WriteByte(UBYTE Value);

中间层墨水屏驱动

e-paper驱动代码文件,在目录:\STM32\STM32-F103ZET6\User\e-Paper
如下图:
E-paper Driver HAT RPI epd.png
打开.h可以看到如下的函数

  • 墨水屏初始化,再屏幕开始工作时和退出睡眠模式之后调用
//1.54inch e-Paper、1.54inch e-Paper V2、2.13inch e-Paper、2.13inch e-Paper  V2、2.13inch e-Paper (D)、2.9inch e-Paper、2.9inch e-Paper (D)
void EPD_xxx_Init(UBYTE Mode); // Mode = 0 全局刷新初始化、Mode = 1 局部刷新初始化
//其他型号
void EPD_xxx_Init(void);

其中xxx表示,墨水屏型号。如是是2.13D,全屏初始化那么是EPD_2IN13D_Init(0),局部刷新初始化EPD_2IN13D_Init(1);如果是1.54 V2,那么EPD_1IN54_V2_Init();如果是7.5B,那就是EPD_7IN5BC_Init(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

  • 清屏,把墨水屏刷成白色
void EPD_xxx_Clear(void); 

其中xxx表示,墨水屏型号。如是是2.13D,那么是EPD_2IN9D_Clear();如果是7.5B,那就是EPD_7IN5_Clear(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

  • 传输一帧的图片数据并打开显示
//黑白双色墨水屏
void EPD_xxx_Display(UBYTE *Image);
//黑白红或黑白黄墨水屏
void EPD_xxx_Display(const UBYTE *blackimage, const UBYTE *ryimage);

需要注意以下的几个是特例:

//对于2.13inch e-paper (D)、2.9inch e-paper (D)两款柔性屏幕,局部刷新
void EPD_2IN13D_DisplayPart(UBYTE *Image);
void EPD_2IN9D_DisplayPart(UBYTE *Image);
//对于1.54inch e-paper V2、2.13inch e-paper V2由于控制芯片升级,对于局部刷新,需要调用EPD_xxx_DisplayPartBaseImage显示静态的背景图片,也就是以这个图片为基础进行局部刷新,然后调用动态的EPD_xxx_DisplayPart()
void EPD_1IN54_V2_DisplayPartBaseImage(UBYTE *Image);
void EPD_1IN54_V2_DisplayPart(UBYTE *Image);
void EPD_2IN13_V2_DisplayPart(UBYTE *Image);
void EPD_2IN13_V2_DisplayPartBaseImage(UBYTE *Image);
  • 进入睡眠模式
void EPD_xxx_Sleep(void);

注意进入了睡眠模式,只有两个方式能够重新工作:第一种硬件复位,第二种重新调用初始化函数
其中xxx表示,墨水屏型号。如是是2.13D,那么是EPD_2IN13D_Sleep();如果是7.5B,那就是EPD_7IN5BC_Sleep(),因为7.5B与7.5C公用驱动代码,只是显示的颜色不一样

上层应用

对于屏幕而言,如果需要进行画图、显示中英文字符、显示图片等怎么办,这些都是上层应用做的。这有很多小伙伴有问到一些图形的处理,我们这里提供了一些基本的功能 在如下的目录中可以找到GUI,在目录:\STM32\STM32-F103ZET6\User\GUI\GUI_Paint.c(.h)
E-paper Driver HAT GUI.png
在如下目录下是GUI依赖的字符字体,在目录:\STM32\STM32-F103ZET6\User\Fonts
E-paper Driver HAT Fonts.png

  • 新建图像属性:新建一个图像属性,这个属性包括图像缓存的名称、宽度、高度、翻转角度、颜色
void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color)
参数:
 	image : 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
 	Width : 图像缓存的宽度;
 	Height: 图像缓存的高度;
 	Rotate:图像的翻转的角度
 	Color :图像的初始颜色;
  • 选择图像缓存:选择图像缓存,选择的目的是你可以创建多个图像属性,图像缓存可以存在多个,你可以选择你所创建的每一张图像
void Paint_SelectImage(UBYTE *image)
参数:
 	image: 图像缓存的名称,实际上是一个指向图像缓存首地址的指针;
  • 图像旋转:设置选择好的图像的旋转角度,最好使用在Paint_SelectImage()后,可以选择旋转0、90、180、270
void Paint_SetRotate(UWORD Rotate)
参数:
 	Rotate: 图像选择角度,可以选择ROTATE_0、ROTATE_90、ROTATE_180、ROTATE_270分别对应0、90、180、270度
【说明】不同选择角度下,坐标对应起始像素点不同,这里以1.54B为例,四张图,按顺序为0°, 90°, 180°, 270°。仅做为参考
SPI-epaper-C-0.png SPI-epaper-C-90.png SPI-epaper-C-180.pngSPI-epaper-C-270.png
  • 图像镜像翻转:设置选择好的图像的镜像翻转,可以选择不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像。
void Paint_SetMirroring(UBYTE mirror)
参数:
 	mirror: 图像的镜像方式,可以选择MIRROR_NONE、MIRROR_HORIZONTAL、MIRROR_VERTICAL、MIRROR_ORIGIN分别对应不镜像、关于水平镜像、关于垂直镜像、关于图像中心镜像
  • 设置点在缓存中显示位置和颜色:这里是GUI最核心的一个函数、处理点在缓存中显示位置和颜色;
void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color)
参数:
 	Xpoint: 点在图像缓存中X位置
 	Ypoint: 点在图像缓存中Y位置
 	Color : 点显示的颜色
  • 图像缓存填充颜色:把图像缓存填充为某颜色,一般作为屏幕刷白的作用
void Paint_Clear(UWORD Color)
参数:
 	Color: 填充的颜色
  • 图像缓存部分窗口填充颜色:把图像缓存的某部分窗口填充为某颜色,一般作为窗口刷白的作用,常用于时间的显示,刷白上一秒
void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color)
参数:
 	Xstart: 窗口的X起点坐标
 	Ystart: 窗口的Y起点坐标
 	Xend: 窗口的X终点坐标
 	Yend: 窗口的Y终点坐标
 	Color: 填充的颜色
  • 画点:在图像缓存中,在(Xpoint, Ypoint)上画点,可以选择颜色,点的大小,点的风格
void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style)
参数:
 	Xpoint: 点的X坐标
 	Ypoint: 点的Y坐标
 	Color: 填充的颜色
 	Dot_Pixel: 点的大小,提供默认的8种大小点
 	 	 typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  , 	 	// 3 X 3
 	 	 	 DOT_PIXEL_4X4  , 	 	// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Dot_Style: 点的风格,大小扩充方式是以点为中心扩大还是以点为左下角往右上扩大
 	 	typedef enum {
 	 	   DOT_FILL_AROUND  = 1,		
 	 	   DOT_FILL_RIGHTUP,
 	 	} DOT_STYLE;
  • 画线:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画线,可以选择颜色,线的宽度,线的风格
void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, LINE_STYLE Line_Style , LINE_STYLE Line_Style)
参数:
 	Xstart: 线的X起点坐标
 	Ystart: 线的Y起点坐标
 	Xend: 线的X终点坐标
 	Yend: 线的Y终点坐标
 	Color: 填充的颜色
 	Line_width: 线的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	 Line_Style: 线的风格,选择线是以直线连接还是以虚线的方式连接
 	 	typedef enum {
 	 	 	 LINE_STYLE_SOLID = 0,
 	 	 	 LINE_STYLE_DOTTED,
 	 	} LINE_STYLE;
  • 画矩形:在图像缓存中,从 (Xstart, Ystart) 到 (Xend, Yend) 画一个矩形,可以选择颜色,线的宽度,是否填充矩形内部
void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
 	Xstart: 矩形的X起点坐标
 	Ystart: 矩形的Y起点坐标
 	Xend: 矩形的X终点坐标
 	Yend: 矩形的Y终点坐标
 	Color: 填充的颜色
 	Line_width: 矩形四边的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Draw_Fill: 填充,是否填充矩形的内部
 	 	typedef enum {
 	 	 	 DRAW_FILL_EMPTY = 0,
 	 	 	 DRAW_FILL_FULL,
 	 	} DRAW_FILL;
  • 画圆:在图像缓存中,以 (X_Center Y_Center) 为圆心,画一个半径为Radius的圆,可以选择颜色,线的宽度,是否填充圆内部
void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
参数:
 	X_Center: 圆心的X坐标
 	Y_Center: 圆心的Y坐标
 	Radius:圆的半径
 	Color: 填充的颜色
 	Line_width: 圆弧的宽度,提供默认的8种宽度
 	 	typedef enum {
 	 	 	 DOT_PIXEL_1X1  = 1,	// 1 x 1
 	 	 	 DOT_PIXEL_2X2  , 		// 2 X 2
 	 	 	 DOT_PIXEL_3X3  ,		// 3 X 3
 	 	 	 DOT_PIXEL_4X4  ,		// 4 X 4
 	 	 	 DOT_PIXEL_5X5  , 		// 5 X 5
 	 	 	 DOT_PIXEL_6X6  , 		// 6 X 6
 	 	 	 DOT_PIXEL_7X7  , 		// 7 X 7
 	 	 	 DOT_PIXEL_8X8  , 		// 8 X 8
 	 	} DOT_PIXEL;
 	Draw_Fill: 填充,是否填充圆的内部
 	 	typedef enum {
 	 	 	 DRAW_FILL_EMPTY = 0,
 	 	 	 DRAW_FILL_FULL,
 	 	} DRAW_FILL;
  • 写Ascii字符:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一个Ascii字符,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawChar(UWORD Xstart, UWORD Ystart, const char Ascii_Char, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	Ascii_Char:Ascii字符
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写英文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串英文字符,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pString:字符串,字符串是一个指针
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写中文字符串:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串中文字符,可以选择GB2312编码字符字库、字体前景色、字体背景色;
void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, cFONT* font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pString:字符串,字符串是一个指针
 	Font: GB2312编码字符字库,在Fonts文件夹中提供了以下字体:
 	 	font12CN:ascii字符字体11*21,中文字体16*21
 	 	font24CN:ascii字符字体24*41,中文字体32*41
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写数字:在图像缓存中,在 (Xstart Ystart) 为左顶点,写一串数字,可以选择Ascii码可视字符字库、字体前景色、字体背景色
void Paint_DrawNum(UWORD Xpoint, UWORD Ypoint, int32_t Nummber, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	Nummber:显示的数字,这里使用的是32位长的int型保存,可以最大显示到2147483647
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 显示时间:在图像缓存中,在 (Xstart Ystart) 为左顶点,显示一段时间,可以选择Ascii码可视字符字库、字体前景色、字体背景色;这里是方便测试局部刷新而写的,因为局部刷新需要的时间为0.3S,整体显示少于1S加上数据的传输,可以做到1S刷新一次
void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground)
参数:
 	Xstart: 字符的左顶点X坐标
 	Ystart: 字体的左顶点Y坐标
 	pTime:显示的时间,这里定义好了一个时间的结构体,只要把时分秒各位数传给参数;
 	Font: Ascii码可视字符字库,在Fonts文件夹中提供了以下字体:
 	 	font8:5*8的字体
 	 	font12:7*12的字体
 	 	font16:11*16的字体
 	 	font20:14*20的字体
 	 	font24:17*24的字体
 	Color_Foreground: 字体颜色
 	Color_Background: 背景颜色
  • 写图片:把一个位图写入图像缓存中
void Paint_DrawBitMap(const unsigned char* image_buffer)
参数:
 	image_buffer: 图像数据的缓存中的首地址

例程均在Arduino uno上进行了测试,如果需要是其他型号的Arduino需要自己确定连接的管脚是否正确。
需要注意的是:由于Arduino UNO的RAM小的可怜,无法分配过大的内存用于处理画图等功能,所以部分大尺寸的屏幕例程只演示刷新图片,这个图片是存储在flash中,我们建议Arduino UNO控制请使用e-paper Shiled体验更佳。

硬件连接

Arduino UNO连接引脚对应关系
e-Paper Arduino
Vcc 5V
GND GND
DIN D11
CLK D13
CS D10
DC D9
RST D8
BUSY D7

连接图如下(点击可放大):
E-paper driver hat to arduino connet.png

安装编译软件(windows教程)

arduino IDE 安装教程

运行程序

在产品百科界面下载程序,然后解压。Arduino程序位于 ~/Arduino/…
E-paper arduino cede1.png

请根据墨水屏型号选择对应的程序打开
E-paper arduino cede2.png
可以查看到所有的屏幕尺寸的测试程序,按照尺寸分类:
1.02寸(128×80):
epd1in02d:对应1.02inch e-paper测试程序;

1.54寸(1.54inch e-paper c:152×152,其他:200×200):
epd1in54: 对应1.54inch e-paper V1(黑)版本测试程序,购买日期早于2019-11-22为V1版本,目前已停产;
epd1in54_V2:对应1.54inch e-paper V2(黑)版本测试程序,购买日期晚于2019-11-22为V2版本,目前出货版本,背面贴有V2标识;
epd1in54b: 对应1.54inch e-paper B(黑)测试程序;
epd1in54c: 对应1.54inch e-paper C(黑)测试程序;

2.7寸(264×176):
epd2in7: 对应2.7inch e-paper(黑)测试程序;
epd2in7b: 对应2.7inch e-paper B(黑)测试程序;

2.9寸(296×128):
epd2in9: 对应2.9inch e-paper(黑)测试程序;
epd2in9bc: 对应2.9inch e-paper B(黑)和2.9inch e-paper C(黑)测试程序;
epd2in9d: 对应2.9inch e-paper D(黑)测试程序;

2.13寸(2.13inch e-Paper:250×122,其他:212×104):
epd2in13: 对应2.13inch e-paper V1(黑)版本测试程序,购买日期早于2019-05-15为V1版本,目前已停产;
epd2in13_V2:对应2.13inch e-paper V2(黑)版本测试程序,购买日期晚于2019-05-15为V2版本,目前出货版本,背面贴有V2标识;
epd2in13bc:对应2.13inch e-paper B(黑)和2.13inch e-paper C(黑)测试程序;
epd2in13d: 对应2.13inch e-paper D(黑)测试程序;

4.2寸(400×300):
epd4in2: 对应4.2inch e-paper(黑)测试程序;
epd4in2bc: 对应4.2inch e-paper B(黑)测试程序;

5.83寸(600×448):
epd5in83: 对应5.83inch e-paper(黑)测试程序;
epd5in83bc: 对应5.83inch e-paper B(黑)和5.83inch e-paper C(黑)测试程序;

7.5寸(V1:640×384,V2:800×480):
epd7in5: 对应7.5inch e-paper(黑)测试程序,购买日期早于2019-12-07为V1版本,目前已停产;
epd7in5bc: 对应7.5inch e-paper B(黑)和7.5inch e-paper C(黑)测试程序,7.5inch e-paper B购买日期早于2019-12-07为V1版本,目前已停产,7.5inch e-paper C正常供货;
epd7in5_V2: 对应7.5inch e-paper V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前出货版本,背面贴有V2标识;
epd7in5bc_V2:对应7.5inch e-paper B V2(黑)测试程序,购买日期晚于2019-12-07为V2版本,目前7.5inch e-paper B出货版本,背面贴有V2标识;

比如1.54inch e-Paper Module. 打开epd1in54文件夹,并运行epd1in54.ino文件。
打开程序,选择开发板型号Arduino UNO
E-paper arduino cede4.png
选择对应COM口
E-paper arduino cede5.png
然后点击编译并下载即可
E-paper arduino cede6.png
由于arduino UNO的flash十分小,几款大尺寸的屏幕使用MEGA2560效果更佳:
E-paper arduino cede3.png

程序说明

文件介绍

以Arduino UNO控制1.54寸墨水屏为例,打开epd1in54目录:
E-paper arduino ide codeDescription1.png
其中:
epd1in54.ino:使用Arduino IDE打开即可;
epd1in54.cpp(.h):是墨水屏的驱动程序;
epdif.cpp(.h):是硬件接口定义,里面封装了读写管脚电平,SPI传输数据,以及管脚初始化;
font8.cpp、font12.cpp、font16.cpp、font20.cpp、font24.cpp、fonts.h:为不同大小字符的模;
imagedata.cpp(.h):是图片数据,这个可以通过Img2Lcd(在开发资料中可下载)把2位深度的BMP图片转换成数组。
程序分为底层硬件接口、中间层墨水屏驱动、上层应用;

底层硬件接口

在epdif.cpp(.h)两个文件中定义了硬件接口,并封装好读写管脚电平、延时、SPI传输等函数。

写管脚电平

void DigitalWrite(int pin, int value)

第一个参数为管脚、第二个为高低电平。

读管脚电平

int DigitalRead(int pin)

参数为管脚,返回值为读取管脚的电平。

延时

DelayMs(unsigned int delaytime)

毫秒级别延时。

SPI输出数据

SpiTransfer(unsigned char data)

参数为char型,占8位。

硬件初始化

int IfInit(void)

里面已经封装好了各管脚的输入输出,以及SPI的初始化。

中间层墨水屏驱动

实例化墨水屏

由于Arduino是C++开发,需要把墨水屏实例化:

Epd epd;

墨水屏初始化,再屏幕开始工作时和退出睡眠模式之后调用

  • 1.54inch e-Paper、1.54inch e-Paper V2、2.13inch e-Paper、2.13inch e-Paper V2、2.13inch e-Paper (D)、2.9inch e-Paper、2.9inch e-Paper (D)
epd.Init(lut_full_update); //全刷初始化
epd.Init(lut_partial_update); //局刷初始化
  • 其他型号
epd.Init();

清屏,把墨水屏刷成白色

epd.clear();

可能某些程序里面会被拆分成两句,但是他们最终的效果都是一样的:

epd.ClearFrameMemory(0xFF); 
epd.DisplayFrame();//打开显示

传输一帧的图片数据并显示

void Display(const unsigned char* frame_buffer);
void DisplayFrame(const unsigned char* frame_buffer_black, const unsigned char* frame_buffer_red); //三色屏幕

睡眠

epd.Sleep();

进入睡眠模式,墨水屏讲进入超低耗电,如果长时间不用需要刷白保存,否则长时间会有残影。

上层应用

上层应用也就是我们的需要用墨水屏实现的功能,一般就是画图、字符等功能,也就是epdpaint.cpp里面定义的功能
首先需要讲解一下缓存的坐标系,为了传输方便通常吧坐上定位原点,往右X轴增加,往下Y轴增加:
E-paper arduino pic1.png

打开epdpaint.h可以看到如下:
E-paper arduino ide codeDescription2.png
只需要看public下函数即可:

初始化图片缓存

Paint(unsigned char* image, int width, int height);

第一个参数是图片缓存,第二个参数是定义图片长度,第三个参数定义图片高度,你可能会在程序中看到如下

Paint paint(image, 0, 0);    // width should be the multiple of 8

第二、三个参数这里设置成0,是因为下面还可以设置。

设置高宽、获取高宽、设置翻转角度、获取翻转角度

int  GetWidth(void); //得到宽度
void SetWidth(int width);//设置宽度
int  GetHeight(void);//得到高度
void SetHeight(int height);//设置高度
int  GetRotate(void);//得到翻转角度
void SetRotate(int rotate);//设置翻转角度

获取图像缓存

unsigned char* GetImage(void);

画点

void DrawPixel(int x, int y, int colored);

在坐标(x,y)

写字符

void DrawCharAt(int x, int y, char ascii_char, sFONT* font, int colored);

在(x,y)这一点为左顶点写字符ascii_char,字体大小为font,颜色为colored

写字符串

void DrawStringAt(int x, int y, const char* text, sFONT* font, int colored);

在(x,y)这一点为左顶点写字符串text,字体大小为font,颜色为colored

画线

void DrawLine(int x0, int y0, int x1, int y1, int colored);

以(x0,y0)为起点,(x1,y1)为终点画一条线,斜率任意;

画横线

void DrawHorizontalLine(int x, int y, int width, int colored);

以(x0,y0)为起点,(x1,y1)为终点画一条横线,速度比DrawLine()快

画竖线

void DrawVerticalLine(int x, int y, int height, int colored);

以(x0,y0)为起点,(x1,y1)为终点画一条竖线,速度比DrawLine()快

矩形,画空心框

void DrawRectangle(int x0, int y0, int x1, int y1, int colored);

以(x0,y0)为起点,(x1,y1)为终点画一个框,边的颜色为colored

填充矩形,画实心框

void DrawFilledRectangle(int x0, int y0, int x1, int y1, int colored);

以(x0,y0)为起点,(x1,y1)为终点画一个框,并且内部填充,颜色为colored

画空心圆

void DrawCircle(int x, int y, int radius, int colored);

以(x,y)为圆心,radius为半斤画一个空心圆,颜色为colored

画实心圆

void DrawFilledCircle(int x, int y, int radius, int colored);

以(x,y)为圆心,radius为半斤画一个实心心圆,颜色为colored



文档

视频

程序

旧版本

数据手册

V2版本

开发资料

相关资料

相关链接

树莓派系列教程
教程名2
  • 列表2
教程名3
  • 列表3
教程名4
  • 列表4
教程名5
  • 列表5
教程名6
  • 列表6

STM32cubeMX系列教程
批量下载教程——请戳Download-icon.png



问题:怎么区分使用的程序版本?
答复:

目前2.13inch e-paper仅存在两种版本的程序,可以通过查看e-paper背面是否有V2标识

E-paper v1&v2.png

2.13inch e-paper HAT存在两种不同的底板,可以通过查看背面是否贴有V2:

2.13inch e-paper HAT v1&v2.jpg



问题:电子墨水屏的使用环境?
答复:
  • 【工作条件】温度范围:0~50°C ;湿度范围:35%~65%RH
  • 【存储条件】:温度范围:30°C以下; 湿度范围:55%RH以下;存储最长时间:6个月
  • 【运输条件】:温度范围:-25~70°C ;运输最长时间:10天
  • 【拆包后】:温度范围:20°C±5°C ; 湿度范围:50±5%RH;存储最长时间:72小时内完成组装



问题:电子墨水屏刷新注意事项
答复:
  • 刷新模式
    • 全刷:电子墨水屏在刷新过程中会闪烁多次(闪烁次数取决于刷新时长),闪烁是为了清除残影达到最佳的显示效果
    • 局刷:电子墨水屏在刷新过程中无闪烁效果。使用局刷功能的用户注意在刷新几次之后,要进行一次全刷操作清除残影,否则残影问题会越来越严重,甚至损坏屏幕(目前只有部分黑白电子墨水屏支持局刷,具体参考产品页面说明)
  • 刷新频率
    • 使用过程中,建议客户设置电子墨水屏的刷新间隔至少为180秒(支持局刷功能的产品除外)
    • 待机过程(即刷新操作后)建议客户将电子墨水屏设置为睡眠模式,或者断电操作(可以将墨水屏供电部分用模拟开关断开), 降低功耗并且延长电子墨水屏寿命。(部分电子墨水屏如果长时间处于上电状态的话,会出现屏幕损坏无法修复的情况
    • 三色电子墨水屏在使用的过程中,建议客户至少每24小时更新一次显示画面(如果屏幕长时间保持同一个画面,会出现烧屏情况难以修复)
  • 使用场所
    • 电子墨水屏建议是在室内使用。如果在户外使用,需要避免电子墨水屏受阳光直射,同时要做好紫外线防护措施。在设计电子墨水屏产品的时候,客户注意要确定好使用环境是否满足电子墨水屏的温湿度要求


问题:Arduino3.3V能不能驱动墨水屏?
答复:
  • 可以,现在已经板载了电平转换芯片,支持3.3V驱动


问题:使用一段时间之后屏幕刷新(全刷)出现严重残影问题无法修复?
答复:
  • 长时间上电开发板,在每次刷新操作之后,建议将屏幕设置为睡眠模式或者直接断电处理,否则屏幕长时间处于高电压状态下可能烧坏屏幕


问题:e-Paper显示偏黑或者颜色偏浅?
答复:
  • 可以调节程序中Vcom的值改变显示对比度,带局刷的屏幕改善效果特别明显。


问题:e-Paper显示黑边框?
答复:
  • 可以通过Border Waveform Control寄存器 或者VCOM AND DATA INTERVAL SETTING寄存器设置边框显示颜色。


问题:屏幕排线接口是什么规格?
答复:
  • 0.5mm间距,24Pin。


问题: 运行python程序的时候报错ImportError: No module named Image?
答复:
  • 使用指令sudo apt-get install python-imaging 安装一下imaging函数库


问题: 多个位置局刷,局刷几次后字体偏浅?
答复:
  • 这种情况需要客户减少局刷位置并且在局刷5次后进行一次清屏(提高VCOM的电压可以改善颜色,但是带来是残影加重)。


问题: 墨水屏进入深入睡眠模式后,是否可以再次刷新?
答复:
  • 可以,但是需要用软件重新做电子纸初始化操作。


问题: 2.9寸的EPD 在deep sleep mode时,第一次唤醒画面刷新会有不干净的问题,请问如何解决?
答复:
  • 电子墨水屏重新唤醒的过程,实际是重新上电的过程,所以EPD在wake up时,要先进行清屏的动作,这样才能最大程度地避免残影现象。


问题: 关于datasheet的问题。客户问字库什么时候传输Data Start Transmission 1,什么时候用 Data Start Transmission 2.在KW mode 下,什么是“OLD”数据,什么是"NEW"数据。
答复:
  • 如果是三色屏,在需要传输B/W数据时,使Data Start Transmission 1,在传输RED数据时,使用Data Start Transmission 2,因为2.13inch e-Paper HAT (D)只能显示黑白两色,所以工作在KW模式Data Start Transmission 1时,发送上一次的数据,即所谓的old,在程序中就直接发送0x00,在Data Start Transmission 2时,就发送需要刷新的数据,即所谓的“NEW”数据。


问题: 墨水屏使用的是什么型号的连接器?
答复:
  • 排线插座 0.5-24pin 后翻盖式 2.0H(FPC连接器)


问题: 裸屏产品出货时是否有表面覆膜?
答复:
  • 有覆膜


问题: 请问e-Paper内置温度传感器吗?
答复:
  • 是的,也可以使用IIC管脚外置LM75温度传感器


问题: 测试程序时,程序一直卡在e-Paper busy
答复:
  • 可能是spi驱动不成功导致的1.先检查接线是否正确2.在检查spi是否开启,参数是否配置正确(spi的波特率,spi模式等参数)


问题: 这款电子墨水屏的刷新次数是多少/使用寿命是多少?
答复:
  • 理想情况下,正常使用,可以刷新1000000次(100万次)


问题: stm32驱动墨水屏,MDK编译显示空间不够?
答复:
  • 我们例程使用的是stm32f103zet6,如果客户在MDK中修改其他的型号,例如stm32f103rbt6,ram空间变小了,需要在原基础上修改启动文件中的stack size和heap size




EMAIL:2355742828@qq.com
电话:0755-83040712
QQ:2355742828
微信:扫下方二维码添加
Chz.png
* 企业微信添加好友时软件无提示,我们无法及时通过客户好友申请。如长时间无响应,请用其他联系方式。

说明:进行售后服务前,请准备好客户信息(定货单位、定货人等),以供验证。

取自“https://www.waveshare.net/w/index.php?title=2.13inch_e-Paper_HAT&oldid=34897
Call-of-duty-V2.jpg       Join-us-V2.jpg