@@ -85,6 +85,10 @@ def __init__(self, port=None, baud=0, filter_data=False,
8585 print ("disconnect, properties: " + str (self .char_discon .propertiesToString ()) + ", supports read: " + str (self .char_discon .supportsRead ()))
8686
8787
88+ # set delegate to handle incoming data
89+ self .delegate = GanglionDelegate ()
90+ self .gang .setDelegate (self .delegate )
91+
8892 print ("Turn on notifications" )
8993 # nead up-to-date bluepy, cf https://github.com/IanHarvey/bluepy/issues/53
9094 self .desc_notify = self .char_read .getDescriptors (forUUID = 0x2902 )[0 ]
@@ -197,98 +201,23 @@ def start_streaming(self, callback, lapse=-1):
197201 self .check_connection ()
198202
199203 while self .streaming :
200-
201- # read current sample
202- # FIXME: several samples per packet
203- sample = self ._read_serial_binary ()
204- #for call in callback:
205- # call(sample)
204+ # at most we will get one sample per packet
205+ self .gang .waitForNotifications (1. / self .getSampleRate ())
206+ # retrieve current samples on the stack
207+ samples = self .delegate .getSamples ()
208+ if not samples :
209+ print ("no new sample" )
210+ else :
211+ for call in callback :
212+ for sample in samples :
213+ call (sample )
206214
207215 if (lapse > 0 and timeit .default_timer () - start_time > lapse ):
208216 self .stop ();
209217 if self .log :
210218 self .log_packet_count = self .log_packet_count + 1 ;
211219
212220
213- """
214- PARSER:
215- Parses incoming data packet into OpenBCISample -- see docs.
216- FIXME: use buffer to account for missed / double packets?
217- """
218- def _read_serial_binary (self ):
219-
220- print ("reading packet" )
221- packet = self .ser_read ()
222- # TODO: better handling of errors...
223- if not packet :
224- self .warn ('Device appears to be stalling.' )
225- return
226- if len (packet ) != 20 :
227- self .warn ('Wrong packet size, ' + str (len (packet )) + ' instead of 20 bytes' )
228- return
229-
230- # bluepy returnds INT with python3 and STR with python2
231- if type (packet ) is str :
232- do_unpack = True
233- start_byte = struct .unpack ('B' , packet [0 ])[0 ]
234- else :
235- do_unpack = False
236- start_byte = packet [0 ]
237-
238- #for b in packet:
239- # if do_unpack:
240- # unpac = struct.unpack('B', b)[0]
241- # else:
242- # unpac = b
243- # print (str(unpac))
244-
245- print (str (start_byte ))
246- # Raw uncompressed
247- if start_byte == 0 :
248- print ("Raw uncompressed" )
249- # 18-bit compression with Accelerometer
250- elif start_byte >= 1 and start_byte <= 100 :
251- print ("18-bit compression with Accelerometer" )
252- # 19-bit compression without Accelerometer
253- elif start_byte >= 101 and start_byte <= 200 :
254- print ("19-bit compression without Accelerometer" )
255- # Impedance Channel
256- elif start_byte >= 201 and start_byte <= 205 :
257- print ("Impedance Channel" )
258- # Part of ASCII
259- elif start_byte == 206 :
260- print ("ASCII message" )
261- print (packet )
262- # End of ASCII message
263- elif start_byte == 207 :
264- print ("End of ASCII message" )
265- print (packet )
266- print ("----" )
267- else :
268- self .warn ("Unknown type of packet: " + str (start_byte ))
269-
270-
271- if False :
272- #3 byte ints
273- literal_read = read (3 )
274-
275- unpacked = struct .unpack ('3B' , literal_read )
276-
277- #3byte int in 2s compliment
278- if (unpacked [0 ] >= 127 ):
279- pre_fix = bytes (bytearray .fromhex ('FF' ))
280- else :
281- pre_fix = bytes (bytearray .fromhex ('00' ))
282-
283- literal_read = pre_fix + literal_read ;
284-
285- #unpack little endian(>) signed integer(i) (makes unpacking platform independent)
286- myInt = struct .unpack ('>i' , literal_read )[0 ]
287-
288- if self .scaling_output :
289- channel_data .append (myInt * scale_fac_uVolts_per_count )
290- else :
291- channel_data .append (myInt )
292221
293222
294223 """
@@ -356,3 +285,85 @@ def __init__(self, packet_id, channel_data, aux_data):
356285 self .channel_data = channel_data ;
357286 self .aux_data = aux_data ;
358287
288+
289+ class GanglionDelegate (DefaultDelegate ):
290+ """ Called by BLE when new data arrive """
291+ def __init__ (self ):
292+ DefaultDelegate .__init__ (self )
293+
294+ def handleNotification (self , cHandle , data ):
295+ print ("handle data!" )
296+ print cHandle
297+ if len (data ) != 20 :
298+ self .warn ('Wrong packet size, ' + str (len (data )) + ' instead of 20 bytes' )
299+ return
300+ self .parse (data )
301+
302+ """
303+ PARSER:
304+ Parses incoming data packet into OpenBCISample -- see docs.
305+ FIXME: use buffer to account for missed / double packets?
306+ """
307+ def parse (self , packet ):
308+ # bluepy returnds INT with python3 and STR with python2
309+ if type (packet ) is str :
310+ # convert a list that must comprises 20 strings to one string
311+ unpac = struct .unpack ('20B' , "" .join (packet ))
312+ else :
313+ unpac = packet
314+
315+ start_byte = unpac [0 ]
316+
317+ for b in unpac :
318+ print (str (b ))
319+
320+ print (str (start_byte ))
321+ # Raw uncompressed
322+ if start_byte == 0 :
323+ print ("Raw uncompressed" )
324+ # 18-bit compression with Accelerometer
325+ elif start_byte >= 1 and start_byte <= 100 :
326+ print ("18-bit compression with Accelerometer" )
327+ # 19-bit compression without Accelerometer
328+ elif start_byte >= 101 and start_byte <= 200 :
329+ print ("19-bit compression without Accelerometer" )
330+ # Impedance Channel
331+ elif start_byte >= 201 and start_byte <= 205 :
332+ print ("Impedance Channel" )
333+ # Part of ASCII
334+ elif start_byte == 206 :
335+ print ("ASCII message" )
336+ print (packet )
337+ # End of ASCII message
338+ elif start_byte == 207 :
339+ print ("End of ASCII message" )
340+ print (packet )
341+ print ("----" )
342+ else :
343+ self .warn ("Unknown type of packet: " + str (start_byte ))
344+
345+
346+ if False :
347+ #3 byte ints
348+ literal_read = read (3 )
349+
350+ unpacked = struct .unpack ('3B' , literal_read )
351+
352+ #3byte int in 2s compliment
353+ if (unpacked [0 ] >= 127 ):
354+ pre_fix = bytes (bytearray .fromhex ('FF' ))
355+ else :
356+ pre_fix = bytes (bytearray .fromhex ('00' ))
357+
358+ literal_read = pre_fix + literal_read ;
359+
360+ #unpack little endian(>) signed integer(i) (makes unpacking platform independent)
361+ myInt = struct .unpack ('>i' , literal_read )[0 ]
362+
363+ if self .scaling_output :
364+ channel_data .append (myInt * scale_fac_uVolts_per_count )
365+ else :
366+ channel_data .append (myInt )
367+
368+ def getSamples (self ):
369+ return None
0 commit comments