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 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()
device.info / get_auxiliary_data() / clear_auxiliary_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.
Hardware and sensors
Every compatible controller uses the same Signalino/BrainFlow board and EEG API. Sensor inventory is read from the physical unit at connection time:
from signalino import Capability, Sensor
with Signalino.usb() as device:
print(device.info.hardware, device.info.firmware)
print(device.info.sensors, device.info.sensor_source)
if Capability.SD_CARD in device.info.capabilities:
print("microSD supported")
if Sensor.ACCELEROMETER in device.info.sensors:
print("accelerometer available")
Sensor packets have their own buffer and never consume EEG data:
from signalino import AuxiliaryPacketType
device.start_streaming()
auxiliary = device.get_auxiliary_data(clear=False)
acceleration = auxiliary.select(AuxiliaryPacketType.ACCELEROMETER)
print(acceleration.raw_values, acceleration.timestamps)
raw_values contains the three signed AUX words from the original 33-byte
frame. packet_types preserves byte 32: 0xC0 accelerometer, 0xC1
gyroscope, 0xC2 environment, and 0xCF no auxiliary sensor data. Physical
unit conversion remains explicit because calibration can vary between sensor
assemblies.
Run python examples/hardware_and_sensors.py for a complete probe of the
connected unit.
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.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| signalino-0.1.4.tar.gz | 29.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| signalino-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:49.3 kB
Release files / signalino-0.1.4.tar.gz
| Download URL | signalino-0.1.4.tar.gz |
|---|---|
| Size | 29.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e7f2cec48727eb1e202dd28d53ea64f4b23753789549c8046d71e596582ae579
|
|
BLAKE2b-256 checksum How to use checksums |
9c82d408a4147ceaf41425f0c15d1f0891560e3d1fe247ac93c0d3d5f1e2aa70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.12
|
Release files / signalino-0.1.4-py3-none-any.whl
| Download URL | signalino-0.1.4-py3-none-any.whl |
|---|---|
| Size | 19.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2b2c5c8e32f3822529097f3cdc7f45925a7711ca58765b75daea3c33a3b54fd1
|
|
BLAKE2b-256 checksum How to use checksums |
0536ad4ce94f098e5e50147e7de606b36203bb1719a4d9d544f5c918c915553e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.12
|