Skip to content

Commit

Permalink
Merge pull request #975 from OpenBCI/development
Browse files Browse the repository at this point in the history
GUI 5.0.5
  • Loading branch information
retiutut authored May 29, 2021
2 parents f78cefa + 408b215 commit df2daa2
Show file tree
Hide file tree
Showing 17 changed files with 997 additions and 76 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# v5.0.5

### Improvements
* Implement Focus Widget using BrainFlow Metrics! #924
* Throw a popup if users are are running an old version of Windows operating system. GUI v5 supports 64-bit Windows 8, 8.1, and 10. #964
* Throw a popup if Windows users are using 32-bit Java and Processing. #964
* Set Networking Widget default baud rate for Serial output to 57600

### Bug Fixes
* Fix Y axis Autoscale in TimeSeries when all values are less than zero. Example: Cyton with filters off
* Gracefully handle cases when Cyton or Cyton+Daisy users want to use 8 or 16 channels #954
* Update Save Session Settings success message. Session settings are no longer auto-loaded on Session start. #969
* Session settings are no longer auto-saved when system is halted #969

# v5.0.4

### Improvements
Expand Down
67 changes: 67 additions & 0 deletions Networking-Test-Kit/LSL/brainflow_lsl_cyton_accel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import argparse
import time
import numpy as np
import brainflow
from brainflow.board_shim import BoardShim, BrainFlowInputParams, LogLevels, BoardIds
from brainflow.data_filter import DataFilter, FilterTypes, AggOperations
from pylsl import StreamInfo, StreamOutlet

#from queue import Queue
BoardShim.enable_dev_board_logger()
params = BrainFlowInputParams()
params.serial_port = '/dev/cu.usbserial-DM00D7TW'
board = BoardShim(BoardIds.CYTON_BOARD.value, params) # added cyton board id here
srate = board.get_sampling_rate(BoardIds.CYTON_BOARD.value)
board.prepare_session()
board.start_stream()
eeg_chan = BoardShim.get_eeg_channels(BoardIds.CYTON_BOARD.value)
aux_chan = BoardShim.get_accel_channels(BoardIds.CYTON_BOARD.value)

print('EEG channels:')
print(eeg_chan)
print('Accelerometer channels')
print(aux_chan)

# define lsl streams

# Defining stream info:
name = 'OpenBCIEEG'
ID = 'OpenBCIEEG'
channels = 8
sample_rate = 250
datatype = 'float32'
streamType = 'EEG'

print(f"Creating LSL stream for EEG. \nName: {name}\nID: {ID}\n")
info_eeg = StreamInfo(name, streamType, channels, sample_rate, datatype, ID)
chns = info_eeg.desc().append_child("channels")
for label in ["AFp1", "AFp2", "C3", "C4", "P7", "P8", "O1", "O2"]:
ch = chns.append_child("channel")
ch.append_child_value("label", label)
info_aux = StreamInfo('OpenBCIAUX', 'AUX', 3, 250, 'float32', 'OpenBCItestAUX')
chns = info_aux.desc().append_child("channels")
for label in ["X", "Y", "Z"]:
ch = chns.append_child("channel")
ch.append_child_value("label", label)
outlet_aux = StreamOutlet(info_aux)
outlet_eeg = StreamOutlet(info_eeg)

# construct a numpy array that contains only eeg channels and aux channels with correct scaling
# this streams to lsl
while True:
data = board.get_board_data() # this gets data continiously
# don't send empty data
if len(data[0]) < 1 : continue
eeg_data = data[eeg_chan]
aux_data = data[aux_chan]
#print(scaled_eeg_data)
#print(scaled_aux_data)
#print('------------------------------------------------------------------------------------------')
eegchunk = []
for i in range(len(eeg_data[0])):
eegchunk.append((eeg_data[:,i]).tolist()) #scale data here
outlet_eeg.push_chunk(eegchunk)
auxchunk = []
for i in range(len(aux_data[0])):
auxchunk.append((aux_data[:,i]).tolist()) #scale data here
outlet_aux.push_chunk(auxchunk)
40 changes: 40 additions & 0 deletions Networking-Test-Kit/splitLargeCSV.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

import os
import csv


def split(filehandler, delimiter=',', row_limit=4000000,
output_name_template='output_%s.csv', output_path='.', keep_headers=True):

reader = csv.reader(filehandler, delimiter=delimiter)
current_piece = 1
current_out_path = os.path.join(
output_path,
output_name_template % current_piece
)
current_out_writer = csv.writer(open(current_out_path, 'w', newline=''), delimiter=delimiter)
current_limit = row_limit
headers = []
if keep_headers:
for i in range (5):
headerRow = next(reader);
headers.append(headerRow)
current_out_writer.writerow(headerRow)

for i, row in enumerate(reader):
if i + 1 > current_limit:
current_piece += 1
current_limit = row_limit * current_piece
current_out_path = os.path.join(
output_path,
output_name_template % current_piece
)
current_out_writer = csv.writer(open(current_out_path, 'w', newline=''), delimiter=delimiter)
if keep_headers:
for headerRowI in headers:
current_out_writer.writerow(headerRowI)
print (headerRowI)
print (i)
current_out_writer.writerow(row)

