Skip to content

Commit 1050c9e

Browse files
author
Andrey Parfenov
committed
Merge remote-tracking branch 'openbci/master'
2 parents 182a73f + 465e90d commit 1050c9e

26 files changed

+330
-45
lines changed

appveyor.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,13 @@ after_test:
139139
# New-Item $env:APPVEYOR_BUILD_FOLDER\linux -itemtype directory
140140
# New-Item $env:APPVEYOR_BUILD_FOLDER\osx -itemtype directory
141141
# aws s3 cp s3://brainflow-artifacts/$env:APPVEYOR_REPO_COMMIT/linux/ $env:APPVEYOR_BUILD_FOLDER\linux\ --recursive
142+
# ls $env:APPVEYOR_BUILD_FOLDER\linux
142143
# aws s3 cp s3://brainflow-artifacts/$env:APPVEYOR_REPO_COMMIT/osx/ $env:APPVEYOR_BUILD_FOLDER\osx\ --recursive
144+
# ls $env:APPVEYOR_BUILD_FOLDER\osx
143145
# cd $env:APPVEYOR_BUILD_FOLDER\java-package\brainflow
146+
# Copy-Item "$env:APPVEYOR_BUILD_FOLDER\linux\*" -Destination "$env:APPVEYOR_BUILD_FOLDER\java-package\brainflow\src\main\resources" -Recurse
147+
# Copy-Item "$env:APPVEYOR_BUILD_FOLDER\osx\*" -Destination "$env:APPVEYOR_BUILD_FOLDER\java-package\brainflow\src\main\resources" -Recurse
148+
# ls $env:APPVEYOR_BUILD_FOLDER\java-package\brainflow\src\main\resources;
144149
# mvn package > mvn_final_stdout.txt
145150
# #upload .jars to aws
146151
# aws s3 cp %APPVEYOR_BUILD_FOLDER%\java-package\brainflow\target\ s3://brainflow-artifacts/%APPVEYOR_REPO_COMMIT%/jars --recursive
@@ -163,7 +168,6 @@ after_test:
163168
# Else {
164169
# write-output "Failed to wait for mac and linux libs"
165170
# }
166-
167171
# on_finish:
168172
# - appveyor PushArtifact %APPVEYOR_BUILD_FOLDER%\build32\brainflow_build32_stdout.txt
169173
# - appveyor PushArtifact %APPVEYOR_BUILD_FOLDER%\build64\brainflow_build64_stdout.txt

