Skip to content

Repository files navigation

M5WatchClicker

日本語版: README.ja.md

M5WatchClicker in the palm of a hand, showing remaining time, current time and projected finish time

A presentation remote built on the M5Stack StopWatch.

It shows the remaining time large on the round AMOLED, advances your slides with a swipe, and buzzes in your hand as the clock runs down.

Every talk brings the same two problems at the same moment: "how much time is left?" and "next slide, please." Each one takes only a second — but it is a second spent looking away from your audience. This project settles both of them with a single device that sits in your palm — nothing to swap hands, no clock to hunt for on the desk.

Nothing to install on the host. The device pairs as a standard BLE HID keyboard: no driver, no companion app, no background service. Pair it once and start your slideshow.

Features

  • Swipe to change slides — brush right across the screen for the next slide, left to go back. It sends real arrow keys, so it works with anything driven by the keyboard: PowerPoint, Keynote, Google Slides, PDF viewers (keys are configurable)
  • Remaining time you don't have to read — the ring drains clockwise from 12 o'clock. You take in the area, not the digits
  • Warnings you can see coming — the remaining arc is split at your alert thresholds and colored green → amber → red. The place where the color changes is your next warning, so "a buzz is coming up soon" is obvious at a glance
  • A nudge in your palm — vibration at 5 minutes left, 1 minute left, or wherever you like: one short buzz for the first threshold, two for the second, and a long pattern at time-up. Just holding it is enough to feel it, and the room hears nothing
  • Carry it whichever way suits you — keep it in your hand, run a strap through it, or use the magnets in the back to clip it onto a shirt pocket like a badge. That last one keeps both hands free: a quick glance down is all it takes to check the time
  • Your finish time, not just a countdownNOW 14:32 / END 15:02. Knowing what time you must finish is often easier to act on than minutes remaining, and it lines up with the clock on the wall
  • Elapsed and total on one lineELAPSED 12:34 / 30:00 tells you how long you have been talking and how long you were given
  • Overtime counts up — at zero the display doesn't freeze; it counts upward in red next to TIME UP, so you know exactly how far over you are
  • Configured on the watch itself — talk length and warning times are edited in mm:ss and stored in flash. The rim dial catches with a short buzz on every five-minute mark, so you can land on 15:00 without staring at the screen
  • Wi-Fi only at boot — it syncs over NTP, writes the time into the built-in RTC, and switches Wi-Fi off. Easy on the battery, and the clock keeps working in venues with no Wi-Fi at all
  • Power-aware, but readable — auto-dims after 5 s idle and wakes on touch. Tap the bulb icon to pin it bright (it turns on by itself when you plug in USB). Battery level shows on-screen and in the host's Bluetooth panel

Setup

Here is the path from a fresh device to your first talk. For the timer and slide control you only need to flash and pair — the Wi-Fi step is optional and only affects the clock display.

1. Flash the firmware

Open M5Burner, find M5WatchClicker under the StopWatch category, and press Burn.

Entering download mode: hold the power button for about 2 seconds until the green LED lights, then start the flash.

To build it yourself, see Development.

2. Pair with your computer

On boot the Bluetooth icon blinks, waiting to pair. Select M5WatchClicker in your computer's Bluetooth settings (the icon goes solid once connected). After the first pairing it reconnects by itself every time you power on.

It shows up as an ordinary keyboard, so there is no driver or app to install. Start your slideshow and brush left or right across the screen to move between slides.

3. Set your talk length and warnings

Swipe up or down to open the settings screen (only while the timer is stopped). Three items, top to bottom: TIME (talk length) / ALERT 1 / ALERT 2.

  1. Tap the item you want to change (a short press of both buttons also moves the selection)
  2. Adjust with BtnA (−) / BtnB (+). Hold a button and the step grows: 1 s → 5 s → 15 s → 1 min → 5 min
  3. For big jumps, trace around the outer rim — 10-second steps, with a small buzz and a catch on every five-minute mark
  4. To silence a warning, tap the ON/OFF button at the right of that item
  5. Swipe up or down to save and return to the timer

