Skip to content

Commit 7b4da47

Browse files
committed
wip
Signed-off-by: Andrey Parfenov <a1994ndrey@gmail.com>
1 parent 5e9029f commit 7b4da47

5 files changed

Lines changed: 103 additions & 11 deletions

File tree

python_package/examples/tests/brainflow_get_data.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ def main():
4040

4141
board = BoardShim(args.board_id, params)
4242
board.prepare_session()
43-
board.start_stream ()
43+
board.add_streamer("file://data.csv:w")
44+
board.start_stream()
4445
time.sleep(10)
4546
# data = board.get_current_board_data (256) # get latest 256 packages or less, doesnt remove them from internal buffer
4647
data = board.get_board_data() # get all data and remove it from internal buffer

src/board_controller/brainflow_boards.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,13 +1237,12 @@ BrainFlowBoards::BrainFlowBoards()
12371237
brainflow_boards_json["boards"]["65"]["auxiliary"] =
12381238
{
12391239
{"name", "MuseAnthenaAux"},
1240-
{"sampling_rate", 52},
1241-
{"timestamp_channel", 7},
1242-
{"marker_channel", 8},
1240+
{"sampling_rate", 64},
1241+
{"timestamp_channel", 4},
1242+
{"marker_channel", 5},
12431243
{"package_num_channel", 0},
1244-
{"num_rows", 9},
1245-
{"accel_channels", {1, 2, 3}},
1246-
{"gyro_channels", {4, 5, 6}}
1244+
{"num_rows", 6},
1245+
{"ppg_channels", {1, 2, 3}},
12471246
};
12481247
}
12491248

src/board_controller/muse/inc/muse_anthena.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class MuseAnthena : public BLELibBoard
2323

2424
std::string bytes_to_string (const uint8_t *data, size_t size);
2525

26+
void parse_eeg_packet (const uint8_t *data, size_t size);
27+
void parse_ppg_packet (const uint8_t *data, size_t size);
28+
2629
public:
2730
MuseAnthena (int board_id, struct BrainFlowInputParams params);
2831
~MuseAnthena ();

src/board_controller/muse/inc/muse_anthena_constants.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#define MUSE_ANTHENA_GATT_ATTR_STREAM_TOGGLE "273e0001-4c4d-454d-96be-f03bac821358"
88
#define MUSE_ANTHENA_GATT_EEG "273e0013-4c4d-454d-96be-f03bac821358"
99
#define MUSE_ANTHENA_GATT_AUX "273e0014-4c4d-454d-96be-f03bac821358"
10+
#define EEG_PACKET_TYPE 0X12
11+
#define PPG_PACKET_TYPE 0x11
1012

1113
// info for equations
1214
#define MUSE_ANTHENA_ACCELEROMETER_SCALE_FACTOR 0.0000610352

