Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion eegnb/devices/eeg.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from muselsl import stream, list_muses, record, constants as mlsl_cnsts
from pylsl import StreamInfo, StreamOutlet, StreamInlet, resolve_byprop

from serial import Serial, EIGHTBITS, PARITY_NONE, STOPBITS_ONE

from eegnb.devices.utils import (
get_openbci_usb,
create_stim_array,
Expand Down Expand Up @@ -108,6 +110,9 @@ def initialize_backend(self):
self._muse_get_recent()
elif self.backend == "kernelflow":
self._init_kf()
elif self.backend == "serialport":
self._init_serial()


def _get_backend(self, device_name):
if device_name in brainflow_devices:
Expand All @@ -116,6 +121,8 @@ def _get_backend(self, device_name):
return "muselsl"
elif device_name in ["kernelflow"]:
return "kernelflow"
elif device_name in ["biosemi"]:
return "serialport"


#####################
Expand Down Expand Up @@ -554,7 +561,51 @@ def _kf_sendeventinfo(self, event_info):
event_info_pack = json.dumps(event_info).encode("utf-8")
msg = struct.pack("!I", len(event_info_pack)) + event_info_pack
self.kf_socket.sendall(msg)




###########################
# Serial Port Function #
###########################


def _init_serial(self):
if self.serial_port: # if a port name is supplied, open a serial port.
self.serial = self._serial_open_port(PORT_ID=self.serial_port)
# (otherwise, don't open; assuming serial obj will be
# manually added)


def _serial_push_sample(self, marker, clearandflush=True, pulse_ms=5):

if not (0 <= marker <= 255): raise ValueError("marker code must be 045255")
self.serial.write(bytes([marker]))
if clearandflush:
self.serial.flush() # push immediately
sleep(pulse_ms / 1000.0)
self.serial.write(b"\x00") # clear back to zero
self.serial.flush()


def _serial_open_port(self,PORT_ID="COM4", BAUD=115200):
"""
PORT_ID = "COM4" # Example of a stimulus delivery computer USB out port name
# on windows it should be sth like # PORT_ID = "COM4"
# on linux it should be sth like # PORT_ID = "/dev/ttyUSB0"
# on macOS it should be sth like # PORT_ID = "/dev/tty.usbserial-XXXX"
BAUD = 115200 # -> This matches BioSemi ActiView's serial settings
"""
my_serial = Serial(PORT_ID, BAUD, bytesize=EIGHTBITS, parity=PARITY_NONE,
stopbits=STOPBITS_ONE, timeout=0, write_timeout=0)

print("\nOpened Serial Port %s\n" %PORT_ID)

return my_serial






#################################
# Highlevel device functions #
Expand All @@ -576,6 +627,9 @@ def start(self, fn, duration=None):
self._start_muse(duration)
elif self.backend == "kernelflow":
self._start_kf()
elif self.backend == "serialport":
pass


def push_sample(self, marker, timestamp, marker_name=None):
"""
Expand All @@ -591,6 +645,9 @@ def push_sample(self, marker, timestamp, marker_name=None):
self._muse_push_sample(marker=marker, timestamp=timestamp)
elif self.backend == "kernelflow":
self._kf_push_sample(marker=marker,timestamp=timestamp, marker_name=marker_name)
elif self.backend == "serialport":
self._serial_push_sample(marker=marker)


def stop(self):
if self.backend == "brainflow":
Expand Down
5 changes: 4 additions & 1 deletion eegnb/devices/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"notion2": BoardShim.get_eeg_names(BoardIds.NOTION_2_BOARD.value),
"crown": BoardShim.get_eeg_names(BoardIds.CROWN_BOARD.value),
"freeeeg32": [f"eeg_{i}" for i in range(0, 32)],
"kernelflow": []
"kernelflow": [],
"biosemi": [],
}

BRAINFLOW_CHANNELS = {
Expand Down Expand Up @@ -58,6 +59,7 @@
"crown": BoardShim.get_eeg_channels(BoardIds.CROWN_BOARD.value),
"freeeeg32": BoardShim.get_eeg_channels(BoardIds.FREEEEG32_BOARD.value),
"kernelflow": [],
"biosemi": [],
}

SAMPLE_FREQS = {
Expand All @@ -81,6 +83,7 @@
"crown": BoardShim.get_sampling_rate(BoardIds.CROWN_BOARD.value),
"freeeeg32": BoardShim.get_sampling_rate(BoardIds.FREEEEG32_BOARD.value),
"kernelflow": [],
"biosemi": [],
}


Expand Down
13 changes: 6 additions & 7 deletions eegnb/experiments/Experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ def setup(self, instructions=True):

# Checking for EEG to setup the EEG stream
if self.eeg:
# If no save_fn passed, generate a new unnamed save file
if self.save_fn is None:
# If no save_fn passed, and data is being streamed, generate a new unnamed save file
if self.save_fn is None and self.eeg.backend not in ['serialport', 'kernelflow']:
# Generating a random int for the filename
random_id = random.randint(1000,10000)
# Generating save function
Expand Down Expand Up @@ -316,13 +316,12 @@ def run(self, instructions=True):
# Setup the experiment
self.setup(instructions)

print("Wait for the EEG-stream to start...")

# Start EEG Stream, wait for signal to settle, and then pull timestamp for start point
if self.eeg:
self.eeg.start(self.save_fn, duration=self.record_duration + 5)

print("EEG Stream started")
if self.eeg.backend not in ['serialport']:
print("Wait for the EEG-stream to start...")
self.eeg.start(self.save_fn, duration=self.record_duration + 5)
print("EEG Stream started")

# Record experiment until a key is pressed or duration has expired.
record_start_time = time()
Expand Down
Loading