Skip to content

Commit 86d4bdd

Browse files
committed
ganglion: scaling output
1 parent 0f1be18 commit 86d4bdd

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

open_bci_ganglion.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ def handle_sample(sample):
1313
1414
TODO: support impedance
1515
TODO: better sample ID
16-
TODO: scale output, both for EEG and AUX
1716
TODO: switch for 18bit aux
1817
TODO: indicate incoming message -- end ascii packet or timeout
1918
@@ -33,7 +32,8 @@ def handle_sample(sample):
3332
from btle import Scanner, DefaultDelegate, Peripheral
3433

3534
SAMPLE_RATE = 200.0 # Hz
36-
scale_fac_uVolts_per_count = 1200 * 8388607.0 * 1.5 * 51.0;
35+
scale_fac_uVolts_per_count = 1200 / (8388607.0 * 1.5 * 51.0)
36+
scale_fac_accel_G_per_count = 0.000032
3737

3838
# service for communication, as per docs
3939
BLE_SERVICE = "fe84"
@@ -70,6 +70,7 @@ def __init__(self, port=None, baud=0, filter_data=False,
7070
self.streaming = False
7171
self.timeout = timeout
7272
self.max_packets_to_skip = max_packets_to_skip
73+
self.scaling_output = scaled_output
7374

7475
print("Looking for Ganglion board")
7576
if port == None:
@@ -79,8 +80,7 @@ def __init__(self, port=None, baud=0, filter_data=False,
7980
self.connect()
8081

8182
self.streaming = False
82-
self.scaling_output = scaled_output
83-
# number of EEG channels and (optionally) accelerometer channel
83+
# number of EEG channels and (optionally) accelerometer channel
8484
self.eeg_channels_per_sample = 4
8585
self.aux_channels_per_sample = 3
8686
self.read_state = 0
@@ -112,7 +112,7 @@ def connect(self):
112112
print ("disconnect, properties: " + str(self.char_discon.propertiesToString()) + ", supports read: " + str(self.char_discon.supportsRead()))
113113

114114
# set delegate to handle incoming data
115-
self.delegate = GanglionDelegate()
115+
self.delegate = GanglionDelegate(self.scaling_output)
116116
self.gang.setDelegate(self.delegate)
117117

118118
print("Turn on notifications")
@@ -328,7 +328,7 @@ def __init__(self, packet_id, channel_data, aux_data):
328328

329329
class GanglionDelegate(DefaultDelegate):
330330
""" Called by bluepy (handling BLE connection) when new data arrive, parses samples. """
331-
def __init__(self):
331+
def __init__(self, scaling_output = True):
332332
DefaultDelegate.__init__(self)
333333
# holds samples until OpenBCIBoard claims them
334334
self.samples = []
@@ -339,6 +339,7 @@ def __init__(self):
339339
self.lastChannelData = [0, 0, 0, 0]
340340
# 18bit data got here and then accelerometer with it
341341
self.lastAcceleromoter = [0, 0, 0]
342+
self.scaling_output = scaling_output
342343

343344
def handleNotification(self, cHandle, data):
344345
if len(data) < 1:
@@ -394,11 +395,19 @@ def parseRaw(self, sample_id, packet):
394395
for i in range(0,12,3):
395396
chan_data.append(conv24bitsToInt(packet[i:i+3]))
396397
# save uncompressed raw channel for future use and append whole sample
397-
sample = OpenBCISample(sample_id, chan_data, [])
398-
self.samples.append(sample)
398+
self.pushSample(sample_id, chan_data, self.lastAcceleromoter)
399399
self.lastChannelData = chan_data
400400
self.updatePacketsCount(sample_id)
401401

402+
def pushSample(self, sample_id, chan_data, aux_data):
403+
""" Add a sample to inner stack, dealing with scaling if necessary """
404+
405+
if self.scaling_output:
406+
chan_data = list(np.array(chan_data) * scale_fac_uVolts_per_count)
407+
aux_data = list(np.array(aux_data) * scale_fac_accel_G_per_count)
408+
sample = OpenBCISample(sample_id, chan_data, aux_data)
409+
self.samples.append(sample)
410+
402411
def parse19bit(self, sample_id, packet):
403412
""" Dealing with "19-bit compression without Accelerometer" """
404413
if len(packet) != 19:
@@ -412,8 +421,7 @@ def parse19bit(self, sample_id, packet):
412421
# TODO: use more broadly numpy
413422
full_data = list(np.array(self.lastChannelData) - np.array(delta))
414423
# NB: aux data updated only in 18bit mode, send values here only to be consistent
415-
sample = OpenBCISample(sample_id, full_data, self.lastAcceleromoter)
416-
self.samples.append(sample)
424+
self.pushSample(sample_id, full_data, self.lastAcceleromoter)
417425
self.lastChannelData = full_data
418426
self.updatePacketsCount(sample_id)
419427

@@ -442,8 +450,7 @@ def parse18bit(self, sample_id, packet):
442450
# 19bit packets hold deltas between two samples
443451
# TODO: use more broadly numpy
444452
full_data = list(np.array(self.lastChannelData) - np.array(delta))
445-
sample = OpenBCISample(sample_id, full_data, self.lastAcceleromoter)
446-
self.samples.append(sample)
453+
self.pushSample(sample_id, full_data, self.lastAcceleromoter)
447454
self.lastChannelData = full_data
448455
self.updatePacketsCount(sample_id)
449456

0 commit comments

Comments
 (0)