epd 墨水屏操作库
作者:江访 | 最后修改:2026-08-19
一、概述
epd 是 LuatOS 的电子墨水屏操作库,基于 tiny_epd 组件实现,支持微雪电子多款 1.54 英寸墨水屏,覆盖黑白(BW)、黑白红(BWR)、黑白红黄(BWRY)三类颜色面板。
与 eink 库不同,epd 库采用面向对象的调用方式:先调用 epd.open() 打开屏幕得到 panel 对象,再通过 panel 对象的方法完成初始化、绘图、刷新、休眠等操作。屏幕刷新采用异步机制,不会阻塞业务代码。
epd 库提供如下几大类功能:
-
屏幕打开与初始化:支持 7 种内置型号和自定义屏幕(custom 模式)
-
基本图形绘制:直线、矩形、圆形、像素点等基本图形的绘制
-
文本显示:支持 UTF-8 中英文字体显示(需固件启用 HZFont 功能)
-
位图显示:支持 XBM 格式位图显示
-
二维码生成:支持二维码生成和显示
-
多种刷新模式:全刷(FULL)、快刷(FAST)、局部刷新(PARTIAL)、局部区域刷新(PARTIAL_RECT)、自动刷新(AUTO)
主要特性:
-
支持 7 种逻辑颜色(黑/白/红/黄/橙/蓝/绿),自动映射到当前面板支持的物理颜色
-
支持画布旋转(0/90/180/270 度),旋转后坐标自动适配
-
刷新异步执行,可通过返回值查询刷新结果
-
支持自定义屏幕(custom 模式),通过命令序列描述任意墨水屏控制器,无需编写 C 驱动
注意事项:
-
墨水屏刷新速度较慢,不适合频繁更新的场景
-
使用前必须先初始化 SPI,再调用
epd.open() -
一次刷新进行期间(刷新未完成),再次调用其他接口会返回
false, "busy" -
中文文本绘制(
panel:drawHzfont())需要固件启用 HZFont 功能,是否支持以具体产品固件为准 -
不同型号支持的刷新模式、颜色不同,可通过
panel:supportsColor()和panel:info()查询
二、核心示例
1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;
2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;
3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo。
关于错误处理写法说明:示例中使用
if not ... then log.error(...) return end的判断方式处理错误,这是实际业务开发推荐的写法。epd库的大部分接口在失败时返回false和错误信息字符串,业务代码应根据返回值做相应处理;直接使用assert()断言会导致失败时程序异常终止,仅适合开发调试阶段。
2.1 核心代码
-- 本核心示例演示 epd 库的基本使用流程:
-- 1、初始化 SPI 设备
-- 2、打开并初始化墨水屏
-- 3、绘制文本和图形
-- 4、刷新显示到屏幕
-- 按实际接线配置 SPI 编号和 GPIO 引脚号
local spi_id = 0
local pin_cs = 8 -- 片选引脚
local pin_dc = 10 -- 数据/命令引脚
local pin_rst = 1 -- 复位引脚
local pin_busy = 22 -- 忙检测引脚
-- 主函数
local function main()
-- 注意:epd.open() 之前必须先初始化 SPI,使用 spi.deviceSetup() 方式初始化
-- 注意:spi_epd 不加 local,后续示例会继续复用该 SPI 设备对象
spi_epd = spi.deviceSetup(spi_id, pin_cs, 0, 0, 8, 20 * 1000 * 1000, spi.MSB, 1, 0)
-- 打开 1.54 英寸黑白墨水屏,port="device" 表示使用上面创建的 SPI 对象
local panel, err = epd.open(epd.MODEL_1IN54,
{ port = "device", pin_dc = pin_dc, pin_rst = pin_rst, pin_busy = pin_busy },
spi_epd)
if not panel then
log.error("epd", "打开屏幕失败", err)
return
end
-- 初始化屏幕
if not panel:init() then
log.error("epd", "初始化失败")
return
end
-- 清屏为白色
panel:clear(epd.WHITE)
-- 设置当前前景色为黑色、背景色为白色
panel:setColor(epd.BLACK, epd.WHITE)
-- 绘制外边框(矩形,空心)
panel:rect(0, 0, 199, 199, epd.BLACK, 0)
-- 绘制分割线(直线)
panel:line(0, 30, 199, 30, epd.BLACK)
-- 绘制实心圆形
panel:circle(50, 110, 30, epd.BLACK, 1)
-- 绘制空心矩形
panel:rect(100, 80, 180, 140, epd.BLACK, 0)
-- 绘制二维码
panel:qrcode(20, 150, "https://docs.openluat.com", 60, epd.BLACK)
-- 异步刷新整屏,.wait() 等待刷新完成,返回 true 或 false + 错误信息
local ok, rerr = panel:refresh(epd.FULL).wait()
if not ok then
log.error("epd", "刷新失败", rerr)
return
end
-- 使用完毕后进入休眠,降低功耗
panel:sleep(epd.SLEEP_DEEP)
end
-- 运行主函数
sys.taskInit(main)
2.2 局部刷新示例
-- 本示例演示局部区域刷新,适合只更新屏幕局部内容的场景
-- 局部刷新可以显著缩短单次刷新耗时,但最终效果以屏幕硬件支持为准
local function main()
-- 注意:spi_epd 不加 local,与其他示例保持一致的全局变量写法
spi_epd = spi.deviceSetup(0, 8, 0, 0, 8, 20 * 1000 * 1000, spi.MSB, 1, 0)
local panel, err = epd.open(epd.MODEL_1IN54,
{ port = "device", pin_dc = 10, pin_rst = 1, pin_busy = 22 }, spi_epd)
if not panel then
log.error("epd", "打开屏幕失败", err)
return
end
panel:init()
panel:clear(epd.WHITE)
-- 在指定区域绘制一个像素点
panel:pixel(12, 18, epd.BLACK)
-- 只刷新该像素点所在的局部区域(x, y, w, h)
-- 注意:仅 PARTIAL_RECT 模式支持指定区域,且需要屏幕硬件支持局部刷新
local ok, rerr = panel:refresh(epd.PARTIAL_RECT, 10, 16, 5, 5).wait()
if not ok then
log.error("epd", "局部刷新失败", rerr)
return
end
panel:sleep(epd.SLEEP_DEEP)
end
sys.taskInit(main)
三、常量详解
核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;
每个常量对应的常量取值仅做日志打印时查询使用,不要将这个常量取值用做具体的业务逻辑判断,因为LuatOS内核固件可能会变更每个常量对应的常量取值;
如果用做具体的业务逻辑判断,一旦常量取值发生改变,业务逻辑就会出错;
3.1 屏幕型号常量
屏幕型号常量用于 epd.open() 的第一个参数,指定墨水屏的具体型号。
epd.MODEL_1IN54
常量含义:微雪 1.54 英寸黑白墨水屏,分辨率 200x200;
数据类型:number;
参数示例:epd.open(epd.MODEL_1IN54, opts, spi_epd);
适用产品型号:以固件支持列表为准;
epd.MODEL_1IN54_V2
常量含义:微雪 1.54 英寸黑白墨水屏 V2 版本,分辨率 200x200;
数据类型:number;
参数示例:epd.open(epd.MODEL_1IN54_V2, opts, spi_epd);
适用产品型号:以固件支持列表为准;
epd.MODEL_1IN54_V3
常量含义:微雪 1.54 英寸黑白墨水屏 V3 版本,分辨率 200x200;
数据类型:number;
参数示例:epd.open(epd.MODEL_1IN54_V3, opts, spi_epd);
适用产品型号:以固件支持列表为准;
epd.MODEL_1IN54_SSD1607
常量含义:SSD1607 控制器 1.54 英寸黑白墨水屏,分辨率 200x200;
数据类型:number;
参数示例:epd.open(epd.MODEL_1IN54_SSD1607, opts, spi_epd);
适用产品型号:以固件支持列表为准;
epd.MODEL_1IN54R
常量含义:微雪 1.54 英寸黑白红墨水屏,分辨率 152x152;
数据类型:number;
参数示例:epd.open(epd.MODEL_1IN54R, opts, spi_epd);
适用产品型号:以固件支持列表为准;
epd.MODEL_1IN54B_V2
常量含义:微雪 1.54 英寸黑白红墨水屏 V2 版本,分辨率 200x200;
数据类型:number;
参数示例:epd.open(epd.MODEL_1IN54B_V2, opts, spi_epd);
适用产品型号:以固件支持列表为准;
epd.MODEL_1IN54G_V2
常量含义:微雪 1.54 英寸四色墨水屏(黑白红黄),分辨率 200x200,支持快刷;
数据类型:number;
参数示例:epd.open(epd.MODEL_1IN54G_V2, opts, spi_epd);
适用产品型号:以固件支持列表为准;
custom 模式(字符串 "custom")
常量含义:自定义墨水屏模式,通过命令序列描述屏幕初始化、刷新、休眠时序;
注意事项:该模式没有对应的数字常量,直接在 epd.open() 的第一个参数传入字符串 "custom";
使用该模式时,opts 配置表中必须额外提供 width、height、init、refresh 等自定义配置,详见 4.1.1 函数详解;
参数示例:epd.open("custom", custom_opts, spi_epd);
适用产品型号:以固件支持列表为准;
3.2 颜色常量
颜色常量用于绘图接口的 color 参数,如 panel:pixel()、panel:line()、panel:rect()、panel:circle() 等。epd 库会自动把逻辑颜色映射到当前面板支持的物理颜色。
epd.BLACK -- 黑色
epd.WHITE -- 白色
epd.RED -- 红色
epd.YELLOW -- 黄色
epd.ORANGE -- 橙色
epd.BLUE -- 蓝色
epd.GREEN -- 绿色
注意事项:
-
并非所有面板都支持所有颜色,黑白屏只支持
epd.BLACK和epd.WHITE -
调用
panel:setColor(fg, bg)设置不支持的组合颜色时,会返回false和错误信息 -
可通过
panel:supportsColor(color)查询某个颜色是否受当前面板支持
3.3 刷新模式常量
刷新模式常量用于 panel:refresh() 的参数,指定屏幕刷新的方式。
| 常量 | 说明 | 适用场景 |
|---|---|---|
| epd.FULL | 全屏刷新,画面整体刷新一次 | 首次显示、整屏内容变化时 |
| epd.FAST | 快速刷新,刷新耗时短,但残留较重 | 支持快刷的屏幕(如 MODEL_1IN54G_V2),需要频繁更新的场景 |
| epd.PARTIAL | 局部刷新(部分 LUT + 完整帧缓冲传输),刷新全帧但显示效果残留较小 | 屏幕支持局部刷新时 |
| epd.PARTIAL_RECT | 局部区域刷新(部分 LUT + 指定矩形区域),只刷新指定区域 | 屏幕支持局部区域刷新,且只想更新局部内容时 |
| epd.AUTO | 自动刷新,屏幕支持局部刷新时自动选择局部刷新,否则全屏刷新 | 不确定选哪个时,建议使用默认值 |
注意事项:
-
panel:refresh()不带参数时默认使用全屏刷新(FULL) -
并非所有型号都支持局部刷新,可通过
panel:info().caps查询能力位
3.4 休眠模式常量
休眠模式常量用于 panel:sleep() 的参数,指定屏幕进入的休眠状态。
| 常量 | 说明 | 适用场景 |
|---|---|---|
| epd.SLEEP_AUTO | 自动休眠,由驱动按屏幕能力选择最深的休眠模式 | 不确定选哪个时,使用默认值即可 |
| epd.SLEEP_STANDBY | 待机休眠 | 屏幕支持待机模式时 |
| epd.SLEEP_DEEP | 深度休眠,功耗最低 | 长时间不再刷新屏幕时 |
注意事项:
-
panel:sleep()不带参数时默认使用SLEEP_AUTO -
深度休眠后,再次刷新屏幕前需要重新调用
panel:init()初始化
3.5 帧缓冲格式常量
帧缓冲格式常量用于自定义屏幕(custom 模式)和 panel:info() 返回的 format 字段。
epd.FORMAT_INDEX1 -- 1 位索引格式,黑白
epd.FORMAT_INDEX2 -- 2 位索引格式,4 色
epd.FORMAT_INDEX4 -- 4 位索引格式
epd.FORMAT_INDEX8 -- 8 位索引格式
epd.FORMAT_PLANAR1 -- 1 位平面格式
3.6 能力位常量
能力位常量用于 panel:info().caps 字段,按位组合标识面板支持的能力。
epd.CAP_REFRESH_FULL -- 支持全屏刷新
epd.CAP_REFRESH_FAST -- 支持快速刷新
epd.CAP_REFRESH_PARTIAL -- 支持局部刷新
epd.CAP_REFRESH_PARTIAL_RECT-- 支持局部区域刷新
epd.CAP_SLEEP_STANDBY -- 支持待机休眠
epd.CAP_SLEEP_DEEP -- 支持深度休眠
epd.CAP_COLOR_BW -- 支持黑白
epd.CAP_COLOR_BWR -- 支持黑白红
epd.CAP_COLOR_BWY -- 支持黑白黄
epd.CAP_COLOR_4 -- 支持 4 色
epd.CAP_COLOR_7 -- 支持 7 色
epd.CAP_GRAY -- 支持灰度
3.7 抖动方式说明(需固件启用 HZFont)
panel:drawHzfont() 内部按阈值抖动方式将灰度文本二值化绘制,阈值固定为 128。
-- 当前版本 drawHzfont 不提供抖动方式常量
-- 如需调整文字灰度表现,可通过字号 size 参数间接控制
注意事项:
-
以上说明仅在固件启用 HZFont 功能时适用
-
当前版本未暴露
epd.DITHER_THRESHOLD/epd.DITHER_BAYER4常量,请勿在代码中直接使用这两个名字,否则会报attempt to index a nil value
四、函数详解
4.1 屏幕打开与初始化
4.1.1 epd.open(model, opts[, spi_device])
功能
打开墨水屏并创建 panel 对象。返回的 panel 对象用于调用后续所有屏幕操作接口。
参数
model
参数含义:墨水屏型号,使用 3.1 章节的屏幕型号常量,或直接传入型号名称字符串
数据类型:number/string
取值范围:epd.MODEL_1IN54、epd.MODEL_1IN54_V2、epd.MODEL_1IN54_V3、epd.MODEL_1IN54_SSD1607、
epd.MODEL_1IN54R、epd.MODEL_1IN54B_V2、epd.MODEL_1IN54G_V2
(也可传入型号名称字符串,如 "1in54"、"1in54_v2"、"custom")
是否必选:是
注意事项:custom 模式需要额外配置自定义屏幕参数,详见本函数示例
参数示例:epd.MODEL_1IN54
opts
参数含义:屏幕配置表,包含 SPI 端口和 GPIO 引脚配置
数据类型:table
取值范围:包含以下参数:
{
参数含义:SPI 端口,可以是 SPI 编号或字符串 "device"
数据类型:number/string
取值范围:SPI 编号(如 0、1);或 "device" 表示使用第三个参数传入的 SPI 设备对象
是否必选:是
注意事项:使用 "device" 方式时必须同时传入第三个参数 spi_device
参数示例:0 或 "device"
opts.port ,
参数含义:数据/命令引脚(DC)
数据类型:number
取值范围:有效 GPIO 编号
是否必选:是
参数示例:10
opts.pin_dc ,
参数含义:复位引脚(RST)
数据类型:number
取值范围:有效 GPIO 编号
是否必选:是
参数示例:1
opts.pin_rst ,
参数含义:忙检测引脚(BUSY)
数据类型:number
取值范围:有效 GPIO 编号
是否必选:是
参数示例:22
opts.pin_busy ,
参数含义:BUSY 引脚的上下拉配置
数据类型:number
取值范围:0 表示使用默认配置,其他值由固件平台决定(如 gpio.PULLUP / gpio.PULLDOWN)
是否必选:否
注意事项:默认 0,使用默认配置即可
参数示例:0
opts.busy_pull ,
参数含义:BUSY 引脚轮询间隔,单位毫秒
数据类型:number
取值范围:大于等于 0
是否必选:否
注意事项:默认 0,此时使用库内部默认轮询间隔 10ms。一般无需修改
参数示例:0
opts.busy_poll_ms ,
参数含义:画布旋转角度
数据类型:number
取值范围:0/90/180/270,或索引 0/1/2/3
是否必选:否
注意事项:不填默认 0 度。也可使用面板方法 panel:setRotation() 动态设置
参数示例:0
opts.rotation ,
参数含义:画布方向(rotation 的别名)
数据类型:number
取值范围:同 rotation,0/90/180/270 或索引 0/1/2/3
是否必选:否
注意事项:当同时传入 rotation 和 direction 时,以 rotation 为准
参数示例:0
opts.direction ,
}
custom 模式附加配置(当 model 传入字符串 "custom" 时必须提供):
参数含义:自定义屏幕配置表,追加在 opts 中
数据类型:table
取值范围:包含以下参数:
{
参数含义:屏幕像素宽度
数据类型:number
取值范围:1~65535
是否必选:是
opts.width ,
参数含义:屏幕像素高度
数据类型:number
取值范围:1~65535
是否必选:是
opts.height ,
参数含义:帧缓冲格式
数据类型:number
取值范围:epd.FORMAT_INDEX1(当前 custom 模式仅支持 1 位索引格式,即黑白屏)
是否必选:否
注意事项:如需自定义彩色屏,请使用内置型号或等待后续版本支持
opts.format ,
参数含义:BUSY 引脚空闲电平
数据类型:number
取值范围:0 或 1
是否必选:否
注意事项:默认 0
opts.busy_level ,
参数含义:BUSY 等待超时时间,单位毫秒
数据类型:number
取值范围:大于等于 0
是否必选:否
opts.busy_timeout ,
参数含义:初始化命令序列
数据类型:table
取值范围:命令步骤列表,每一步支持以下格式之一:
{cmd=命令字, data={数据...}} 发送命令及可选数据
{reset={high=高电平毫秒, low=低电平毫秒, high2=再高电平毫秒}} 复位时序
{delay=毫秒} 延时
{busy=空闲电平[, timeout=毫秒]} 等待屏幕空闲
{write_ram=命令字} 写入整帧 RAM
{write_ram2=命令字} 写入第二平面 RAM
是否必选:是
参数示例:{ {reset={high=20, low=2, high2=20}}, {cmd=0x01, data={0x03}} }
opts.init ,
参数含义:快速刷新初始化命令序列(可选)
数据类型:table
取值范围:同 init
是否必选:否
opts.fast_init ,
参数含义:刷新命令序列
数据类型:table
取值范围:包含 full / fast / partial 三个可选子序列,子序列格式同 init;
其中 full 为必填
是否必选:是(full 必填)
参数示例:{ full = { {cmd=0x22, data={0xF7}} } }
opts.refresh ,
参数含义:休眠命令序列
数据类型:table
取值范围:包含 deep 子序列,格式同 init
是否必选:否
opts.sleep ,
}
spi_device
参数含义:SPI 设备对象
数据类型:userdata
取值范围:spi.deviceSetup() 的返回值
是否必选:仅当 opts.port = "device" 时必须传入
注意事项:使用该方式时,SPI 对象由 epd 库持有,panel 关闭时自动释放
参数示例:spi.deviceSetup(0, 8, 0, 0, 8, 20 * 1000 * 1000, spi.MSB, 1, 0)
返回值
panel
含义说明:成功时返回墨水屏 panel 对象
数据类型:userdata
返回示例:epd 库定义的 panel 对象
err
含义说明:失败时返回错误信息
数据类型:string
注意事项:成功时无此返回值
返回示例:"unsupported epd model"
示例
-- ===== 方式一:使用 SPI 编号 =====
-- 适合已用 spi.setup() 配置好 SPI 的场景,opts 里直接用 SPI 编号
local panel, err = epd.open(epd.MODEL_1IN54,
{ port = 0, pin_dc = 10, pin_rst = 1, pin_busy = 22 })
if not panel then
log.error("epd", "打开屏幕失败", err)
return
end
-- ===== 方式二:使用 SPI 设备对象(推荐)=====
-- 注意:spi_epd 不加 local,后续示例会继续复用该 SPI 设备对象
spi_epd = spi.deviceSetup(0, 8, 0, 0, 8, 20 * 1000 * 1000, spi.MSB, 1, 0)
local panel, err = epd.open(epd.MODEL_1IN54,
{ port = "device", pin_dc = 10, pin_rst = 1, pin_busy = 22 }, spi_epd)
if not panel then
log.error("epd", "打开屏幕失败", err)
return
end
-- ===== 方式三:2.13 寸墨水屏(custom 模式)=====
-- epd 库内置型号只覆盖 1.54 寸,其他尺寸屏幕需用 custom 模式,
-- 通过命令序列描述控制器的初始化、刷新、休眠时序。
-- 以下示例为微雪 2.13 寸 e-Paper V4(122x250)的完整配置,其他型号需对照其官方驱动改写。
spi_epd = spi.deviceSetup(0, 8, 0, 0, 8, 20 * 1000 * 1000, spi.MSB, 1, 0)
local panel, err = epd.open("custom", {
port = "device",
pin_dc = 10, -- 数据/命令引脚
pin_rst = 1, -- 复位引脚
pin_busy = 2, -- 忙检测引脚
width = 122, -- 控制器 RAM 宽(竖屏 122x250)
height = 250, -- 控制器 RAM 高
busy_level = 0, -- BUSY 空闲电平
busy_timeout = 30000, -- BUSY 等待超时(毫秒)
-- 初始化命令序列(对照官方 EPD_2in13_V4_Init())
init = {
{reset = {high = 20, low = 2, high2 = 20}}, -- 复位时序
{busy = 0}, -- 等待空闲
{cmd = 0x12}, -- SWRESET 软复位
{busy = 0},
{cmd = 0x01, data = {0xF9, 0x00, 0x00}}, -- 驱动输出控制
{cmd = 0x11, data = {0x03}}, -- 数据进入模式
{cmd = 0x44, data = {0x00, 0x0F}}, -- 设置 RAM X 范围
{cmd = 0x45, data = {0x00, 0x00, 0xF9, 0x00}},-- 设置 RAM Y 范围
{cmd = 0x4E, data = {0x00}}, -- 设置 RAM X 指针
{cmd = 0x4F, data = {0x00, 0x00}}, -- 设置 RAM Y 指针
{cmd = 0x3C, data = {0x05}}, -- 边框波形
{cmd = 0x21, data = {0x00, 0x80}}, -- 显示更新控制
{cmd = 0x18, data = {0x80}}, -- 读取内置温度传感器
{busy = 0},
},
-- 刷新命令序列(full 全刷 / partial 局部刷)
refresh = {
full = {
{cmd = 0x44, data = {0x00, 0x0F}},
{cmd = 0x45, data = {0x00, 0x00, 0xF9, 0x00}},
{cmd = 0x4E, data = {0x00}},
{cmd = 0x4F, data = {0x00, 0x00}},
{write_ram = 0x24}, -- 写整帧 RAM(0x24)
{write_ram2 = 0x26}, -- 写第二平面 RAM(0x26),建立局部刷新基帧
{cmd = 0x22, data = {0xF7}}, -- 显示更新控制
{cmd = 0x20}, -- 激活显示更新
{busy = 0},
},
partial = {
{reset = {high = 0, low = 1, high2 = 20}},
{cmd = 0x3C, data = {0x80}},
{cmd = 0x01, data = {0xF9, 0x00, 0x00}},
{cmd = 0x11, data = {0x03}},
{cmd = 0x44, data = {0x00, 0x0F}},
{cmd = 0x45, data = {0x00, 0x00, 0xF9, 0x00}},
{cmd = 0x4E, data = {0x00}},
{cmd = 0x4F, data = {0x00, 0x00}},
{write_ram = 0x24},
{cmd = 0x22, data = {0xFF}}, -- 局部刷新显示更新
{cmd = 0x20},
{busy = 0},
},
},
-- 休眠命令序列(进入深度睡眠)
sleep = {
deep = {
{cmd = 0x10, data = {0x01}}, -- 深度睡眠
{delay = 100},
},
},
}, spi_epd)
if not panel then
log.error("epd", "打开 2.13 寸屏失败", err)
return
end
-- 旋转 90 度,将 122x250 竖屏变为 250x122 横屏使用
panel:setRotation(90)
4.1.2 panel:init()
功能
初始化墨水屏。执行屏幕上电、复位、初始化命令序列等操作。打开屏幕后必须先调用本方法,才能进行绘图和刷新。
参数
无
返回值
result
含义说明:初始化是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
err
含义说明:失败时的错误信息
数据类型:string
注意事项:成功时无此返回值
返回示例:"invalid parameter"
示例
-- 打开屏幕后必须先初始化
local panel, err = epd.open(epd.MODEL_1IN54,
{ port = "device", pin_dc = 10, pin_rst = 1, pin_busy = 22 }, spi_epd)
if not panel then
log.error("epd", "打开屏幕失败", err)
return
end
-- 初始化屏幕,成功后才能绘图和刷新
if not panel:init() then
log.error("epd", "初始化失败")
return
end
4.1.3 panel:close()
功能
关闭并释放墨水屏资源。关闭后 panel 对象不再可用,需要重新调用 epd.open() 才能再次使用屏幕。
参数
无
返回值
result
含义说明:关闭是否成功
数据类型:boolean
取值范围:true 成功
返回示例:true
示例
-- 使用完毕后关闭并释放屏幕资源
panel:close()
4.2 屏幕控制
4.2.1 panel:refresh([mode[, x, y, w, h]])
功能
刷新屏幕,将帧缓冲区内容显示到屏幕上。本方法为异步执行,返回一个可等待的结果对象,通过 .wait() 等待刷新完成。
参数
mode
参数含义:刷新模式
数据类型:number
取值范围:epd.FULL(默认)、epd.FAST、epd.PARTIAL、epd.PARTIAL_RECT、epd.AUTO
是否必选:否
注意事项:不带参数时默认全屏刷新(FULL)。FAST/PARTIAL/PARTIAL_RECT 需要屏幕硬件支持,可查看面板 info().caps 能力位确认
参数示例:epd.FULL
x
参数含义:局部刷新区域的起点 X 坐标
数据类型:number
取值范围:0~65535,且必须在画布范围内
是否必选:仅当 mode = epd.PARTIAL_RECT 时可选
注意事项:只有 PARTIAL_RECT 模式支持传入区域参数;其他模式传入多余参数会返回参数错误
参数示例:10
y
参数含义:局部刷新区域的起点 Y 坐标
数据类型:number
取值范围:0~65535,且必须在画布范围内
是否必选:仅当 mode = epd.PARTIAL_RECT 时可选
注意事项:只有 PARTIAL_RECT 模式支持传入区域参数
参数示例:16
w
参数含义:局部刷新区域的宽度
数据类型:number
取值范围:0~65535,且必须在画布范围内
是否必选:仅当 mode = epd.PARTIAL_RECT 时可选
注意事项:只有 PARTIAL_RECT 模式支持传入区域参数
参数示例:5
h
参数含义:局部刷新区域的高度
数据类型:number
取值范围:0~65535,且必须在画布范围内
是否必选:仅当 mode = epd.PARTIAL_RECT 时可选
注意事项:只有 PARTIAL_RECT 模式支持传入区域参数
参数示例:5
返回值
result
含义说明:异步刷新结果,需调用 .wait() 获取
数据类型:cwait 结果对象
取值范围:.wait() 返回 true 表示刷新成功;返回 false 和错误信息表示刷新失败
注意事项:刷新进行期间再次调用屏幕接口会返回 false, "busy"
返回示例:panel:refresh(epd.FULL).wait()
示例
-- 全屏刷新并等待完成
local ok, rerr = panel:refresh(epd.FULL).wait()
if not ok then
log.error("epd", "全屏刷新失败", rerr)
end
-- 局部区域刷新(仅 PARTIAL_RECT 支持指定区域)
panel:pixel(12, 18, epd.BLACK)
local ok, rerr = panel:refresh(epd.PARTIAL_RECT, 10, 16, 5, 5).wait()
if not ok then
log.error("epd", "局部刷新失败", rerr)
end
4.2.2 panel:sleep([mode])
功能
进入休眠状态,降低屏幕功耗。深度休眠后,再次刷新屏幕前需要重新调用 panel:init()。
参数
mode
参数含义:休眠模式
数据类型:number/string
取值范围:epd.SLEEP_AUTO(默认)/ epd.SLEEP_STANDBY / epd.SLEEP_DEEP,或字符串 "auto" / "standby" / "deep"
是否必选:否
注意事项:不带参数时默认 SLEEP_AUTO。长时间不再刷新屏幕时建议使用 SLEEP_DEEP,功耗最低
参数示例:epd.SLEEP_DEEP
返回值
result
含义说明:休眠是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 长时间不再刷新时使用深度休眠,功耗最低
panel:sleep(epd.SLEEP_DEEP)
4.2.3 panel:setRotation(rotate)
功能
设置画布旋转方向。旋转后,逻辑画布宽高会互换(90/270 度),后续绘图坐标自动适配。
参数
rotate
参数含义:旋转角度
数据类型:number
取值范围:0/90/180/270(角度值),或 0/1/2/3(索引值)
是否必选:是
注意事项:旋转以屏幕物理方向为基准,旋转后 (0,0) 原点位置随之改变
参数示例:90
返回值
result
含义说明:设置是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 旋转 90 度后再绘图
panel:setRotation(90)
panel:line(0, 0, 100, 100, epd.BLACK)
4.2.4 panel:clear([color])
功能
清空画布为指定颜色。只修改内存中的帧缓冲区,需调用 panel:refresh() 刷新后屏幕才显示。
参数
color
参数含义:清屏颜色
数据类型:number
取值范围:epd.BLACK / epd.WHITE / epd.RED 等 3.2 章节颜色常量;不带参数时使用当前背景色
是否必选:否
注意事项:所传颜色必须是当前面板支持的逻辑颜色,否则返回 false
参数示例:epd.WHITE
返回值
result
含义说明:清屏是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 清屏为白色
panel:clear(epd.WHITE)
4.3 颜色设置
4.3.1 panel:setColor(fg, bg)
功能
设置当前前景色和背景色。设置后,后续未显式传颜色的绘图接口默认使用当前前景色绘制、背景色填充。
参数
fg
参数含义:前景色
数据类型:number
取值范围:epd.BLACK / epd.WHITE / epd.RED 等 3.2 章节颜色常量
是否必选:是
注意事项:前景色和背景色必须都是当前面板支持的逻辑颜色,否则返回 false
参数示例:epd.BLACK
bg
参数含义:背景色
数据类型:number
取值范围:同 fg
是否必选:是
注意事项:同上
参数示例:epd.WHITE
返回值
result
含义说明:设置是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 设置黑色前景、白色背景
panel:setColor(epd.BLACK, epd.WHITE)
4.3.2 panel:getColor()
功能
获取当前前景色和背景色。
参数
无
返回值
fg
含义说明:当前前景色
数据类型:number
取值范围:3.2 章节颜色常量
返回示例:epd.BLACK(数值 0)
bg
含义说明:当前背景色
数据类型:number
取值范围:3.2 章节颜色常量
返回示例:epd.WHITE(数值 1)
示例
-- 获取当前前景色和背景色
local fg, bg = panel:getColor()
log.info("epd", "fg", fg, "bg", bg)
4.3.3 panel:supportsColor(color)
功能
查询某个逻辑颜色是否受当前面板支持。
参数
color
参数含义:要查询的逻辑颜色
数据类型:number
取值范围:3.2 章节颜色常量
是否必选:是
参数示例:epd.RED
返回值
result
含义说明:颜色是否受支持
数据类型:boolean
取值范围:true 支持;false 不支持
返回示例:false -- 黑白屏不支持红色
示例
-- 查询红色是否受当前面板支持
if panel:supportsColor(epd.RED) then
log.info("epd", "支持红色")
end
4.4 基本图形绘制
4.4.1 panel:pixel(x, y[, color])
功能
在指定位置绘制一个像素点。
参数
x
参数含义:像素点 X 坐标
数据类型:number
取值范围:-32768~32767,实际有效范围为画布内
是否必选:是
参数示例:12
y
参数含义:像素点 Y 坐标
数据类型:number
取值范围:-32768~32767,实际有效范围为画布内
是否必选:是
参数示例:18
color
参数含义:像素颜色
数据类型:number
取值范围:3.2 章节颜色常量
是否必选:否
注意事项:不带参数时使用当前前景色
参数示例:epd.BLACK
返回值
result
含义说明:绘制是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 在 (12, 18) 绘制一个黑色像素点
panel:pixel(12, 18, epd.BLACK)
4.4.2 panel:line(x0, y0, x1, y1[, color])
功能
绘制一条直线,从起点 (x0, y0) 到终点 (x1, y1)。
参数
x0
参数含义:直线起点的 X 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:0
y0
参数含义:直线起点的 Y 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:0
x1
参数含义:直线终点的 X 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:100
y1
参数含义:直线终点的 Y 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:100
color
参数含义:线条颜色
数据类型:number
取值范围:3.2 章节颜色常量
是否必选:否
注意事项:不带参数时使用当前前景色
参数示例:epd.BLACK
返回值
result
含义说明:绘制是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 绘制从 (0,0) 到 (100,100) 的黑色直线
panel:line(0, 0, 100, 100, epd.BLACK)
4.4.3 panel:rect(x, y, x2, y2[, color[, fill]])
功能
绘制矩形,左上角 (x, y) 到右下角 (x2, y2)。
参数
x
参数含义:矩形左上角的 X 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:0
y
参数含义:矩形左上角的 Y 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:0
x2
参数含义:矩形右下角的 X 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:199
y2
参数含义:矩形右下角的 Y 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:199
color
参数含义:矩形颜色
数据类型:number
取值范围:3.2 章节颜色常量
是否必选:否
注意事项:不带参数时使用当前前景色
参数示例:epd.BLACK
fill
参数含义:是否填充
数据类型:number
取值范围:0 空心(默认);1 实心
是否必选:否
注意事项:默认 0 空心
参数示例:1
返回值
result
含义说明:绘制是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 绘制实心矩形
panel:rect(0, 0, 199, 199, epd.BLACK, 1)
-- 绘制空心矩形
panel:rect(20, 20, 80, 80, epd.BLACK, 0)
4.4.4 panel:circle(x, y, r[, color[, fill]])
功能
绘制圆形,圆心 (x, y),半径 r。
参数
x
参数含义:圆心的 X 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:100
y
参数含义:圆心的 Y 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:100
r
参数含义:半径
数据类型:number
取值范围:0~255
是否必选:是
参数示例:50
color
参数含义:圆形颜色
数据类型:number
取值范围:3.2 章节颜色常量
是否必选:否
注意事项:不带参数时使用当前前景色
参数示例:epd.BLACK
fill
参数含义:是否填充
数据类型:number
取值范围:0 空心(默认);1 实心
是否必选:否
注意事项:默认 0 空心
参数示例:0
返回值
result
含义说明:绘制是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 绘制空心圆形
panel:circle(100, 100, 50, epd.BLACK, 0)
-- 绘制实心圆形
panel:circle(100, 100, 20, epd.BLACK, 1)
4.5 位图与二维码
4.5.1 panel:drawXbm(x, y, width, height, data[, fg[, bg]])
功能
绘制 XBM 格式位图。XBM 数据逐行存储,每行占 ceil(width/8) 字节,字节内低位在左。
参数
x
参数含义:位图左上角的 X 坐标
数据类型:number
取值范围:-32768~32767,允许负值,屏幕外部分自动裁剪
是否必选:是
参数示例:20
y
参数含义:位图左上角的 Y 坐标
数据类型:number
取值范围:-32768~32767,允许负值,屏幕外部分自动裁剪
是否必选:是
参数示例:30
width
参数含义:位图像素宽度
数据类型:number
取值范围:1~65535
是否必选:是
参数示例:8
height
参数含义:位图像素高度
数据类型:number
取值范围:1~65535
是否必选:是
参数示例:8
data
参数含义:XBM 位图数据
数据类型:string
取值范围:长度至少为 ceil(width/8) * height 字节,每行 ceil(width/8) 字节,低位在左
是否必选:是
参数示例:string.char(0x81, 0x42, 0x24, 0x18, 0x24, 0x42, 0x81, 0x00)
fg
参数含义:置位(1)像素颜色
数据类型:number
取值范围:3.2 章节颜色常量
是否必选:否
注意事项:不带参数时使用当前前景色
参数示例:epd.BLACK
bg
参数含义:清零(0)像素颜色
数据类型:number/nil
取值范围:3.2 章节颜色常量;传 nil 表示透明(不绘制清零像素)
是否必选:否
注意事项:不带参数时使用当前背景色;传 nil 表示清零像素透明
参数示例:epd.WHITE
返回值
result
含义说明:绘制是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 绘制 8x8 XBM 位图,置位像素黑色,清零像素白色
local xbm = string.char(0x81, 0x42, 0x24, 0x18, 0x24, 0x42, 0x81, 0x00)
panel:drawXbm(20, 30, 8, 8, xbm, epd.BLACK, epd.WHITE)
-- 清零像素透明模式
panel:drawXbm(20, 30, 8, 8, xbm, epd.BLACK, nil)
4.5.2 panel:qrcode(x, y, str[, size[, color]])
功能
在指定位置绘制二维码。
参数
x
参数含义:二维码左上角的 X 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:10
y
参数含义:二维码左上角的 Y 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:10
str
参数含义:二维码内容
数据类型:string
取值范围:任意字符串,实际可编码长度受二维码版本和画布大小限制
是否必选:是
参数示例:"https://openluat.com"
size
参数含义:二维码像素边长
数据类型:number
取值范围:0~65535;0 表示按剩余区域自动适配
是否必选:否
注意事项:默认 0,自动适配。指定大小时建议留出定位角(白边)余量
参数示例:120
color
参数含义:二维码颜色
数据类型:number
取值范围:3.2 章节颜色常量
是否必选:否
注意事项:不带参数时使用当前前景色
参数示例:epd.BLACK
返回值
result
含义说明:绘制是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 在 (10,10) 绘制内容为 https://openluat.com 的二维码,边长 120
panel:qrcode(10, 10, "https://openluat.com", 120, epd.BLACK)
4.6 文本显示(需固件启用 HZFont)
4.6.1 panel:drawHzfont(x, y, text, size)
功能
绘制 UTF-8 编码文本,支持中文。文本以基线为基准绘制,y 参数为基线 Y 坐标。需固件启用 HZFont 功能,未启用时返回错误。
参数
x
参数含义:文本起始 X 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
参数示例:10
y
参数含义:文本基线 Y 坐标
数据类型:number
取值范围:-32768~32767
是否必选:是
注意事项:y 为文本基线的 Y 坐标,不是文字顶部
参数示例:36
text
参数含义:要绘制的文本
数据类型:string
取值范围:UTF-8 编码字符串,支持中文
是否必选:是
参数示例:"合宙LuatOS"
size
参数含义:字号
数据类型:number
取值范围:1~255
是否必选:是
参数示例:24
注意事项:
-
当前版本仅支持上述 4 个参数,不提供第 5 个样式表参数(
style) -
文字的前景色和背景色通过
panel:setColor(fg, bg)设置,drawHzfont内部使用当前前景/背景色绘制 -
不支持抗锯齿级别、灰度阈值、抖动方式等样式调节
返回值
result
含义说明:绘制是否成功
数据类型:boolean
取值范围:true 成功;false 失败
注意事项:失败时返回 false 和错误信息字符串
返回示例:true
示例
-- 先设置文字前景色和背景色
panel:setColor(epd.BLACK, epd.WHITE)
-- 绘制中文文本,字号 24
panel:drawHzfont(10, 36, "合宙LuatOS", 24)
-- 绘制英文文本
panel:drawHzfont(10, 68, "Hello World", 20)
4.6.2 panel:getHzfontWidth(text, size)
功能
获取指定字号下文本的像素宽度,可用于计算文本绘制位置。
参数
text
参数含义:要计算宽度的文本
数据类型:string
取值范围:UTF-8 编码字符串
是否必选:是
参数示例:"Hello"
size
参数含义:字号
数据类型:number
取值范围:1~255
是否必选:是
参数示例:20
返回值
width
含义说明:文本像素宽度
数据类型:number
取值范围:0 表示参数错误或文本为空
返回示例:60
示例
-- 计算文本宽度,用于居中显示
local w = panel:getHzfontWidth("Hello", 20)
local x = math.floor((200 - w) / 2) -- 200 为屏幕宽度,居中计算
panel:drawHzfont(x, 40, "Hello", 20)
4.7 面板信息查询
4.7.1 panel:info()
功能
获取面板详细信息,包括画布尺寸、帧缓冲格式、颜色支持、能力位等。
参数
无
返回值
info
含义说明:面板信息表
数据类型:table
取值范围:包含以下字段:
{
参数含义:逻辑画布宽度(已按旋转方向调整)
数据类型:number
info.width ,
参数含义:逻辑画布高度(已按旋转方向调整)
数据类型:number
info.height ,
参数含义:物理面板宽度
数据类型:number
info.native_width ,
参数含义:物理面板高度
数据类型:number
info.native_height ,
参数含义:帧缓冲每行字节数
数据类型:number
info.stride ,
参数含义:每个像素位数
数据类型:number
info.bits_per_pixel ,
参数含义:帧缓冲平面数
数据类型:number
info.plane_count ,
参数含义:帧缓冲格式
数据类型:number
取值范围:epd.FORMAT_INDEX1 / FORMAT_INDEX2 / FORMAT_INDEX4 / FORMAT_INDEX8 / FORMAT_PLANAR1
info.format ,
参数含义:调色板颜色数量
数据类型:number
info.color_count ,
参数含义:调色板,按索引排列的颜色描述表
数据类型:table
取值范围:每个元素包含 color(逻辑颜色)/ code(存储编码)/ rgb(RGB 值)
info.palette ,
参数含义:能力位掩码
数据类型:number
取值范围:按 3.6 章节能力位常量按位组合
info.caps ,
参数含义:当前旋转角度
数据类型:number
取值范围:0/90/180/270
info.rotate ,
}
示例
-- 查询面板信息
local info = panel:info()
log.info("epd", "size", info.width, info.height, "format", info.format, "caps", info.caps)
-- 判断屏幕是否支持局部区域刷新
if bit.band(info.caps, epd.CAP_REFRESH_PARTIAL_RECT) ~= 0 then
log.info("epd", "支持局部区域刷新")
end
五、产品支持说明
不同产品的 LuatOS 固件对 epd 核心库的支持情况不同,具体支持型号以固件为准。
各产品固件支持核心库列表详细说明参考下面链接:
Air780EX2/Air700ECP/Air780EPM/Air780EGP固件支持列表
Air700ECH/Air780EHM/EHV/EGH/EGG/EHU/EHN固件支持列表
六、更新说明
epd V 1.0
-
更新时间:2026-08-07
-
更新内容:
-
初版,基于 tiny_epd 组件实现墨水屏操作库
-
支持 7 种内置 1.54 英寸墨水屏型号和自定义屏幕(custom)模式
-
支持直线、矩形、圆形、像素点、XBM 位图、二维码、UTF-8 文本绘制
-
支持全刷、快刷、局部刷新、局部区域刷新、自动刷新五种刷新模式
-
支持画布旋转、前景/背景色设置、逻辑颜色自动映射
-
刷新采用异步机制,通过 cwait 方式等待刷新结果
-