src/board_controller/muse/muse_anthena.cpp

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ int MuseAnthena::prepare_session ()
211211
}
212212
if (res == (int)BrainFlowExitCodes::STATUS_OK)
213213
{
214-
// p21 - eeg only
214+
// enable everything by default
215+
// p21(eeg only) and p1034(sleep mode) and p1035 are also available
215216
res = config_board ("p21");
216217
}
217218
else
@@ -399,15 +400,101 @@ void MuseAnthena::adapter_on_scan_found (
399400
void MuseAnthena::peripheral_on_eeg (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
400401
simpleble_uuid_t characteristic, const uint8_t *data, size_t size)
401402
{
402-
safe_logger (spdlog::level::trace, "EEG packet: {}", bytes_to_string (data, size));
403-
// TODO parse it and fill default preset
403+
safe_logger (spdlog::level::trace, "incoming packet: {}", bytes_to_string (data, size));
404+
if (size < 200)
405+
{
406+
safe_logger (spdlog::level::trace, "unexpected size: {}", size);
407+
return;
408+
}
409+
// it ignores the 1st ble package since it has smth in the beginning and blocks with 0x11 +
410+
// packet sub number later
411+
// TODO: find out what is there in the beginning
412+
if ((data[9] == 0x11) || (data[9] == 0x12))
413+
{
414+
parse_eeg_packet (data, size);
415+
}
416+
else
417+
{
418+
safe_logger (spdlog::level::trace, "unsupported packet type: {}", data[9]);
419+
}
420+
}
421+
422+
void MuseAnthena::parse_eeg_packet (const uint8_t *data, size_t size)
423+
{
424+
int sub_number = (int)data[10];
425+
int last_index = 0;
426+
int num_rows = board_descr["default"]["num_rows"];
427+
double *package = new double[num_rows];
428+
std::vector<int> eeg_channels = board_descr["default"]["eeg_channels"];
429+
for (int i = 0; i < num_rows; i++)
430+
{
431+
package[i] = 0.0;
432+
}
433+
package[board_descr["default"]["package_num_channel"].get<int> ()] = (double)data[1];
434+
package[board_descr["default"]["timestamp_channel"].get<int> ()] = get_timestamp ();
435+
436+
for (int i = 9; i < (int)size - 8; i++)
437+
{
438+
if ((data[i] == EEG_PACKET_TYPE) && (data[i + 1] == sub_number) && (last_index <= i - 9))
439+
{
440+
double gain = 1.0; // random value, I am not sure in equations at all
441+
double eeg_scale = (double)(4.5 / float ((pow (2, 16) - 1)) / gain * 1000000.);
442+
int eeg1_value = eeg_scale * cast_16bit_to_int32_swap_order (data + i + 2);
443+
int eeg2_value = eeg_scale * cast_16bit_to_int32_swap_order (data + i + 4);
444+
int eeg3_value = eeg_scale * cast_16bit_to_int32_swap_order (data + i + 6);
445+
int eeg4_value = eeg_scale * cast_16bit_to_int32_swap_order (data + i + 8);
446+
sub_number++;
447+
last_index = i;
448+
package[eeg_channels[0]] = eeg1_value;
449+
package[eeg_channels[1]] = eeg2_value;
450+
package[eeg_channels[2]] = eeg3_value;
451+
package[eeg_channels[3]] = eeg4_value;
452+
}
453+
}
454+
455+
push_package (package, (int)BrainFlowPresets::DEFAULT_PRESET);
456+
457+
delete[] package;
458+
}
459+
460+
void MuseAnthena::parse_ppg_packet (const uint8_t *data, size_t size)
461+
{
462+
int sub_number = (int)data[10];
463+
int last_index = 0;
464+
int num_rows = board_descr["auxiliary"]["num_rows"];
465+
double *package = new double[num_rows];
466+
std::vector<int> ppg_channels = board_descr["default"]["ppg_channels"];
467+
for (int i = 0; i < num_rows; i++)
468+
{
469+
package[i] = 0.0;
470+
}
471+
package[board_descr["default"]["package_num_channel"].get<int> ()] = (double)data[1];
472+
package[board_descr["default"]["timestamp_channel"].get<int> ()] = get_timestamp ();
473+
474+
for (int i = 9; i < (int)size - 8; i++)
475+
{
476+
if ((data[i] == PPG_PACKET_TYPE) && (data[i + 1] == sub_number) && (last_index <= i - 9))
477+
{
478+
sub_number++;
479+
last_index = i;
480+
package[ppg_channels[0]] = (double)cast_24bit_to_int32 ((unsigned char *)&data[2 + i]);
481+
package[ppg_channels[1]] =
482+
(double)cast_24bit_to_int32 ((unsigned char *)&data[2 + i + 3]);
483+
package[ppg_channels[2]] =
484+
(double)cast_24bit_to_int32 ((unsigned char *)&data[2 + i + 6]);
485+
}
486+
}
487+
488+
push_package (package, (int)BrainFlowPresets::AUXILIARY_PRESET);
489+
490+
delete[] package;
404491
}
405492

406493
void MuseAnthena::peripheral_on_aux (simpleble_peripheral_t peripheral, simpleble_uuid_t service,
407494
simpleble_uuid_t characteristic, const uint8_t *data, size_t size)
408495
{
496+
// never seen smth in this char, keep it here just in case
409497
safe_logger (spdlog::level::trace, "AUX packet: {}", bytes_to_string (data, size));
410-
// TODO parse it and fill aux preset
411498
}
412499

413500

0 commit comments

Comments
 (0)