> For the complete documentation index, see [llms.txt](https://docs.anthriq.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.anthriq.com/bxi-studio/developer/overview/devices/xbud.md).

# xBud

USB analog acquisition through an NI DAQ, exposing a single analog input feature. No registers, motors, impedance, or firmware over the SDK.

|             |                        |
| ----------- | ---------------------- |
| Device type | `ni-usb-daq`           |
| Transport   | In-process bridge stub |
| Electrodes  | External               |

> **Note:** The device type is spelled `ni-usb-daq`, after the acquisition path rather than the product. Pass that string wherever a device type is required.

## What it supports

| Feature        | Use it for                                         | Page                                                                                 |
| -------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `analog_input` | Configuring a task and reading samples             | [Acquire analog input](/bxi-studio/developer/overview/devices/xbud/analog-input.md)  |
| `system`       | Capabilities, connection state, and `scan_devices` | [Read device information](/bxi-studio/developer/overview/get-started/device-info.md) |

`scan_devices` is unique to xBud; Anthriq headsets do not declare it. Registers, motors, impedance, EXG, and firmware belong to [Instinct](/bxi-studio/developer/overview/devices/instinct.md) and [xSys](/bxi-studio/developer/overview/devices/xsys.md).

## Set up

xBud exposes one acquisition feature, `analog_input`, and no registers, motors, impedance, or firmware. Configure a task, then read from it.

{% tabs %}
{% tab title="Node.js" %}

```typescript
import { BxiClient, parseSubscriptionFrame } from "@anthriq_dev/bxi-interface";

const client = new BxiClient<"ni-usb-daq">({ deviceType: "ni-usb-daq" });

// 1. Reach the bridge, then the device.
await client.initialize("localhost");
await client.connect();

// 2. Ask the hardware what it can do before choosing a rate.
const info = await client.features.executeOperation("analog_input", "query", {
  device_name: "Dev1",
});
console.log(info.data);

// 3. Configure the acquisition task. Later reads use this cached config.
await client.features.executeOperation("analog_input", "configure", {
  device_name: "Dev1",
  ai_channels: "Dev1/ai0:3",
  sample_clock_rate_hz: 1000,
  terminal_config: "RSE",
  sample_mode: "CONTINUOUS",
});

// 4. Subscribe, then start streaming.
const subscription = await client.features.subscribeToOperation(
  "analog_input",
  "stream",
  (update) => {
    if (!update.success) return;
    const frame = parseSubscriptionFrame(update.data);
    process(frame.samples);
  },
  {}
);

await client.features.executeOperation("analog_input", "start_stream", {});
await new Promise((r) => setTimeout(r, 10000));

// 5. Stop before shutting down: the task lives in the bridge.
await client.features.executeOperation("analog_input", "stop_stream", {});
await client.features.unsubscribeFromOperation("analog_input", "stream", {
  subscriptionId: subscription.data.subscriptionId,
});

await client.shutdown();
```

{% endtab %}

{% tab title="Python" %}

```python
import asyncio
from anthriq_bxi_interface import BxiClient, parse_subscription_frame

client = BxiClient(device_type="ni-usb-daq")

# 1. Reach the bridge, then the device.
await client.initialize("localhost")
await client.connect()

# 2. Ask the hardware what it can do before choosing a rate.
info = await client.execute_operation("analog_input", "query", {"device_name": "Dev1"})
print(info.data)

# 3. Configure the acquisition task. Later reads use this cached config.
await client.execute_operation("analog_input", "configure", {
    "device_name": "Dev1",
    "ai_channels": "Dev1/ai0:3",
    "sample_clock_rate_hz": 1000,
    "terminal_config": "RSE",
    "sample_mode": "CONTINUOUS",
})

# 4. Subscribe, then start streaming.
def on_frame(update):
    if not update.success:
        return
    frame = parse_subscription_frame(update.data)
    process(frame["samples"])

subscription = await client.subscribe_to_operation(
    "analog_input", "stream", on_frame, {}
)

await client.execute_operation("analog_input", "start_stream", {})
await asyncio.sleep(10)

# 5. Stop before shutting down: the task lives in the bridge.
await client.execute_operation("analog_input", "stop_stream", {})
await client.unsubscribe_from_operation(
    "analog_input", "stream", {"subscriptionId": subscription.subscription_id}
)

await client.shutdown()
```

{% endtab %}
{% endtabs %}

[Acquire analog input](/bxi-studio/developer/overview/devices/xbud/analog-input.md) covers the full option set, trigger configuration, and reading a fixed block instead of streaming.

Each step in depth: [Acquire analog input](/bxi-studio/developer/overview/devices/xbud/analog-input.md).
