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 impedance mode for ANT neuro devices #751

Merged
merged 20 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from 10 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
15 changes: 13 additions & 2 deletions docs/SupportedBoards.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1026,12 +1026,20 @@ Ant Neuro has many devices and all of them are supported by BrainFlow:
- :code:`ANT_NEURO_EE_225_BOARD`
- :code:`ANT_NEURO_EE_511_BOARD`

Initialization Example:
Initialization and EEG reading example:

.. code-block:: python

params = BrainFlowInputParams()
board = BoardShim(BoardIds.ANT_NEURO_EE_410_BOARD, params)
board = BoardShim(BoardIds.ANT_NEURO_EE_410_BOARD, params) # 8 channel amplifier
Copy link
Member

Choose a reason for hiding this comment

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

that should not be here, its meant to be just a part to init the device
device specific code samples can be pushed into python_package/examples/tests
You can create an example with impedance checking and add a link for it to the docs

board.prepare_session()
board.start_stream()
for i in range(3):
time.sleep(1)
data = board.get_board_data() # get all data and remove it from internal buffer
print(f'{data.shape[0]} channels x {data.shape[1]} samples')
board.stop_stream()
board.release_session()

Supported platforms:

Expand All @@ -1040,7 +1048,10 @@ Supported platforms:

Available commands:

- Set impedance mode: :code:`board.config_board("impedance_mode:1")`, mode 0 or 1.
- Set sampling rate: :code:`board.config_board("sampling_rate:500")`, for available values check docs from Ant Neuro.
- Set reference range: :code:`board.config_board("reference_range:1.0")`, for available values check docs from Ant Neuro.
- Set bipolar range: :code:`board.config_board("bipolar_range:2.5")`, for available values check docs from Ant Neuro.

For more information about Ant Neuro boards please refer to their User Manual.

Expand Down
29 changes: 29 additions & 0 deletions python_package/examples/tests/eego_impedances_and_eeg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import time

from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds

if __name__ == '__main__':
params = BrainFlowInputParams()
board = BoardShim(BoardIds.ANT_NEURO_EE_410_BOARD, params) # 8 channel amplifier
board.prepare_session()

# Get impedance data
board.config_board('impedance_mode:1')
board.start_stream()
for i in range(5):
Andrey1994 marked this conversation as resolved.
Show resolved Hide resolved
time.sleep(1)
data = board.get_board_data() # get all data and remove it from internal buffer
print(f'{data.shape[0]} channels x {data.shape[1]} samples')
board.stop_stream()

# Get EEG data
board.config_board('impedance_mode:0')
board.start_stream()
for i in range(3):
Andrey1994 marked this conversation as resolved.
Show resolved Hide resolved
time.sleep(1)
data = board.get_board_data() # get all data and remove it from internal buffer
print(f'{data.shape[0]} channels x {data.shape[1]} samples')
board.stop_stream()

board.release_session()

52 changes: 48 additions & 4 deletions src/board_controller/ant_neuro/ant_neuro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ int AntNeuroBoard::prepare_session ()
fact->getVersion ().major, fact->getVersion ().minor, fact->getVersion ().micro,
fact->getVersion ().build);
amp = fact->getAmplifier ();
impedance_mode = false;
reference_range = amp->getReferenceRangesAvailable ()[0];
bipolar_range = amp->getBipolarRangesAvailable ()[0];
if (sampling_rate < 0)
Expand Down Expand Up @@ -143,10 +144,18 @@ int AntNeuroBoard::start_stream (int buffer_size, const char *streamer_params)

try
{
safe_logger (spdlog::level::info,
"sampling rate: {}, reference range: {}, bipolar range: {}", sampling_rate,
reference_range, bipolar_range);
stream = amp->OpenEegStream (sampling_rate, reference_range, bipolar_range);
if (impedance_mode)
{
safe_logger (spdlog::level::info, "start impedance stream");
stream = amp->OpenImpedanceStream ();
}
else
{
safe_logger (spdlog::level::info,
"sampling rate: {}, reference range: {}, bipolar range: {}", sampling_rate,
reference_range, bipolar_range);
stream = amp->OpenEegStream (sampling_rate, reference_range, bipolar_range);
}
}
catch (const std::runtime_error &e)
{
Expand Down Expand Up @@ -272,6 +281,12 @@ void AntNeuroBoard::read_thread ()
push_package (package);
}
std::this_thread::sleep_for (std::chrono::milliseconds (1));
if (impedance_mode)
{
// some more sleep; twice every second should be more than enough
// if left out, it yields impedances at around 64 Hz
std::this_thread::sleep_for (std::chrono::milliseconds (500));
Andrey1994 marked this conversation as resolved.
Show resolved Hide resolved
}
}
catch (...)
{
Expand All @@ -293,6 +308,7 @@ int AntNeuroBoard::config_board (std::string config, std::string &response)
std::string prefix = "sampling_rate:";
std::string rv_prefix = "reference_range:";
std::string bv_prefix = "bipolar_range:";
std::string mode_prefix = "impedance_mode:";

if (config.find (prefix) != std::string::npos)
{
Expand Down Expand Up @@ -391,6 +407,34 @@ int AntNeuroBoard::config_board (std::string config, std::string &response)

return (int)BrainFlowExitCodes::STATUS_OK;
}
else if (config.find (mode_prefix) != std::string::npos)
{
bool new_impedance_mode;
std::string value = config.substr (mode_prefix.size ());

if (value == "0" || value == "1")
{
try
{
new_impedance_mode = static_cast<bool> (std::stod (value));
}
catch (...)
{
safe_logger (spdlog::level::err, "format is '{}value'", mode_prefix.c_str ());
return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR;
}

impedance_mode = new_impedance_mode;
return (int)BrainFlowExitCodes::STATUS_OK;
}
else
{
safe_logger (spdlog::level::err, "not supported value provided");
safe_logger (spdlog::level::debug, "supported values: '0' or '1'");
return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR;
}
}

safe_logger (spdlog::level::err, "format is '{}value'", prefix.c_str ());
return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR;
}
Expand Down
1 change: 1 addition & 0 deletions src/board_controller/ant_neuro/inc/ant_neuro.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class AntNeuroBoard : public Board
int sampling_rate;
double reference_range;
double bipolar_range;
bool impedance_mode;

void read_thread ();
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/board_controller/board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ int Board::get_board_data (int data_count, int preset, double *data_buf)
if (dbs.find (preset) == dbs.end ())
{
safe_logger (spdlog::level::err,
"stream is not startted or no preset: {} found for this board", preset);
"stream is not started or no preset: {} found for this board", preset);
return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR;
}
if (!dbs[preset])
Expand Down
Loading