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

Added support for PiEEG #723

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 48 additions & 47 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,70 +1,71 @@
cmake_minimum_required (VERSION 3.13)
project (brainflow)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these code style changes are not related to pieeg, and should be reverted

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted the code style changes not related to PIEEG as requested.

cmake_minimum_required(VERSION 3.13)
project(brainflow)

SET (CMAKE_CXX_STANDARD 11)
SET (CMAKE_VERBOSE_MAKEFILE ON)
SET (BRAINFLOW_VERSION "0.0.1" CACHE STRING "BrainFlow Version")
SET (VERSION ${BRAINFLOW_VERSION})
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(BRAINFLOW_VERSION "0.0.1" CACHE STRING "BrainFlow Version")
set(VERSION ${BRAINFLOW_VERSION})

SET (CMAKE_CXX_VISIBILITY_PRESET hidden)
SET (CMAKE_C_VISIBILITY_PRESET hidden)
SET (CMAKE_POSITION_INDEPENDENT_CODE ON)
SET (VERSION_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/compiled/brainflowConfigVersion.cmake)
SET (CONFIG_INSTALL_DIR lib/cmake/brainflow)
SET (PROJECT_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/compiled/brainflowConfig.cmake)
SET (TARGETS_EXPORT_NAME brainflowTargets)
SET (PACKAGE_LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib)
SET (PACKAGE_INC_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/inc)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(VERSION_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/compiled/brainflowConfigVersion.cmake)
set(CONFIG_INSTALL_DIR lib/cmake/brainflow)
set(PROJECT_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/compiled/brainflowConfig.cmake)
set(TARGETS_EXPORT_NAME brainflowTargets)
set(PACKAGE_LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib)
set(PACKAGE_INC_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/inc)

option (USE_LIBFTDI "USE_LIBFTDI" OFF)
option (USE_OPENMP "USE_OPENMP" OFF)
option (WARNINGS_AS_ERRORS "WARNINGS_AS_ERRORS" OFF)
option (BUILD_OYMOTION_SDK "BUILD_OYMOTION_SDK" OFF)
option (BUILD_BLUETOOTH "BUILD_BLUETOOTH" OFF)
option (BUILD_BLE "BUILD_BLE" OFF)
option (BUILD_ONNX "BUILD_ONNX" OFF)
option (BUILD_TESTS "BUILD_TESTS" OFF)
option(USE_LIBFTDI "USE_LIBFTDI" OFF)
option(USE_OPENMP "USE_OPENMP" OFF)
option(WARNINGS_AS_ERRORS "WARNINGS_AS_ERRORS" OFF)
option(BUILD_OYMOTION_SDK "BUILD_OYMOTION_SDK" OFF)
option(BUILD_BLUETOOTH "BUILD_BLUETOOTH" OFF)
option(BUILD_BLE "BUILD_BLE" OFF)
option(BUILD_ONNX "BUILD_ONNX" OFF)
option(BUILD_TESTS "BUILD_TESTS" OFF)
option(BUILD_PERIPHERY "BUILD_PERIPHERY" OFF)

include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros.cmake)
configure_msvc_runtime ()
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/macros.cmake)
configure_msvc_runtime()

if (WARNINGS_AS_ERRORS)
if (MSVC)
add_compile_options (/WX)
if (CMAKE_BUILD_TYPE EQUAL "DEBUG")
add_compile_options (/bigobj)
endif (CMAKE_BUILD_TYPE EQUAL "DEBUG")
else ()
add_compile_options (-Werror -Wno-varargs)
endif ()
endif (WARNINGS_AS_ERRORS)
if(WARNINGS_AS_ERRORS)
if(MSVC)
add_compile_options(/WX)
if(CMAKE_BUILD_TYPE EQUAL "DEBUG")
add_compile_options(/bigobj)
endif()
else()
add_compile_options(-Werror -Wno-varargs)
endif()
endif()

