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

Arduino 上手教程

2. 设备开发 & 案例程序

5. 扩展模块

6. 应用案例

PaperDIY 电源管理

1. 多级电源开关设计

PaperDIY 内部集成 M5PM1,结合硬件电路实现了多级电源开关,不同的级别的电源开关可控制不同的外设与接口供电。用户可根据运行需求,切换不同级别的电源使能,关闭未使用的外设部分,实现整机低功耗。

M5PM1 驱动库

使用 M5PM1 驱动库可以配置电源输出、GPIO、充电控制、定时器和休眠功能。

注意事项
PaperDIY 的多级电源开关设计并非串联结构。L1 ~ L3B 开关的电源输入均来自于 L0 (SYS_VBUS) 级源头,而非上一级电源,因此支持独立控制不同级别的电源开关,以上分级根据外设供电与功耗进行区分。M5PM1 启动上电后 L1,L2,L3A 将自动开启。

L0

此级电源条件下,电池保持对 M5PM1 与 FPC-I2S 接口供电,其余外设可关闭供电。电池电量未耗尽的情况下,该层电源将一直保持,M5PM1 支持电源按键开关机等操作。

L1

此电源条件下设备处于待机状态,电池保持对 M5PM1 供电,支持操作同 L0 级别。

L2 / L3A

此级电源条件下,将新启用 ESP32-S3、microSD、用户按键和 FPC-SPI 接口电源。M5PM1 的 DCDC3V3_EN_PP 控制 3V3_L2 电源开关,ESP32-S3 运行时该电源为工作电源,可通过以下 API 实现开关控制。

pm1.setDcdcEnable(true); // L2 ON
pm1.setDcdcEnable(false); // L2 OFF 

当 ESP32-S3 处于休眠状态时,电源处于 L2 级。当 ESP32-S3 处于工作状态时,电源处于 L3A 级。 ESP32-S3 可通过控制 M5PM1 进入休眠,关断自身的供电 (L2 -> L1/L0)。

L3B

该层级控制电子墨水屏电源、FPC 控制信号和充电状态等,M5PM1 连接到 FPC 接口的 GPIO 可自定义功能,用户可通过 M5PM1 API 控制电子墨水屏电源开关、充电功能及一些自定义外设。

M5PM1 PYG0 PYG1 PYG2 PYG3 PYG4
FPC - I2S PY_G0
FPC - SPI PY_G1 PY_G4
E-Paper EPD_PWR
Charge CHG_STAT
  • PYG0(PY_G0): FPC - I2S 接口扩展信号
  • PYG1(PY_G1): FPC - SPI 接口开关信号
  • PYG2(EPD_PWR): 电子墨水屏及其驱动电路电源使能
  • PYG3(CHG_STAT): 充电状态
  • PYG4(PY_G4): FPC - SPI 接口复位信号

M5PM1 PYG2 连接到 EPD_PWR,控制电子墨水屏面板及其驱动电路的电源。电子墨水屏升压使能由 ESP32-S3 GPIO46 (BST_EN) 控制,二者都处于有效状态时才可以正常刷新屏幕。

pm1.gpioSetFunc(M5PM1_GPIO_NUM_2, M5PM1_GPIO_FUNC_GPIO);
pm1.gpioSetMode(M5PM1_GPIO_NUM_2, M5PM1_GPIO_MODE_OUTPUT);
pm1.gpioSetDrive(M5PM1_GPIO_NUM_2, M5PM1_GPIO_DRIVE_PUSHPULL);
pm1.gpioSetOutput(M5PM1_GPIO_NUM_2, true); // EPD_PWR ON

电池状态

PaperDIY 的电池电压通过 BAT_ADC 送入 M5PM1,可使用 readVbat() 读取。

uint16_t batteryMv = 0;
if (pm1.readVbat(&batteryMv) == M5PM1_OK) {
    Serial.printf("VBAT: %u mV\n", batteryMv);
}

充电使能由 CHG_EN 控制,充电状态由 PYG3 上的 CHG_STAT 读取,低电平表示正在充电。

pm1.setChargeEnable(true);  // 开启充电

pm1.gpioSetFunc(M5PM1_GPIO_NUM_3, M5PM1_GPIO_FUNC_GPIO);
pm1.gpioSetMode(M5PM1_GPIO_NUM_3, M5PM1_GPIO_MODE_INPUT);
pm1.gpioSetPull(M5PM1_GPIO_NUM_3, M5PM1_GPIO_PULL_UP);

uint8_t chgStat = 1;
if (pm1.gpioGetInput(M5PM1_GPIO_NUM_3, &chgStat) == M5PM1_OK) {
    bool charging = (chgStat == 0);  // CHRG 低电平表示正在充电
}

2. M5PM1 休眠

手动休眠

M5PM1 可以通过程序手动进入休眠状态,以降低整机功耗。默认情况下,调用 shutdown() 后会关闭 3V3_L2,ESP32-S3 停止运行,仅保留 M5PM1 的基础电源管理功能。

pm1.shutdown();

如果外部电路需要在休眠期间继续供电,应在调用 shutdown() 前配置对应的电源保持条件。PaperDIY 的电子墨水屏和 FPC 外设不应在未保存状态时直接断电。

I2C 空闲休眠

M5PM1 支持在 I2C 总线空闲一段时间后自动进入低功耗模式:

pm1.setI2cSleepTime(10); // I2C 空闲 10 秒后进入低功耗模式

进入该模式后,ESP32-S3 与 M5PM1 的首次通信用于唤醒芯片,该次通信可能不会完成有效读写;唤醒后的下一次通信再读取或写入目标寄存器。

3. M5PM1 Timer 定时器

M5PM1 支持配置定时器,在计时结束后执行开机、关机、复位或设置标志等操作。

m5pm1_err_t timerSet(uint32_t seconds, m5pm1_tim_action_t action);
typedef enum {
    M5PM1_TIM_ACTION_STOP = 0b000,     // 停止,无动作
                                       // Stop, no action
    M5PM1_TIM_ACTION_FLAG = 0b001,     // 仅设置标志
                                       // Set flag only
    M5PM1_TIM_ACTION_REBOOT = 0b010,   // 系统复位
                                       // System reboot
    M5PM1_TIM_ACTION_POWERON = 0b011,  // 开机
                                       // Power on
    M5PM1_TIM_ACTION_POWEROFF = 0b100  // 关机
                                       // Power off
} m5pm1_tim_action_t;

定时开机 / 关机案例

设备开机后,单击按键 A 配置 3 秒后重新开机,单击按键 B 配置 3 秒后关机。

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
#include <M5Unified.h>
#include <M5PM1.h>

M5PM1 pm1;
bool pm1Ready = false;

static void drawMessage(const char* line1, const char* line2)
{
    M5.Display.clear();
    M5.Display.setTextDatum(middle_center);
    M5.Display.setFont(&fonts::FreeSansBold24pt7b);
    M5.Display.drawString(line1, M5.Display.width() / 2, M5.Display.height() / 2 - 30);
    M5.Display.setFont(&fonts::FreeSansBold18pt7b);
    M5.Display.drawString(line2, M5.Display.width() / 2, M5.Display.height() / 2 + 35);
}

static void drawTimerHome()
{
    M5.Display.clear();
    M5.Display.setTextDatum(middle_center);
    M5.Display.setFont(&fonts::FreeSansBold24pt7b);
    M5.Display.drawString("M5PM1 TIMER", M5.Display.width() / 2, M5.Display.height() / 2 - 110);
    M5.Display.setFont(&fonts::FreeSansBold18pt7b);
    M5.Display.drawString("Btn A: power on after 3 seconds", M5.Display.width() / 2, M5.Display.height() / 2 - 35);
    M5.Display.drawString("Btn B: power off after 3 seconds", M5.Display.width() / 2, M5.Display.height() / 2 + 20);
    M5.Display.drawString("Press A or B to start the timer", M5.Display.width() / 2, M5.Display.height() / 2 + 75);
}

void setup()
{
    auto cfg = M5.config();
    cfg.clear_display = false;
    M5.begin(cfg);
    Serial.begin(115200);

    M5.Display.setEpdMode(epd_mode_t::epd_text);
    const m5pm1_err_t err =
        pm1.begin(&M5.In_I2C, M5PM1_DEFAULT_ADDR, M5PM1_I2C_FREQ_100K);
    pm1Ready = (err == M5PM1_OK);

    if (!pm1Ready) {
        Serial.printf("M5PM1 init failed: %d\n", err);
        drawMessage("M5PM1 ERROR", "Check I2C");
        return;
    }

    Serial.println("BtnA: power on after 3s");
    Serial.println("BtnB: power off after 3s");
    drawTimerHome();
}

void loop()
{
    M5.update();
    if (!pm1Ready) {
        delay(1000);
        return;
    }

    if (M5.BtnA.wasPressed()) {
        drawMessage("Power OFF", "Power ON after 3s");
        delay(500);
        if (pm1.timerSet(3, M5PM1_TIM_ACTION_POWERON) == M5PM1_OK) {
            Serial.println("Power-on timer configured");
            pm1.shutdown();
        } else {
            Serial.println("Power-on timer configuration failed");
            drawMessage("Timer ERROR", "Power-on failed");
        }
    }

    if (M5.BtnB.wasPressed()) {
        drawMessage("Power OFF", "After 3 seconds");
        if (pm1.timerSet(3, M5PM1_TIM_ACTION_POWEROFF) == M5PM1_OK) {
            Serial.println("Power-off timer configured");
        } else {
            Serial.println("Power-off timer configuration failed");
            drawMessage("Timer ERROR", "Power-off failed");
        }
    }

    delay(20);
}
Page Tools
PDF
On This Page