Skip to content

Commit 901f73c

Browse files
authored
Merge pull request #1090 from OpenBCI/ganglion-native-ble
Ganglion Native BLE
2 parents afb3ecf + 62ecdeb commit 901f73c

6 files changed

Lines changed: 145 additions & 38 deletions

File tree

.travis.yml

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
1-
2-
language: python # this works for Linux but is an error on macOS or Windows
1+
language: python # this works for Linux but is an error on macOS or Windows
32
jobs:
4-
include:
5-
- name: "Python 3.7.4 on Xenial Linux"
3+
include:
4+
- name: "Python 3.7.4 on Xenial Linux"
65
os: linux
7-
python: 3.7.4 # this works for Linux but is ignored on macOS or Windows
8-
- name: "Python 3.7.4 on macOS"
9-
os: osx
10-
osx_image: xcode11.2 # Python 3.7.4 running on macOS 10.14.6
11-
language: shell # 'language: python' is an error on Travis CI macOS
6+
python: 3.7.4 # this works for Linux but is ignored on macOS or Windows
7+
- name: "Python 3.7.4 on macOS"
8+
os: osx
9+
osx_image: xcode11.2 # Python 3.7.4 running on macOS 10.14.6
10+
language: shell # 'language: python' is an error on Travis CI macOS
1211

1312
branches:
1413
only:
15-
- master
16-
- development
14+
- master
15+
- development
1716

1817
before_install:
19-
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then openssl aes-256-cbc -K $encrypted_2f5d2771e3cb_key -iv $encrypted_2f5d2771e3cb_iv -in release_script/mac_only/Certificates.p12.enc -out release_script/mac_only/Certificates.p12 -d; fi
20-
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then chmod +x release_script/mac_only/add-osx-cert.sh; fi
21-
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then ./release_script/mac_only/add-osx-cert.sh; fi
18+
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then openssl aes-256-cbc -K $encrypted_2f5d2771e3cb_key -iv $encrypted_2f5d2771e3cb_iv -in release_script/mac_only/Certificates.p12.enc -out release_script/mac_only/Certificates.p12 -d; fi
19+
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then chmod +x release_script/mac_only/add-osx-cert.sh; fi
20+
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then ./release_script/mac_only/add-osx-cert.sh; fi
2221

2322
install:
2423
# used for getting commit timestamp
@@ -28,15 +27,15 @@ install:
2827

2928
- mkdir $TRAVIS_BUILD_DIR/temp; cd $TRAVIS_BUILD_DIR/temp
3029

31-
### ### LINUX ### ###
30+
### ### LINUX ### ###
3231
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -O -L --insecure https://github.com/processing/processing/releases/download/processing-0269-3.5.3/processing-3.5.3-linux64.tgz ;fi
3332
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then tar -xzvf processing-3.5.3-linux64.tgz ;fi
3433
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then export PATH=$TRAVIS_BUILD_DIR/temp/processing-3.5.3:$PATH ;fi
3534
# copy libraries to linux location
3635
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then mkdir -p $HOME/sketchbook/libraries/ ;fi
3736
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cp -a $TRAVIS_BUILD_DIR/OpenBCI_GUI/libraries/. $HOME/sketchbook/libraries/ ;fi
38-
39-
### ### MAC ### ###
37+
38+
### ### MAC ### ###
4039
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then curl -O -L --insecure https://github.com/processing/processing/releases/download/processing-0269-3.5.3/processing-3.5.3-macosx.zip ;fi
4140
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then unzip processing-3.5.3-macosx.zip ;fi
4241
# Processing.app must be in this location for processing-java to work
@@ -59,12 +58,12 @@ script:
5958

6059
after_success:
6160
# delete old files in latest
62-
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then aws s3 rm s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_linux64.zip" ;fi
63-
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then aws s3 rm s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_macosx.dmg" ;fi
64-
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then aws s3 cp $TRAVIS_BUILD_DIR/. s3://openbci-gui/${TRAVIS_BRANCH}/${GUI_VERSION_STRING}_${GUI_COMMIT_TIME} --recursive --exclude "*" --include "openbcigui_*_linux64.zip" ;fi
65-
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then aws s3 cp $TRAVIS_BUILD_DIR/. s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_linux64.zip" ;fi
66-
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then aws s3 cp $TRAVIS_BUILD_DIR/. s3://openbci-gui/${TRAVIS_BRANCH}/${GUI_VERSION_STRING}_${GUI_COMMIT_TIME} --recursive --exclude "*" --include "openbcigui_*_macosx.dmg" ;fi
67-
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then aws s3 cp $TRAVIS_BUILD_DIR/. s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_macosx.dmg" ;fi
61+
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then aws s3 rm s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_linux64.zip" ;fi
62+
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then aws s3 rm s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_macosx.dmg" ;fi
63+
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then aws s3 cp $TRAVIS_BUILD_DIR/. s3://openbci-gui/${TRAVIS_BRANCH}/${GUI_VERSION_STRING}_${GUI_COMMIT_TIME} --recursive --exclude "*" --include "openbcigui_*_linux64.zip" ;fi
64+
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then aws s3 cp $TRAVIS_BUILD_DIR/. s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_linux64.zip" ;fi
65+
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then aws s3 cp $TRAVIS_BUILD_DIR/. s3://openbci-gui/${TRAVIS_BRANCH}/${GUI_VERSION_STRING}_${GUI_COMMIT_TIME} --recursive --exclude "*" --include "openbcigui_*_macosx.dmg" ;fi
66+
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then aws s3 cp $TRAVIS_BUILD_DIR/. s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_macosx.dmg" ;fi
6867

