batterie.ino
The Core's IP5306 PMIC reports battery level, charge state and three sleep depths. lightSleep halts the CPU and screen without losing context: the right way to wait without draining the battery.
Hardware required
An M5Stack Core Basic/Gray (ESP32 in an enclosure with a 320×240 TFT, A/B/C buttons, speaker, microSD slot, 110 mAh battery). None; a USB cable to watch the charge state flip.
Wiring
No wiring. The internal battery charges over USB-C; charge LEDs live on the PMIC.
How it works
getBatteryLevel polls the PMIC over I2C (0x34); lightSleep(ms) pauses the core with PowerKey (button C) or timeout wake. RAM context survives, unlike deep sleep. In the Arduino IDE (esp32 package), board « M5Stack-Core-ESP32 »; install the « M5Stack » (or M5Unified) library from the Library Manager, then Upload.
Going further
Move to deep sleep + timed wake for a station that sleeps for hours, accepting context loss.
batterie.ino
// Batterie 110 mAh (IP5306) : niveau, charge, veille et reveil bouton.
#include <M5Stack.h>
void setup() {
M5.begin(true, false, true, true);
M5.Power.begin();
M5.Lcd.setTextSize(2);
}
void loop() {
M5.update();
M5.Lcd.setCursor(10, 20);
M5.Lcd.printf("Batterie : %3d %%\n", M5.Power.getBatteryLevel());
M5.Lcd.printf("Charge : %s\n",
M5.Power.isCharging() ? "OUI" : "non");
M5.Lcd.printf("Prise : %s\n",
M5.Power.isChargeFull() ? "pleine" : "-");
M5.Lcd.drawString("Bouton A = 10 s de veille", 10, 140, 2);
if (M5.BtnA.wasPressed()) {
M5.Lcd.fillScreen(TFT_BLACK);
M5.Lcd.drawString("Veille... bouton C", 30, 110, 2);
M5.Power.lightSleep(10000); // CPU halt 10 s, ecran coupe, reveil C
M5.Lcd.fillScreen(TFT_BLACK);
}
delay(500);
}