Skip to content

Repository files navigation

BrushAR

An AR toothbrushing coach for Snap Spectacles (2024) that talks to real Philips Sonicare toothbrushes over Bluetooth — and puts the brushing HUD on your reflection in the bathroom mirror.

BrushAR.Short.Video.mov

Connect a Sonicare, walk up to your mirror, and press the brush's own button: a face-anchored HUD appears at your reflection's chin with the session timer, a progress board whose boxes fill the way your teeth face (uppers pour down, lowers rise up), sparkle bursts at your mouth, a celebration finale, and an AM/PM streak system with a global leaderboard. On a DiamondClean Smart 9300, advanced mode goes full pro: the board becomes the manual's true 6-zone mouth map (mirrored for the mirror — your upper-right is the top-right box) paced by each mode's real schedule (Clean, White+ with its polish steps, Gum Health with its gum-care steps, DeepClean+, Tongue Care), with the current mode name on display, a live pressure gauge (green → amber → red from the brush's real sensor and over-pressure alarm), the handle's 3-light intensity setting as dots, and frame-accurate session states from the brush's own session engine — including treating the 9300's auto-power-off at routine end as the completion signal it is.

Why this repo might interest you even if you never brush your teeth

  1. Mirror AR that actually works. Face-tracking your reflection on Spectacles (2024) breaks nearly every assumption the Head Binding API invites you to make. docs/MIRROR-AR.md documents the mechanism that survived twenty rounds of on-device elimination — including the depth and lateral corrections a stereo display demands — and everything that doesn't work, so you don't have to rediscover it.
  2. A reusable Sonicare BLE client for Lens Studio. docs/SONICARE-BLE.md covers the GATT protocol, the Spectacles BLE quirks (indications silently die; subscriptions keep the link alive), and how to drop SonicareClient into your own project.
  3. The whole experience runs in the editor with zero hardware. No Spectacles, no toothbrush required: simulateInEditor fakes the brush, the face-lock, a 12×-speed brushing session, a mid-session disconnect drill, and the 9300's pressure stream — the full loop, every run.

Hardware

Piece Notes
Snap Spectacles (2024) Experimental API enabled (BLE requires it)
Philips Sonicare For Kids HX6321 The kids flow (timer-guided quadrants)
Philips DiamondClean Smart HX992x Advanced mode: pressure gauge + true session states

⚠️ Buying a brush for this? Get the DiamondClean Smart HX992x family only. The 9900 Prestige, ExpertClean, and 7100 lines require BLE bonding, which Spectacles cannot do.

Quick start

  1. Lens Studio 5.15.4 — exactly. That's the Spectacles (2024) release; opening the project in 5.22+ performs a one-way migration aimed at the newer hardware generation.
  2. Open BrushAR.esproj.
  3. Press play. The editor simulation runs the entire experience: detection modal → mirror face-lock → brushing with quadrant fills, chimes, and mouth sparkles → celebration → streak + leaderboard, plus a brush-disconnect drill. Flip SIM_PROFILE at the top of BrushARController.ts between 'kids' and 'advanced' to preview either tier.
  4. On device: Project Settings → enable Experimental API → push to Spectacles. Take the brush off its charger (Sonicares never advertise while charging) and press its button once to wake it. Close the Philips phone app — the brush accepts a single BLE connection. Stand at a bathroom mirror.

The flow

MENU (auto-scan) ── brush found ──► BRUSH DETECTED (name · battery · mode)
        ▲                                │ OK tap · face fast-path (2 s) · or motor-on shortcut
        │                                ▼
   CONGRATS ◄── 2 s sparkle       MIRROR (4 s face-lock on your reflection)
   streaks ·      celebration            │
   leaderboard        ▲                  ▼
        ▲             │            READY "Start brushing!"
        └─────────────┴── BRUSHING ◄─────┘
                          face-anchored HUD · anatomical progress board
                          (kids 2x2 · 9300 6-zone mouth map + mode name,
                          pressure gauge, intensity dots) · chimes ·
                          zone flashes · mouth sparkles

Niceties along the way: pressing the brush's physical button anywhere in the flow jumps straight to brushing (the HUD syncs to the brush's own session clock); a mid-session pause re-prompts and resumes; losing the brush entirely fails into a rescan flow; sessions record into an AM/PM streak model with comeback messaging.

Architecture

Piece Role
Assets/Scripts/BrushARController.ts The state machine, panel layout (all code-side), the face-anchored HUD twin + mirror composition, celebrations, editor sim
Assets/Scripts/Sonicare/SonicareGatt.ts Protocol tables: UUID scheme, services, characteristic definitions, decoders
Assets/Scripts/Sonicare/SonicareClient.ts Reusable BLE client: scan → connect → subscribe → typed live state, poll/notify hybrid, sensor stream control
Assets/Scripts/Sonicare/BrushProfile.ts Family + capability detection (from the discovered GATT topology, not the model name)
Assets/Scripts/Sonicare/SonicareProbe.ts Disabled-by-default GATT exploration tool
Assets/Scripts/Screens/ ForeheadHud (kids quad board + 6-zone segment board, pressure gauge, intensity dots, mode caption), MirrorSeekScreen (face-lock ring), LeaderboardPanel, BatteryBadge, shared palette
Assets/Scripts/StreakStore.ts Persistent AM/PM streak model

Credits

  • Sonicare GATT knowledge builds on mtheli/philips_sonicare_ble — an excellent protocol reference.
  • Built with Snap's Spectacles Interaction Kit + UI Kit.
  • Sounds and the sparkle VFX are project-local assets.

License

MIT — take the client, the mirror math, whatever helps. Built by Ralph Barbagallo (@flarb).

About

AR tooth-brushing assistant for Snap Spectacles (2024) - connects to Philips Sonicare toothbrushes over BLE

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages