From a0b554d24354306f97ce63b668067ef7c78e45f5 Mon Sep 17 00:00:00 2001 From: Sarthak Malik <69571797+Sarthak031@users.noreply.github.com> Date: Wed, 3 Jul 2024 23:07:26 +0300 Subject: [PATCH] Brainflow BA_v4 integration (#730) * BrainAlive v4 --------- Co-authored-by: sarveshdhar --- .../brainalive/brainalive.cpp | 86 +++++++++++++------ .../brainalive/inc/brainalive.h | 61 +++++++++++++ src/board_controller/brainflow_boards.cpp | 8 +- 3 files changed, 126 insertions(+), 29 deletions(-) diff --git a/src/board_controller/brainalive/brainalive.cpp b/src/board_controller/brainalive/brainalive.cpp index e9f388f60..fbd95e341 100644 --- a/src/board_controller/brainalive/brainalive.cpp +++ b/src/board_controller/brainalive/brainalive.cpp @@ -1,12 +1,8 @@ -#include - #include "brainalive.h" #include "custom_cast.h" #include "get_dll_dir.h" #include "timestamp.h" - -// common constants -#define BRAINALIVE_PACKET_SIZE 224 +#include // info about services and chars #define START_BYTE 0x0A @@ -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) @@ -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) @@ -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; @@ -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; } @@ -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 eeg_channels = board_descr["default"]["eeg_channels"]; + std::vector accel_channels = board_descr["default"]["accel_channels"]; + std::vector gyro_channels = board_descr["default"]["gyro_channels"]; + + package[board_descr["default"]["package_num_channel"].get ()] = + 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 ()] = + data[(brainalive_packet_index + 1) + i]; + package[board_descr["default"]["timestamp_channel"].get ()] = 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; } } diff --git a/src/board_controller/brainalive/inc/brainalive.h b/src/board_controller/brainalive/inc/brainalive.h index ef893ccc1..b1800911f 100644 --- a/src/board_controller/brainalive/inc/brainalive.h +++ b/src/board_controller/brainalive/inc/brainalive.h @@ -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 (); @@ -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; diff --git a/src/board_controller/brainflow_boards.cpp b/src/board_controller/brainflow_boards.cpp index c1aef65bb..0057d82d8 100644 --- a/src/board_controller/brainflow_boards.cpp +++ b/src/board_controller/brainflow_boards.cpp @@ -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"] = {