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 制御信号、充電状態などを制御します。FPC インターフェースに接続された M5PM1 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 から読み取り、Low レベルの場合は充電中です。

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 タイマー

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;

タイマーによる電源オン / オフの例

デバイスの起動後、BtnA を押すと 3 秒後の電源オンを設定し、BtnB を押すと 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