1818from muselsl import stream , list_muses , record , constants as mlsl_cnsts
1919from pylsl import StreamInfo , StreamOutlet , StreamInlet , resolve_byprop
2020
21+ from serial import Serial , EIGHTBITS , PARITY_NONE , STOPBITS_ONE
22+
2123from eegnb .devices .utils import (
2224 get_openbci_usb ,
2325 create_stim_array ,
@@ -108,6 +110,9 @@ def initialize_backend(self):
108110 self ._muse_get_recent ()
109111 elif self .backend == "kernelflow" :
110112 self ._init_kf ()
113+ elif self .backend == "serialport" :
114+ self ._init_serial ()
115+
111116
112117 def _get_backend (self , device_name ):
113118 if device_name in brainflow_devices :
@@ -116,6 +121,8 @@ def _get_backend(self, device_name):
116121 return "muselsl"
117122 elif device_name in ["kernelflow" ]:
118123 return "kernelflow"
124+ elif device_name in ["biosemi" ]:
125+ return "serialport"
119126
120127
121128 #####################
@@ -554,7 +561,51 @@ def _kf_sendeventinfo(self, event_info):
554561 event_info_pack = json .dumps (event_info ).encode ("utf-8" )
555562 msg = struct .pack ("!I" , len (event_info_pack )) + event_info_pack
556563 self .kf_socket .sendall (msg )
557-
564+
565+
566+
567+ ###########################
568+ # Serial Port Function #
569+ ###########################
570+
571+
572+ def _init_serial (self ):
573+ if self .serial_port : # if a port name is supplied, open a serial port.
574+ self .serial = self ._serial_open_port (PORT_ID = self .serial_port )
575+ # (otherwise, don't open; assuming serial obj will be
576+ # manually added)
577+
578+
579+ def _serial_push_sample (self , marker , clearandflush = True , pulse_ms = 5 ):
580+
581+ if not (0 <= marker <= 255 ): raise ValueError ("marker code must be 045255" )
582+ self .serial .write (bytes ([marker ]))
583+ if clearandflush :
584+ self .serial .flush () # push immediately
585+ sleep (pulse_ms / 1000.0 )
586+ self .serial .write (b"\x00 " ) # clear back to zero
587+ self .serial .flush ()
588+
589+
590+ def _serial_open_port (self ,PORT_ID = "COM4" , BAUD = 115200 ):
591+ """
592+ PORT_ID = "COM4" # Example of a stimulus delivery computer USB out port name
593+ # on windows it should be sth like # PORT_ID = "COM4"
594+ # on linux it should be sth like # PORT_ID = "/dev/ttyUSB0"
595+ # on macOS it should be sth like # PORT_ID = "/dev/tty.usbserial-XXXX"
596+ BAUD = 115200 # -> This matches BioSemi ActiView's serial settings
597+ """
598+ my_serial = Serial (PORT_ID , BAUD , bytesize = EIGHTBITS , parity = PARITY_NONE ,
599+ stopbits = STOPBITS_ONE , timeout = 0 , write_timeout = 0 )
600+
601+ print ("\n Opened Serial Port %s\n " % PORT_ID )
602+
603+ return my_serial
604+
605+
606+
607+
608+
558609
559610 #################################
560611 # Highlevel device functions #
@@ -576,6 +627,9 @@ def start(self, fn, duration=None):
576627 self ._start_muse (duration )
577628 elif self .backend == "kernelflow" :
578629 self ._start_kf ()
630+ elif self .backend == "serialport" :
631+ pass
632+
579633
580634 def push_sample (self , marker , timestamp , marker_name = None ):
581635 """
@@ -591,6 +645,9 @@ def push_sample(self, marker, timestamp, marker_name=None):
591645 self ._muse_push_sample (marker = marker , timestamp = timestamp )
592646 elif self .backend == "kernelflow" :
593647 self ._kf_push_sample (marker = marker ,timestamp = timestamp , marker_name = marker_name )
648+ elif self .backend == "serialport" :
649+ self ._serial_push_sample (marker = marker )
650+
594651
595652 def stop (self ):
596653 if self .backend == "brainflow" :
0 commit comments