brainflow_boards.json

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,24 @@
1313
"eda_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
1414
"ppg_channels" : [],
1515
"accel_channels" : [9, 10, 11],
16+
"analog_channels" : [],
1617
"gyro_channels": [],
1718
"other_channels": []
1819
},
1920
"0" : {
2021
"name": "Cyton",
2122
"sampling_rate": 250,
2223
"package_num_channel" : 0,
23-
"timestamp_channel" : 19,
24-
"num_rows" : 20,
24+
"timestamp_channel" : 22,
25+
"num_rows" : 23,
2526
"eeg_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
2627
"emg_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
2728
"ecg_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
2829
"eog_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
2930
"eda_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
3031
"ppg_channels" : [],
3132
"accel_channels" : [9, 10, 11],
33+
"analog_channels" : [19, 20, 21],
3234
"gyro_channels": [],
3335
"other_channels": [12, 13, 14, 15, 16, 17, 18]
3436
},
@@ -45,22 +47,24 @@
4547
"eda_channels" : [1, 2, 3, 4],
4648
"ppg_channels" : [],
4749
"accel_channels" : [5, 6, 8],
50+
"analog_channels" : [],
4851
"gyro_channels": [],
4952
"other_channels": []
5053
},
5154
"2" : {
5255
"name": "CytonDaisy",
5356
"sampling_rate": 125,
5457
"package_num_channel" : 0,
55-
"timestamp_channel" : 27,
56-
"num_rows" : 28,
58+
"timestamp_channel" : 30,
59+
"num_rows" : 31,
5760
"eeg_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
5861
"emg_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
5962
"ecg_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
6063
"eog_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
6164
"eda_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
6265
"ppg_channels" : [],
6366
"accel_channels" : [17, 18, 19],
67+
"analog_channels" : [27, 28, 29],
6468
"gyro_channels": [],
6569
"other_channels": [20, 21, 22, 23, 24, 25, 26]
6670
},
@@ -77,56 +81,60 @@
7781
"eda_channels" : [18],
7882
"ppg_channels" : [17],
7983
"accel_channels" : [19, 20, 21],
84+
"analog_channels" : [],
8085
"gyro_channels": [22, 23, 24],
8186
"other_channels": []
8287
},
8388
"4" : {
8489
"name": "GanglionWifi",
8590
"sampling_rate": 1600,
8691
"package_num_channel" : 0,
87-
"timestamp_channel" : 15,
88-
"num_rows" : 16,
92+
"timestamp_channel" : 18,
93+
"num_rows" : 19,
8994
"eeg_channels" : [1, 2, 3, 4],
9095
"emg_channels" : [1, 2, 3, 4],
9196
"ecg_channels" : [1, 2, 3, 4],
9297
"eog_channels" : [1, 2, 3, 4],
9398
"eda_channels" : [1, 2, 3, 4],
9499
"ppg_channels" : [],
95100
"accel_channels" : [5, 6, 7],
101+
"analog_channels" : [15, 16, 17],
96102
"gyro_channels": [],
97103
"other_channels": [8, 9, 10, 11, 12, 13, 14]
98104
},
99105
"5" : {
100106
"name": "CytonWifi",
101107
"sampling_rate": 1000,
102108
"package_num_channel" : 0,
103-
"timestamp_channel" : 19,
104-
"num_rows" : 20,
109+
"timestamp_channel" : 22,
110+
"num_rows" : 23,
105111
"eeg_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
106112
"emg_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
107113
"ecg_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
108114
"eog_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
109115
"eda_channels" : [1, 2, 3, 4, 5, 6, 7, 8],
110116
"ppg_channels" : [],
111117
"accel_channels" : [8, 10, 11],
118+
"analog_channels" : [19, 20, 21],
112119
"gyro_channels": [],
113120
"other_channels": [12, 13, 14, 15, 16, 17, 18]
114121
},
115122
"6" : {
116123
"name": "CytonDaisyWifi",
117124
"sampling_rate": 1000,
118125
"package_num_channel" : 0,
119-
"timestamp_channel" : 27,
120-
"num_rows" : 28,
126+
"timestamp_channel" : 30,
127+
"num_rows" : 31,
121128
"eeg_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
122129
"emg_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
123130
"ecg_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
124131
"eog_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
125132
"eda_channels" : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
126133
"ppg_channels" : [],
127134
"accel_channels" : [17, 18, 19],
135+
"analog_channels" : [27, 28, 29],
128136
"gyro_channels": [],
129-
"other_channels": [20, 21, 22, 23, 24, 25, 26, 27]
137+
"other_channels": [20, 21, 22, 23, 24, 25, 26]
130138
}
131139
}
132140
}

cpp-package/src/board_shim.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,17 @@ int *BoardShim::get_accel_channels (int board_id, int *len)
317317
return accel_channels;
318318
}
319319

