微雪墨水屏简单开发记录
毕业的事情忙完了开始搭建自己的信息收集渠道,然后电脑桌边上需要一个常量显示即时信息,但是又不需要亮着的玩意儿,那么就只能是墨水屏了。
这篇博文选用的是微雪的 7.5inch HD e-Paper V2 + ESP32 带 WIFI 的开发板来实现信息的渲染,微雪官方提供了对应的 Arduino 开发库和示例程序。
最开始在某宝看到这个套装还以为 ESP32 提供的 ESP32 WIFI 渲染程序是有一个接口的,可以在装载启动后直接提供一个内网的服务用来发送图片上去渲染。也就是官网的 WIFI 例程:https://www.waveshare.net/wiki/E-Paper_ESP32_Driver_Board。
在拿到板子后刷进去才发现,这个例程确实提供了一个网页用来上传图片并且进行采样生成 LCD 图片,但是它没有一个具体的接口,而且一张图片上传渲染完成之后就会关闭服务,所以需要达到自己想要的效果也就只能自己写程序了。示例程序可以用来测试一下板子正不正常,第四步里一种尺寸的板子有不同的型号,也需要正确选择才能正常渲染。
渲染接口
ESP32 的示例程序里有一个名为 esp32-waveshare-epd 的文件夹,在按照微雪文档里的指示放到 Arduino 文件夹里就可以,这里也没有太多好写的,配置过程不管是官网还是网上也有不少。这个文件夹里包含了一系列的示例程序和开发所需要用到的库(这里好评,不用自己去慢慢学更底层的代码)。
需要明确的一点是这款墨水屏里长的那一侧为 x 轴,另外一侧为 y 轴,在摆正后以左上角为原点,y 轴向下。摆正的方向的话 7.5 inch 这块板子是排线向下为正,其他的就需要自己测试了。下面的函数调用需要引入 EPD.h 和 DEV_Config.h 文件。
示例程序里基本上以调用 DEV_Module_Init
开始,这个函数是用来初始化引脚的,只管启动就调
根据屏幕使用的不同,需要调用屏幕的初始化和清屏函数,通常是下面这样:
1 | EPD_7IN5_V2_Init(); |
这两个函数根据使用屏幕的型号不同也存在差异,在 sp32-waveshare-epd\src\utility
中可以根据型号找到对应的 .h 文件查看有哪些函数
Init 函数在 7.5 inch 这款屏中有四种,对应了后续不同的渲染过程
1 | UBYTE EPD_7IN5_V2_Init(void); // 完全渲染,在后续渲染屏幕的时候整个屏幕会闪烁刷新 |
清屏也存在两种,分别对应了将整个屏幕刷黑和刷白
1 | void EPD_7IN5_V2_Clear(void); |
然后是渲染函数,传入图像数组进行渲染
1 | void EPD_7IN5_V2_Display(UBYTE *blackimage); |
这几个函数都是传入 byte 类型的图像进行渲染,对图像的绘制由另外一个库来实现。EPD_7IN5_V2_Display_Part
函数用于进行部分渲染,部分渲染之前需要调用 EPD_7IN5_V2_Init_Part
函数,否则部分渲染的部分还是会进行闪烁。
图像绘制
上面的各种 Display
函数需要传入一个 Image 数组进行渲染,微雪所提供的库里也包含了绘制图像的方法,需要引入 GUI_Paint.h 文件
在绘制图像之前需要定义这个数组并初始化,通常直接全局声明避免爆栈,也可以参考一下示例程序,这里主要对不同的函数调用说明。这样的话主文件的头部如下
1 | UBYTE *BlackImage; |
Paint_NewImage
传入 BlackImage 用于设定图像,其实可以直接把它理解为一个画板了,后面的所有绘制操作本质上都是在这个画板上实现
Paint_Clear
将画板刷为对应的颜色,还有另外一个 Paint_ClearWindows
在局部刷新的时候用于刷新单独的一个长方形区域
Paint 还有其他的函数,但是这次开发没有涉及到也就不说明,感兴趣可以探索一下(懒了
1 | void Paint_SelectImage(UBYTE *image); |
点、线、面
绘制点、线、面有四个函数,分别绘制点、线、长方形和圆形:
1 | void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_FillWay); |
这些函数里需要传入的有:
坐标:Xpoint
、Ypoint
或者 Xstart
、Ystart
这样的字段都是用于指示坐标,直接传入整数,注意不要超过绘制范围,也就是屏幕的像素长宽
颜色:在墨水屏里就只有 BLACK 和 WHITE 黑白两种选项,其他类型的屏幕里可能会有 RED 这样的红色选项
画笔粗细:也就是 DOT_PIXEL
,可以直接使用定义好的 DOT_PIXEL_1X1
到 DOT_PIXEL_8X8
,DOT_PIXEL_DFT
默认为 1x1
点、线、面里存在不同的是最后一个参数
- 在点的绘制里,
DOT_STYLE
可选为DOT_FILL_AROUND
或DOT_FILL_RIGHTUP
,代表的是 1x1 或 2x2 的像素点 - 在线的绘制里,
LINE_STYLE
可选为LINE_STYLE_SOLID
或LINE_STYLE_DOTTED
代表实线和虚线 - 在面的绘制里,
DRAW_FILL
可选为DRAW_FILL_EMPTY
或DRAW_FILL_FULL
代表空心或实心
文字
微雪的库里自带了一些英文或中文的文字库,如果需要引入其他字体就需要自行构建文字库进行传入绘制,绘制文字的函数有:
1 | void Paint_DrawChar(UWORD Xstart, UWORD Ystart, const char Acsii_Char, sFONT* Font, UWORD Color_Foreground, UWORD Color_Background); |
Paint_DrawChar
:绘制单个 ascii 字符
Paint_DrawString_EN
:绘制英文字符串
Paint_DrawString_CN
:绘制中文字符串,也可以混杂英文
Paint_DrawNum
:绘制数字
Paint_DrawTime
:绘制时间序列
(Xpoint,Ypoint)和 (Xstart, Ystart) 这样的字样也不用多说,代表坐标,随后的就是字符、字符串或者时间序列
cFONT 和 sFONT 则代表了不同的字体的定义,可以直接看它们的定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 >//ASCII
>typedef struct _tFont
>{
const uint8_t *table;
uint16_t Width;
uint16_t Height;
>} sFONT;
>//GB2312
>typedef struct // 汉字字模数据结构
>{
unsigned char index[3]; // 汉字内码索引
const char matrix[MAX_HEIGHT_FONT*MAX_WIDTH_FONT/8]; // 点阵码数据
>}CH_CN;
>typedef struct
>{
const CH_CN *table;
uint16_t size;
uint16_t ASCII_Width;
uint16_t Width;
uint16_t Height;
>}cFONT;在不需要使用其他字体的时候可以不用管,直接传入定义好的字体就可以,例如下面就是英文和中文里各种字号的字体
1
2
3
4
5
6
7
8 >extern sFONT Font24;
>extern sFONT Font20;
>extern sFONT Font16;
>extern sFONT Font12;
>extern sFONT Font8;
>extern cFONT Font12CN;
>extern cFONT Font24CN;如果需要使用自定义字体,那么需要将它们导出,例如 github 上的 https://github.com/theHEXstyle/font2bytes 是一个将 ASCII 字符导出为字节码的程序,应该也有中文的相关开源库。在导出为字节码后放入到项目目录里引用就可以,例如我用了 Firacode 字体,那么就是先声明一个 external_fonts.h 文件:
1
2
3
4
5
6
7
8 >
>
>
>extern sFONT FiraBoldFont42;
>然后将转换好的字形文件导入,并把主要的字形类改为对应的名字,在 external_fonts.cpp 文件里:
1
2
3
4
5 >sFONT FiraBoldFont42 = {
FiraBoldFont42_Table,
26, /* Width */
42, /* Height */
>};
Color_Foreground
和 Color_Background
字段分别代表了文字的颜色和背景颜色
在所需要的绘制完成后,通过前面的各种 Display 函数就可以将图像显示在屏幕上