Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/cppcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
env:
DEBIAN_FRONTEND: noninteractive
- name: Run Cppcheck
run: cppcheck --std=c++11 -ithird_party/spdlog -ithird_party/libsvm -ithird_party/SimpleBLE -ithird_party/fmt -ithird_party/SimpleDBus -ithird_party/SimpleBluez -ithird_party/kissfft -isrc/utils/os_serial_ioctl.cpp --error-exitcode=1 --xml --xml-version=2 --force src cpp_package third_party 2>cppcheck_res.xml
run: cppcheck --std=c++11 -ithird_party/wavelib -ithird_party/spdlog -ithird_party/libsvm -ithird_party/SimpleBLE -ithird_party/fmt -ithird_party/SimpleDBus -ithird_party/SimpleBluez -ithird_party/kissfft -isrc/utils/os_serial_ioctl.cpp --error-exitcode=1 --xml --xml-version=2 --force src cpp_package third_party 2>cppcheck_res.xml
- name: Generate Report
if: ${{ failure() }}
run: cppcheck-htmlreport --title=BrainFlow --file=cppcheck_res.xml --report-dir=report
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run_android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
cd $GITHUB_WORKSPACE/tools
zip -r jniLibs.zip jniLibs
- name: Install AWS CLI
run: sudo -H python3 -m pip install awscli==1.21.10
run: sudo -H python3 -m pip install awscli==1.35.24
- name: Upload To AWS
if: ${{ github.event_name == 'push' && github.repository == 'brainflow-dev/brainflow' }}
run: |
Expand Down
9 changes: 7 additions & 2 deletions docs/SupportedBoards.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1026,12 +1026,14 @@ 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 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


`More elaborate example <https://github.com/brainflow-dev/brainflow/blob/master/python_package/examples/tests/eego_impedances_and_eeg.py>`_ (reading EEG and impedances)

Supported platforms:

Expand All @@ -1040,7 +1042,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_411_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):
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):
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()

89 changes: 85 additions & 4 deletions src/board_controller/ant_neuro/ant_neuro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ AntNeuroBoard::AntNeuroBoard (int board_id, struct BrainFlowInputParams params)
}
reference_range = -1.0;
bipolar_range = -1.0;
impedance_mode = false;
impedance_package_num = -1;
}

AntNeuroBoard::~AntNeuroBoard ()
Expand Down Expand Up @@ -100,6 +102,8 @@ int AntNeuroBoard::prepare_session ()
{
sampling_rate = amp->getSamplingRatesAvailable ()[0];
}
impedance_mode = false;
impedance_package_num = 0;
}
catch (const exceptions::notFound &e)
{
Expand Down Expand Up @@ -143,10 +147,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,
"start eeg stream (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 @@ -217,6 +229,7 @@ void AntNeuroBoard::read_thread ()
}
std::vector<int> emg_channels;
std::vector<int> eeg_channels;
std::vector<int> resistance_channels;
try
{
emg_channels = board_descr["default"]["emg_channels"].get<std::vector<int>> ();
Expand All @@ -233,6 +246,15 @@ void AntNeuroBoard::read_thread ()
{
safe_logger (spdlog::level::trace, "device has no eeg channels");
}
try
{
resistance_channels =
board_descr["default"]["resistance_channels"].get<std::vector<int>> ();
}
catch (...)
{
safe_logger (spdlog::level::trace, "device has no resistance_channels channels");
}
std::vector<channel> ant_channels = stream->getChannelList ();

while (keep_alive)
Expand All @@ -245,17 +267,26 @@ void AntNeuroBoard::read_thread ()
{
int eeg_counter = 0;
int emg_counter = 0;
int resistance_counter = 0;
for (int j = 0; j < buf_channels_len; j++)
{
if ((ant_channels[j].getType () == channel::reference) &&
(eeg_counter < (int)eeg_channels.size ()))
{
package[eeg_channels[eeg_counter++]] = buf.getSample (j, i);
if (impedance_mode)
{
resistance_counter++;
}
}
if ((ant_channels[j].getType () == channel::bipolar) &&
(emg_counter < (int)emg_channels.size ()))
{
package[emg_channels[emg_counter++]] = buf.getSample (j, i);
if (impedance_mode)
{
resistance_counter++;
}
}
if (ant_channels[j].getType () == channel::sample_counter)
{
Expand All @@ -267,11 +298,32 @@ void AntNeuroBoard::read_thread ()
package[board_descr["default"]["other_channels"][0].get<int> ()] =
buf.getSample (j, i);
}
if ((ant_channels[j].getType () == channel::impedance_reference) &&
(resistance_counter < (int)resistance_channels.size ()))
{
package[resistance_channels[resistance_counter++]] = buf.getSample (j, i);
}
if ((ant_channels[j].getType () == channel::impedance_ground) &&
(resistance_counter < (int)resistance_channels.size ()))
{
package[resistance_channels[resistance_counter++]] = buf.getSample (j, i);
}
}
package[board_descr["default"]["timestamp_channel"].get<int> ()] = get_timestamp ();
if (impedance_mode)
{
package[board_descr["default"]["package_num_channel"].get<int> ()] =
impedance_package_num++;
}
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));
}
}
catch (...)
{
Expand All @@ -293,6 +345,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 +444,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
2 changes: 2 additions & 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,8 @@ class AntNeuroBoard : public Board
int sampling_rate;
double reference_range;
double bipolar_range;
bool impedance_mode;
int impedance_package_num;

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
Loading