def main (): parser = argparse.ArgumentParser () parser.add_argument ('--ip-address', type = str, help = 'ip address', required = True) parser.add_argument ('--ip-port', type = int, help = 'ip port', required = True) args = parser.parse_args () BoardShim.enable_dev_board_logger () params = BrainFlowInputParams () params.ip_address = args.ip_address; params.ip_port = args.ip_port; board = BoardShim (BoardIds.GANGLION_WIFI_BOARD.value, params) board.prepare_session () # 5 seconds of resistance data board.config_board ('z') board.start_stream (45000, 'file://raw_data_resistance.csv:w') time.sleep (5) data = board.get_board_data () board.stop_stream () # now get eeg data board.config_board ('Z') board.start_stream (45000, 'file://raw_data_eeg.csv:w') time.sleep (5) data = board.get_board_data () board.stop_stream () board.release_session () print (data)
def main(): BoardShim.enable_dev_board_logger() parser = argparse.ArgumentParser() parser.add_argument('--serial-port', type=str, help='serial port', required=True) args = parser.parse_args() params = BrainFlowInputParams() params.serial_port = args.serial_port board = BoardShim(BoardIds.CYTON_BOARD, params) try: board.prepare_session() resp = board.config_board('?') print(resp) # check that there is a response if streaming is off if not resp: raise ValueError('resp is None') board.start_stream() time.sleep(5) resp = board.config_board('?') print(resp) # check that there is no response if streaming is on if resp: raise ValueError('resp is not None') finally: if board.is_prepared(): board.release_session()
class CytonBoard(object): def __init__(self, file): self.params = BrainFlowInputParams() #self.params.serial_port = serial_port self.params.file = file self.params.other_info = str(BoardIds.CYTON_BOARD.value) self.board = BoardShim(BoardIds.PLAYBACK_FILE_BOARD.value, self.params) def start_stream(self): self.board.prepare_session() #self.board.config_board ('loopback_true') self.board.config_board('old_timestamps') self.board.start_stream() def stop_stream(self): self.board.stop_stream() self.board.release_session() def poll(self, sample_num): try: while self.board.get_board_data_count() < sample_num: time.sleep(0.02) except Exception as e: raise (e) #print(self.board.get_board_data_count()) board_data = self.board.get_board_data() #df = board_2_df(np.transpose(board_data)) return board_data def sampling_frequency(self): sampling_freq = self.board.get_sampling_rate( BoardIds.CYTON_BOARD.value) return sampling_freq
def main (): parser = argparse.ArgumentParser () # use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port parser.add_argument ('--ip-port', type = int, help = 'ip port', required = False, default = 0) parser.add_argument ('--ip-protocol', type = int, help = 'ip protocol, check IpProtocolType enum', required = False, default = 0) parser.add_argument ('--ip-address', type = str, help = 'ip address', required = False, default = '') parser.add_argument ('--serial-port', type = str, help = 'serial port', required = False, default = '') parser.add_argument ('--mac-address', type = str, help = 'mac address', required = False, default = '') parser.add_argument ('--other-info', type = str, help = 'other info', required = False, default = '') parser.add_argument ('--streamer-params', type = str, help = 'other info', required = False, default = '') parser.add_argument ('--board-id', type = int, help = 'board id, check docs to get a list of supported boards', required = True) parser.add_argument ('--log', action = 'store_true') args = parser.parse_args () params = BrainFlowInputParams () params.ip_port = args.ip_port params.serial_port = args.serial_port params.mac_address = args.mac_address params.other_info = args.other_info params.ip_address = args.ip_address params.ip_protocol = args.ip_protocol if (args.log): BoardShim.enable_dev_board_logger () else: BoardShim.disable_board_logger () board = BoardShim (args.board_id, params) board.prepare_session () board.start_stream () print('Session Started') for x in range(2): time.sleep (5) board.config_board ('/2') # enable analog mode only for Cyton Based Boards! time.sleep (5) data = board.get_board_data () board.stop_stream () board.release_session () """ data[BoardShim.get_other_channels(args.board_id)[0]] contains cyton end byte data[BoardShim.get_other_channels(args.board_id)[1....]] contains unprocessed bytes if end byte is 0xC0 there are accel data in data[BoardShim.get_accel_channels(args.board_id)[....]] else there are zeros if end byte is 0xC1 there are analog data in data[BoardShim.get_analog_channels(args.board_id)[....]] else there are zeros """ print (data[BoardShim.get_other_channels(args.board_id)[0]][0:5]) # should be standard end byte 0xC0 print (data[BoardShim.get_other_channels(args.board_id)[0]][-5:]) # should be analog and byte 0xC1 DataFilter.write_file (data, 'cyton_data_new.txt', 'w')
def main (): parser = argparse.ArgumentParser () # use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port parser.add_argument ('--ip-port', type = int, help = 'ip port', required = False, default = 0) parser.add_argument ('--ip-protocol', type = int, help = 'ip protocol, check IpProtocolType enum', required = False, default = 0) parser.add_argument ('--ip-address', type = str, help = 'ip address', required = False, default = '') parser.add_argument ('--serial-port', type = str, help = 'serial port', required = False, default = '') parser.add_argument ('--mac-address', type = str, help = 'mac address', required = False, default = '') parser.add_argument ('--other-info', type = str, help = 'other info', required = False, default = '') parser.add_argument ('--board-id', type = int, help = 'board id, check docs to get a list of supported boards', required = True) parser.add_argument ('--log', action = 'store_true') args = parser.parse_args () params = BrainFlowInputParams () params.ip_port = args.ip_port params.serial_port = args.serial_port params.mac_address = args.mac_address params.other_info = args.other_info params.ip_address = args.ip_address params.ip_protocol = args.ip_protocol if (args.log): BoardShim.enable_dev_board_logger () else: BoardShim.disable_board_logger () board = BoardShim (args.board_id, params) board.prepare_session () # disable 2nd channel for cyton use real board to check it, emulator ignores commands if args.board_id == brainflow.board_shim.BoardIds.CYTON_BOARD.value: board.config_board ('x2100000X') board.start_stream () time.sleep (10) data = board.get_board_data () board.stop_stream () board.release_session () eeg_channels = BoardShim.get_eeg_channels (args.board_id) for count, channel in enumerate (eeg_channels): if count == 0: DataFilter.perform_bandpass (data[channel], BoardShim.get_sampling_rate (args.board_id), 15.0, 6.0, 4, FilterTypes.BESSEL.value, 0) elif count == 1: DataFilter.perform_bandstop (data[channel], BoardShim.get_sampling_rate (args.board_id), 5.0, 1.0, 3, FilterTypes.BUTTERWORTH.value, 0) elif count == 2: DataFilter.perform_lowpass (data[channel], BoardShim.get_sampling_rate (args.board_id), 9.0, 5, FilterTypes.CHEBYSHEV_TYPE_1.value, 1) elif count == 3: DataFilter.perform_highpass (data[channel], BoardShim.get_sampling_rate (args.board_id), 3.0, 4, FilterTypes.BUTTERWORTH.value, 0)
def main(): BoardShim.enable_dev_board_logger() params = BrainFlowInputParams() board = BoardShim(BoardIds.MUSE_S_BOARD, params) board.prepare_session() board.config_board('p61') board.start_stream(45000, 'file://data.csv:w') time.sleep(10) data = board.get_board_data() board.stop_stream() board.release_session() print(data)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--serial-port', type=str, help='serial port', required=True) parser.add_argument('--mac-address', type=str, help='mac address', required=False, default='') args = parser.parse_args() BoardShim.enable_dev_board_logger() params = BrainFlowInputParams() params.serial_port = args.serial_port params.mac_address = args.mac_address board = BoardShim(BoardIds.GANGLION_BOARD.value, params) board.prepare_session() # expected result: 5 seconds of resistance data(unknown sampling rate) after that 5 seconds of exg data board.config_board('z') board.start_stream(45000, 'file://raw_data.csv:w') time.sleep(5) board.config_board('Z') time.sleep(5) data = board.get_board_data() board.stop_stream() board.release_session() print(data) resistance_channels = BoardShim.get_resistance_channels( BoardIds.GANGLION_BOARD.value) print(resistance_channels)
def main(): BoardShim.enable_dev_board_logger() params = BrainFlowInputParams() board = BoardShim(BoardIds.BRAINBIT_BOARD.value, params) board.prepare_session() board.start_stream(45000, 'file://raw_data.csv:w') # its a little tricky and unclear, need to call start_stream to create data acquisition thread(it also sends CommandStartSignal) # after that send CommandStartResist, CommandStopResist and to get EEG data call CommandStartSignal manually board.config_board('CommandStartResist') time.sleep(5) board.config_board('CommandStopResist') board.config_board('CommandStartSignal') time.sleep(5) data = board.get_board_data() board.stop_stream() board.release_session() print(data)
def main(): parser = argparse.ArgumentParser() # use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port parser.add_argument('--ip-port', type=int, help='ip port', required=False, default=0) parser.add_argument('--ip-protocol', type=int, help='ip protocol, check IpProtocolType enum', required=False, default=0) parser.add_argument('--ip-address', type=str, help='ip address', required=False, default='') parser.add_argument('--serial-port', type=str, help='serial port', required=False, default='') parser.add_argument('--mac-address', type=str, help='mac address', required=False, default='') parser.add_argument('--other-info', type=str, help='other info', required=False, default='') parser.add_argument('--streamer-params', type=str, help='other info', required=False, default='') parser.add_argument( '--board-id', type=int, help='board id, check docs to get a list of supported boards', required=True) parser.add_argument('--log', action='store_true') parser.add_argument('--run-time', type=int, help='run time for one iteration in sec', required=True) parser.add_argument('--num-iters', type=int, help='number of iterations', default=1) parser.add_argument( '--channels', type=str, help='channels to plot in format 0,1,2 by default plot all channels', default=None) parser.add_argument('--config-file', type=str, help='file with strings to send to device', default=None) args = parser.parse_args() params = BrainFlowInputParams() params.ip_port = args.ip_port params.serial_port = args.serial_port params.mac_address = args.mac_address params.other_info = args.other_info params.ip_address = args.ip_address params.ip_protocol = args.ip_protocol if (args.log): BoardShim.enable_dev_board_logger() else: BoardShim.disable_board_logger() # for streaming board need to use master board id master_board_id = args.board_id if args.board_id == BoardIds.STREAMING_BOARD.value: master_board_id = int(params.other_info) board = BoardShim(args.board_id, params) board.prepare_session() if args.config_file: with open(args.config_file) as file: lines = file.readlines() for line in lines: board.config_board(line) buffer_size = int( BoardShim.get_sampling_rate(master_board_id) * args.run_time * 1.2) # + 20% for safety if master_board_id in (BoardIds.CYTON_BOARD.value, BoardIds.CYTON_WIFI_BOARD.value, BoardIds.GANGLION_WIFI_BOARD.value): bytes_per_package = 33 elif master_board_id in (BoardIds.CYTON_DAISY_BOARD, BoardIds.CYTON_DAISY_WIFI_BOARD.value): bytes_per_package = 66 elif master_board_id == BoardIds.SYNTHETIC_BOARD.value: bytes_per_package = 104 elif master_board_id == BoardIds.NOVAXR_BOARD.value: bytes_per_package = 72 else: raise ValueError('unsupported board') timestamp_channel = BoardShim.get_timestamp_channel(master_board_id) package_num_channel = BoardShim.get_package_num_channel(master_board_id) try: cur_id = 0 for i in range(args.num_iters): # wait for an input input('Press Enter to continue...') BoardShim.log_message( LogLevels.LEVEL_INFO.value, '\nRunning iteration %d/%d\n' % (i, args.num_iters)) # start stream and get data board.start_stream(buffer_size, args.streamer_params) time.sleep(args.run_time) board.stop_stream() data = board.get_board_data() if data.shape[1] == 0: BoardShim.log_message(LogLevels.LEVEL_WARN.value, '\nNo data received!\n') continue # calculate some metrics total_bytes_received = bytes_per_package * data.shape[1] packages_per_sec = float(data.shape[1]) / float(args.run_time) timestamp_array = data[timestamp_channel] time_diff_array = list() for i in range(0, timestamp_array.size - 1): time_diff_array.append(timestamp_array[i + 1] - timestamp_array[i]) package_num_array = data[package_num_channel] lost_packages = 0 expected = package_num_array[0] while cur_id < package_num_array.size: if expected == 256: expected = 0 if package_num_array[cur_id] != expected: BoardShim.log_message( LogLevels.LEVEL_WARN.value, 'package loss detected: position %d package_num value %d expected value %d' % (cur_id, package_num_array[cur_id], expected)) lost_packages = lost_packages + 1 else: cur_id = cur_id + 1 expected = expected + 1 package_loss = (lost_packages / data.shape[1]) * 100 # provide results for iteration BoardShim.log_message(LogLevels.LEVEL_INFO.value, '\nResults:\n') BoardShim.log_message(LogLevels.LEVEL_INFO.value, 'package loss percent %f' % package_loss) BoardShim.log_message( LogLevels.LEVEL_INFO.value, 'average time delta %f' % statistics.mean(time_diff_array)) BoardShim.log_message( LogLevels.LEVEL_INFO.value, 'std deviation of time delta %f' % statistics.pstdev(time_diff_array)) BoardShim.log_message(LogLevels.LEVEL_INFO.value, 'total packages received %d' % data.shape[1]) BoardShim.log_message(LogLevels.LEVEL_INFO.value, 'packages per sec %f' % packages_per_sec) BoardShim.log_message( LogLevels.LEVEL_INFO.value, 'total bytes received %d' % total_bytes_received) # plot data eeg_channels = BoardShim.get_eeg_channels(master_board_id) emg_channels = BoardShim.get_emg_channels(master_board_id) total_channels = list() if args.channels is not None: selected_channels = [int(x) for x in args.channels.split(',')] temp_channels = eeg_channels for ch in emg_channels: if ch not in temp_channels: temp_channels.append(ch) for i in range(len(temp_channels)): if i in selected_channels: total_channels.append(temp_channels[i]) else: # for cyton/ganglion eeg_channels and emg_channels are the same array because we can not split it # for novaxr its 2 different arrays, join them total_channels = eeg_channels for ch in emg_channels: if ch not in total_channels: total_channels.append(ch) total_channels.append(timestamp_channel) columns = list() for i in range(len(total_channels) - 1): columns.append('channel_%d' % (int(total_channels[i]) - 1)) columns.append('timestamp') df = pd.DataFrame(np.transpose(data)) df.to_csv('all_data_%d.csv' % i) df_to_plot = df[total_channels] df_to_plot.columns = columns df_to_plot.to_csv('selected_data_%d.csv' % i) df_to_plot.plot(subplots=True, x='timestamp', style='.-') plt.show() finally: # release session in the end board.release_session()
def __init__(self, debug=False, display=True, num_channels=None, wifi=True): # make audio stream self.audio_stream = sd.InputStream(device=None, channels=1, samplerate=16000) # make emg stream params = BrainFlowInputParams() if debug: board_id = -1 # synthetic sample_rate = 256 elif not wifi: board_id = BoardIds.CYTON_BOARD.value params.serial_port = '/dev/ttyUSB0' sample_rate = 250 else: board_id = BoardIds.CYTON_WIFI_BOARD.value params.ip_port = 8001 params.ip_address = '192.168.4.1' sample_rate = 1000 self.emg_channels = BoardShim.get_emg_channels(board_id) if num_channels is not None: self.emg_channels = self.emg_channels[:num_channels] board = BoardShim(board_id, params) board.prepare_session() board.config_board('/3') # configure for digital read board.start_stream() self.board = board # config and make data holders audio_multiplier = int(16000 / sample_rate) window = sample_rate * 5 self.audio_data = [] self.emg_data = [] self.button_data = [] self.debug = debug self.previous_sample_number = -1 # plot setup self.display = display if display: plt.ion() fig, (audio_ax, emg_ax) = plt.subplots(2) audio_ax.axis((0, window * audio_multiplier, -1, 1)) emg_ax.axis((0, window, -300, 300)) audio_lines = audio_ax.plot(np.zeros(window * audio_multiplier)) emg_lines = emg_ax.plot(np.zeros((window, len(self.emg_channels)))) for l, c in zip(emg_lines, [ 'grey', 'mediumpurple', 'blue', 'green', 'yellow', 'orange', 'red', 'sienna' ]): l.set_color(c) text = emg_ax.text(50, -250, 'RMS: 0') for ax in (audio_ax, emg_ax): ax.set_yticks([0]) ax.yaxis.grid(True) ax.tick_params(bottom=False, top=False, labelbottom=False, right=False, left=False, labelleft=False) fig.tight_layout(pad=0) def update_plot(frame): """ This is called by matplotlib for each plot update. """ audio_to_plot = get_last_sequence(self.audio_data, window * audio_multiplier, 1, False, sample_rate) audio_to_plot = audio_to_plot.squeeze(1) audio_lines[0].set_ydata(audio_to_plot) emg_to_plot = get_last_sequence(self.emg_data, window, len(self.emg_channels), True, sample_rate) for column, line in enumerate(emg_lines): line.set_ydata(emg_to_plot[:, column]) text.set_text('RMS: ' + str(emg_to_plot[-sample_rate * 2:-sample_rate // 2].std())) return audio_lines + emg_lines self.ani = FuncAnimation(fig, update_plot, interval=30)
def main(): parser = argparse.ArgumentParser() # use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port parser.add_argument('--ip-port', type=int, help='ip port', required=False, default=0) parser.add_argument('--ip-protocol', type=int, help='ip protocol, check IpProtocolType enum', required=False, default=0) parser.add_argument('--ip-address', type=str, help='ip address', required=False, default='') parser.add_argument('--serial-port', type=str, help='serial port', required=False, default='') parser.add_argument('--mac-address', type=str, help='mac address', required=False, default='') parser.add_argument('--other-info', type=str, help='other info', required=False, default='') parser.add_argument( '--board-id', type=int, help='board id, check docs to get a list of supported boards', required=True) parser.add_argument('--log', action='store_true') args = parser.parse_args() # in fact it can be CytonDaisy or Wifi Shield based boards, limit it to only Cyton in demo if args.board_id != BoardIds.CYTON_BOARD.value: raise ValueError('wrong board id, should be Cyton') params = BrainFlowInputParams() params.ip_port = args.ip_port params.serial_port = args.serial_port params.mac_address = args.mac_address params.other_info = args.other_info params.ip_address = args.ip_address params.ip_protocol = args.ip_protocol if (args.log): BoardShim.enable_dev_board_logger() else: BoardShim.disable_board_logger() board = BoardShim(args.board_id, params) board.prepare_session() board.config_board('/2') # enable analog mode only for Cyton Based Boards! board.start_stream() time.sleep(10) data = board.get_board_data() board.stop_stream() board.release_session() other_channels = BoardShim.get_other_channels(args.board_id) accel_channels = BoardShim.get_accel_channels(args.board_id) analog_channels = BoardShim.get_analog_channels(args.board_id) """ data format for cyton with analog and accel data, data[get_other_channels(board_id)[0]] contains cyton end byte if end byte is 0xC0 there are accel data in data[get_accel_channels(board_id)[....]] else there are zeros if end byte is 0xC1 there are analog data in data[get_analog_channels(board_id)[....]] else there are zeros """ if not other_channels: raise ValueError('no cyton end byte foud') print('end bytes for first 20 packages:') print(data[other_channels[0]][0:20]) # we send /2 to enable analog mode so here we will see zeroes print('accel data for first 20 packages:') for count, channel in enumerate(accel_channels): print(data[channel][0:20]) # analog data are in int32 format but we return single array fron low level api so it was casted to double wo any changes print('analog data for first 20 packages:') for count, channel in enumerate(analog_channels): print(data[channel][0:20])
def main(): parser = argparse.ArgumentParser() # use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port parser.add_argument('--ip-port', type=int, help='ip port', required=False, default=0) parser.add_argument('--ip-protocol', type=int, help='ip protocol, check IpProtocolType enum', required=False, default=0) parser.add_argument('--ip-address', type=str, help='ip address', required=False, default='') parser.add_argument('--serial-port', type=str, help='serial port', required=False, default='') parser.add_argument('--mac-address', type=str, help='mac address', required=False, default='') parser.add_argument('--other-info', type=str, help='other info', required=False, default='') parser.add_argument( '--board-id', type=int, help='board id, check docs to get a list of supported boards', required=True) parser.add_argument('--log', action='store_true') args = parser.parse_args() params = BrainFlowInputParams() params.ip_port = args.ip_port params.serial_port = args.serial_port params.mac_address = args.mac_address params.other_info = args.other_info params.ip_address = args.ip_address params.ip_protocol = args.ip_protocol if (args.log): BoardShim.enable_dev_board_logger() else: BoardShim.disable_board_logger() board = BoardShim(args.board_id, params) board.prepare_session() # disable 2nd channel for cyton use real board to check it, emulator ignores commands if args.board_id == brainflow.board_shim.BoardIds.CYTON_BOARD.value: board.config_board('x2100000X') board.start_stream() time.sleep(10) data = board.get_board_data() board.stop_stream() board.release_session() print(data)
def main (): params = BrainFlowInputParams () params.board_id = 1 board_id = 1 params.serial_port = 'COM3' sampling_rate = BoardShim.get_sampling_rate (board_id) time_thres = 100 max_val = -100000000000 vals_mean = 0 num_samples = 5000 samples = 0 BoardShim.enable_dev_board_logger () board = BoardShim (board_id, params) board.prepare_session () if board_id == brainflow.board_shim.BoardIds.GANGLION_BOARD.value: board.config_board ('x1060000X') board.start_stream (45000) print("starting calibration") time.sleep(5) data = board.get_board_data() print("start blinking") while(samples < num_samples): data = board.get_board_data() if(len(data[1]) > 0): DataFilter.perform_rolling_filter (data[1], 2, AggOperations.MEAN.value) vals_mean += sum([data[1,i]/num_samples for i in range(len(data[1]))]) samples += len(data[1]) if(np.amax(data[1]) > max_val): max_val = np.amax(data[1]) blink_thres = 0.5*((max_val - vals_mean)**2) print("mean value") print(vals_mean) print("max value") print(max_val) print("threshold") print(blink_thres) print("CALIBRATION DONE START PLAYING") prev_time = int(round(time.time() * 1000)) while True: data = board.get_board_data() if(len(data[1]) > 0): DataFilter.perform_rolling_filter (data[1], 2, AggOperations.MEAN.value) if((int(round(time.time() * 1000)) - time_thres) > prev_time): prev_time = int(round(time.time() * 1000)) for element in data[1]: if(((element - vals_mean)**2) >= blink_thres): pydirectinput.press('space') break board.stop_stream () board.release_session ()
def main(argv): '''Takes args and initiates streaming''' if argv: # manage settings read form a yaml file if argv[0] == '--set': file_settings = argv[1] data = read_settings(file_settings) if not data: print('The end') sys.exit() args, arduino, chan_commands = manage_settings_data(data) else: print(CRED + "Use --set *.yml to load settings" + CEND, "\nThe end", sep='') sys.exit() # debug / check data from settings #print(f"args:\n{args}\narduino:\n{arduino}\ncommands:\n{chan_commands}\n") # open serial port for external triggers (arduino/serial) ser = None if arduino: print("Connecting to serial port...") try: ser = serial.Serial(arduino["serial_port"], arduino['baud'], write_timeout=0) time.sleep(3) # minimum 2 sec to wake device up! except (serial.SerialException, ValueError) as err: print(CRED + f"Error: {err}" + CEND) if ser: ser_data = ser.readline().decode( 'utf-8', errors='ignore').strip().split(",") ser.write("a".encode()) # message for arduino to give "on" sound time.sleep( 0.5) # must be longer than time of "on" sound from arduino print(100 * '-') print( CGREEN + f'Established serial connection to Arduino on port: {arduino["serial_port"]} as {arduino["name"]}' + CEND + f"\nMessage from board: {ser_data[0]}, reading sensor at {ser_data[1]} Hz" ) ping_time = ping( ser, 10) # estimate mean ping time between pc and arduino # LSL external outlet (stream form arduino/serial) configuration and initialization if ser: marker_delay = arduino.get( 'delay', 0) + ping_time / 2 # half the two way transfer time info = StreamInfo(name=arduino['name'], type=arduino['type'], channel_count=arduino['channel_count'], channel_format=arduino['channel_format'], source_id=arduino['source_id']) outlet_ext = StreamOutlet(info) print(50 * '-') print(CGREEN + f'LSL Stream: {info.name()} initialized' + CEND) user_choice("Initiate? 'y' -> yes, 'q' -> quit\n--> ", serial=ser) BoardShim.enable_dev_board_logger() # brainflow initialization params = BrainFlowInputParams() params.serial_port = args['serial_port'] params.ip_address = args['ip_address'] board = BoardShim(args['board_id'], params) # LSL internal outlet (stream form board) configuration and initialization channel_names = {} n_channels = {} srate = {} info = {} outlet_int = {} fw_delay = {} for type in args['data_type']: channel_names[type] = args['channel_names'][type].split(',') n_channels[type] = len(channel_names[type]) srate[type] = board.get_sampling_rate(args['board_id']) name = args['name'] + "_" + type uid = args['uid'] + "_" + type info[type] = StreamInfo(name, type, n_channels[type], srate[type], 'double64', uid) # add channel labels chans = info[type].desc().append_child("channels") for label in channel_names[type]: chan = chans.append_child("channel") chan.append_child_value("label", label) outlet_int[type] = StreamOutlet(info[type]) fw_delay[type] = args['delay'] # prepare session; exit if board is not ready try: board.prepare_session() except brainflow.board_shim.BrainFlowError as e: print(CRED + f"Error: {e}" + CEND) if ser: ser.write("c".encode()) # message for arduino to stop streaming time.sleep(1) ser.close() print("The end") time.sleep(1) sys.exit() # remove daisy if attached, when using only Cyton if (args['board_id'] == 0) and (args['daisy_attached']): res_query = board.config_board("c") time.sleep(0.5) print(f"Response to query register settings:\n{res_query}") # wait until user accepts user_choice("Send commands to board? 'y' -> yes, 'q' -> quit\n--> ", board=board, serial=ser) # iterate over channel commands, send one and wait for a response from board # to restore default channel settings 'd' can be sent for chan, command in chan_commands.items(): res_string = board.config_board(command) time.sleep(0.1) if res_string.find('Success') != -1: res = CGREEN + res_string + CEND else: res = CRED + res_string + CEND print(f"Response from {chan}: {res}") # show stream configuration and wait until user accepts or quits print(50 * "-") for type in args['data_type']: print( f"{type}:\nNumber of channels: {n_channels[type]}\nSampling rate: {srate[type]}\n" f"Time limit: {args['max_time'] // 60} min. {args['max_time'] % 60} sec.\n" ) user_choice("Start streaming? 'y' -> yes, 'q' -> quit\n--> ", board=board, serial=ser) # board starts streaming board.start_stream(45000, args['streamer_params']) time.sleep(1) # define threads which will collect continuous data (e.g. EEG) and markers (if arduino/serial is set up) thread_cont = threading.Thread( target=collect_cont, args=[board, args, srate, outlet_int, fw_delay]) thread_cont.start() if ser: thread_markers = threading.Thread(target=collect_markers, args=[ser, outlet_ext, marker_delay]) thread_markers.start() # wait for stop message from user while running data collecting threads time.sleep(2) user_choice("To stop streaming and quit press 'q' + ENTER\n--> ", board=board, serial=ser, thread_initiated=True)