Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Brainflow BA_v4 integration #730

Merged
86 changes: 61 additions & 25 deletions src/board_controller/brainalive/brainalive.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
#include <string>

#include "brainalive.h"
#include "custom_cast.h"
#include "get_dll_dir.h"
#include "timestamp.h"

// common constants
#define BRAINALIVE_PACKET_SIZE 224
#include <string.h>

// info about services and chars
#define START_BYTE 0x0A
Expand All @@ -15,10 +11,6 @@
#define BRAINALIVE_WRITE_CHAR "0000fe41-8e22-4541-9d4c-21edae82ed19"
#define BRAINALIVE_NOTIFY_CHAR "0000fe42-8e22-4541-9d4c-21edae82ed19"

// info for equations
#define BRAINALIVE_EEG_SCALE_FACTOR 0.0476837158203125
#define BRAINALIVE_EEG_GAIN_VALUE 12


static void brainalive_adapter_1_on_scan_found (
simpleble_adapter_t adapter, simpleble_peripheral_t peripheral, void *board)
Expand All @@ -29,7 +21,16 @@ static void brainalive_adapter_1_on_scan_found (
static void brainalive_read_notifications (simpleble_uuid_t service,
simpleble_uuid_t characteristic, uint8_t *data, size_t size, void *board)
{
((BrainAlive *)(board))->read_data (service, characteristic, data, size, 0);
if (size == BrainAlive::brainalive_handshaking_packet_size)
{
((BrainAlive *)(board))->setSoftwareGain (data[1]);
((BrainAlive *)(board))->setHardwareGain (data[2]);
((BrainAlive *)(board))->setReferenceVoltage (((data[3] << 8) | data[4]));
}
else
{
((BrainAlive *)(board))->read_data (service, characteristic, data, size, 0);
}
}

BrainAlive::BrainAlive (struct BrainFlowInputParams params)
Expand Down Expand Up @@ -302,7 +303,6 @@ int BrainAlive::config_board (std::string config)
return (int)BrainFlowExitCodes::BOARD_NOT_CREATED_ERROR;
}
uint8_t command[5];
size_t len = config.size ();
command[0] = 0x0a;
command[1] = 0x81; // it is hardcoded for now only
command[2] = 0x00;
Expand Down Expand Up @@ -342,7 +342,7 @@ void BrainAlive::adapter_1_on_scan_found (
}
else
{
if (strncmp (peripheral_identified, "ORION_1", 7) == 0)
if (strncmp (peripheral_identified, "BA_FLEX", 7) == 0)
{
found = true;
}
Expand Down Expand Up @@ -371,21 +371,57 @@ void BrainAlive::adapter_1_on_scan_found (
void BrainAlive::read_data (simpleble_uuid_t service, simpleble_uuid_t characteristic,
uint8_t *data, size_t size, int channel_num)
{
if (size != BRAINALIVE_PACKET_SIZE)
if (size == brainalive_packet_size)
{
safe_logger (spdlog::level::warn, "unknown size of BrainAlive Data {}", size);
return;
}

for (int i = 0; i < (int)size; i += 32)
{
double eeg_data[9] = {0};
for (int j = i + 4, k = 0; j < i + 28; j += 3, k++)
for (int i = 0; i < (int)size; i += brainalive_single_packet_size)
{
eeg_data[k] = (((data[j] << 16 | data[j + 1] << 8 | data[j + 2]) << 8) >> 8) *
BRAINALIVE_EEG_SCALE_FACTOR / BRAINALIVE_EEG_GAIN_VALUE;

int num_rows = board_descr["default"]["num_rows"];
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"];
std::vector<int> accel_channels = board_descr["default"]["accel_channels"];
std::vector<int> gyro_channels = board_descr["default"]["gyro_channels"];

package[board_descr["default"]["package_num_channel"].get<int> ()] =
data[brainalive_packet_index + i];

for (int j = i + brainalive_eeg_Start_index, k = 0; j < i + brainalive_eeg_end_index;
j += 3, k++)
{
package[eeg_channels[k]] =
(float)(((data[j] << 16 | data[j + 1] << 8 | data[j + 2]) << 8) >> 8) *
((((float)getReferenceVoltage () * 1000) /
(float)(getSoftwareGain () * getHardwareGain () * FSR_Value)));
}

for (int j = i + brainalive_axl_start_index, k = 0; j < i + brainalive_axl_end_index;
j += 2, k++)
{
package[accel_channels[k]] = (data[j] << 8) | data[j + 1];
if (package[accel_channels[k]] > 32767)
package[accel_channels[k]] = package[accel_channels[k]] - 65535;
}
for (int j = i + brainalive_gyro_start_index, k = 0; j < i + brainalive_gyro_end_index;
j += 2, k++)
{
package[gyro_channels[k]] = (data[j] << 8) | data[j + 1];
if (package[gyro_channels[k]] > 32767)
package[gyro_channels[k]] = package[gyro_channels[k]] - 65535;
}
package[board_descr["default"]["marker_channel"].get<int> ()] =
data[(brainalive_packet_index + 1) + i];
package[board_descr["default"]["timestamp_channel"].get<int> ()] = get_timestamp ();

push_package (&package[0]);
}
eeg_data[8] = data[i + 29];
push_package (&eeg_data[0]);
}
else
{
safe_logger (spdlog::level::warn, "unknown size of BrainAlive Data {}", size);
return;
}
}
61 changes: 61 additions & 0 deletions src/board_controller/brainalive/inc/brainalive.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

class BrainAlive : public BLELibBoard
{

private:
int software_gain = 0;
int hardware_gain = 0;
int reference_voltage = 0;

public:
BrainAlive (struct BrainFlowInputParams params);
~BrainAlive ();
Expand All @@ -22,6 +28,61 @@ class BrainAlive : public BLELibBoard
void adapter_1_on_scan_found (simpleble_adapter_t adapter, simpleble_peripheral_t peripheral);
void read_data (simpleble_uuid_t service, simpleble_uuid_t characteristic, uint8_t *data,
size_t size, int channel_num);
void setSoftwareGain (int gain)
{
software_gain = gain;
}

void setHardwareGain (int gain)
{
hardware_gain = gain;
}

void setReferenceVoltage (int voltage)
{
reference_voltage = voltage;
}

int getSoftwareGain () const
{
return software_gain;
}

int getHardwareGain () const
{
return hardware_gain;
}

int getReferenceVoltage () const
{
return reference_voltage;
}

// common constants
static constexpr int brainalive_packet_size = 220;
static constexpr int brainalive_single_packet_size = 44;
static constexpr int num_of_packets = brainalive_packet_size / brainalive_single_packet_size;

static constexpr int brainalive_packet_index = (brainalive_single_packet_size - 3);

static constexpr int brainalive_eeg_data_szie = 24;
static constexpr int brainalive_eeg_Start_index = 4;
static constexpr int brainalive_eeg_end_index =
(brainalive_eeg_Start_index + brainalive_eeg_data_szie);

static constexpr int brainalive_axl_data_size = 6;
static constexpr int brainalive_gyro_data_size = 6;
static constexpr int brainalive_axl_start_index = brainalive_eeg_end_index;
static constexpr int brainalive_axl_end_index =
brainalive_axl_start_index + brainalive_axl_data_size;
static constexpr int brainalive_gyro_start_index = brainalive_axl_end_index;
static constexpr int brainalive_gyro_end_index =
brainalive_gyro_start_index + brainalive_gyro_data_size;
static constexpr int FSR_Value = 8388607;
static constexpr int ba_brainflow_package_size = 17;

static constexpr int brainalive_handshaking_packet_size = 6;


protected:
volatile simpleble_adapter_t brainalive_adapter;
Expand Down
8 changes: 4 additions & 4 deletions src/board_controller/brainflow_boards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,14 +710,14 @@ BrainFlowBoards::BrainFlowBoards()
{
{"name", "BrainAlive"},
{"sampling_rate", 250},
{"timestamp_channel", 15},
{"marker_channel", 16},
{"package_num_channel", 0},
{"marker_channel", 15},
{"timestamp_channel", 16},
{"num_rows", 17},
{"package_num_channel", 0},
{"eeg_channels", {1, 2, 3, 4, 5, 6, 7, 8}},
{"eeg_names", "F7,FT7,T7,CP5,CZ,C6,FC6,F4"},
{"accel_channels", {9, 10, 11}},
{"ppg_channels", {12, 13, 14}}
{"gyro_channels", {12, 13, 14}}
};
brainflow_boards_json["boards"]["41"]["default"] =
{
Expand Down
Loading