Settings are stored on the device and survive a power cycle. See Settings screen for the details.

4. Set the clock (optional)

Configure Wi-Fi if you want the NOW / END and date displays. The timer and slide control work fine without it.

  1. Get a serial connection ready on your computer (115200 baud — M5Burner's serial monitor, screen, CoolTerm, anything)
  2. Hold BtnA while powering on. The screen shows WiFi SETUP
  3. At the SSID> prompt type your SSID and press Enter, then your password at PASSWORD>
  4. Once saved it connects, fetches the time over NTP, and writes it into the built-in RTC

The credentials stay on the device, so every later boot syncs automatically. Press BtnB if you want to skip the setup and boot normally.

The NTP / RTC labels near the bottom of the screen tell you whether the sync worked (see Reading the screen).

Usage

Timer screen

The buttons behave like an ordinary stopwatch: the right one runs it, the left one clears it. Reset is a long press so that a mis-tap can never cost you your elapsed time.

Action Result
Swipe right Next slide
Swipe left Previous slide
BtnB (right) Start / stop
Hold BtnA (left) Reset (re-applies the configured talk length)
Hold both buttons Reset (same)
Swipe up / down Open settings (disabled while the timer runs)
BtnB (after time-up) Stop / resume the overtime counter

Vertical swipes are ignored on purpose while the timer runs: a slightly crooked page-turn swipe should never drop you into a settings screen mid-talk.

Settings screen

Open it with an up or down swipe. Three items: talk length / alert 1 / alert 2.

Action Result
BtnA / BtnB Decrease / increase (hold to accelerate)
Tap an item Select it
Both buttons, short press Next item
Trace the outer rim (dial) Clockwise increases, counter-clockwise decreases
Tap the ON/OFF button at the right Enable / disable that alert
Swipe up / down Save and return to the timer

There is no digit to choose. Values read as mm:ss, but all you select is the item. Hold a button and the step grows automatically — 1 s → 5 s → 15 s → 1 min → 5 min — and any step larger than one second snaps to a round value (12:47 +1 min → 13:00). The step in effect is shown under the value.

Use the dial for big moves. Trace around the rim and the value follows; one full turn spans the whole range (90 minutes for the talk length, the talk length itself for alerts), with an arc on the rim showing where you are. It moves in 10-second steps and catches with a short buzz on every five-minute mark — a physical detent you can feel, so you can stop on 15:00 without looking. Keep turning and it moves on. Use the buttons for one-second trimming.

There are no [-] [+] buttons in the middle of the screen: a stray finger should not change a value, so fine adjustment lives on the physical buttons. The area outside the item boxes is mostly dial, so make the save-and-return swipe from on top of an item box.

Consistency check: if a warning is later than the talk itself, or alert 2 is earlier than alert 1, the offending item turns red and you cannot leave until it is fixed. The firmware never silently rewrites what you typed.

Reading the screen

  • Ring — remaining time, draining clockwise from 12 o'clock, split into colored zones at your alert thresholds (green → amber → red)
  • NOW / END — current time and projected finish time (hidden if no clock is available)
  • ELAPSED — elapsed time / configured talk length
  • Top line — the date before you start, PAUSE while paused, TIME UP after the deadline (nothing while running)
  • Digit and ring color — green (normal) → amber (past alert 1) → red (past alert 2)
  • Battery — green, red at 20 % or below, with the percentage underneath. A lightning bolt (⚡) overlays it while USB is connected
  • Bluetooth — blinking = pairing / waiting, solid = connected
  • Wi-Fi — blinking = syncing, solid = synced, dim = not configured, dim red = sync failed (Wi-Fi is switched off after syncing)
  • NTP / RTC (right of the Wi-Fi icon) — where the clock came from. NTP lit = boot-time sync succeeded, RTC lit = running on the built-in RTC, both gray = no time available (clock and date stay hidden)
  • Bulb (below the Bluetooth icon) — tap to toggle "never dim". While lit (yellow) the screen stays bright. Plugging in USB turns it on and unplugging turns it off, but a tap afterwards always wins — including dimming while powered

Configuration file (data/config.json)

Changes made in the on-device settings screen are stored as this file on the device's LittleFS. With a development environment you can also write the whole file at once with pio run -t uploadfs.

After flashing with M5Burner the file does not exist yet, so the device starts with defaults. Talk length and warnings are set from the settings screen and Wi-Fi from the serial console — both are saved on the device, so there is no need to edit this file by hand.

{
  "presentation_sec": 1800,
  "alerts": [
    { "before_sec": 300, "enabled": true },
    { "before_sec": 60,  "enabled": true }
  ],
  "swipe_keys": { "next": "RIGHT", "prev": "LEFT" },
  "brightness": 80,
  "dim_brightness": 10,
  "wifi": { "ssid": "", "password": "" },
  "ntp": { "server": "pool.ntp.org", "timezone": "JST-9" },
  "date_locale": "ja"
}
Key Description
presentation_sec Talk length in seconds. 10 s – 90 min
alerts[].before_sec Seconds remaining when the alert fires. List them earliest first
alerts[].enabled Whether that alert is active
swipe_keys.next Key sent by a right swipe (next slide). Default RIGHT
swipe_keys.prev Key sent by a left swipe (previous slide). Default LEFT
Available keys: RIGHT LEFT UP DOWN PAGE_UP PAGE_DOWN SPACE ENTER
brightness Normal screen brightness (%)
dim_brightness Brightness after 5 s of inactivity (%)
wifi.ssid / wifi.password Wi-Fi used for time sync. Empty means no sync
ntp.server NTP server (default pool.ntp.org)
ntp.timezone POSIX TZ string (default JST-9)
date_locale Date language. ja (default) = 2026/07/29(水) / en = 2026-07-29 (Wed)

You can list three or more alerts. Vibration counts are assigned automatically: one short buzz for the earliest, two for the next, and so on, with a long pattern × (number of alerts + 1) at time-up.

If the file is missing or corrupt, defaults are restored automatically (30 min / 5 min / 1 min).

Setting the clock (Wi-Fi / NTP)

Wi-Fi connects only at boot: it fetches the time over NTP, writes it to the built-in RTC, and disconnects. Because it never stays connected, the battery cost is limited to startup, and the clock keeps running from the RTC afterwards — so the display still works in venues without Wi-Fi.

If you would rather not keep a password in config.json in plain text, hold BtnA while powering on. The screen shows WiFi SETUP and you can type the SSID and password over the serial console (115200 baud). What you enter is saved to the config.json on the device.

pio device monitor    # open this first, then power on while holding BtnA

⚠️ The wifi fields in the repository's data/config.json are intentionally empty. If you fill in your own credentials, take care not to git commit them.

Development

To build it yourself you need PlatformIO.

Shared board settings come from a submodule (config/), so clone with --recursive.

git clone --recursive https://github.com/3110/M5WatchClicker.git
cd M5WatchClicker

If you forgot --recursive, fetch it afterwards:

git submodule update --init --recursive
pio run                  # build
pio run -t upload        # flash the firmware
pio run -t uploadfs      # write data/config.json to LittleFS
pio device monitor       # serial monitor (115200)
./tests/run_tests.sh     # host tests (verify logic on your PC)

Entering download mode: hold the power button for about 2 seconds until the green LED lights, then run upload.

Timer, input, and alert logic run as plain host builds against a mocked M5Unified, so 24 behavioral scenarios are verified on a laptop in about a second. GitHub Actions runs those tests plus a full firmware build on every push.

About

A presentation remote built on the M5Stack StopWatch / M5Stack社のStopWatchを使用したプレゼン用クリッカー

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages