boutons.ino
wasPressed for the click, wasHold(1000) for the long press: M5Unified ships the full button semantics, debounce included. Button C blanks the screen without dropping the load — the battery-saving gesture.
Hardware required
An M5StickC Plus2 (ESP32-PICO-V3-02, 135×240 display, A/B/C buttons, passive buzzer on G2, IR + red LED on G19, MPU6886 IMU, microphone, 200 mAh battery). None.
Wiring
No wiring. A on G38, B on G37, C (Power) on G35. HOLD G4 must stay high on battery (held by firmware).
How it works
Button objects latch edges and durations; wasHold(ms) only fires past the duration. setBrightness(0) kills the backlight while the ESP32 keeps running. In the Arduino IDE (esp32 package), board « M5StickCPlus2 »; « M5StickCPlus2 » or M5Unified library. On the PMIC-less v2, hold button C for >2 s to power on; HOLD (G4) latches the power.
Going further
Double-click by measuring the interval between wasPressed calls, or a context menu on long click.
boutons.ino
// A (G38, flanc), B (G37, bas), C (G35, sous l'ecran = Power).
#include <M5Unified.h>
int page = 0;
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
M5.Display.setRotation(1);
M5.Display.setTextSize(2);
}
void loop() {
M5.update();
if (M5.BtnA.wasPressed()) page = (page + 1) % 3; // appui court
if (M5.BtnA.wasHold(1000)) page = (page + 2) % 3; // appui long
if (M5.BtnB.wasPressed()) M5.Spk.tone(660, 60);
M5.Display.fillScreen(TFT_BLACK);
M5.Display.setCursor(6, 20);
M5.Display.printf("Page %d\n", page);
M5.Display.setTextSize(1);
M5.Display.setCursor(6, 60);
M5.Display.printf("A court=%d long=%d B=%d\n",
M5.BtnA.wasPressed(), M5.BtnA.wasHold(1000),
M5.BtnB.isPressed());
// Bouton C = Power : eteint l'ecran puis le HOLD laisse la charge
if (M5.BtnC.wasPressed()) M5.Display.setBrightness(
M5.Display.getBrightness() > 0 ? 0 : 128);
delay(50);
}