Skip to content

EEG Triggering via stim channels#158

Open
tab-cmd wants to merge 1 commit into
kirtonBCIlab:mainfrom
tab-cmd:serialportIntegration
Open

EEG Triggering via stim channels#158
tab-cmd wants to merge 1 commit into
kirtonBCIlab:mainfrom
tab-cmd:serialportIntegration

Conversation

@tab-cmd

@tab-cmd tab-cmd commented Mar 16, 2026

Copy link
Copy Markdown

Overview

Adds support for reading BCI markers from an EEG stim channel as an alternative to LSL marker streams. This enables a hardware trigger box workflow where Unity sends trigger bytes over serial, the trigger box injects them into the EEG amplifier's stim channel, and Python extracts them from the LSL EEG stream.

See the related Unity PR for more details.

PR Checklist

  • make lint passes (black + flake8)
  • make test passes (all 164 tests)
  • triggers.py constants match Unity's SerialTriggerWriter defaults (240–245 for status, 1–N for stimuli)
  • Trigger map builder output matches what each paradigm's process_markers expects
  • LslStimMarkerSource returns the same ([[marker]], [timestamp]) format as LslMarkerSource
  • EegStimTriggerMarkerSource properly delegates all EegSource properties
  • No changes to existing behavior. BciController works identically with either marker source
  • Examples run without error (hardware not required for trigger_stim_example.py)

Files Changed

File Status Description
bci_essentials/triggers.py Added MarkerTypes, TriggerByte, TriggerDetector, trigger map builders
bci_essentials/io/lsl_stim_marker_source.py Added LslStimMarkerSource. Online use, opens own LSL inlet
bci_essentials/io/eeg_trigger_sources.py Added EegStimTriggerMarkerSource. Wraps any EegSource, for testing/offline
bci_essentials/io/fake_stim_source.py Added FakeStimEegSource. Synthetic EEG (0 values) with programmable stim channel
tests/test_triggers.py Added 49 tests: constants, trigger maps, TriggerDetector, end-to-end
tests/test_eeg_trigger_sources.py Added 54 tests: construction, rise/change detection, toggle, edge cases
examples/trigger_stim_example.py Added Standalone demo
examples/p300_trigger_stim_backend.py Added P300 backend using stim triggers
bci_essentials/bci_controller.py Modified Imports MarkerTypes from triggers.py
bci_essentials/paradigm/paradigm.py Modified Imports resting state markers from triggers.py
bci_essentials/io/__init__.py Modified Re-exports new classes
README.md Modified Serial trigger docs, development section
Makefile Added install, dev-install, test, lint, format targets
pyproject.toml Modified Added pyserial dependency
.flake8, .gitignore Modified Minor updates

Testing

make dev-install       # install package + black/flake8
make test              # run all tests (python -m unittest)
make lint              # black --check + flake8

AI disclosure

The code and text in this pull request were written by a human developer, with AI tools used for drafting and editing. The AI was used as a writing and development aid, not as the source of technical content. I reviewed and edited all AI generated work to ensure accuracy and coherence with the bci-essentials-python package. All tests were done manually to confirm the working implementation of the serial feature in python.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant