@@ -11,6 +11,7 @@ def handle_sample(sample):
1111
1212TODO: Pick between several boards
1313TODO: support impedance
14+ TODO: support accelerometer with n / N codes
1415
1516"""
1617import struct
@@ -151,11 +152,11 @@ def handleDiscovery(self, dev, isNewDev, isNewData):
151152
152153 def ser_write (self , b ):
153154 """Access serial port object for write"""
154- self .ser .write (b )
155+ self .char_write .write (b )
155156
156157 def ser_read (self ):
157158 """Access serial port object for read"""
158- return self .ser .read ()
159+ return self .char_read .read ()
159160
160161 def getSampleRate (self ):
161162 return SAMPLE_RATE
@@ -177,7 +178,7 @@ def start_streaming(self, callback, lapse=-1):
177178 OpenBCISample object captured.
178179 """
179180 if not self .streaming :
180- self .ser .write (b'b' )
181+ self .char_write .write (b'b' )
181182 self .streaming = True
182183
183184 start_time = timeit .default_timer ()
@@ -193,9 +194,10 @@ def start_streaming(self, callback, lapse=-1):
193194 while self .streaming :
194195
195196 # read current sample
197+ # FIXME: several samples per packet
196198 sample = self ._read_serial_binary ()
197- for call in callback :
198- call (sample )
199+ # for call in callback:
200+ # call(sample)
199201
200202 if (lapse > 0 and timeit .default_timer () - start_time > lapse ):
201203 self .stop ();
@@ -205,58 +207,64 @@ def start_streaming(self, callback, lapse=-1):
205207
206208 """
207209 PARSER:
208- Parses incoming data packet into OpenBCISample.
209- Incoming Packet Structure:
210- Start Byte(1)|Sample ID(1)|Channel Data(24)|Aux Data(6)|End Byte(1)
211- 0xA0|0-255|8, 3-byte signed ints|3 2-byte signed ints|0xC0
212-
210+ Parses incoming data packet into OpenBCISample -- see docs.
211+ FIXME: use buffer to account for missed / double packets?
213212 """
214- def _read_serial_binary (self , max_bytes_to_skip = 3000 ):
215- def read (n ):
216- bb = self .ser .read (n )
217- if not bb :
218- self .warn ('Device appears to be stalled. Quitting...' )
219- sys .exit ()
220- raise Exception ('Device Stalled' )
221- sys .exit ()
222- return '\xFF '
223- else :
224- return bb
225-
226- for rep in range (max_bytes_to_skip ):
227-
228- #---------Start Byte & ID---------
229- if self .read_state == 0 :
230-
231- b = read (1 )
232-
233- if struct .unpack ('B' , b )[0 ] == START_BYTE :
234- if (rep != 0 ):
235- self .warn ('Skipped %d bytes before start found' % (rep ))
236- rep = 0 ;
237- packet_id = struct .unpack ('B' , read (1 ))[0 ] #packet id goes from 0-255
238- log_bytes_in = str (packet_id );
239-
240- self .read_state = 1
241-
242- #---------Channel Data---------
243- elif self .read_state == 1 :
244- channel_data = []
245- for c in range (self .eeg_channels_per_sample ):
213+ def _read_serial_binary (self ):
214+
215+ print ("reading packet" )
216+ packet = self .ser_read ()
217+ # poor handling of errors...
218+ if not packet :
219+ self .warn ('Device appears to be stalling.' )
220+ return
221+ if len (packet ) != 20 :
222+ self .warn ('Wrong packet size, ' + str (len (packet )) + ' instead of 20 bytes' )
223+ return
224+
225+ for b in packet :
226+ unpac = struct .unpack ('B' , b )
227+ print unpac
228+
229+ start_byte = struct .unpack ('B' , packet [0 ])
230+ print (str (start_byte ))
231+ # Raw uncompressed
232+ if start_byte == 0 :
233+ print ("Raw uncompressed" )
234+ # 18-bit compression with Accelerometer
235+ elif start_byte >= 1 and start_byte <= 100 :
236+ print ("18-bit compression with Accelerometer" )
237+ # 19-bit compression without Accelerometer
238+ elif start_byte >= 101 and start_byte <= 200 :
239+ print ("19-bit compression without Accelerometer" )
240+ # Impedance Channel
241+ elif start_byte >= 201 and start_byte <= 205 :
242+ print ("Impedance Channel" )
243+ # Part of ASCII
244+ elif start_byte == 206 :
245+ print ("ASCII message" )
246+ print (packet )
247+ # End of ASCII message
248+ elif start_byte == 207 :
249+ print ("End of ASCII message" )
250+ print (packet )
251+ print ("----" )
252+ else :
253+ self .warn ("Unknown type of packet: " + str (start_byte ))
254+
246255
256+ if False :
247257 #3 byte ints
248258 literal_read = read (3 )
249259
250260 unpacked = struct .unpack ('3B' , literal_read )
251- log_bytes_in = log_bytes_in + '|' + str (literal_read );
252261
253262 #3byte int in 2s compliment
254263 if (unpacked [0 ] >= 127 ):
255264 pre_fix = bytes (bytearray .fromhex ('FF' ))
256265 else :
257266 pre_fix = bytes (bytearray .fromhex ('00' ))
258267
259-
260268 literal_read = pre_fix + literal_read ;
261269
262270 #unpack little endian(>) signed integer(i) (makes unpacking platform independent)
@@ -267,37 +275,6 @@ def read(n):
267275 else :
268276 channel_data .append (myInt )
269277
270- self .read_state = 2 ;
271-
272- #---------Accelerometer Data---------
273- elif self .read_state == 2 :
274- aux_data = []
275- for a in range (self .aux_channels_per_sample ):
276-
277- #short = h
278- acc = struct .unpack ('>h' , read (2 ))[0 ]
279- log_bytes_in = log_bytes_in + '|' + str (acc );
280-
281- if self .scaling_output :
282- aux_data .append (acc * scale_fac_accel_G_per_count )
283- else :
284- aux_data .append (acc )
285-
286- self .read_state = 3 ;
287- #---------End Byte---------
288- elif self .read_state == 3 :
289- val = struct .unpack ('B' , read (1 ))[0 ]
290- log_bytes_in = log_bytes_in + '|' + str (val );
291- self .read_state = 0 #read next packet
292- if (val == END_BYTE ):
293- sample = OpenBCISample (packet_id , channel_data , aux_data )
294- self .packets_dropped = 0
295- return sample
296- else :
297- self .warn ("ID:<%d> <Unexpected END_BYTE found <%s> instead of <%s>"
298- % (packet_id , val , END_BYTE ))
299- logging .debug (log_bytes_in );
300- self .packets_dropped = self .packets_dropped + 1
301278
302279 """
303280
@@ -307,17 +284,18 @@ def read(n):
307284 def stop (self ):
308285 print ("Stopping streaming...\n Wait for buffer to flush..." )
309286 self .streaming = False
310- self .ser .write (b's' )
287+ self .char_write .write (b's' )
311288 if self .log :
312289 logging .warning ('sent <s>: stopped streaming' )
313290
314291 def disconnect (self ):
315292 if (self .streaming == True ):
316293 self .stop ()
317- if (self .ser .isOpen ()):
318- print ("Closing Serial..." )
319- self .ser .close ()
320- logging .warning ('serial closed' )
294+ print ("Closing BLE.." )
295+ self .char_discon .write (' ' )
296+ # should not try to read/write anything after that, will crash
297+ self .gang .disconnect ()
298+ logging .warning ('BLE closed' )
321299
322300
323301 """
0 commit comments