pdf-icon

Arduino Quick Start

2. Devices & Examples

5. Extensions

6. Applications

Stamp-S3Bat Wakeup

Stamp-S3Bat wakeup-related APIs and example programs.

Example Programs

Compilation Requirements

  • M5Stack Board Manager Version >= 3.2.6
  • Board Option = M5StampS3Bat
  • M5PM1 Library Version >= 1.0.7

M5PM1 Timer Wakeup

After startup, the Stamp-S3Bat can configure the M5PM1 timer to achieve a scheduled wakeup function after power-off.

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 88 89 90
#include <Arduino.h>
#include <M5PM1.h>
#include <Wire.h>

M5PM1 pm1;

static const uint8_t PIN_SDA = 48;
static const uint8_t PIN_SCL = 47;

static const uint8_t LED_COUNT      = 1;
static const uint8_t LED_BRIGHTNESS = 64;
static const uint32_t WAKEUP_SEC    = 10;
static const uint32_t GREEN_HOLD_MS = 2000;

static const m5pm1_rgb_t COLOR_RED   = {LED_BRIGHTNESS, 0, 0};
static const m5pm1_rgb_t COLOR_GREEN = {0, LED_BRIGHTNESS, 0};
static const m5pm1_rgb_t COLOR_OFF   = {0, 0, 0};

static bool setSingleLedColor(m5pm1_rgb_t color)
{
    if (pm1.setLedColor(0, color) != M5PM1_OK) {
        return false;
    }
    return pm1.refreshLeds() == M5PM1_OK;
}

void setup()
{
    Serial.begin(115200);
    delay(300);

    Wire.end();
    Wire.begin(PIN_SDA, PIN_SCL, 100000U);

    // Initialize PM1
    m5pm1_err_t err = pm1.begin(&Wire, M5PM1_DEFAULT_ADDR, PIN_SDA, PIN_SCL, M5PM1_I2C_FREQ_100K);

    if (err != M5PM1_OK) {
        Serial.printf("[PM1][E] PM1 initialization failed: %d\r\n", err);
        while (true) {
            delay(1000);
        }
    }
    Serial.printf("[PM1][I] PM1 initialization successful\r\n");

    // Configuration Option 1
    pm1.gpioSetFunc(M5PM1_GPIO_NUM_0, M5PM1_GPIO_FUNC_OTHER);
    pm1.gpioSetDrive(M5PM1_GPIO_NUM_0, M5PM1_GPIO_DRIVE_PUSHPULL);
    pm1.gpioSetOutput(M5PM1_GPIO_NUM_0, true);
    // Configuration Option 2 (Equivalent, converted to Option 1 internally by the library)
    pm1.pinMode(M5PM1_GPIO_NUM_0, M5PM1_OTHER);

    // Configure LED output: enable output + set LED count
    m5pm1_err_t err1 = pm1.setLedEnLevel(true);
    m5pm1_err_t err2 = pm1.setLedCount(LED_COUNT);
    if (err1 != M5PM1_OK || err2 != M5PM1_OK) {
        Serial.printf("[PM1][E] LED init failed, en:%d count:%d\r\n", err1, err2);
    }

    if (!setSingleLedColor(COLOR_GREEN)) {
        Serial.printf("[PM1][E] Failed to set boot GREEN LED\r\n");
    }
    delay(GREEN_HOLD_MS);

    if (!setSingleLedColor(COLOR_RED)) {
        Serial.printf("[PM1][E] Failed to set pre-sleep RED LED\r\n");
    }
    delay(200);
    setSingleLedColor(COLOR_OFF);
    delay(120);

    m5pm1_err_t err_timer = pm1.timerSet(WAKEUP_SEC, M5PM1_TIM_ACTION_POWERON);
    if (err_timer != M5PM1_OK) {
        Serial.printf("[PM1][E] timerSet failed: %d\r\n", err_timer);
        while (true) {
            delay(1000);
        }
    }
    Serial.printf("[PM1][I] Shutdown now, wake up in %lu s\r\n", static_cast<unsigned long>(WAKEUP_SEC));

    m5pm1_err_t err_shutdown = pm1.shutdown();
    if (err_shutdown != M5PM1_OK) {
        Serial.printf("[PM1][E] shutdown failed: %d\r\n", err_shutdown);
    }
}

void loop()
{
    delay(1000);
}

M5PM1 IO Wakeup

After startup, the Stamp‑S3Bat configures G4 (WAKE) of the M5PM1 as the wakeup IO. After power-off, pulling the WAKE pin low to create a falling edge will wake up the device.

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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
#include <Arduino.h>
#include <M5PM1.h>
#include <Wire.h>

M5PM1 pm1;

