DustinYe / gesture-media-controller
git clone https://github.com/DustinYe/gesture-media-controller.git
Infrared gesture-based BLE media controller for AtomS3R and PAJ7620U2; C++ firmware, trajectory replay, and documented v24 baseline.
—
stars, 24h
+177
stars, 7 days · #316
+177
stars, 30 days · #1,426
177
★ total · +177% this week
28
forks · 0 open issues
Star history starts 2026-10-20; the chart appears after the second daily snapshot.
LanguageC++
License—
Created2026-10-18 (2d ago)
Last push2d ago
Watchers175
OwnerUser
GitHub topics
Links
README excerpt
# Gesture Media ### Infrared gestures → Bluetooth media control 简体中文 · Build guide · Version history · Validation A working embedded media-controller prototype built with an **M5Stack AtomS3R** and **Unit Gesture / PAJ7620U2**. Hand movements become standard BLE HID Consumer Control commands for a connected computer, phone, or tablet. Normal use requires power and a compatible BLE host; a PC relay, cloud service, or project-specific host application is not required. **Published baseline: v24.** The main sketch is byte-for-byte identical to the archived v24 sources that were compiled, flashed, and user-tested. The later fist/slap filtering draft is retained separately as an **unverified v25 experiment**, not an implemented fix. ## Interaction | Input | Action | |---|---| | Open palm, then close fingers into a fist toward the sensor | Play / pause | | Left slap-style movement | Previous track | | Right slap-style movement | Next track | | Each completed clockwise circle | One volume-up key | | Each completed counterclockwise circle | One volume-down key | | Front screen button: one click | Pause / resume gesture control | | Front screen button: double-click | Disconnect the current host and wait for another | | Double-click again while waiting | Cancel host switching | | Hold front screen button for 3 seconds | Clear stored Bluetooth bonds | The front screen is pressed as a physical button. It is distinct from the side Reset button. A single click is decided about 350 ms after release so a double-click does not also pause control. Volume step size and previous-track behavior are determined by the host/player. ## Hardware - AtomS3R: ESP32-S3, 128 × 128 display, front button, USB-C power/programming. - Unit Gesture U127: PAJ7620U2 infrared optical sensor. - Grove cable for I²C and power; sensor address `0x73`. - Existing calibrated mounting: sensor face vertical, toward the user. Start around 8–10 cm away and keep the motion in front of the sensor. Official references: AtomS3R, Unit Gesture. ## Architecture [code] The C++/Arduino firmware polls the sensor about every 4 ms and samples trajectories about every 16 ms. These are scheduling intervals, **not measured end-to-end latency**. - `SweepTracker` estimates horizontal motion and suppresses held-hand withdrawal. - `GripTracker` combines recent area contraction, centroid changes, endpoint settling, and a one-event latch. - `CircleTracker` integrates changes in motion heading, checks circular extent, and counts turns. Native sensor hints assist a clipped final arc. - `MediaHid` exposes a consumer-only, two-byte media input report, with encrypted report access and automatic key release. - Host switching preserves bonds, rejects the previous host during switching, and completes after a different host authenticates and subscribes. The firmware uses an existing BLE stack; it does not implement a new Bluetooth protocol. It transmits media commands, not audio. ## Build Pinned baseline: M5Stack ESP32 core