6968
notifications:
7069
email:

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# v5.1.1
22

33
### Bug Fixes
4+
- Fix LSL AvgBandPower data type only one value is sent #1098
45

56
### Improvements
7+
- Update to BrainFlow 5.5.0
8+
- Add feature to connect to Ganglion using Native Bluetooth [#1080](https://github.com/OpenBCI/OpenBCI_GUI/issues/1080)
69

7-
- Update to BrainFlow 5.1.0
8-
- Fix LSL AvgBandPower data type only one value is sent #1098
910

1011
# v5.1.0
1112

OpenBCI_GUI/BoardGanglion.pde

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
class BoardGanglionNative extends BoardGanglion {
2+
3+
private PacketLossTrackerGanglionBLE packetLossTrackerGanglionNative;
4+
private String boardName;
5+
6+
public BoardGanglionNative() {
7+
super();
8+
}
9+
10+
public BoardGanglionNative(String name) {
11+
super();
12+
this.boardName = name;
13+
}
14+
15+
@Override
16+
protected BrainFlowInputParams getParams() {
17+
BrainFlowInputParams params = new BrainFlowInputParams();
18+
params.serial_number = boardName;
19+
return params;
20+
}
21+
22+
@Override
23+
public BoardIds getBoardId() {
24+
return BoardIds.GANGLION_NATIVE_BOARD;
25+
}
26+
27+
@Override
28+
public void setAccelerometerActive(boolean active) {
29+
super.setAccelerometerActive(active);
30+
31+
if (packetLossTrackerGanglionNative != null) {
32+
// notify the packet loss tracker, because the sample indices change based
33+
// on whether accel is active or not
34+
packetLossTrackerGanglionNative.setAccelerometerActive(active);
35+
}
36+
}
37+
38+
@Override
39+
protected PacketLossTracker setupPacketLossTracker() {
40+
packetLossTrackerGanglionNative = new PacketLossTrackerGanglionBLE(getSampleIndexChannel(), getTimestampChannel());
41+
packetLossTrackerGanglionNative.setAccelerometerActive(isAccelerometerActive());
42+
return packetLossTrackerGanglionNative;
43+
}
44+
};
45+
146
class BoardGanglionBLE extends BoardGanglion {
247

348
private PacketLossTrackerGanglionBLE packetLossTrackerGanglionBLE;

OpenBCI_GUI/ControlPanel.pde

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ class ControlPanel {
240240
interfaceBoxGanglion.draw();
241241
} else {
242242
interfaceBoxGanglion.draw();
243-
if (selectedProtocol == BoardProtocol.BLED112) {
243+
if (selectedProtocol == BoardProtocol.BLED112 || selectedProtocol == BoardProtocol.NATIVE_BLE) {
244244
bleBox.y = interfaceBoxGanglion.y + interfaceBoxGanglion.h;
245245
dataLogBoxGanglion.y = bleBox.y + bleBox.h;
246246
bleBox.draw();
@@ -724,12 +724,46 @@ class BLEBox {
724724
bleBox_cp5.draw();
725725
}
726726

727+
private void refreshGanglionNativeList() {
728+
if (bleIsRefreshing) {
729+
output("Search for Ganglions using Native Bluetooth is in progress.");
730+
return;
731+
}
732+
output("Refreshing available Ganglions using Native Bluetooth...");
733+
bleList.items.clear();
734+
735+
Thread thread = new Thread(){
736+
public void run(){
737+
refreshBLE.getCaptionLabel().setText("SEARCHING...");
738+
bleIsRefreshing = true;
739+
740+
try {
741+
bleMACAddrMap = GUIHelper.scan_for_ganglions (3);
742+
for (Map.Entry<String, String> entry : bleMACAddrMap.entrySet ())
743+
{
744+
bleList.addItem(entry.getKey(), entry.getValue(), "");
745+
bleList.updateMenu();
746+
println("Found Ganglion Board: " + entry.getKey() + " " + entry.getValue());
747+
}
748+
} catch (GanglionError e)
749+
{
750+
e.printStackTrace();
751+
}
752+
753+
refreshBLE.getCaptionLabel().setText("START SEARCH");
754+
bleIsRefreshing = false;
755+
}
756+
};
757+
758+
thread.start();
759+
}
760+
727761
private void refreshGanglionBLEList() {
728762
if (bleIsRefreshing) {
729-
output("BLE Devices Refreshing in progress");
763+
output("Search for Ganglions using BLED112 Dongle is in progress.");
730764
return;
731765
}
732-
output("BLE Devices Refreshing");
766+
output("Refreshing available Ganglions using BLED112 Dongle...");
733767
bleList.items.clear();
734768

735769
Thread thread = new Thread(){
@@ -779,7 +813,11 @@ class BLEBox {
779813
refreshBLE = createButton(bleBox_cp5, name, text, _x, _y, _w, _h);
780814
refreshBLE.onRelease(new CallbackListener() {
781815
public void controlEvent(CallbackEvent theEvent) {
782-
refreshGanglionBLEList();
816+
if (selectedProtocol == BoardProtocol.BLED112) {
817+
refreshGanglionBLEList();
818+
} else {
819+
refreshGanglionNativeList();
820+
}
783821
}
784822
});
785823
}
@@ -1114,6 +1152,7 @@ class InterfaceBoxCyton {
11141152
class InterfaceBoxGanglion {
11151153
public int x, y, w, h, padding; //size and position
11161154
private ControlP5 ifbg_cp5;
1155+
private Button protocolGanglionNativeBLE;
11171156
private Button protocolBLED112Ganglion;
11181157
private Button protocolWifiGanglion;
11191158

@@ -1122,16 +1161,17 @@ class InterfaceBoxGanglion {
11221161
y = _y;
11231162
w = _w;
11241163
padding = _padding;
1125-
h = (24 + _padding) * 3;
1164+
h = (24 + _padding) * 4;
11261165
int buttonHeight = 24;
11271166

11281167
//Instantiate local cp5 for this box
11291168
ifbg_cp5 = new ControlP5(ourApplet);
11301169
ifbg_cp5.setGraphics(ourApplet, 0,0);
11311170
ifbg_cp5.setAutoDraw(false);
11321171

1133-
createBLED112Button("protocolBLED112Ganglion", "Bluetooth (BLED112 Dongle)", false, x + padding, y + padding * 3 + 4, w - padding * 2, 24);
1134-
createGanglionWifiButton("protocolWifiGanglion", "Wifi (from Wifi Shield)", false, x + padding, y + padding * 4 + 24 + 4, w - padding * 2, 24);
1172+
createGanglionNativeBLEButton("protocolNativeBLEGanglion", "Bluetooth (Native)", false, x + padding, y + padding * 3 + 4, w - padding * 2, 24);
1173+
createBLED112Button("protocolBLED112Ganglion", "Bluetooth (BLED112 Dongle)", false, x + padding, y + (padding * 4) + 24 + 4, w - padding * 2, 24);
1174+
createGanglionWifiButton("protocolWifiGanglion", "Wifi (from Wifi Shield)", false, x + padding, y + (padding * 5) + (24 * 2) + 4, w - padding * 2, 24);
11351175
}
11361176

11371177
public void update() {}
@@ -1161,6 +1201,21 @@ class InterfaceBoxGanglion {
11611201
return b;
11621202
}
11631203

1204+
private void createGanglionNativeBLEButton(String name, String text, boolean isToggled, int _x, int _y, int _w, int _h) {
1205+
protocolGanglionNativeBLE = createIFBGButton(name, text, isToggled, _x, _y, _w, _h);
1206+
protocolGanglionNativeBLE.onRelease(new CallbackListener() {
1207+
public void controlEvent(CallbackEvent theEvent) {
1208+
controlPanel.wifiBox.wifiList.items.clear();
1209+
controlPanel.bleBox.bleList.items.clear();
1210+
selectedProtocol = BoardProtocol.NATIVE_BLE;
1211+
controlPanel.bleBox.refreshGanglionNativeList();
1212+
protocolGanglionNativeBLE.setOn();
1213+
protocolBLED112Ganglion.setOff();
1214+
protocolWifiGanglion.setOff();
1215+
}
1216+
});
1217+
}
1218+
11641219
private void createBLED112Button(String name, String text, boolean isToggled, int _x, int _y, int _w, int _h) {
11651220
protocolBLED112Ganglion = createIFBGButton(name, text, isToggled, _x, _y, _w, _h);
11661221
protocolBLED112Ganglion.onRelease(new CallbackListener() {
@@ -1169,6 +1224,7 @@ class InterfaceBoxGanglion {
11691224
controlPanel.bleBox.bleList.items.clear();
11701225
selectedProtocol = BoardProtocol.BLED112;
11711226
controlPanel.bleBox.refreshGanglionBLEList();
1227+
protocolGanglionNativeBLE.setOff();
11721228
protocolBLED112Ganglion.setOn();
11731229
protocolWifiGanglion.setOff();
11741230
}
@@ -1182,13 +1238,15 @@ class InterfaceBoxGanglion {
11821238
controlPanel.wifiBox.wifiList.items.clear();
11831239
controlPanel.bleBox.bleList.items.clear();
11841240
selectedProtocol = BoardProtocol.WIFI;
1241+
protocolGanglionNativeBLE.setOff();
11851242
protocolBLED112Ganglion.setOff();
11861243
protocolWifiGanglion.setOn();
11871244
}
11881245
});
11891246
}
11901247

11911248
public void resetGanglionSelectedProtocol() {
1249+
protocolGanglionNativeBLE.setOff();
11921250
protocolBLED112Ganglion.setOff();
11931251
protocolWifiGanglion.setOff();
11941252
selectedProtocol = BoardProtocol.NONE;
@@ -2913,7 +2971,7 @@ class InitBox {
29132971
} else if (eegDataSource == DATASOURCE_PLAYBACKFILE && playbackData_fname == "N/A" && sdData_fname == "N/A") { //if data source == playback && playback file == 'N/A'
29142972
outputWarn("No playback file selected. Please select a playback file and retry system initiation."); // tell user that they need to select a file before the system can be started
29152973
return;
2916-
} else if (eegDataSource == DATASOURCE_GANGLION && (selectedProtocol == BoardProtocol.BLE || selectedProtocol == BoardProtocol.BLED112) && ganglion_portName == "N/A") {
2974+
} else if (eegDataSource == DATASOURCE_GANGLION && (selectedProtocol == BoardProtocol.NATIVE_BLE || selectedProtocol == BoardProtocol.BLED112) && ganglion_portName == "N/A") {
29172975
outputWarn("No BLE device selected. Please select your Ganglion device and retry system initiation.");
29182976
return;
29192977
} else if (eegDataSource == DATASOURCE_GANGLION && selectedProtocol == BoardProtocol.WIFI && wifi_portName == "N/A" && controlPanel.getWifiSearchStyle() == controlPanel.WIFI_DYNAMIC) {

OpenBCI_GUI/OpenBCI_GUI.pde

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
import ddf.minim.*; // To make sound. Following minim example "frequencyModulation"
2323
import ddf.minim.ugens.*; // To make sound. Following minim example "frequencyModulation"
2424
import java.lang.Math; //for exp, log, sqrt...they seem better than Processing's built-in
25-
import processing.core.PApplet;
25+
import processing.core.*;
26+
import processing.data.*;
2627
import java.util.*; //for Array.copyOfRange()
2728
import processing.serial.*; //for serial communication to Arduino/OpenBCI
2829
import java.awt.event.*; //to allow for event listener on screen resize
@@ -102,7 +103,7 @@ final static int NUM_ACCEL_DIMS = 3;
102103
enum BoardProtocol {
103104
NONE,
104105
SERIAL,
105-
BLE,
106+
NATIVE_BLE,
106107
WIFI,
107108
BLED112
108109
}
@@ -604,14 +605,17 @@ void initSystem() {
604605
case DATASOURCE_GANGLION:
605606
if (selectedProtocol == BoardProtocol.WIFI) {
606607
currentBoard = new BoardGanglionWifi(wifi_ipAddress, selectedSamplingRate);
607-
}
608-
else {
609-
// todo[brainflow] temp hardcode
608+
} else if (selectedProtocol == BoardProtocol.BLED112) {
610609
String ganglionName = (String)(controlPanel.bleBox.bleList.getItem(controlPanel.bleBox.bleList.activeItem).get("headline"));
611610
String ganglionPort = (String)(controlPanel.bleBox.bleList.getItem(controlPanel.bleBox.bleList.activeItem).get("subline"));
612611
String ganglionMac = controlPanel.bleBox.bleMACAddrMap.get(ganglionName);
613612
println("MAC address for Ganglion is " + ganglionMac);
614613
currentBoard = new BoardGanglionBLE(ganglionPort, ganglionMac);
614+
} else if (selectedProtocol == BoardProtocol.NATIVE_BLE) {
615+
String ganglionName = (String)(controlPanel.bleBox.bleList.getItem(controlPanel.bleBox.bleList.activeItem).get("headline"));
616+
String ganglionMac = controlPanel.bleBox.bleMACAddrMap.get(ganglionName);
617+
println("MAC address for Ganglion is " + ganglionName);
618+
currentBoard = new BoardGanglionNative(ganglionName);
615619
}
616620
break;
617621
case DATASOURCE_STREAMING:
Binary file not shown.

0 commit comments

Comments
 (0)