Skip to content

Commit

Permalink
Add NTL Wifi Board (#634)
Browse files Browse the repository at this point in the history
* Add NTL Wifi Board

Signed-off-by: Andrey Parfenov <a1994ndrey@gmail.com>
Co-authored-by: Andrey Parfenov <a1994ndrey@gmail.com>
  • Loading branch information
justinmccombs and Andrey1994 committed Jun 4, 2023
1 parent f495392 commit aaa651b
Show file tree
Hide file tree
Showing 12 changed files with 195 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public enum BoardIds
EMOTIBIT_BOARD = 47,
GALEA_BOARD_V4 = 48,
GALEA_SERIAL_BOARD_V4 = 49,
NTL_WIFI_BOARD = 50,
ANT_NEURO_EE_511_BOARD = 51
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public enum BoardIds
EMOTIBIT_BOARD (47),
GALEA_BOARD_V4 (48),
GALEA_SERIAL_BOARD_V4 (49),
NTL_WIFI_BOARD (50),
ANT_NEURO_EE_511_BOARD (51);

private final int board_id;
Expand Down
1 change: 1 addition & 0 deletions julia_package/brainflow/src/board_shim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export BrainFlowInputParams
EMOTIBIT_BOARD = 47
GALEA_BOARD_V4 = 48
GALEA_SERIAL_BOARD_V4 = 49
NTL_WIFI_BOARD = 50
ANT_NEURO_EE_511_BOARD = 51

end
Expand Down
1 change: 1 addition & 0 deletions matlab_package/brainflow/BoardIds.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
EMOTIBIT_BOARD(47)
GALEA_BOARD_V4(48)
GALEA_SERIAL_BOARD_V4(49)
NTL_WIFI_BOARD(50)
ANT_NEURO_EE_511_BOARD(51)
end
end
1 change: 1 addition & 0 deletions python_package/brainflow/board_shim.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class BoardIds(enum.IntEnum):
EMOTIBIT_BOARD = 47 #:
GALEA_BOARD_V4 = 48 #:
GALEA_SERIAL_BOARD_V4 = 49 #:
NTL_WIFI_BOARD = 50 #:
ANT_NEURO_EE_511_BOARD = 51 #:


Expand Down
1 change: 1 addition & 0 deletions rust_package/brainflow/src/ffi/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub enum BoardIds {
EmotibitBoard = 47,
GaleaBoardV4 = 48,
GaleaSerialBoardV4 = 49,
NtlWifiBoard = 50,
}
#[repr(i32)]
#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone, Hash, PartialEq, Eq)]
Expand Down
4 changes: 4 additions & 0 deletions src/board_controller/board_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "muse.h"
#include "muse_bled.h"
#include "notion_osc.h"
#include "ntl_wifi.h"
#include "playback_file_board.h"
#include "streaming_board.h"
#include "synthetic_board.h"
Expand Down Expand Up @@ -260,6 +261,9 @@ int prepare_session (int board_id, const char *json_brainflow_input_params)
board = std::shared_ptr<Board> (
new AntNeuroBoard ((int)BoardIds::ANT_NEURO_EE_511_BOARD, params));
break;
case BoardIds::NTL_WIFI_BOARD:
board = std::shared_ptr<Board> (new NtlWifi (params));
break;
default:
return (int)BrainFlowExitCodes::UNSUPPORTED_BOARD_ERROR;
}
Expand Down
19 changes: 19 additions & 0 deletions src/board_controller/brainflow_boards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ BrainFlowBoards::BrainFlowBoards()
{"47", json::object()},
{"48", json::object()},
{"49", json::object()},
{"50", json::object()},
{"51", json::object()}
}
}};
Expand Down Expand Up @@ -946,6 +947,24 @@ BrainFlowBoards::BrainFlowBoards()
{"other_channels", {15, 16}},
{"temperature_channels", {4}}
};
brainflow_boards_json["boards"]["50"]["default"] =
{
{"name", "NtlWifi"},
{"sampling_rate", 250},
{"package_num_channel", 0},
{"timestamp_channel", 23},
{"marker_channel", 24},
{"num_rows", 25},
{"eeg_channels", {1, 2, 3, 4, 5, 6, 7, 8}},
{"eeg_names", "Fp1,Fp2,C3,C4,P7,P8,O1,O2"},
{"emg_channels", {1, 2, 3, 4, 5, 6, 7, 8}},
{"ecg_channels", {1, 2, 3, 4, 5, 6, 7, 8}},
{"eog_channels", {1, 2, 3, 4, 5, 6, 7, 8}},
{"accel_channels", {9, 10, 11}},
{"analog_channels", {19, 20, 21}},
{"other_channels", {12, 13, 14, 15, 16, 17, 18}},
{"battery_channel", 22}
};
brainflow_boards_json["boards"]["51"]["default"] =
{
{"name", "AntNeuroEE511"},
Expand Down
2 changes: 2 additions & 0 deletions src/board_controller/build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ SET (BOARD_CONTROLLER_SRC
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/muse/muse.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/brainalive/brainalive.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/emotibit/emotibit.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/ntl/ntl_wifi.cpp
)

include (${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/ant_neuro/build.cmake)
Expand Down Expand Up @@ -136,6 +137,7 @@ target_include_directories (
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/brainalive/inc
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/mentalab/inc
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/emotibit/inc
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/ntl/inc
)

target_compile_definitions(${BOARD_CONTROLLER_NAME} PRIVATE NOMINMAX BRAINFLOW_VERSION=${BRAINFLOW_VERSION})
Expand Down
26 changes: 26 additions & 0 deletions src/board_controller/ntl/inc/ntl_wifi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <math.h>

#include "openbci_wifi_shield_board.h"

#define ADS1299_Vref 4.5
#define ADS1299_gain 24.0

class NtlWifi : public OpenBCIWifiShieldBoard
{
double eeg_scale = (double)(ADS1299_Vref / float ((pow (2, 23) - 1)) / ADS1299_gain * 1000000.);
double accel_scale = (double)(0.002 / (pow (2, 4)));

protected:
void read_thread ();

public:
// package num, 8 eeg channels, 3 accel channels
NtlWifi (struct BrainFlowInputParams params)
: OpenBCIWifiShieldBoard (params, (int)BoardIds::NTL_WIFI_BOARD)
{
}

int prepare_session ();
};
137 changes: 137 additions & 0 deletions src/board_controller/ntl/ntl_wifi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include <vector>

#include "custom_cast.h"
#include "ntl_wifi.h"
#include "timestamp.h"

#ifndef _WIN32
#include <errno.h>
#endif


#define START_BYTE 0xA0
#define END_BYTE_STANDARD 0xC0
#define END_BYTE_ANALOG 0xC1
#define END_BYTE_MAX 0xC6


// load default settings for cyton boards
int NtlWifi::prepare_session ()
{
int res = OpenBCIWifiShieldBoard::prepare_session ();
if (res != (int)BrainFlowExitCodes::STATUS_OK)
{
return res;
}
return send_config ("d");
}

void NtlWifi::read_thread ()
{
/*
Byte 1: 0xA0
Byte 2: Sample Number
Bytes 3-5: Data value for EEG channel 1
Bytes 6-8: Data value for EEG channel 2
Bytes 9-11: Data value for EEG channel 3
Bytes 12-14: Data value for EEG channel 4
Bytes 15-17: Data value for EEG channel 5
Bytes 18-20: Data value for EEG channel 6
Bytes 21-23: Data value for EEG channel 6
Bytes 24-26: Data value for EEG channel 8
Aux Data Bytes 27-32: 6 bytes of data
Byte 33: 0xCX where X is 0-F in hex
*/
int res;
unsigned char b[OpenBCIWifiShieldBoard::package_size];
double accel[3] = {0.};
int num_rows = board_descr["default"]["num_rows"].get<int> ();
double *package = new double[num_rows];
for (int i = 0; i < num_rows; i++)
{
package[i] = 0.0;
}
std::vector<int> eeg_channels = board_descr["default"]["eeg_channels"];

while (keep_alive)
{
// check start byte
res = server_socket->recv (b, OpenBCIWifiShieldBoard::package_size);
if (res != OpenBCIWifiShieldBoard::package_size)
{
if (res < 0)
{
#ifdef _WIN32
safe_logger (spdlog::level::warn, "WSAGetLastError is {}", WSAGetLastError ());
#else
safe_logger (spdlog::level::warn, "errno {} message {}", errno, strerror (errno));
#endif
}

continue;
}

if (b[0] != START_BYTE)
{
continue;
}
unsigned char *bytes = b + 1; // for better consistency between plain cyton and wifi, in
// plain cyton index is shifted by 1

if ((bytes[31] < END_BYTE_STANDARD) || (bytes[31] > END_BYTE_MAX))
{
safe_logger (spdlog::level::warn, "Wrong end byte {}", bytes[31]);
continue;
}

// package num
package[board_descr["default"]["package_num_channel"].get<int> ()] = (double)bytes[0];
// eeg
for (unsigned int i = 0; i < eeg_channels.size (); i++)
{
package[eeg_channels[i]] = eeg_scale * cast_24bit_to_int32 (bytes + 1 + 3 * i);
}
package[board_descr["default"]["other_channels"][0].get<int> ()] =
(double)bytes[31]; // end byte
// place unprocessed bytes for all modes to other_channels
package[board_descr["default"]["other_channels"][1].get<int> ()] = (double)bytes[25];
package[board_descr["default"]["other_channels"][2].get<int> ()] = (double)bytes[26];
package[board_descr["default"]["other_channels"][3].get<int> ()] = (double)bytes[27];
package[board_descr["default"]["other_channels"][4].get<int> ()] = (double)bytes[28];
package[board_descr["default"]["other_channels"][5].get<int> ()] = (double)bytes[29];
package[board_descr["default"]["other_channels"][6].get<int> ()] = (double)bytes[30];
// place processed bytes for accel
if (bytes[31] == END_BYTE_STANDARD)
{
int32_t accel_temp[3] = {0};
accel_temp[0] = cast_16bit_to_int32 (bytes + 25);
accel_temp[1] = cast_16bit_to_int32 (bytes + 27);
accel_temp[2] = cast_16bit_to_int32 (bytes + 29);

if (accel_temp[0] != 0)
{
accel[0] = accel_scale * accel_temp[0];
accel[1] = accel_scale * accel_temp[1];
accel[2] = accel_scale * accel_temp[2];
}
package[board_descr["default"]["battery_channel"].get<int> ()] = (double)bytes[28];
package[board_descr["default"]["accel_channels"][0].get<int> ()] = accel[0];
package[board_descr["default"]["accel_channels"][1].get<int> ()] = accel[1];
package[board_descr["default"]["accel_channels"][2].get<int> ()] = accel[2];
}
// place processed bytes for analog
if (bytes[31] == END_BYTE_ANALOG)
{
package[board_descr["default"]["analog_channels"][0].get<int> ()] =
cast_16bit_to_int32 (bytes + 25);
package[board_descr["default"]["analog_channels"][1].get<int> ()] =
cast_16bit_to_int32 (bytes + 27);
package[board_descr["default"]["analog_channels"][2].get<int> ()] =
cast_16bit_to_int32 (bytes + 29);
}

package[board_descr["default"]["timestamp_channel"].get<int> ()] = get_timestamp ();
push_package (package);
}
delete[] package;
}
1 change: 1 addition & 0 deletions src/utils/inc/brainflow_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ enum class BoardIds : int
EMOTIBIT_BOARD = 47,
GALEA_BOARD_V4 = 48,
GALEA_SERIAL_BOARD_V4 = 49,
NTL_WIFI_BOARD = 50,
ANT_NEURO_EE_511_BOARD = 51,
// use it to iterate
FIRST = PLAYBACK_FILE_BOARD,
Expand Down

0 comments on commit aaa651b

Please sign in to comment.