Skip to content

Commit

Permalink
Merge pull request #882 from OpenBCI/development
Browse files Browse the repository at this point in the history
Development 5.0.1 -> Master
  • Loading branch information
retiutut authored Sep 21, 2020
2 parents d730c63 + 83a68e4 commit 9a8a644
Show file tree
Hide file tree
Showing 85 changed files with 6,411 additions and 804 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ OpenBCI_GUI/SavedData/EEG_Data/SDconverted-*
OpenBCI_GUI/data/EEG_Data/*
OpenBCI_GUI/data/OpenBCIHub/*
OpenBCI_GUI/application.*
OpenBCI_GUI_unittests/UNITTEST_FAILURE
openbcigui_*
application.*
*.autosave
.vscode/*
temp/*
48 changes: 32 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
os:
- linux
- osx

addons:
artifacts:
paths:
- $(ls $TRAVIS_BUILD_DIR/openbcigui_*_macosx.dmg | tr "\n" ":")
- $(ls $TRAVIS_BUILD_DIR/openbcigui_*_linux64.zip | tr "\n" ":")
target_paths:
- /${TRAVIS_BRANCH}/${TRAVIS_COMMIT}
- /${TRAVIS_BRANCH}/latest
working_dir: $TRAVIS_BUILD_DIR

language: python # this works for Linux but is an error on macOS or Windows
jobs:
include:
- name: "Python 3.7.4 on Xenial Linux"
os: linux
python: 3.7.4 # this works for Linux but is ignored on macOS or Windows
- name: "Python 3.7.4 on macOS"
os: osx
osx_image: xcode11.2 # Python 3.7.4 running on macOS 10.14.6
language: shell # 'language: python' is an error on Travis CI macOS

before_install:
- 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
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then chmod +x release_script/mac_only/add-osx-cert.sh; fi
- if [ "$TRAVIS_OS_NAME" = osx ] && [ "$TRAVIS_PULL_REQUEST" == "false" ]; then ./release_script/mac_only/add-osx-cert.sh; fi

install:
# used for getting commit timestamp
- pip3 install requests
- pip3 install beautifulsoup4
- pip3 install awscli

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

### ### LINUX ### ###
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -O -L http://download.processing.org/processing-3.5.3-linux64.tgz ;fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then curl -O -L --insecure https://download.processing.org/processing-3.5.3-linux64.tgz ;fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then tar -xzvf processing-3.5.3-linux64.tgz ;fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then export PATH=$TRAVIS_BUILD_DIR/temp/processing-3.5.3:$PATH ;fi
# copy libraries to linux location
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then mkdir -p $HOME/sketchbook/libraries/ ;fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cp -a $TRAVIS_BUILD_DIR/OpenBCI_GUI/libraries/. $HOME/sketchbook/libraries/ ;fi

### ### MAC ### ###
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then curl -O -L http://download.processing.org/processing-3.5.3-macosx.zip ;fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then curl -O -L --insecure https://download.processing.org/processing-3.5.3-macosx.zip ;fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then unzip processing-3.5.3-macosx.zip ;fi
# Processing.app must be in this location for processing-java to work
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then mv Processing.app /Applications/Processing.app ;fi
Expand All @@ -43,7 +46,20 @@ install:

script:
- cd $TRAVIS_BUILD_DIR
- python $TRAVIS_BUILD_DIR/release_script/make-release.py --no-prompts
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then python $TRAVIS_BUILD_DIR/OpenBCI_GUI_UnitTests/run-unittests.py ;fi
- python3 $TRAVIS_BUILD_DIR/release_script/make-release.py --no-prompts
# over script will write version and timestamp here
- GUI_COMMIT_TIME=`cat temp/timestamp.txt`
- GUI_VERSION_STRING=`cat temp/versionstring.txt`

after_success:
# delete old files in latest
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then aws s3 rm s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_linux64.zip" ;fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then aws s3 rm s3://openbci-gui/${TRAVIS_BRANCH}/latest --recursive --exclude "*" --include "openbcigui_*_macosx.dmg" ;fi
- 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
- 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
- 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
- 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

notifications:
email:
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# v5.0.1

### Improvements
* Add ability to save and load hardware settings
* Add configurable gain behaviour
* Add custom vertical scale UI to Time Series

### Bug Fixes
* Fix #805
* Covert GUI v4 sample data to GUI v5 format #830
* Display GUI version in title bar, along with FPS

### Bug Fixes
* Check internet connection to Github using a timeout, so the app doesn't stall

# v5.0.0

### Improvements
Expand All @@ -11,6 +26,7 @@
* Add data smoothing option for live Cyton data
* Cyton Port manual selection only displays serial ports with a dongle connected.
* Cyton SD file read works without conversion to playback file
* Add BrainFlow Streaming Board as Data Source option
* Use BrainFlow filters, add 1-100 BandPass filter
* Can Hide/Show channels in time series

Expand Down
175 changes: 136 additions & 39 deletions OpenBCI_GUI/ADS1299SettingsBoard.pde
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.*;


interface ADSSettingsEnum {
public String getName();
public ADSSettingsEnum getNext();
public ADSSettingsEnum getPrev();
}

enum PowerDown implements ADSSettingsEnum {
Expand All @@ -24,6 +29,12 @@ enum PowerDown implements ADSSettingsEnum {
PowerDown[] vals = values();
return vals[(this.ordinal()+1) % vals.length];
}

@Override
public PowerDown getPrev() {
PowerDown[] vals = values();
return vals[(this.ordinal()-1+vals.length) % vals.length];
}
}

// the scalar values are actually used to scale eeg data
Expand Down Expand Up @@ -56,6 +67,12 @@ enum Gain implements ADSSettingsEnum {
return vals[(this.ordinal()+1) % vals.length];
}

@Override
public Gain getPrev() {
Gain[] vals = values();
return vals[(this.ordinal()-1+vals.length) % vals.length];
}

public double getScalar() {
return scalar;
}
Expand Down Expand Up @@ -87,6 +104,12 @@ enum InputType implements ADSSettingsEnum {
InputType[] vals = values();
return vals[(this.ordinal()+1) % vals.length];
}

@Override
public InputType getPrev() {
InputType[] vals = values();
return vals[(this.ordinal()-1+vals.length) % vals.length];
}
}

enum Bias implements ADSSettingsEnum {
Expand All @@ -109,6 +132,12 @@ enum Bias implements ADSSettingsEnum {
Bias[] vals = values();
return vals[(this.ordinal()+1) % vals.length];
}

@Override
public Bias getPrev() {
Bias[] vals = values();
return vals[(this.ordinal()-1+vals.length) % vals.length];
}
}

enum Srb2 implements ADSSettingsEnum {
Expand All @@ -131,6 +160,12 @@ enum Srb2 implements ADSSettingsEnum {
Srb2[] vals = values();
return vals[(this.ordinal()+1) % vals.length];
}

@Override
public Srb2 getPrev() {
Srb2[] vals = values();
return vals[(this.ordinal()-1+vals.length) % vals.length];
}
}

enum Srb1 implements ADSSettingsEnum {
Expand All @@ -153,81 +188,142 @@ enum Srb1 implements ADSSettingsEnum {
Srb1[] vals = values();
return vals[(this.ordinal()+1) % vals.length];
}

@Override
public Srb1 getPrev() {
Srb1[] vals = values();
return vals[(this.ordinal()-1+vals.length) % vals.length];
}
}

public class ADS1299SettingsValues {
public PowerDown[] powerDown;
public Gain[] gain;
public InputType[] inputType;
public Bias[] bias;
public Srb2[] srb2;
public Srb1[] srb1;

public Bias[] previousBias;
public Srb2[] previousSrb2;
public InputType[] previousInputType;

public ADS1299SettingsValues() {
}
}

class ADS1299Settings {
protected PowerDown[] powerDown;
protected Gain[] gain;
protected InputType[] inputType;
protected Bias[] bias;
protected Srb2[] srb2;
protected Srb1[] srb1;

public ADS1299SettingsValues values;

protected Board board;
protected ADS1299SettingsBoard settingsBoard;

private Bias[] previousBias;
private Srb2[] previousSrb2;

ADS1299Settings(Board theBoard) {
board = theBoard;
settingsBoard = (ADS1299SettingsBoard)theBoard;
values = new ADS1299SettingsValues();

int channelCount = board.getNumEXGChannels();

// initialize all arrays with some defaults
// (which happen to be Cyton defaults, but they don't have to be.
// we set defaults on board contruction)
powerDown = new PowerDown[channelCount];
Arrays.fill(powerDown, PowerDown.ON);
values.powerDown = new PowerDown[channelCount];
Arrays.fill(values.powerDown, PowerDown.ON);

gain = new Gain[channelCount];
Arrays.fill(gain, Gain.X24);
values.gain = new Gain[channelCount];
Arrays.fill(values.gain, Gain.X24);

inputType = new InputType[channelCount];
Arrays.fill(inputType, InputType.NORMAL);
values.inputType = new InputType[channelCount];
Arrays.fill(values.inputType, InputType.NORMAL);

bias = new Bias[channelCount];
Arrays.fill(bias, Bias.INCLUDE);
values.bias = new Bias[channelCount];
Arrays.fill(values.bias, Bias.INCLUDE);

srb2 = new Srb2[channelCount];
Arrays.fill(srb2, Srb2.CONNECT);
values.srb2 = new Srb2[channelCount];
Arrays.fill(values.srb2, Srb2.CONNECT);

srb1 = new Srb1[channelCount];
Arrays.fill(srb1, Srb1.DISCONNECT);
values.srb1 = new Srb1[channelCount];
Arrays.fill(values.srb1, Srb1.DISCONNECT);

previousBias = bias.clone();
previousSrb2 = srb2.clone();
values.previousBias = values.bias.clone();
values.previousSrb2 = values.srb2.clone();
values.previousInputType = values.inputType.clone();
}

public boolean loadSettingsValues(String filename) {
try {
File file = new File(filename);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
while(scanner.hasNextLine()) {
fileContents.append(scanner.nextLine() + System.lineSeparator());
}
Gson gson = new Gson();
values = gson.fromJson(fileContents.toString(), ADS1299SettingsValues.class);
commitAll();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}

public String getJson() {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
return gson.toJson(values);
}

public boolean saveToFile(String filename) {
String json = getJson();
try {
FileWriter writer = new FileWriter(filename);
writer.write(json);
writer.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}

public boolean isChannelActive(int chan) {
return powerDown[chan] == PowerDown.ON;
return values.powerDown[chan] == PowerDown.ON;
}

public void setChannelActive(int chan, boolean active) {
String oldValues = getJson();
if (active) {
bias[chan] = previousBias[chan];
srb2[chan] = previousSrb2[chan];

values.bias[chan] = values.previousBias[chan];
values.srb2[chan] = values.previousSrb2[chan];
values.inputType[chan] = values.previousInputType[chan];
} else {
previousBias[chan] = bias[chan];
previousSrb2[chan] = srb2[chan];
values.previousBias[chan] = values.bias[chan];
values.previousSrb2[chan] = values.srb2[chan];
values.previousInputType[chan] = values.inputType[chan];

bias[chan] = Bias.NO_INCLUDE;
srb2[chan] = Srb2.DISCONNECT;
values.bias[chan] = Bias.NO_INCLUDE;
values.srb2[chan] = Srb2.DISCONNECT;
values.inputType[chan] = InputType.SHORTED;
}

powerDown[chan] = active ? PowerDown.ON : PowerDown.OFF;
commit(chan);
values.powerDown[chan] = active ? PowerDown.ON : PowerDown.OFF;
boolean res = commit(chan);
if (!res) {
// restore old settings in UI
Gson gson = new Gson();
values = gson.fromJson(oldValues, ADS1299SettingsValues.class);
}
}

public void commit(int chan) {
public boolean commit(int chan) {
String command = String.format("x%c%d%d%d%d%d%dX", settingsBoard.getChannelSelector(chan),
powerDown[chan].ordinal(), gain[chan].ordinal(),
inputType[chan].ordinal(), bias[chan].ordinal(),
srb2[chan].ordinal(), srb1[chan].ordinal());
values.powerDown[chan].ordinal(), values.gain[chan].ordinal(),
values.inputType[chan].ordinal(), values.bias[chan].ordinal(),
values.srb2[chan].ordinal(), values.srb1[chan].ordinal());

board.sendCommand(command);
return board.sendCommand(command);
}

public void commitAll() {
Expand All @@ -237,11 +333,12 @@ class ADS1299Settings {
}
}


interface ADS1299SettingsBoard {

// Interface methods
public ADS1299Settings getADS1299Settings();
public char getChannelSelector(int channel);
public double getGain(int channel);
public void setUseDynamicScaler(boolean val);
public boolean getUseDynamicScaler();
};
Loading

0 comments on commit 9a8a644

Please sign in to comment.