简体中文
English
简体中文
日本語

Arduino 上手教程

2. 设备开发 & 案例程序

5. 扩展模块

6. 应用案例

PaperDIY Display 屏幕显示

PaperDIY 电子纸显示相关 API 与案例程序。

案例程序

编译要求

  • M5Stack 板管理版本 >= 3.3.10
  • 开发板选项 = M5PaperDIY
  • M5Unified 库版本 >= 0.2.26
  • M5GFX 库版本 >= 0.2.33

基础显示

cpp
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
#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。连续进行多次局部快速刷新后,应适时进行一次全屏高质量刷新以减轻残影。

cpp
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
#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);
}
Page Tools
PDF
On This Page