diff --git a/open_bci_v3.py b/open_bci_v3.py index 013cb58..3925474 100644 --- a/open_bci_v3.py +++ b/open_bci_v3.py @@ -30,11 +30,12 @@ def handle_sample(sample): SAMPLE_RATE = 250.0 # Hz START_BYTE = 0xA0 # start of data packet -END_BYTE = 0xC0 # end of data packet +END_BYTE_ACCEL = 0xC0 # end of data packet with accel data +END_BYTE_AUX = 0xC1 # end of data packet with aux data ADS1299_Vref = 4.5 #reference voltage for ADC in ADS1299. set by its hardware ADS1299_gain = 24.0 #assumed gain setting for ADS1299. set by its Arduino code scale_fac_uVolts_per_count = ADS1299_Vref/float((pow(2,23)-1))/ADS1299_gain*1000000. -scale_fac_accel_G_per_count = 0.002 /(pow(2,4)) #assume set to +/4G, so 2 mG +scale_fac_accel_G_per_count = 0.002 /(pow(2,4)) #assume set to +/4G, so 2 mG ''' #Commands for in SDK http://docs.openbci.com/software/01-Open BCI_SDK: @@ -68,7 +69,7 @@ class OpenBCIBoard(object): """ def __init__(self, port=None, baud=115200, filter_data=True, - scaled_output=True, daisy=False, aux=False, impedance=False, log=True, timeout=None): + scaled_output=True, scaled_accel=True, daisy=False, aux=False, impedance=False, log=True, timeout=None): self.log = log # print_incoming_text needs log self.streaming = False self.baudrate = baud @@ -94,6 +95,7 @@ def __init__(self, port=None, baud=115200, filter_data=True, self.streaming = False self.filtering_data = filter_data self.scaling_output = scaled_output + self.scaling_aux = scaled_accel 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 @@ -112,35 +114,35 @@ def __init__(self, port=None, baud=115200, filter_data=True, def getBoardType(self): """ Returns the version of the board """ return self.board_type - + def setImpedance(self, flag): """ Enable/disable impedance measure. Not implemented at the moment on Cyton. """ return - + def ser_write(self, b): - """Access serial port object for write""" + """Access serial port object for write""" self.ser.write(b) def ser_read(self): - """Access serial port object for read""" + """Access serial port object for read""" return self.ser.read() def ser_inWaiting(self): - """Access serial port object for inWaiting""" + """Access serial port object for inWaiting""" return self.ser.inWaiting(); - + def getSampleRate(self): if self.daisy: return SAMPLE_RATE/2 else: return SAMPLE_RATE - + def getNbEEGChannels(self): if self.daisy: return self.eeg_channels_per_sample*2 else: return self.eeg_channels_per_sample - + def getNbAUXChannels(self): return self.aux_channels_per_sample @@ -165,7 +167,7 @@ def start_streaming(self, callback, lapse=-1): # Enclose callback funtion in a list if it comes alone if not isinstance(callback, list): callback = [callback] - + #Initialize check connection self.check_connection() @@ -189,13 +191,13 @@ def start_streaming(self, callback, lapse=-1): else: for call in callback: call(sample) - + if(lapse > 0 and timeit.default_timer() - start_time > lapse): self.stop(); if self.log: self.log_packet_count = self.log_packet_count + 1; - - + + """ PARSER: Parses incoming data packet into OpenBCISample. @@ -220,9 +222,9 @@ def read(n): #---------Start Byte & ID--------- if self.read_state == 0: - + b = read(1) - + if struct.unpack('B', b)[0] == START_BYTE: if(rep != 0): self.warn('Skipped %d bytes before start found' %(rep)) @@ -245,7 +247,7 @@ def read(n): #3byte int in 2s compliment if (unpacked[0] > 127): - pre_fix = bytes(bytearray.fromhex('FF')) + pre_fix = bytes(bytearray.fromhex('FF')) else: pre_fix = bytes(bytearray.fromhex('00')) @@ -271,10 +273,10 @@ def read(n): acc = struct.unpack('>h', read(2))[0] log_bytes_in = log_bytes_in + '|' + str(acc); - if self.scaling_output: + if self.scaling_aux: aux_data.append(acc*scale_fac_accel_G_per_count) else: - aux_data.append(acc) + aux_data.append(acc) self.read_state = 3; #---------End Byte--------- @@ -282,16 +284,24 @@ def read(n): val = struct.unpack('B', read(1))[0] log_bytes_in = log_bytes_in + '|' + str(val); self.read_state = 0 #read next packet - if (val == END_BYTE): + if (val == END_BYTE_ACCEL): + if not self.scaling_aux: + self.scaling_aux = True + sample = OpenBCISample(packet_id, channel_data, aux_data) + self.packets_dropped = 0 + return sample + elif (val == END_BYTE_AUX): + if self.scaling_aux: + self.scaling_aux = False sample = OpenBCISample(packet_id, channel_data, aux_data) self.packets_dropped = 0 return sample else: - self.warn("ID:<%d> instead of <%s>" - %(packet_id, val, END_BYTE)) + self.warn("ID:<%d> instead of <%s> or <%s>" + %(packet_id, val, END_BYTE_ACCEL, END_BYTE_AUX)) logging.debug(log_bytes_in); self.packets_dropped = self.packets_dropped + 1 - + """ Clean Up (atexit) @@ -311,7 +321,7 @@ def disconnect(self): print("Closing Serial...") self.ser.close() logging.warning('serial closed') - + """ @@ -338,7 +348,7 @@ def print_incoming_text(self): line = '' #Wait for device to send data time.sleep(1) - + if self.ser.inWaiting(): line = '' c = '' @@ -359,7 +369,7 @@ def openbci_id(self, serial): line = '' #Wait for device to send data time.sleep(2) - + if serial.inWaiting(): line = '' c = '' @@ -390,7 +400,7 @@ def print_bytes_in(self): def print_packets_in(self): while self.streaming: b = struct.unpack('B', self.ser.read())[0]; - + if b == START_BYTE: self.attempt_reconnect = False if skipped_str: @@ -400,7 +410,7 @@ def print_packets_in(self): packet_str = "%03d"%(b) + '|'; b = struct.unpack('B', self.ser.read())[0]; packet_str = packet_str + "%03d"%(b) + '|'; - + #data channels for i in range(24-1): b = struct.unpack('B', self.ser.read())[0]; @@ -413,29 +423,29 @@ def print_packets_in(self): for i in range(6-1): b = struct.unpack('B', self.ser.read())[0]; packet_str = packet_str + '.' + "%03d"%(b); - + b = struct.unpack('B', self.ser.read())[0]; packet_str = packet_str + '.' + "%03d"%(b) + '|'; #end byte b = struct.unpack('B', self.ser.read())[0]; - + #Valid Packet - if b == END_BYTE: + if b == END_BYTE_ACCEL or b == END_BYTE_AUX: packet_str = packet_str + '.' + "%03d"%(b) + '|VAL'; print(packet_str) #logging.debug(packet_str) - + #Invalid Packet else: packet_str = packet_str + '.' + "%03d"%(b) + '|INV'; #Reset self.attempt_reconnect = True - - + + else: print(b) - if b == END_BYTE: + if b == END_BYTE_ACCEL or b == END_BYTE_AUX: skipped_str = skipped_str + '|END|' else: skipped_str = skipped_str + "%03d"%(b) + '.' @@ -444,7 +454,7 @@ def print_packets_in(self): self.last_reconnect = timeit.default_timer() self.warn('Reconnecting') self.reconnect() - + def check_connection(self, interval = 2, max_packets_to_skip=10):