BLE API Reference
Every Sticky is an independent BLE peripheral exposing a role-specific GATT service — Sensing or Feedback — depending on which firmware it runs (see Stickies + Your Own Control Layer). You can build your own software against this API directly, without using the companion app.
Sensing service (0x0001)
| Characteristic | UUID | Direction | Format |
|---|---|---|---|
| Capabilities | 0x0001 | Read | u8 flags (bit 0: tactile present) |
| IMU Data | 0x0002 | Notify | u8 sample_count; per sample: i16×3 accel, i16×3 gyro, u32 timestamp |
| Tactile Data | 0x0005 | Notify | u32 timestamp; u8[64] 8×8 pressure matrix |
| Config | 0x0003 | Write | u8 imu_rate_hz; u8 tactile_rate_hz |
| Echo | 0x0004 | Write / Notify | — |
A sensing sticky automatically detects whether a tactile extension is attached at boot, so no manual device-type selection is needed. IMU streaming defaults to 100 Hz; tactile streaming defaults to 30 Hz, both reconfigurable via the Config characteristic.
Feedback service (0x0002)
| Characteristic | UUID | Direction | Format |
|---|---|---|---|
| Motor Command (Stop) | 0x0001 | Write | u8 cmd = 0x00; u8 motor_id |
| Motor Command (Play) | 0x0001 | Write | u8 cmd = 0x01, u8 motor_id; u16 duration_ms, u8 count; u16 gap_ms, u8 intensity |
| Echo | 0x0002 | Write / Notify | — |
Feedback firmware renders vibration patterns locally from a single Motor Command (Play) write — duration, repeat count, inter-pulse gap, and intensity are all specified in one command, so the host doesn't need to drive timing itself.
Notes
Echoon both services is used for latency measurement (periodic echo request/response), not application data.- Both services expose device identity over BLE so a host app can distinguish sensing vs. feedback stickies without manual selection.
- This API is deliberately raw/streaming — task semantics (metrics, calibration, feedback policies) are a host-side concern. See Reference Implementations for how the companion app builds on top of it.