Skip to content

Commit 7680f93

Browse files
committed
ganglion: deco/reco
1 parent eddcd69 commit 7680f93

File tree

1 file changed

+34
-29
lines changed

1 file changed

+34
-29
lines changed

open_bci_ganglion.py

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class OpenBCIBoard(object):
5858
"""
5959

6060
def __init__(self, port=None, baud=0, filter_data=False,
61-
scaled_output=True, daisy=False, log=True, timeout=-1, max_packets_to_skip=10):
61+
scaled_output=True, daisy=False, log=True, timeout=-1, max_packets_to_skip=20):
6262
self.log = log # print_incoming_text needs log
6363
self.streaming = False
6464
self.timeout = timeout
@@ -69,9 +69,24 @@ def __init__(self, port=None, baud=0, filter_data=False,
6969
port = self.find_port()
7070
self.port = port # find_port might not return string
7171

72+
self.connect()
73+
74+
self.streaming = False
75+
self.scaling_output = scaled_output
76+
self.eeg_channels_per_sample = 4 # number of EEG channels per sample *from the board*
77+
self.read_state = 0
78+
self.log_packet_count = 0
79+
self.packets_dropped = 0
80+
self.time_last_packet = 0
81+
82+
# Disconnects from board when terminated
83+
atexit.register(self.disconnect)
84+
85+
def connect(self):
86+
""" Connecting to board. Note: recreates various objects upon call. """
7287
print ("Init BLE connection with MAC: " + self.port)
7388
print ("NB: if it fails, try with root privileges.")
74-
self.gang = Peripheral(port, 'random') # ADDR_TYPE_RANDOM
89+
self.gang = Peripheral(self.port, 'random') # ADDR_TYPE_RANDOM
7590

7691
print ("Get mainservice...")
7792
self.service = self.gang.getServiceByUUID(BLE_SERVICE)
@@ -87,7 +102,6 @@ def __init__(self, port=None, baud=0, filter_data=False,
87102
self.char_discon = self.service.getCharacteristics(BLE_CHAR_DISCONNECT)[0]
88103
print ("disconnect, properties: " + str(self.char_discon.propertiesToString()) + ", supports read: " + str(self.char_discon.supportsRead()))
89104

90-
91105
# set delegate to handle incoming data
92106
self.delegate = GanglionDelegate()
93107
self.gang.setDelegate(self.delegate)
@@ -99,20 +113,13 @@ def __init__(self, port=None, baud=0, filter_data=False,
99113

100114
print("Connection established")
101115

102-
#wait for device to be ready, just in case
103-
time.sleep(1)
104-
105-
self.streaming = False
106-
self.scaling_output = scaled_output
107-
self.eeg_channels_per_sample = 4 # number of EEG channels per sample *from the board*
108-
self.read_state = 0
109-
self.log_packet_count = 0
116+
def init_steaming(self):
117+
""" Tell the board to record like crazy. """
118+
self.char_write.write(b'b')
119+
self.streaming = True
110120
self.packets_dropped = 0
111-
self.time_last_packet = 0
112-
113-
#Disconnects from board when terminated
114-
atexit.register(self.disconnect)
115-
121+
self.time_last_packet = timeit.default_timer()
122+
116123
def find_port(self):
117124
"""DetectsGanglion board MAC address -- if more than 1 around, will select first. Needs root privilege."""
118125

@@ -191,9 +198,7 @@ def start_streaming(self, callback, lapse=-1):
191198
OpenBCISample object captured.
192199
"""
193200
if not self.streaming:
194-
self.char_write.write(b'b')
195-
self.streaming = True
196-
self.time_last_packet = timeit.default_timer()
201+
self.init_steaming()
197202

198203
start_time = timeit.default_timer()
199204

@@ -220,7 +225,6 @@ def start_streaming(self, callback, lapse=-1):
220225

221226
# Checking connection -- timeout and packets dropped
222227
self.check_connection()
223-
224228

225229

226230
"""
@@ -239,7 +243,7 @@ def disconnect(self):
239243
if(self.streaming == True):
240244
self.stop()
241245
print("Closing BLE..")
242-
self.char_discon.write(' ')
246+
self.char_discon.write(b' ')
243247
# should not try to read/write anything after that, will crash
244248
self.gang.disconnect()
245249
logging.warning('BLE closed')
@@ -260,37 +264,37 @@ def warn(self, text):
260264
print("Warning: %s" % text)
261265

262266
def check_connection(self):
267+
""" Check connection quality in term of lag and number of packets drop. Reinit connection if necessary. FIXME: parameters given to the board will be lost."""
263268
# stop checking when we're no longer streaming
264269
if not self.streaming:
265270
return
266271
#check number of dropped packets and duration without new packets, deco/reco if too large
267272
if self.packets_dropped > self.max_packets_to_skip:
268273
self.warn("Too many packets dropped, attempt to reconnect")
274+
self.reconnect()
269275
elif self.timeout > 0 and timeit.default_timer() - self.time_last_packet > self.timeout:
270276
self.warn("Too long since got new data, attempt to reconnect")
271277
#if error, attempt to reconect
272278
self.reconnect()
273279

274280
def reconnect(self):
281+
""" In case of poor connection, will shut down and relaunch everything. FIXME: parameters given to the board will be lost."""
275282
self.warn('Reconnecting')
276283
self.stop()
277-
time.sleep(0.5)
278-
self.ser.write(b'b')
279-
self.streaming = True
280-
self.packets_dropped = 0
281-
self.time_last_packet = timeit.default_timer()
282-
284+
self.disconnect()
285+
self.connect()
286+
self.init_steaming()
283287

284288
class OpenBCISample(object):
285-
"""Object encapulsating a single sample from the OpenBCI board."""
289+
"""Object encapulsating a single sample from the OpenBCI board. Note for Ganglion board: since most of the time two samples are compressed in one BLE packet, two consecutive samples will likely have the same ID."""
286290
def __init__(self, packet_id, channel_data, aux_data):
287291
self.id = packet_id;
288292
self.channel_data = channel_data;
289293
self.aux_data = aux_data;
290294

291295

292296
class GanglionDelegate(DefaultDelegate):
293-
""" Called by BLE when new data arrive """
297+
""" Called by bluepy (handling BLE connection) when new data arrive, parses samples. """
294298
def __init__(self):
295299
DefaultDelegate.__init__(self)
296300
# holds samples until OpenBCIBoard claims them
@@ -362,6 +366,7 @@ def updatePacketsCount(self, sample_id):
362366
if self.last_id == -1:
363367
self.last_id = sample_id
364368
self.packets_dropped = 0
369+
return
365370
# ID loops every 101 packets
366371
if sample_id > self.last_id:
367372
self.packets_dropped = sample_id - self.last_id - 1

0 commit comments

Comments
 (0)