include (${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/build.cmake)
include (${CMAKE_CURRENT_SOURCE_DIR}/src/data_handler/build.cmake)
include (${CMAKE_CURRENT_SOURCE_DIR}/src/ml/build.cmake)
include (${CMAKE_CURRENT_SOURCE_DIR}/cpp_package/build.cmake)
if (BUILD_TESTS)
include (${CMAKE_CURRENT_SOURCE_DIR}/src/tests/build.cmake)
endif (BUILD_TESTS)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/build.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/data_handler/build.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/ml/build.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cpp_package/build.cmake)
if(BUILD_TESTS)
include(${CMAKE_CURRENT_SOURCE_DIR}/src/tests/build.cmake)
endif()

include (CMakePackageConfigHelpers)
include(CMakePackageConfigHelpers)

write_basic_package_version_file (
write_basic_package_version_file(
${VERSION_CONFIG}
VERSION ${BRAINFLOW_VERSION}
COMPATIBILITY AnyNewerVersion
)
configure_package_config_file (
configure_package_config_file(
cmake/Config.cmake.in
${PROJECT_CONFIG}
INSTALL_DESTINATION ${CONFIG_INSTALL_DIR}
)

install (
install(
FILES ${PROJECT_CONFIG} ${VERSION_CONFIG}
DESTINATION ${CONFIG_INSTALL_DIR}
)
install (
install(
EXPORT ${TARGETS_EXPORT_NAME}
NAMESPACE brainflow::
DESTINATION ${CONFIG_INSTALL_DIR}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ public enum BoardIds
FREEEEG128_BOARD = 52,
AAVAA_V3_BOARD = 53,
EXPLORE_PLUS_8_CHAN_BOARD = 54,
EXPLORE_PLUS_32_CHAN_BOARD = 55
EXPLORE_PLUS_32_CHAN_BOARD = 55,
PIEEG_BOARD = 60
};


Expand Down
56 changes: 56 additions & 0 deletions docs/SupportedBoards.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1268,3 +1268,59 @@ Available :ref:`presets-label`:
- :code:`BrainFlowPresets.DEFAULT_PRESET`, it contains accelerometer, gyroscope and magnetometer data
- :code:`BrainFlowPresets.AUXILIARY_PRESET`, it contains PPG data
- :code:`BrainFlowPresets.ANCILLARY_PRESET`, it contains EDA and temperature data

PiEEG
------

PiEEG Board
~~~~~~~~~~~

PiEEG (Measure EEG with RaspberryPi) – Brain-computer interface (EEG, EMG, and ECG bio-signals) is an open-source Raspberry Pi shield that measures biosignals such as those used in electroencephalography (EEG), electromyography (EMG), and electrocardiography (ECG). It integrates seamlessly with BrainFlow's API, allowing for easy data streaming, processing, and analysis.

.. image:: https://github.com/Pi-EEG/EEGwithRaspberryPI/blob/master/Supplementary%20files/Fig.3.jpg
:width: 500px
:height: 299px

`PiEEG Website <https://pieeg.com/>`_

To create such a board, you need to specify the following board ID and fields of the BrainFlowInputParams object:

- :code:`BoardIds.PIEEG_BOARD`
- :code:`serial_port`, e.g., COM3, /dev/spidev0.0, etc.

Initialization Example:

.. code-block:: python

from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds

params = BrainFlowInputParams()
params.serial_port = "/dev/spidev0.0"
board = BoardShim(BoardIds.PIEEG_BOARD, params)
board.prepare_session()
board.start_stream()

Supported platforms:

- Linux
- MacOS
- Devices like Raspberry Pi

**Note**: Currently relies on c-periphery https://github.com/vsergeev/c-periphery/>.

**Note**: Ensure that you have the necessary permissions to access the serial port on your operating system. For Unix-like systems, you may need to configure permissions for the serial port or run with sudo.

Available commands for :code:`config_board`:

- :code:`"set_sampling_rate:<rate>"` - Set the sampling rate for the EEG data acquisition.
- :code:`"enable_channels:<channels>"` - Enable specific EEG channels.
- :code:`"disable_channels:<channels>"` - Disable specific EEG channels.
- :code:`"set_gain:<gain>"` - Set the gain for the EEG channels.

Example usage for setting configurations:

.. code-block:: python

board.config_board("set_sampling_rate:250")
board.config_board("enable_channels:1,2,3,4")
board.config_board("set_gain:24")
3 changes: 2 additions & 1 deletion java_package/brainflow/src/main/java/brainflow/BoardIds.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public enum BoardIds
FREEEEG128_BOARD (52),
AAVAA_V3_BOARD(53),
EXPLORE_PLUS_8_CHAN_BOARD(54),
EXPLORE_PLUS_32_CHAN_BOARD(55);
EXPLORE_PLUS_32_CHAN_BOARD(55),
PIEEEG_BOARD(60);

private final int board_id;
private static final Map<Integer, BoardIds> bi_map = new HashMap<Integer, BoardIds> ();
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 @@ -60,6 +60,7 @@ export BrainFlowInputParams
AAVAA_V3_BOARD = 53
EXPLORE_PLUS_8_CHAN_BOARD = 54
EXPLORE_PLUS_32_CHAN_BOARD = 55
PIEEG_BOARD = 60

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 @@ -58,5 +58,6 @@
AAVAA_V3_BOARD(53)
EXPLORE_PLUS_8_CHAN_BOARD(54)
EXPLORE_PLUS_32_CHAN_BOARD(55)
PIEEG_BOARD(60)
end
end
3 changes: 2 additions & 1 deletion nodejs_package/brainflow/brainflow.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ export enum BoardIds {
NTL_WIFI_BOARD = 50,
ANT_NEURO_EE_511_BOARD = 51,
EXPLORE_PLUS_8_CHAN_BOARD = 54,
EXPLORE_PLUS_32_CHAN_BOARD = 55
EXPLORE_PLUS_32_CHAN_BOARD = 55,
PIEEG_BOARD = 60,
}

export enum IpProtocolTypes {
Expand Down
1 change: 1 addition & 0 deletions python_package/brainflow/board_shim.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class BoardIds(enum.IntEnum):
AAVAA_V3_BOARD = 53 #:
EXPLORE_PLUS_8_CHAN_BOARD = 54 #:
EXPLORE_PLUS_32_CHAN_BOARD = 55 #:
PIEEG_BOARD = 60 #:


class IpProtocolTypes(enum.IntEnum):
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 @@ -94,6 +94,7 @@ pub enum BoardIds {
AavaaV3Board = 53,
ExplorePlus8ChanBoard = 54,
ExplorePlus32ChanBoard = 55,
PieegBoard = 60,
}
#[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 @@ -53,6 +53,7 @@
#include "streaming_board.h"
#include "synthetic_board.h"
#include "unicorn_board.h"
#include "pieeg_board.h"

#include "json.hpp"

Expand Down Expand Up @@ -277,6 +278,9 @@ int prepare_session (int board_id, const char *json_brainflow_input_params)
case BoardIds::EXPLORE_PLUS_32_CHAN_BOARD:
board = std::shared_ptr<Board> (new Explore (board_id, params));
break;
case BoardIds::PIEEG_BOARD:
board = std::shared_ptr<Board> (new PIEEGBoard (board_id, params));
break;
default:
return (int)BrainFlowExitCodes::UNSUPPORTED_BOARD_ERROR;
}
Expand Down
13 changes: 12 additions & 1 deletion src/board_controller/brainflow_boards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ BrainFlowBoards::BrainFlowBoards()
{"50", json::object()},
{"51", json::object()},
{"52", json::object()},
{"53", json::object()}
{"53", json::object()},
{"60", json::object()}
}
}};

Expand Down Expand Up @@ -1082,6 +1083,16 @@ BrainFlowBoards::BrainFlowBoards()
{"battery_channel", 2},
{"other_channels", {3}}
};
brainflow_boards_json["boards"]["60"]["default"] = {
{"name", "PIEEG"},
{"sampling_rate", 250},
{"package_num_channel", 21},
{"timestamp_channel", 22},
{"marker_channel", 23},
{"num_rows", 24},
{"eeg_channels", {0, 1, 2, 3, 4, 5, 6, 7}},
{"eeg_names", "Fp1,Fp2,C3,C4,P7,P8,O1,O2"}
};
}

