> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nimbusbci.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Real-Time BCI Setup

> Set up low-latency BCI acquisition pipelines with LSL, BrainFlow, preprocessing, and streaming handoff to Nimbus SDKs.

# Real-Time BCI Setup

This page owns hardware and acquisition setup: how EEG gets from an amplifier into feature chunks that Nimbus can classify. For SDK streaming APIs, see [Streaming Inference Configuration](/inference-configuration/streaming-inference), [Python Streaming Inference](/python-sdk/streaming-inference), and [Julia Streaming Inference](/julia-sdk/streaming-inference).

## Real-Time Pipeline

```text theme={null}
EEG amplifier -> acquisition transport -> preprocessing -> feature chunks -> Nimbus streaming session -> application command
```

Nimbus expects **feature chunks**, not raw EEG. Your acquisition loop should filter, clean, epoch/window, and extract features before calling the SDK.

## Acquisition Options

| Option                    | Best for                                       | Notes                                                     |
| ------------------------- | ---------------------------------------------- | --------------------------------------------------------- |
| Lab Streaming Layer (LSL) | Research labs and multi-device synchronization | Common for EEG streams and markers                        |
| BrainFlow                 | Consumer and research EEG hardware             | Unified API for many boards                               |
| Vendor SDK                | Production devices                             | Lowest integration overhead when the vendor API is stable |
| File replay               | Testing and demos                              | Useful for deterministic latency tests                    |

## Setup Checklist

1. Confirm amplifier sampling rate and channel order.
2. Synchronize event markers with EEG samples.
3. Apply artifact handling and feature extraction in the same way as calibration.
4. Emit chunks with stable shape: `(n_features, chunk_size)`.
5. Use the same normalization parameters from training.
6. Measure latency around preprocessing and SDK inference separately.
7. Add rejection thresholds for low-confidence or high-entropy decisions.

## LSL Pattern

Use LSL when you need synchronized EEG and marker streams.

```python theme={null}
from pylsl import StreamInlet, resolve_stream

eeg_stream = resolve_stream("type", "EEG")[0]
marker_stream = resolve_stream("type", "Markers")[0]

eeg_inlet = StreamInlet(eeg_stream)
marker_inlet = StreamInlet(marker_stream)

while True:
    samples, timestamps = eeg_inlet.pull_chunk(timeout=0.0)
    markers, marker_times = marker_inlet.pull_chunk(timeout=0.0)

    if samples:
        feature_chunk = preprocess_to_features(samples, markers)
        result = session.process_chunk(feature_chunk)
        handle_prediction(result.prediction, result.confidence)
```

## BrainFlow Pattern

Use BrainFlow when you want one API across supported EEG boards.

```python theme={null}
from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds

params = BrainFlowInputParams()
board = BoardShim(BoardIds.CYTON_BOARD.value, params)

board.prepare_session()
board.start_stream()

try:
    while True:
        data = board.get_current_board_data(250)
        feature_chunk = preprocess_to_features(data)
        result = session.process_chunk(feature_chunk)
        handle_prediction(result.prediction, result.confidence)
finally:
    board.stop_stream()
    board.release_session()
```

## Latency Budget

| Stage                                | Target                            |
| ------------------------------------ | --------------------------------- |
| Acquisition buffer                   | 1-10ms                            |
| Preprocessing and feature extraction | 5-50ms, depending on feature type |
| Nimbus inference                     | 10-25ms typical                   |
| Application command                  | 1-10ms                            |

<Tip>
  Profile each stage separately. If latency is high, the bottleneck is often acquisition buffering or feature extraction rather than model inference.
</Tip>

## Production Guardrails

* Warm up model and preprocessing code before the session starts.
* Use fixed-size buffers to avoid unbounded memory growth.
* Reset streaming sessions between trials.
* Log per-stage latency, confidence, entropy, and rejection decisions.
* Keep calibration preprocessing and online preprocessing identical.

## Next Read

<CardGroup cols={2}>
  <Card title="Streaming Inference Configuration" icon="play" href="/inference-configuration/streaming-inference">
    Choose chunk sizes and aggregation methods.
  </Card>

  <Card title="Python Streaming Inference" icon="activity" href="/python-sdk/streaming-inference">
    Use `StreamingSession` in Python.
  </Card>

  <Card title="Julia Streaming Inference" icon="rss" href="/julia-sdk/streaming-inference">
    Use `init_streaming`, `process_chunk`, and `finalize_trial` in Julia.
  </Card>

  <Card title="Preprocessing Requirements" icon="list-filter" href="/inference-configuration/preprocessing-requirements">
    Prepare feature-space inputs correctly.
  </Card>
</CardGroup>