320+
int *BoardShim::get_analog_channels (int board_id, int *len)
321+
{
322+
int *analog_channels = new int[MAX_CHANNELS];
323+
int res = ::get_analog_channels (board_id, analog_channels, len);
324+
if (res != STATUS_OK)
325+
{
326+
throw BrainFlowException ("failed get board info", res);
327+
}
328+
return analog_channels;
329+
}
330+
320331
int *BoardShim::get_other_channels (int board_id, int *len)
321332
{
322333
int *other_channels = new int[MAX_CHANNELS];

cpp-package/src/board_shim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class BoardShim
3333
static int *get_ppg_channels (int board_id, int *len);
3434
static int *get_eda_channels (int board_id, int *len);
3535
static int *get_accel_channels (int board_id, int *len);
36+
static int *get_analog_channels (int board_id, int *len);
3637
static int *get_gyro_channels (int board_id, int *len);
3738
static int *get_other_channels (int board_id, int *len);
3839

csharp-package/brainflow/brainflow/board_controller_library.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ public static class BoardControllerLibrary64
8989
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
9090
public static extern int get_accel_channels (int board_id, int[] channels, int[] len);
9191
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
92+
public static extern int get_analog_channels (int board_id, int[] channels, int[] len);
93+
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
9294
public static extern int get_gyro_channels (int board_id, int[] channels, int[] len);
9395
[DllImport ("BoardController.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
9496
public static extern int get_other_channels (int board_id, int[] channels, int[] len);
@@ -139,6 +141,8 @@ public static class BoardControllerLibrary32
139141
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
140142
public static extern int get_accel_channels (int board_id, int[] channels, int[] len);
141143
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
144+
public static extern int get_analog_channels (int board_id, int[] channels, int[] len);
145+
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
142146
public static extern int get_gyro_channels (int board_id, int[] channels, int[] len);
143147
[DllImport ("BoardController32.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
144148
public static extern int get_other_channels (int board_id, int[] channels, int[] len);
@@ -314,6 +318,14 @@ public static int get_accel_channels (int board_id, int[] channels, int[] len)
314318
return BoardControllerLibrary32.get_accel_channels (board_id, channels, len);
315319
}
316320

321+
public static int get_analog_channels (int board_id, int[] channels, int[] len)
322+
{
323+
if (System.Environment.Is64BitProcess)
324+
return BoardControllerLibrary64.get_analog_channels (board_id, channels, len);
325+
else
326+
return BoardControllerLibrary32.get_analog_channels (board_id, channels, len);
327+
}
328+
317329
public static int get_gyro_channels (int board_id, int[] channels, int[] len)
318330
{
319331
if (System.Environment.Is64BitProcess)

csharp-package/brainflow/brainflow/board_shim.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,23 @@ public static int[] get_accel_channels (int board_id)
179179
return result;
180180
}
181181

182+
public static int[] get_analog_channels (int board_id)
183+
{
184+
int[] len = new int[1];
185+
int[] channels = new int[512];
186+
int res = BoardControllerLibrary.get_analog_channels (board_id, channels, len);
187+
if (res != (int)CustomExitCodes.STATUS_OK)
188+
{
189+
throw new BrainFlowException (res);
190+
}
191+
int[] result = new int[len[0]];
192+
for (int i = 0; i < len[0]; i++)
193+
{
194+
result[i] = channels[i];
195+
}
196+
return result;
197+
}
198+
182199
public static int[] get_gyro_channels (int board_id)
183200
{
184201
int[] len = new int[1];

docs/BuildBrainFlow.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Common requirements
66

77
- Windows >= 8.1/Linux/MacOS
88
- On Windows we support x86/x64 libraries, for MacOS and Linux - only x64 bit libraries, if you need 32bit libraries for Linux you should compile them by yourself
9-
- For Ganglion on Windows if you dont compile brainflow by yorself you may need to install `redist_x64 <https://aka.ms/vs/16/release/vc_redist.x64.exe>`_ or `redist_x86 <https://aka.ms/vs/16/release/vc_redist.x86.exe>`_ (but more likely you have it preinstalled) to use built-in Bluetooth API also you need Windows >= 10
9+
- For Ganglion on Windows if you dont compile brainflow by yourself you may need to install `redist_x64 <https://aka.ms/vs/16/release/vc_redist.x64.exe>`_ or `redist_x86 <https://aka.ms/vs/16/release/vc_redist.x86.exe>`_ (but more likely you have it preinstalled) to use built-in Bluetooth API also you need Windows >= 10
1010
- For Ganglion on Linux/MacOS you need to use dongle, for Windows dongle is not required if you have Bluetooth on your laptop
1111

1212
Compilation (Core module)
@@ -73,7 +73,7 @@ C#
7373

7474
For C# only Windows is currently supported
7575

76-
You can download latest release from `Nuget <https://www.nuget.org/packages/brainflow/>`_ or build it youself:
76+
You can download latest release from `Nuget <https://www.nuget.org/packages/brainflow/>`_ or build it yourself:
7777

7878
- Compile BrainFlow's core module
7979
- open Visual Studio Solution

docs/DataFormatDesc.rst

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
Data Format Description
2+
=========================
3+
4+
**Methods like:**
5+
6+
.. code-block:: python
7+
8+
get_board_data ()
9+
get_current_board_data (max_num_packages)
10+
11+
**Return 2d double array [num_channels x num_data_points], rows of this array contain data for EEG, EMG, Accel, Timesteps and other kinds of data.**
12+
13+
Exact format for this array is board specific but to keep API uniform we have methods like:
14+
15+
.. code-block:: python
16+
17+
# these methods return an array of rows in this 2d array containing eeg\emg\ecg\accel data
18+
get_eeg_channels (board_id)
19+
get_emg_channels (board_id)
20+
get_ecg_channels (board_id)
21+
get_accel_channels (board_id)
22+
# and so on, check docs for full list
23+
# also we have methods to get sampling rate from board id, get number of timestamp channel and others
24+
get_sampling_rate (board_id)
25+
get_timestamp_channel (board_id)
26+
# and so on
27+
28+
Using methods above you can write completely board agnostic code and switch boards using single parameter! Even if you have only one board using these methods you can easily switch to Synthetic board for development and run code without real hardware.
29+
30+
Special channels for Cyton Based boards
31+
-----------------------------------------
32+
33+
`Cyton based boards from OpenBCI <https://docs.openbci.com/Tutorials/00-Tutorials>`_ suport different output formats like described `here <https://docs.openbci.com/docs/02Cyton/CytonDataFormat#firmware-version-200-fall-2016-to-now-1>`_.
34+
35+
**For Cyton based boards we add Cyton End byte to a first channel from:**
36+
37+
.. code-block:: python
38+
39+
get_other_channels (board_id)
40+
41+
**If Cyton End bytes is equal to 0xC0 we add accel data, to get rows which contain accel data use:**
42+
43+
.. code-block:: python
44+
45+
get_accel_channels (board_id)
46+
47+
**If Cyton End bytes is equal to 0xC1 we add analog data, to get rows which contain analog data use:**
48+
49+
.. code-block:: python
50+
51+
get_analog_channels (board_id)
52+
53+
For analog data we return int32 values but from low level API we return double array so these values were casted to double wo any changes.
54+
55+
**If Cyton End Byte is between 0xC2 and 0xC6 we add raw unprocessed bytes to the second and following channels returned by:**
56+
57+
.. code-block:: python
58+
59+
get_other_channels (board_id)
60+
61+
For such data we return unprocessed raw bytes you should cast them to integer or floats
62+
63+
If Cyton End Byte outside `this range <https://docs.openbci.com/docs/02Cyton/CytonDataFormat#firmware-version-200-fall-2016-to-now-1>`_ we drop entire package.
64+
65+
**Check this example for details:**
66+
67+
.. literalinclude:: ../tests/python/brainflow_analog_mode_other_data.py
68+
:language: py

docs/UserAPI.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,4 @@ Check R sample to see how to use it.
116116
Full code for R binding:
117117

118118
.. literalinclude:: ../r-package/brainflow/R/board_shim.R
119-
:language: r
119+
:language: r

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ These versions are exactly the same, choose one and use it
2121
BuildBrainFlow
2222
CoreModuleAPI
2323
UserAPI
24+
DataFormatDesc
2425
Examples
2526
BrainFlowDev
2627
BrainFlowEmulator

java-package/brainflow/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<include>libBoardController.dylib</include>
2828
<include>brainflow_boards.json</include>
2929
<include>DataHandler.dll</include>
30-
<include>libDataHandler.dll</include>
30+
<include>libDataHandler.so</include>
3131
<include>libDataHandler.dylib</include>
3232
</includes>
3333
</resource>

java-package/brainflow/src/main/java/brainflow/BoardShim.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ private interface DllInterface extends Library {
3535
int get_eda_channels (int board_id, int[] eda_channels, int[] len);
3636
int get_ppg_channels (int board_id, int[] ppg_channels, int[] len);
3737
int get_accel_channels (int board_id, int[] accel_channels, int[] len);
38+
int get_analog_channels (int board_id, int[] analog_channels, int[] len);
3839
int get_gyro_channels (int board_id, int[] gyro_channels, int[] len);
3940
int get_other_channels (int board_id, int[] other_channels, int[] len);
4041
}
@@ -212,6 +213,17 @@ public static int[] get_accel_channels (int board_id) throws BrainFlowError {
212213

213214
return Arrays.copyOfRange(channels, 0, len[0]);
214215
}
216+
217+
public static int[] get_analog_channels (int board_id) throws BrainFlowError {
218+
int[] len = new int[1];
219+
int[] channels = new int[512];
220+
int ec = instance.get_analog_channels (board_id, channels, len);
221+
if (ec != ExitCode.STATUS_OK.get_code ()) {
222+
throw new BrainFlowError ("Error in board info getter", ec);
223+
}
224+
225+
return Arrays.copyOfRange(channels, 0, len[0]);
226+
}
215227

216228
public static int[] get_gyro_channels (int board_id) throws BrainFlowError {
217229
int[] len = new int[1];

0 commit comments

Comments
 (0)