Skip to main content

signalino

signalino is the high-level Python API for Signalino 4 EEG devices. It wraps the Signalino board implemented in BrainFlow and adds a non-destructive sample buffer, typed battery and impedance results, Lab Streaming Layer publishing, and conversion to MNE-Python.

This is research software. It is not a medical device and must not be used for diagnosis or patient monitoring.

Status

The package is ready to build and test but has not been published to PyPI. Signalino support currently lives in the Signalino-enabled BrainFlow repository. The official brainflow wheel does not yet contain board ID 69, so install the matching Signalino-enabled BrainFlow Python package and native library before connecting hardware. The wrapper verifies both the Python binding and native library and reports a clear error when they do not match.

Installation

Build BrainFlow first, then install its Python package and this wrapper:

cmake -S ../brainflow-signalino -B ../brainflow-signalino/build \
  -DCMAKE_BUILD_TYPE=Release -DBUILD_BLE=ON
cmake --build ../brainflow-signalino/build --parallel
python -m pip install ../brainflow-signalino/python_package
python -m pip install .

The BrainFlow fork currently uses a development package version (0.0.1). The signalino dependency intentionally does not impose a misleading BrainFlow version floor; runtime capability checks are authoritative until board 69 is available in an official BrainFlow release.

Install optional integrations as needed:

python -m pip install ".[lsl]"
python -m pip install ".[mne]"
python -m pip install ".[all]"

For development:

python -m pip install -e ".[dev,all]"
pytest

USB

import time

from signalino import Signalino

with Signalino.usb() as device:  # Automatically chooses the most probable port
    device.start_streaming()
    time.sleep(2)
    eeg_uv = device.get_data()

print(eeg_uv.shape)  # (8, approximately 500)

Use COM3-style names on Windows and /dev/ttyACM0-style names on Linux. Pass one explicitly as Signalino.usb("/dev/cu.usbmodem1101") when needed. Discovery only examines port names and USB descriptors; it does not open ports. Use find_usb_ports() to display every probable candidate. If two devices are equally likely, automatic selection refuses to guess.

Bluetooth LE

from signalino import Signalino

device = Signalino.ble("Signalino-852960")
device.connect()
device.start_streaming()

When only one Signalino is advertising, Signalino.ble() lets BrainFlow choose it automatically. Provide the advertised name whenever multiple devices may be present.

Data

get_data() returns a NumPy array in microvolts with shape (channels, samples). Data is consumed oldest first by default:

latest_copy = device.get_data(250, clear=False)
oldest_consumed = device.get_data(250)

For timestamps, use get_data_batch():

batch = device.get_data_batch()
print(batch.samples_uv.shape)
print(batch.timestamps)

The package continuously drains BrainFlow into its own bounded buffer. LSL and get_data() therefore receive the same samples without stealing data from one another.

Public API

The stable top-level API is:

Signalino.usb(...) / Signalino.ble(...)
find_usb_port() / find_usb_ports()
connect() / disconnect()
start_streaming() / stop_streaming()
get_data() / get_data_batch() / clear_data()
battery() / impedance()
start_lsl() / stop_lsl()
to_mne()

Public result types and exceptions are importable directly from signalino. Implementation modules whose names begin with an underscore are private.

Battery

status = device.battery()
print(status.volts, status.percent, status.charging)

With the current USB BrainFlow bridge, battery replies cannot be collected while binary EEG is streaming. Stop USB streaming before refreshing the value. BLE uses a separate control characteristic and can refresh battery state while EEG is active.

Impedance

reading = device.impedance()
print(reading.kiloohms)

The ADS1299 cannot emit normal EEG while measuring impedance. If streaming is active, impedance() pauses EEG, takes one reading, exits impedance mode, and restores both EEG acquisition and the previous LSL outlet. This produces a short, timestamp-visible gap by design.

LSL

device.start_streaming()
stream = device.start_lsl()
print(stream.name, stream.source_id)

The outlet contains eight float32 EEG channels in microvolts. It is closed automatically before acquisition stops, so Signalino never leaves an advertised but empty LSL stream behind.

MNE

raw = device.to_mne(clear=False)
print(raw.info["sfreq"])

MNE stores EEG in volts; conversion from Signalino's microvolts is automatic. Pass an MNE montage with device.to_mne(montage=montage) when channel names have been assigned to physical electrode positions.

Development and release checks

ruff check .
ruff format --check .
pytest --cov=signalino
python -m build
python -m twine check dist/*

Building creates an sdist and a platform-independent wheel. Publishing is deliberately not part of the build process.

License

MIT

Release files for signalino 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for signalino 0.1.0
File Size Uploaded
signalino-0.1.0.tar.gz 19.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for signalino 0.1.0
File Interpreter ABI Platform
signalino-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size:35.1 kB

Release files / signalino-0.1.0.tar.gz

Download URL signalino-0.1.0.tar.gz
Size 19.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f6d880639c0af36b95e7a4ed65ebd45c61da3db0d85a58e7560249bda35b3bde
BLAKE2b-256 checksum
How to use checksums
6114ff55ce041ea3e3e90cea1faa6044cfa490e3927ccaebffa1f3cc425db97d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release files / signalino-0.1.0-py3-none-any.whl

Download URL signalino-0.1.0-py3-none-any.whl
Size 15.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6ba04f482dc717aa8e3f9809dbc0741c62aa116c066d3ea8b91dccc957fc0dd2
BLAKE2b-256 checksum
How to use checksums
4d5250e7fc05fd20d03710eca4a7daf4d94227ec7ca8938ba46a8cac074c1469
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 11, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.1

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page