PaperDIY 电子纸显示相关 API 与案例程序。
M5PaperDIY#include <Arduino.h>
#include <M5Unified.h>
M5Canvas canvas(&M5.Display);
static void drawBlackBorder()
{
const int screenW = M5.Display.width();
const int screenH = M5.Display.height();
canvas.drawRect(0, 0, screenW, screenH, TFT_BLACK);
canvas.drawRect(2, 2, screenW - 4, screenH - 4, TFT_BLACK);
canvas.drawRect(4, 4, screenW - 8, screenH - 8, TFT_BLACK);
}
static void drawMainDemo()
{
const int screenW = M5.Display.width();
const int screenH = M5.Display.height();
static const uint16_t diyColors[4] = {
TFT_BLACK,
TFT_DARKGREY,
TFT_LIGHTGREY,
TFT_BLACK
};
canvas.fillSprite(TFT_WHITE);
drawBlackBorder();
canvas.setTextDatum(middle_center);
canvas.setTextColor(TFT_BLACK);
canvas.setFont(&fonts::FreeSansBold24pt7b);
canvas.drawString("PAPERDIY", screenW / 2, 115);
canvas.setFont(&fonts::FreeSansBold18pt7b);
canvas.drawString("Panel: AXE544127", screenW / 2, 205);
char resolutionBuf[32];
snprintf(resolutionBuf, sizeof(resolutionBuf), "Resolution: %d x %d", screenW, screenH);
canvas.drawString(resolutionBuf, screenW / 2, 255);
canvas.drawString("16-Level Grayscale E-Paper", screenW / 2, 305);
const int barX = 120;
const int barY = 370;
const int barW = screenW - 240;
const int barH = 58;
const int cellW = barW / 4;
for (int i = 0; i < 4; ++i) {
const int x = barX + i * cellW;
const int w = (i == 3) ? (barX + barW - x) : cellW;
canvas.fillRect(x, barY, w, barH, diyColors[i]);
canvas.drawRect(x, barY, w, barH, TFT_BLACK);
}
canvas.pushSprite(0, 0);
}
void setup()
{
auto cfg = M5.config();
cfg.clear_display = false;
M5.begin(cfg);
M5.Display.setEpdMode(epd_mode_t::epd_quality);
canvas.createSprite(M5.Display.width(), M5.Display.height());
drawMainDemo();
}
void loop()
{
M5.update();
delay(100);
}
PaperDIY 支持以下四种电子纸刷新模式。刷新速度越快,显示质量和残影控制通常越弱,实际刷新时间还会受图像内容影响。下面的程序使用两个用户按键选择刷新模式,并在每次选择后刷新一次屏幕。
M5.Display.setEpdMode(epd_mode_t::epd_quality); // High quality, slowest refresh
M5.Display.setEpdMode(epd_mode_t::epd_text); // Text mode, faster refresh
M5.Display.setEpdMode(epd_mode_t::epd_fast); // Fast refresh
M5.Display.setEpdMode(epd_mode_t::epd_fastest); // Fastest refresh 调用 M5.Display.setEpdMode() 后,后续的屏幕更新将使用对应模式。建议在文字界面使用 epd_text,在图片或需要较好灰度效果的场景使用 epd_quality。连续进行多次局部快速刷新后,应适时进行一次全屏高质量刷新以减轻残影。
#include <M5Unified.h>
M5Canvas canvas(&M5.Display);
struct ModeOption {
const char* name;
epd_mode_t mode;
};
const ModeOption modeOptions[] = {
{"epd_quality", epd_mode_t::epd_quality},
{"epd_text", epd_mode_t::epd_text},
{"epd_fast", epd_mode_t::epd_fast},
{"epd_fastest", epd_mode_t::epd_fastest},
};
constexpr std::size_t MODE_COUNT = sizeof(modeOptions) / sizeof(modeOptions[0]);
std::size_t selectedMode = 0;
uint32_t refreshCount = 0;
void drawScreen()
{
const int w = M5.Display.width();
const int h = M5.Display.height();
canvas.fillSprite(TFT_WHITE);
canvas.setTextDatum(middle_center);
canvas.setTextColor(TFT_BLACK);
canvas.setFont(&fonts::FreeSansBold24pt7b);
canvas.drawString("E-Paper Refresh Mode", w / 2, 90);
canvas.setFont(&fonts::FreeSansBold18pt7b);
char selectedText[48];
snprintf(selectedText, sizeof(selectedText), "Selected: %s", modeOptions[selectedMode].name);
canvas.drawString(selectedText, w / 2, 175);
canvas.drawString("BtnA: previous BtnB: next", w / 2, 245);
canvas.setFont(&fonts::FreeSansBold18pt7b);
for (std::size_t i = 0; i < MODE_COUNT; ++i) {
const int y = 315 + static_cast<int>(i) * 42;
const bool selected = i == selectedMode;
canvas.setTextColor(selected ? TFT_BLACK : TFT_DARKGREY);
canvas.drawString(selected ? ">" : " ", w / 2 - 180, y);
canvas.drawString(modeOptions[i].name, w / 2, y);
}
canvas.setFont(&fonts::FreeSansBold12pt7b);
char countText[32];
snprintf(countText, sizeof(countText), "Refresh count: %lu", (unsigned long)refreshCount);
canvas.setTextColor(TFT_BLACK);
canvas.drawString(countText, w / 2, h - 35);
canvas.pushSprite(0, 0);
}
void selectMode(std::size_t index)
{
selectedMode = index % MODE_COUNT;
M5.Display.setEpdMode(modeOptions[selectedMode].mode);
++refreshCount;
drawScreen();
}
void setup()
{
auto cfg = M5.config();
cfg.clear_display = false;
M5.begin(cfg);
M5.Display.setEpdMode(modeOptions[selectedMode].mode);
canvas.createSprite(M5.Display.width(), M5.Display.height());
drawScreen();
}
void loop()
{
M5.update();
if (M5.BtnA.wasPressed()) {
selectMode(selectedMode + MODE_COUNT - 1);
}
if (M5.BtnB.wasPressed()) {
selectMode(selectedMode + 1);
}
delay(20);
}