split(open('OpenBCI-RAW-2021-04-05_21-49-12.txt', 'r'));
21 changes: 11 additions & 10 deletions OpenBCI_GUI/ADS1299SettingsController.pde
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ class ADS1299SettingsController {
resizeDropdowns(chanBar_h);

resizeCustomCommandUI();

}

//Returns true if board and UI are in sync
Expand Down Expand Up @@ -382,10 +383,10 @@ class ADS1299SettingsController {
}

private void createCustomCommandUI() {
final Textfield _tf = hwsCp5.addTextfield("customCommand")
customCommandTF = hwsCp5.addTextfield("customCommand")
.setPosition(0, 0)
.setCaptionLabel("")
.setSize(10, 10)
.setSize(120, 20)
.setFont(f2)
.setFocus(false)
.setColor(color(26, 26, 26))
Expand All @@ -398,22 +399,21 @@ class ADS1299SettingsController {
.align(5, 10, 20, 40)
.setAutoClear(false) //Don't clear textfield when pressing Enter key
;
_tf.setDescription("Type a custom command and Send to board.");
customCommandTF.setDescription("Type a custom command and Send to board.");
//Clear textfield on double click
_tf.onDoublePress(new CallbackListener() {
customCommandTF.onDoublePress(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
output("[ExpertMode] Enter the custom command you would like to send to the board.");
_tf.clear();
customCommandTF.clear();
}
});
_tf.addCallback(new CallbackListener() {
customCommandTF.addCallback(new CallbackListener() {
public void controlEvent(CallbackEvent theEvent) {
if ((theEvent.getAction() == ControlP5.ACTION_BROADCAST) || (theEvent.getAction() == ControlP5.ACTION_LEAVE)) {
_tf.setFocus(false);
customCommandTF.setFocus(false);
}
}
});
customCommandTF = _tf;

sendCustomCmdButton = createButton(hwsCp5, "sendCustomCommand", "Send Custom Command", 0, 0, 10, 10);
sendCustomCmdButton.setBorderColor(OBJECT_BORDER_GREY);
Expand All @@ -434,7 +434,7 @@ class ADS1299SettingsController {
resizeCustomCommandUI();
}

private void resizeCustomCommandUI() {
public void resizeCustomCommandUI() {
customCmdUI_x = x;
customCmdUI_w = w + 1;
int tf_w = Math.round(button_w * 1.8);
Expand All @@ -445,7 +445,8 @@ class ADS1299SettingsController {
//int tf_w = Math.round((customCmdUI_w - padding_3*2) * .75);
int tf_h = commandBarH - padding_3*2;
customCommandTF.setPosition(tf_x, tf_y);
customCommandTF.setSize(tf_w, tf_h);
customCommandTF.setWidth(tf_w);
customCommandTF.setHeight(tf_h);
int but_x = tf_x + customCommandTF.getWidth() + padding_3;
sendCustomCmdButton.setPosition(but_x, tf_y);
sendCustomCmdButton.setSize(but_w, tf_h - 1);
Expand Down
1 change: 0 additions & 1 deletion OpenBCI_GUI/DataProcessing.pde
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ void processNewData() {

//update the data buffers
for (int Ichan=0; Ichan < channelCount; Ichan++) {

for(int i = 0; i < getCurrentBoardBufferSize(); i++) {
dataProcessingRawBuffer[Ichan][i] = (float)currentData.get(i)[exgChannels[Ichan]];
}
Expand Down
16 changes: 16 additions & 0 deletions OpenBCI_GUI/Extras.pde
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ private boolean isMac() {
return !isWindows() && !isLinux();
}

//BrainFlow only supports Windows 8 and 10. This will help with OpenBCI support tickets. #964
private void checkIsOldVersionOfWindowsOS() {
boolean isOld = SystemUtils.IS_OS_WINDOWS_7 || SystemUtils.IS_OS_WINDOWS_VISTA || SystemUtils.IS_OS_WINDOWS_XP;
if (isOld) {
PopupMessage msg = new PopupMessage("Old Windows OS Detected", "OpenBCI GUI v5 and BrainFlow are made for 64-bit Windows 8, 8.1, and 10. Please update your OS, computer, or revert to GUI v4.2.0.");
}
}

//Sanity check for 64-bit Java for Windows users #964
private void checkIs64BitJava() {
boolean is64Bit = System.getProperty("sun.arch.data.model").indexOf("64") >= 0;
if (!is64Bit) {
PopupMessage msg = new PopupMessage("32-bit Java Detected", "OpenBCI GUI v5 and BrainFlow are made for 64-bit Java (Windows, Linux, and Mac). Please update your OS, computer, Processing IDE, or revert to GUI v4 or earlier.");
}
}


//compute the standard deviation
float std(float[] data) {
Expand Down
Loading

0 comments on commit df2daa2

Please sign in to comment.