API reference
The public methods of the Hapbeat class (src/Hapbeat.h). The code is the
source of truth.
Connection
Section titled “Connection”| Method | Description |
|---|---|
bool begin(uint16_t port = 7700, const char* appName = "") | open the UDP socket; appName (≤16 chars) shows on the connected Hapbeat OLED. Call after Wi-Fi connects |
void end() | announce the app is leaving (clears the OLED app name) |
void setGroup(uint8_t group) | group id sent in CONNECT_STATUS (level-1 default 0) |
command (fire)
Section titled “command (fire)”| Method | Description |
|---|---|
void play(const char* eventId, float gain = 1.0f, const char* target = "") | fire a kit event (gain 0..1). eventId is <kit-name>.<file-name> |
void stop(const char* eventId, const char* target = "") | stop a specific event |
void stopAll(const char* target = "") | stop everything |
void ping() | keep-alive / RTT probe |
Synthesized sine
Section titled “Synthesized sine”| Method | Description |
|---|---|
void playSine(float freqHz, float intensity, uint32_t durationMs, const char* target = "") | one-shot sine (blocks ~durationMs). intensity 0..1 |
void beginSine(float freqHz, float intensity, const char* target = "") | start a continuous sine |
void pumpSine() | keep the device ring filled (call often from loop()) |
void endSine() | stop the continuous sine |
bool sineActive() | is a continuous sine running |
Discovery / addressing
Section titled “Discovery / addressing”| Method | Description |
|---|---|
bool discover(uint32_t timeoutMs = 1500) | broadcast PING → register every device that replies (blocks the full timeout); sends then unicast |
void poll() | consume arrived PONGs (optional — sends do it too) |
uint8_t deviceCount() | live known devices (0 = sends broadcast) |
IPAddress deviceIp() | first known device IP |
void setDeviceIp(IPAddress ip) | pin an IP (never expires); 0.0.0.0 clears |
void setDeviceTimeout(uint32_t ms) | liveness window (default 15000) |
void setBroadcastOnly(bool on) | always broadcast |
target: "" (every device) / "player_1/pos_neck" / "*/pos_neck" / "*/*/group_2".
Matching is positional, so "group_2" on its own is compared with the player
slot and never matches, and * is only a wildcard as a whole segment ("pos_*"
does not match).
level-1 notes
Section titled “level-1 notes”This version has no EventMap class. Keep tuning (intensity / loop, etc.) in the kit on the Hapbeat. Stored-WAV / clip streaming and ESP-NOW transport are not supported yet (see command vs sine).
For the byte-level wire format, see docs/wire-format.md and
src/HapbeatProtocol.h in the repo. It is byte-compatible with hapbeat-contracts
and the Python / Unity / JS SDKs.