iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🛏️

[M5Stack] Implementing Custom Shutdown Logic

に公開

When using an M5Stack, you may sometimes want to retain specific data even after shutting down. To do this, you might use LittleFS or NVS, but unlike RAM, these have write limits and cannot be overwritten indefinitely. Therefore, you want to perform save operations upon shutdown; unfortunately, the M5Stack does not seem to allow triggering processes based on shutdown.

A wise person once said, "If you can't do it by default, why not modify it so you can?"

Environment

M5Stack

  • M5Stack Core2 v1.1
    (Operation on the original Core2, Core2 v1.3, or CoreS3 series is untested, but it should work.)

Development Environment

  • Windows 11 Home
  • VSCode + PlatformIO

Libraries/Other

  • Arduino Platform
  • M5Unified 0.2.13

Source Code for Detecting Shutdown

On a standard M5Stack, the AXP192/AXP2101 handles the power control, which shuts down after the power button is held for 6 seconds. The ESP32 cannot intervene in this specific control. This source code triggers a custom shutdown process when the power button is held for 2 seconds or longer.

/*
  MIT License

  Copyright (c) 2026 K-Nana

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
*/

#include <M5Unified.h>

void shutdown() {
  // Perform shutdown operations here
  // Note: Ensure the shutdown process completes within 4 seconds.
  // If it takes longer than 4 seconds, the power will be forced off.
  Serial.println("Shutting down..."); // For verification, can be removed
  M5.Power.powerOff();
}

void setup() {
  // Only M5.begin(); is needed if Serial is not required
  auto config = M5.config();
  config.serial_baudrate = 115200;
  M5.begin(config);
  // Add initialization code here as desired
}

void loop() {
  M5.update();
  if (M5.BtnPWR.getState() == m5::Button_Class::state_hold) {
    shutdown();
  }
  // Add loop execution code here as desired
}

Points to Note

  • As explained, using this source code shortens the power button hold time required for shutdown from 6 seconds to 2 seconds, as the state_hold flag is triggered at 2 seconds. I attempted to use functions like wasReleaseFor(), but they did not work.
  • This code does not have a feature to cancel the 6-second hardware shutdown, so if your shutdown process takes more than 4 seconds, it might be forcibly shut down by the hardware. If you absolutely need more than 4 seconds, consider displaying a message on the screen asking the user to release the button; as long as the button is not held, the AXP will not trigger its own shutdown. However, unless you are writing a massive amount of data, this should be safe.
  • Power to the M5Stack is not always turned off via the power button. It may also cut off due to accidents like running out of battery. In such cases, this shutdown process will not run. Furthermore, the program might reset suddenly due to bugs or accidental operation of the reset button. I recommend implementing strategies like "saving data once per hour" as a precaution.

Aside


This occurred during testing, and I found it amusing that the debug message was cut off like a dying breath.

Afterword

Although the approach this time feels a bit forceful, I was able to implement a shutdown process by using a "Marie Antoinette-style" solution. Since I am building a smartwatch with an M5Stack, I felt it was important to be able to monitor battery usage, which led me to devise this source code. I hope this code proves useful to someone. Until next time.

Discussion