iTranslated by AI
[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_holdflag is triggered at 2 seconds. I attempted to use functions likewasReleaseFor(), 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