A bridge between Hasomed ScienceMode 4 stimulation/measurement devices and Lab Streaming Layer (LSL), allowing experiment-control software such as PsychoPy to trigger electrical stimulation and receive measurement data over the network in real time.
It wraps the science_mode_4 Python package to talk to a P24 (stimulator) or I24 (Dyscom measurement) device over a serial port, and exposes that device to the outside world purely through two LSL streams. Any LSL-aware application can therefore drive the device and consume its data without needing to know anything about the ScienceMode protocol itself.
The core script, science_mode_lsl.py, runs an asyncio event loop that:
- Connects to a ScienceMode device (P24 or I24) over a serial ("COM") port. If no port is given, it auto-detects the first available ScienceMode device.
- Resolves an input LSL stream (default name
ScienceMode-Control) used to receive text commands. - Creates an output LSL stream (default name
ScienceMode-Measurement-Data) used to publish measurement samples coming from the device. - Loops continuously: pulling commands from the control stream and forwarding them to the device, while pushing any measurement data produced by the device onto the measurement stream.
Device-specific behavior lives in small wrapper classes:
- sm4_device.py —
ScienceModeDevice, the common base class. Handles the serial connection and the genericSTART/STOPcommands. - p24_device.py —
P24Device, for stimulation. AddsSTIM_1andSTIM_2commands that send two example stimulation channel configurations (pulse patterns) to the device, and reports back stimulation measurement samples. - i24_device.py —
I24Device, for Dyscom measurement. Starts an EMG measurement onSTARTand streams live samples pulled from the device's packet buffer.
Each device class implements handle_command() (to react to an incoming LSL control message), get_measurement_data() (to produce outgoing samples), and get_available_commands() (to advertise which commands it understands).
| Argument | Description | Default |
|---|---|---|
--sciencemode_device |
Device type: P24 or I24 |
P24 |
--sciencemode_device_port |
Serial port of the device (e.g. COM3); auto-detected if omitted |
None |
--lsl_control_stream_name |
Name of the LSL stream to read commands from | ScienceMode-Control |
--lsl_measurement_stream_name |
Name of the LSL stream to publish measurement data to | ScienceMode-Measurement-Data |
Example:
python science_mode_lsl.py --sciencemode_device P24 --sciencemode_device_port COM3PsychoPy is not aware of the ScienceMode device or protocol at all — it only ever talks LSL, using the pylsl package (bundled with recent PsychoPy versions, or installable separately). The included psychopy_example.psyexp experiment shows the pattern:
-
A PsychoPy Code Component creates a
StreamOutletonce at the start of the experiment:from pylsl import StreamInfo, StreamOutlet info = StreamInfo( name='ScienceMode-Control', type='Markers', channel_count=1, nominal_srate=0, # irregular rate, markers arrive sporadically channel_format='string', source_id='psychopy_marker_stream_001' ) outlet = StreamOutlet(info)
The stream name (
ScienceMode-Control) must match the--lsl_control_stream_nameargument passed toscience_mode_lsl.pyso that the script'sresolve_bypropcall finds it. -
At the appropriate points in the experiment timeline (routine start/end, button presses, etc.), the Code Component pushes single-word string commands onto that outlet, e.g.:
outlet.push_sample(['START']) ... outlet.push_sample(['STOP']) outlet.push_sample(['STIM_1']) # P24 only outlet.push_sample(['STIM_2']) # P24 only
science_mode_lsl.pypulls these samples from itsStreamInletand forwards them todevice.handle_command(), which starts/stops the measurement or triggers a stimulation pattern accordingly. -
Optionally, a PsychoPy component can create a matching
StreamInletforScienceMode-Measurement-Datato record incoming stimulation/measurement samples alongside the rest of the experiment data.
Because the coupling is entirely through LSL, PsychoPy and science_mode_lsl.py can run as separate processes — even on separate machines on the same network — and any other LSL-capable tool (e.g. LabRecorder, or a custom LSL client) can observe the same streams for synchronized recording.
pip install -r requirements.txtDependencies: pylsl and science_mode_4.
- see file psychopy_example.psyexp