# 7. EffectReceiver — Receiving Binary Commands

EffectReceiver lets your device receive haptic commands over a binary protocol. You feed raw bytes (from serial, BLE, WiFi, or another interface) into the receiver, and it parses packets, validates CRC, and triggers the corresponding haptic effects. This is suited for production use where you want low-overhead, structured commands instead of text.

---

## 7.1 Setup

Include the EffectReceiver header and pass it as an extension module during init:

```cpp
#include <VHEffectReceiver.h>

VHEffectReceiver receiver;

void setup() {
    channels.add(1, {YOUR_OUTPUT_PIN}, {"main"});
    vh.init(&board, {&channels, &receiver});
}
```

The receiver starts a background parsing task. Whenever you receive binary data from your transport (serial, BLE, WiFi), feed it into the engine:

```cpp
void loop() {
    if (Serial.available()) {
        uint8_t buffer[256];
        size_t len = Serial.readBytes(buffer, sizeof(buffer));
        vh.executeCommand(buffer, len);
    }
}
```

Replace `Serial` with your actual data source—e.g. a BLE characteristic callback or WiFi socket.

---

## 7.2 Packet Structure

Each packet has:

- **Header (5 bytes):** sync bytes (0xAA 0x55), command type, sub-command, payload length
- **Payload:** variable-length data depending on the command
- **CRC:** 1-byte CRC-8 (polynomial 0x07) over payload (PLAY/QUEUE struct-style commands only)

All multibyte values are little-endian. For the complete binary format, header layout, payload structures, and full command list, see **API_REFERENCE.md § EffectReceiver → Binary Command Format**.

---

## 7.3 Command IDs and Payloads

Typical commands include:

| Command ID | Effect  | Payload fields |
|------------|---------|----------------|
| PULSE      | Pulse   | channel, duration, intensity, sharpness |
| TICK       | Tick    | Same as PULSE |
| VIBRATE    | Vibrate | channel, duration, intensity, frequency, sharpness |
| PAUSE      | Pause   | channel, duration |
| ERM        | ERM     | channel, duration, intensity, direction (0=negative, non-zero=positive) |
| SWEEP      | Sweep   | channel, duration, start/end intensity/freq/sharpness, transitions |
| PCM        | PCM     | channel, raw PCM data (variable length) |
| AUDIO_STREAM | Audio  | channel, duration, intensity, audioChannel |
| CUSTOM_PRIM | Custom  | channel, index, duration, params (floats) |
| HDI D      | Device info | No payload — returns device info including **custom primitive index and parameter order** |
| HDI C      | All channels | No payload |
| HDI        | Channel info | Optional 1-byte channel number |

**Custom primitives:** The primitive **index** and **parameter order** for binary `VH_CUSTOM_PRIM` commands can be obtained from the **HDI D** (device info) response. Send a binary `HDI D` command (or text `HDI D` via DevTools); the response includes a "Custom Primitives" section listing each primitive as `[index] Name => param1 : val, param2 : val, ...`. The index is the number in brackets; the parameter order in the binary payload must match the order shown (duration first, then param0, param1, ...).

For a concise module-level overview, see **MODULES.md § VHEffectReceiver**. For the full command table, payload layouts, CRC rules, and `TransitionType` enum, see **API_REFERENCE.md § EffectReceiver → Binary Command Format**.

