Skip to content

Repository files navigation

M5StopWatch-Flux

FLUXtime becomes light

Custom firmware for the M5Stack StopWatch (ESP32-S3, 466x466 round AMOLED, BMI270 IMU, CST820 touch, haptics, speaker/mic). Built on the factory UserDemo HAL, with the entire app layer replaced by a direct-render neon particle engine.

Apps

App What it does
FLUX TIME The flagship watch face. The time itself is made of ~1300 glowing particles. Tilt the watch and time sags like liquid. Shake it and time shatters, bounces around the round rim, then flows back together. Touch parts the particles around your finger. Minute changes melt into the next time. A = cycle 4 color themes (plasma / ember / aurora / sakura), B = manual burst.
CHRONO A stopwatch where a golden comet orbits the bezel once per minute, leaving a glowing trail. Laps freeze cyan markers on the orbit. Tap or A = start/stop, B = lap (running) / reset (stopped). Haptic feedback on everything. 10ms precision.
MU A little spirit that lives in the watch. Its eyes roll with gravity (IMU), it watches your finger, gets dizzy when shaken, chirps when poked, purrs (haptics) when petted, and falls asleep if ignored.
SPECTRUM Factory mic FFT visualizer.
ALARM Factory alarm clock.
SETUP Brightness / volume / buttons / time / about.

Navigation: swipe or tap the arrows in the launcher, tap an icon to open. Hold A+B together to go home from any app.

Engine (main/apps/common/fx)

  • Renders straight into the AMOLED panel framebuffer (PSRAM row pointers exposed via Panel_FrameBufferBase::getLinesBuffer()), one QSPI flush per frame — no LVGL, no full-sprite copy.
  • Additive-blended integer glow stamps (radius 1..56, lazily built).
  • Dirty-rect erasing instead of full clears (only regions drawn last frame are cleared).
  • IMU polled in a background task on core 1; render loop never blocks on i2c.
  • Steady 33 fps at full 466x466.

Build & flash

ESP-IDF v5.5.4:

python3 ./fetch_repos.py   # fetch components (applies patches/M5GFX.patch etc.)
idf.py build
idf.py -p /dev/ttyACM0 flash

Dev tools (USB serial debug channel)

The firmware listens on the USB-Serial-JTAG console for single-byte commands (see main/hal/hal_debug.cpp):

Cmd Effect
P Dump a real screenshot of the panel framebuffer as base64
C / L / R Inject tap: center / left arrow / right arrow
@x,y,ms\n Inject tap at x,y for ms
a / b Inject button A / B click
Q Go home
D YYYY-MM-DD HH:MM:SS\n Set RTC

Host helpers:

python3 tools/screenshot.py out.png     # capture screenshot
python3 tools/ctl.py settime            # sync RTC to host clock
python3 tools/ctl.py tap 233 233 200    # tap injection
python3 tools/ctl.py log 10             # tail serial log

Icons in assets_src/ were generated with gpt-image-2 and converted with tools/png2lvgl.py.

Credits & license

Based on M5Stack's M5StopWatch-UserDemo (MIT) — the HAL, launcher, and the SPECTRUM / ALARM / SETUP apps come from it. Third-party components (M5GFX, LVGL, mooncake, smooth_ui_toolkit, ArduinoJson, BMI270 driver) are fetched by fetch_repos.py under their respective MIT/BSD licenses; patches/M5GFX.patch adds a one-line framebuffer accessor used by the fx engine. This project is released under the MIT License (see LICENSE).

About

No description, website, or topics provided.

Resources

Stars

32 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages