From 64999d362f05d0ff9f676c13fecc1897106ee635 Mon Sep 17 00:00:00 2001 From: jfrey Date: Fri, 3 Mar 2017 00:28:50 +0100 Subject: [PATCH] Stub for some support of impedance check. --- open_bci_ganglion.py | 15 +++++++++++---- open_bci_v3.py | 15 ++++++++++----- plugin_interface.py | 3 ++- plugins/print.py | 8 ++++++-- plugins/streamer_lsl.py | 23 ++++++++++++++++++----- user.py | 2 +- 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/open_bci_ganglion.py b/open_bci_ganglion.py index 6ed77c4..bfd5380 100644 --- a/open_bci_ganglion.py +++ b/open_bci_ganglion.py @@ -85,6 +85,7 @@ def __init__(self, port=None, baud=0, filter_data=False, # number of EEG channels and (optionally) accelerometer channel self.eeg_channels_per_sample = 4 self.aux_channels_per_sample = 3 + self.imp_channels_per_sample = 0 self.read_state = 0 self.log_packet_count = 0 self.packets_dropped = 0 @@ -220,12 +221,17 @@ def getSampleRate(self): return SAMPLE_RATE def getNbEEGChannels(self): - return self.eeg_channels_per_sample + """Will not get new data on impedance check.""" + return self.eeg_channels_per_sample def getNbAUXChannels(self): """Might not be used depending on the mode.""" return self.aux_channels_per_sample + def getNbImpChannels(self): + """Might not be used depending on the mode.""" + return self.imp_channels_per_sample + def start_streaming(self, callback, lapse=-1): """ Start handling streaming data from the board. Call a provided callback @@ -387,9 +393,10 @@ def reconnect(self): class OpenBCISample(object): """Object encapulsating a single sample from the OpenBCI board.""" def __init__(self, packet_id, channel_data, aux_data): - self.id = packet_id; - self.channel_data = channel_data; - self.aux_data = aux_data; + self.id = packet_id + self.channel_data = channel_data + self.aux_data = aux_data + self.imp_data = [] class GanglionDelegate(DefaultDelegate): diff --git a/open_bci_v3.py b/open_bci_v3.py index f1ed821..e2d563b 100644 --- a/open_bci_v3.py +++ b/open_bci_v3.py @@ -13,7 +13,7 @@ def handle_sample(sample): NOTE: If daisy modules is enabled, the callback will occur every two samples, hence "packet_id" will only contain even numbers. As a side effect, the sampling rate will be divided by 2. FIXME: at the moment we can just force daisy mode, do not check that the module is detected. - +TODO: enable impedance """ import serial @@ -97,6 +97,7 @@ def __init__(self, port=None, baud=115200, filter_data=True, self.scaling_output = scaled_output self.eeg_channels_per_sample = 8 # number of EEG channels per sample *from the board* self.aux_channels_per_sample = 3 # number of AUX channels per sample *from the board* + self.imp_channels_per_sample = 0 # impedance check not supported at the moment self.read_state = 0 self.daisy = daisy self.last_odd_sample = OpenBCISample(-1, [], []) # used for daisy @@ -140,6 +141,9 @@ def getNbEEGChannels(self): def getNbAUXChannels(self): return self.aux_channels_per_sample + def getNbImpChannels(self): + return self.imp_channels_per_sample + def start_streaming(self, callback, lapse=-1): """ Start handling streaming data from the board. Call a provided callback @@ -594,10 +598,11 @@ def find_port(self): return openbci_port class OpenBCISample(object): - """Object encapulsating a single sample from the OpenBCI board.""" + """Object encapulsating a single sample from the OpenBCI board. NB: dummy imp for plugin compatiblity""" def __init__(self, packet_id, channel_data, aux_data): - self.id = packet_id; - self.channel_data = channel_data; - self.aux_data = aux_data; + self.id = packet_id + self.channel_data = channel_data + self.aux_data = aux_data + self.imp_data = [] diff --git a/plugin_interface.py b/plugin_interface.py index c306b33..58623a3 100644 --- a/plugin_interface.py +++ b/plugin_interface.py @@ -22,11 +22,12 @@ class PluginExample(plugintypes.IPluginExtended): class IPluginExtended(IPlugin): # args: passed by command line - def pre_activate(self, args, sample_rate=250, eeg_channels=8, aux_channels=3): + def pre_activate(self, args, sample_rate=250, eeg_channels=8, aux_channels=3, imp_channels=0): self.args = args self.sample_rate = sample_rate self.eeg_channels = eeg_channels self.aux_channels = aux_channels + self.imp_channels = imp_channels # by default we say that activation was okay -- inherited from IPlugin self.is_activated = True self.activate() diff --git a/plugins/print.py b/plugins/print.py index b895d70..4c85b5e 100644 --- a/plugins/print.py +++ b/plugins/print.py @@ -7,7 +7,11 @@ def activate(self): # called with each new sample def __call__(self, sample): if sample: - sample_string = "ID: %f\n%s\n%s" %(sample.id, str(sample.channel_data)[1:-1], str(sample.aux_data)[1:-1]) + # print impedance if supported + if self.imp_channels > 0: + sample_string = "ID: %f\n%s\n%s\%s" %(sample.id, str(sample.channel_data)[1:-1], str(sample.aux_data)[1:-1], str(sample.imp_data)[1:-1]) + else: + sample_string = "ID: %f\n%s\n%s" %(sample.id, str(sample.channel_data)[1:-1], str(sample.aux_data)[1:-1]) print "---------------------------------" print sample_string print "---------------------------------" @@ -19,4 +23,4 @@ def __call__(self, sample): # print "Not a ascii-encoded unicode string" # else: # print sample_string - \ No newline at end of file + diff --git a/plugins/streamer_lsl.py b/plugins/streamer_lsl.py index d8982bb..5a102b7 100644 --- a/plugins/streamer_lsl.py +++ b/plugins/streamer_lsl.py @@ -6,7 +6,7 @@ from pylsl import StreamInfo, StreamOutlet import plugin_interface as plugintypes -# Use LSL protocol to broadcast data using one stream for EEG and one stream for AUX +# Use LSL protocol to broadcast data using one stream for EEG, one stream for AUX, one last for impedance testing (on supported board, if enabled) class StreamerLSL(plugintypes.IPluginExtended): # From IPlugin def activate(self): @@ -14,6 +14,8 @@ def activate(self): eeg_id = "openbci_eeg_id1" aux_stream = "OpenBCI_AUX" aux_id = "openbci_aux_id1" + imp_stream = "OpenBCI_Impedance" + imp_id = "openbci_imp_id1" if len(self.args) > 0: eeg_stream = self.args[0] @@ -23,6 +25,10 @@ def activate(self): aux_stream = self.args[2] if len(self.args) > 3: aux_id = self.args[3] + if len(self.args) > 4: + imp_stream = self.args[4] + if len(self.args) > 5: + imp_id = self.args[5] # Create a new streams info, one for EEG values, one for AUX (eg, accelerometer) values print "Creating LSL stream for EEG. Name:", eeg_stream, "- ID:", eeg_id, "- data type: float32.", self.eeg_channels, "channels at", self.sample_rate, "Hz." @@ -30,16 +36,23 @@ def activate(self): # NB: set float32 instead of int16 so as OpenViBE takes it into account print "Creating LSL stream for AUX. Name:", aux_stream, "- ID:", aux_id, "- data type: float32.", self.aux_channels, "channels at", self.sample_rate, "Hz." info_aux = StreamInfo(aux_stream, 'AUX', self.aux_channels,self.sample_rate,'float32',aux_id); - + # make outlets self.outlet_eeg = StreamOutlet(info_eeg) self.outlet_aux = StreamOutlet(info_aux) - + + if self.imp_channels > 0: + print "Creating LSL stream for Impedance. Name:", imp_stream, "- ID:", imp_id, "- data type: float32.", self.imp_channels, "channels at", self.sample_rate, "Hz." + info_imp = StreamInfo(imp_stream, 'Impedance', self.imp_channels,self.sample_rate,'float32',imp_id); + self.outlet_imp = StreamOutlet(info_imp) + # send channels values def __call__(self, sample): self.outlet_eeg.push_sample(sample.channel_data) self.outlet_aux.push_sample(sample.aux_data) + if self.imp_channels > 0: + self.outlet_imp.push_sample(sample.imp_data) def show_help(self): - print """Optional arguments: [EEG_stream_name [EEG_stream_ID [AUX_stream_name [AUX_stream_ID]]]] - \t Defaults: "OpenBCI_EEG" / "openbci_eeg_id1" and "OpenBCI_AUX" / "openbci_aux_id1".""" + print """Optional arguments: [EEG_stream_name [EEG_stream_ID [AUX_stream_name [AUX_stream_ID [Impedance_steam_name [Impedance_stream_ID]]]]]] + \t Defaults: "OpenBCI_EEG" / "openbci_eeg_id1" and "OpenBCI_AUX" / "openbci_aux_id1" / "OpenBCI_Impedance" / "openbci_imp_id1".""" diff --git a/user.py b/user.py index 7bca1c9..eddda49 100644 --- a/user.py +++ b/user.py @@ -149,7 +149,7 @@ print ("Error: [ " + plug_name + " ] not found or could not be loaded. Check name and requirements.") else: print ("\nActivating [ " + plug_name + " ] plugin...") - if not plug.plugin_object.pre_activate(plug_args, sample_rate=board.getSampleRate(), eeg_channels=board.getNbEEGChannels(), aux_channels=board.getNbAUXChannels()): + if not plug.plugin_object.pre_activate(plug_args, sample_rate=board.getSampleRate(), eeg_channels=board.getNbEEGChannels(), aux_channels=board.getNbAUXChannels(), imp_channels=board.getNbImpChannels()): print ("Error while activating [ " + plug_name + " ], check output for more info.") else: print ("Plugin [ " + plug_name + "] added to the list")