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.

Installation

Linux x86_64 (Intel/AMD 64-bit)

Python 3.10+ and glibc 2.35+ are required for the current Linux wheels.

python -m pip install --upgrade signalino

Starting with 0.1.2, this installs brainflow-signalino==0.1.0 automatically. It contains the compiled Signalino driver and uses the brainflow_signalino Python module, so it can coexist with official brainflow without overwriting files. No compiler, CMake or private repository access is required. ARM/Raspberry Pi, Alpine/musl and older glibc are not covered by these wheels. USB/RFCOMM permissions and Bluetooth adapter setup remain host OS requirements.

macOS Apple Silicon

Starting with 0.1.3, the same command installs a precompiled ARM64 backend on Apple Silicon Macs running macOS 12 or later:

python -m pip install --upgrade signalino

It supports USB/serial, paired Bluetooth Classic serial ports and BLE through CoreBluetooth. Like the Linux package, it uses the isolated brainflow_signalino module and can coexist with official brainflow.

Windows and Intel Mac

Precompiled brainflow-signalino wheels are not available for these platforms in this release. Keep using the existing Signalino-enabled BrainFlow build from JABarios/brainflow-signalino. The wrapper uses the existing brainflow module on these platforms. Official BrainFlow alone does not yet include board 69; a matching native build is needed.

Optional integrations and examples

python -m pip install 'signalino[viewer]'
python -m pip install 'signalino[lsl]'
python -m pip install 'signalino[mne]'

Examples live in this repository's examples/ directory and are not included in the installed wheel. examples/check_import.py does not connect hardware.

For development, install .[dev,all] and run 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.

Bluetooth Classic

Signalino devices fitted with an HC-06 appear as a serial port after pairing. The example can locate a probable paired port automatically:

python examples/basic_classic_bluetooth.py

The example automatically selects a probable Signalino port. Pass the port as an argument if several paired devices are plausible. On Linux the port is commonly /dev/rfcomm0; on Windows it is a COM port. On macOS the example uses the RFCOMM bridge bundled with Signalino Suite.

Measure the effective rate and detect packet-counter gaps over 30 seconds:

python examples/measure_classic_bluetooth.py

Live viewer

Install the viewer extra and open the eight-channel rolling display:

python -m pip install "matplotlib>=3.9,<4"
python examples/live_viewer.py

Bluetooth Classic is selected by default. Use --transport usb or --transport ble for the other connections. Press Space to pause the display without stopping acquisition, and press Q or Escape to close it.

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 wrapper wheel. The native backend is distributed separately as a platform wheel. Publishing is deliberately not part of the local build process.

License

MIT

Release files for signalino 0.1.3

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.3
File Size Uploaded
signalino-0.1.3.tar.gz 25.1 kB Details

Built distribution (wheel)

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

Total release size:41.8 kB

Release files / signalino-0.1.3.tar.gz

Download URL signalino-0.1.3.tar.gz
Size 25.1 kB
Tags Source
SHA-256 checksum
How to use checksums
d40d34b6150d8bc3d427c617209e5bb2c0d734665d48787c990973bf8ddfd1ff
BLAKE2b-256 checksum
How to use checksums
b56ac2b94f43e02b2a2d80f9bb7abefa298d73ca37326b05678db627cbf9b1e2
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 12, 2026.

Transparency log

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

Download URL signalino-0.1.3-py3-none-any.whl
Size 16.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a2937f6a8acc6da47d8b44ee3d77f785918c8d5b4a7c107cdf0ecae31ccec8ef
BLAKE2b-256 checksum
How to use checksums
0f8070a633a73fb152702d07cb9b9f5ae638b5532dbaf111299e305f6d274ba7
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 12, 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

This release

0.1.3 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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