BrainFlowBoards boards_struct;
26 changes: 21 additions & 5 deletions src/board_controller/build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ SET (BOARD_CONTROLLER_SRC
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/emotibit/emotibit.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/ntl/ntl_wifi.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/aavaa/aavaa_v3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/pieeg/pieeg_board.cpp
)

include (${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/ant_neuro/build.cmake)
Expand All @@ -97,7 +98,9 @@ if (BUILD_OYMOTION_SDK)
endif (BUILD_OYMOTION_SDK)

if (BUILD_BLUETOOTH)
include (${CMAKE_CURRENT_SOURCE_DIR}/src/utils/bluetooth/build.cmake)
if (NOT ANDROID)
include (${CMAKE_CURRENT_SOURCE_DIR}/src/utils/bluetooth/build.cmake)
endif (NOT ANDROID)
endif (BUILD_BLUETOOTH)

if (BUILD_BLE)
Expand Down Expand Up @@ -140,6 +143,7 @@ target_include_directories (
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/emotibit/inc
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/ntl/inc
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/aavaa/inc
${CMAKE_CURRENT_SOURCE_DIR}/src/board_controller/pieeg/inc
)

target_compile_definitions(${BOARD_CONTROLLER_NAME} PRIVATE NOMINMAX BRAINFLOW_VERSION=${BRAINFLOW_VERSION})
Expand All @@ -151,6 +155,22 @@ set_target_properties (${BOARD_CONTROLLER_NAME}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/compiled
)

find_package(Threads REQUIRED)

if (ANDROID)
find_library(log-lib log)
target_link_libraries(${BOARD_CONTROLLER_NAME} PRIVATE ${log-lib})
else()
target_link_libraries(${BOARD_CONTROLLER_NAME} PRIVATE pthread dl)
endif (ANDROID)

if (BUILD_PERIPHERY)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/periphery)
target_compile_definitions(${BOARD_CONTROLLER_NAME} PRIVATE USE_PERIPHERY)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/periphery)
target_link_libraries(${BOARD_CONTROLLER_NAME} PRIVATE periphery ${CMAKE_THREAD_LIBS_INIT} dl)
endif (BUILD_PERIPHERY)