static const uint8_t PIN_SDA = 48;
static const uint8_t PIN_SCL = 47;

static const uint8_t LED_COUNT      = 1;
static const uint8_t LED_BRIGHTNESS = 64;
static const uint32_t GREEN_HOLD_MS = 2000;

static const m5pm1_rgb_t COLOR_RED   = {LED_BRIGHTNESS, 0, 0};
static const m5pm1_rgb_t COLOR_GREEN = {0, LED_BRIGHTNESS, 0};
static const m5pm1_rgb_t COLOR_OFF   = {0, 0, 0};

static bool setSingleLedColor(m5pm1_rgb_t color)
{
    if (pm1.setLedColor(0, color) != M5PM1_OK) {
        return false;
    }
    return pm1.refreshLeds() == M5PM1_OK;
}

void setup()
{
    Serial.begin(115200);
    delay(300);

    Wire.end();
    Wire.begin(PIN_SDA, PIN_SCL, 100000U);

    // Initialize PM1
    m5pm1_err_t err = pm1.begin(&Wire, M5PM1_DEFAULT_ADDR, PIN_SDA, PIN_SCL, M5PM1_I2C_FREQ_100K);

    if (err != M5PM1_OK) {
        Serial.printf("[PM1][E] PM1 initialization failed: %d\r\n", err);
        while (true) {
            delay(1000);
        }
    }
    Serial.printf("[PM1][I] PM1 initialization successful\r\n");

    pm1.irqClearGpioAll();
    pm1.irqClearSysAll();
    pm1.irqClearBtnAll();

    pm1.irqSetGpioMaskAll(M5PM1_IRQ_MASK_ENABLE);
    pm1.irqSetSysMaskAll(M5PM1_IRQ_MASK_ENABLE);
    pm1.irqSetBtnMaskAll(M5PM1_IRQ_MASK_ENABLE);

    pm1.irqSetGpioMask(M5PM1_IRQ_GPIO4, M5PM1_IRQ_MASK_DISABLE);
    pm1.gpioSetMode(M5PM1_GPIO_NUM_4, M5PM1_GPIO_MODE_INPUT);
    pm1.gpioSetPull(M5PM1_GPIO_NUM_4, M5PM1_GPIO_PULL_UP);

    pm1.gpioSetFunc(M5PM1_GPIO_NUM_0, M5PM1_GPIO_FUNC_OTHER);
    pm1.gpioSetDrive(M5PM1_GPIO_NUM_0, M5PM1_GPIO_DRIVE_PUSHPULL);
    pm1.gpioSetOutput(M5PM1_GPIO_NUM_0, true);
    pm1.pinMode(M5PM1_GPIO_NUM_0, M5PM1_OTHER);

    m5pm1_err_t err1 = pm1.setLedEnLevel(true);
    m5pm1_err_t err2 = pm1.setLedCount(LED_COUNT);
    if (err1 != M5PM1_OK || err2 != M5PM1_OK) {
        Serial.printf("[PM1][E] LED init failed, en:%d count:%d\r\n", err1, err2);
    }

    if (!setSingleLedColor(COLOR_GREEN)) {
        Serial.printf("[PM1][E] Failed to set boot GREEN LED\r\n");
    }
    delay(GREEN_HOLD_MS);

    // Configure G4 as IO wake source: low-level trigger (falling edge)
    m5pm1_err_t err_wake_en = pm1.gpioSetWakeEnable(M5PM1_GPIO_NUM_4, true);
    m5pm1_err_t err_wake_ed = pm1.gpioSetWakeEdge(M5PM1_GPIO_NUM_4, M5PM1_GPIO_WAKE_FALLING);
    if (err_wake_en != M5PM1_OK || err_wake_ed != M5PM1_OK) {
        Serial.printf("[PM1][E] GPIO wake config failed, en:%d edge:%d\r\n", err_wake_en, err_wake_ed);
        while (true) {
            delay(1000);
        }
    }

    // Blink red LED, then enter sleep and wait for wakeup
    for (int i = 0; i < 4; ++i) {
        if (!setSingleLedColor(COLOR_RED)) {
            Serial.printf("[PM1][E] Failed to blink RED LED\r\n");
            break;
        }
        delay(150);
        setSingleLedColor(COLOR_OFF);
        delay(150);
    }

    Serial.printf("[PM1][I] Shutdown now, wait GPIO4 low level to wake\r\n");

    m5pm1_err_t err_shutdown = pm1.shutdown();
    if (err_shutdown != M5PM1_OK) {
        Serial.printf("[PM1][E] shutdown failed: %d\r\n", err_shutdown);
    }
}

void loop()
{
    delay(1000);
}
On This Page