Skip to content

Commit 07b16c7

Browse files
committed
ganglion: starting to read stuff
1 parent b88239e commit 07b16c7

File tree

1 file changed

+58
-80
lines changed

1 file changed

+58
-80
lines changed

open_bci_ganglion.py

Lines changed: 58 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def handle_sample(sample):
1111
1212
TODO: Pick between several boards
1313
TODO: support impedance
14+
TODO: support accelerometer with n / N codes
1415
1516
"""
1617
import 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...\nWait 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

Comments
 (0)