if (USE_LIBFTDI)
find_package (LibFTDI1 NO_MODULE)
if (LibFTDI1_FOUND)
Expand Down Expand Up @@ -231,10 +251,6 @@ endif (ANDROID)
if (UNIX AND NOT ANDROID)
target_link_libraries (${BOARD_CONTROLLER_NAME} PRIVATE pthread dl)
endif (UNIX AND NOT ANDROID)
if (ANDROID)
find_library (log-lib log)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored find_library for 'log-lib' to ensure proper Android linking.

target_link_libraries (${BOARD_CONTROLLER_NAME} PRIVATE log)
endif (ANDROID)

install (
FILES
Expand Down
2 changes: 1 addition & 1 deletion src/board_controller/emotibit/emotibit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,4 +844,4 @@ void Emotibit::ping_thread ()
safe_logger (spdlog::level::err, "failed to send adv package, res is {}", bytes_send);
}
}
}
}
41 changes: 41 additions & 0 deletions src/board_controller/pieeg/inc/pieeg_board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <string>
#include <thread>

#include "board.h"
#include "board_controller.h"
#include "math.h"
#include "socket_server_tcp.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does it need socket?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the unnecessary socket_server_tcp.h inclusion.


#ifdef USE_PERIPHERY
#include "gpio.h"
#include "spi.h"
#endif

class PIEEGBoard : public Board
{
protected:
#ifdef USE_PERIPHERY
volatile bool keep_alive;
bool initialized;
std::thread streaming_thread;
spi_t *spi;
gpio_t *gpio_in;
SocketServerTCP *server_socket;
void read_thread ();
int write_reg (uint8_t reg_address, uint8_t val);
int send_command (uint8_t command);
#endif

public:
PIEEGBoard (int board_id, struct BrainFlowInputParams params);
~PIEEGBoard ();

int prepare_session ();
int start_stream (int buffer_size, const char *streamer_params);
int stop_stream ();
int release_session ();
int config_board (std::string config, std::string &response);
};

Loading