1// This is the main file for a Bluetooth EEG system application, connection
2// example. It includes necessary headers, defines sleep functions, and
3// initializes variables.
4
5#include "bacore.h" // Include the core library
6#include "eeg_manager.h" // Include the EEG manager library
7#include <stdio.h> // Include standard I/O library for printing
8#include <string.h> // Include string manipulation functions
9
10#ifdef _WIN32
11#include <windows.h> // Windows-specific sleep function
12#define sleep_ms(x) Sleep(x)
13#else
14#include <unistd.h> // POSIX (Linux/Unix) sleep function
15#define sleep_ms(x) usleep((x) * 1000) // usleep takes microseconds
16#endif
17
18#define DEVICE_NAME "BA MINI 018"
19#define DEVICE_CHANNEL 4
20#define RUNTIME 5
21ba_eeg_manager* manager1;
22
23/**
24 * @brief Callback function to handle EEG data chunks.
25 *
26 * This function processes the EEG data received in chunks. It extracts the
27 * sample number and channel data, and prints the data for each sample.
28 *
29 * @param data Pointer to the array of data pointers for each channel.
30 * @param size Number of samples in the data chunk.
31 * @param user_data User-defined data (not used in this function).
32 */
33static void chunk_callback(const void* const* data, size_t size, void* user_data)
34{
35 // Get the data for the sample number and channels
36 const size_t* eeg_data_sample_number = (const size_t*)data[ba_eeg_manager_get_channel_index(manager1, BA_EEG_CHANNEL_ID_SAMPLE_NUMBER)];
37
38 for (size_t i = 0; i < size; ++i)
39 {
40 // Process the data directly without storing it in a structure
41 printf("[%zu]", eeg_data_sample_number[i]);
42 for (int j = 0; j < DEVICE_CHANNEL; ++j)
43 {
44 const bool* eeg_data_channel = (const bool*)data[ba_eeg_manager_get_channel_index(manager1, BA_EEG_CHANNEL_ID_ELECTRODE_CONTACT + j)];
45 printf(" %d", eeg_data_channel[i]);
46 }
47 printf("\n");
48 }
49}
50
51/**
52 * @brief Callback function to handle disconnection events.
53 *
54 * This function is called when the EEG device is disconnected. It prints a
55 * message indicating that the device has been disconnected.
56 *
57 * @param data User-defined data (not used in this function).
58 */
59void disconnect_callback(void* data)
60{
61 printf("Disconnected\n");
62}
63
64// Main function to run the Bluetooth EEG system application
65int main()
66{
67 ba_core_init(); // Initialize the core library
68 ba_ble_device* device_list = NULL; // Pointer to the list of Bluetooth devices
69 size_t device_list_size = 0; // Size of the device list
70 ba_init_error status_core = ba_core_scan(&device_list,
71 &device_list_size); // Scan for available Bluetooth devices
72
73 printf("Scan returned with status: %d | device count: %zu\n", status_core,
74 device_list_size); // Print scan status and device count
75 printf("Printing device list: \n");
76 for (size_t i = 0; i < device_list_size; ++i)
77 {
78 printf("device %zu name: %s MAC: %s \n", i, device_list[i].name,
79 device_list[i].mac_address); // Print each device's name and MAC address
80 }
81
82 manager1 = ba_eeg_manager_new(); // Create a new EEG manager instance
83 ba_callback_disconnect disconnect_cb = disconnect_callback; // Define the disconnect callback function
84 ba_eeg_manager_set_callback_disconnect(manager1, disconnect_cb,
85 NULL); // Set the disconnect callback for the EEG manager
86 uint8_t status = BA_ERROR_OK; // Initialize the status variable
87
88 status = ba_eeg_manager_connect(manager1, DEVICE_NAME, NULL, NULL); // Connect to the EEG device
89 if (status != BA_ERROR_OK)
90 {
91 printf("Failed to connect with error: %d\n",
92 status); // Print an error message if connection fails
93 }
94
95 printf("Connected\n"); // Print a message indicating successful connection
96
97 // Enable and set the gain for all electrode channels
98 for (int i = 0; i < DEVICE_CHANNEL; ++i)
99 {
100 // Enable electrode contact channel
101 ba_eeg_manager_set_channel_enabled(manager1, BA_EEG_CHANNEL_ID_ELECTRODE_CONTACT + i, true);
102 // Enable electrode measurement channel
103 ba_eeg_manager_set_channel_enabled(manager1, BA_EEG_CHANNEL_ID_ELECTRODE_MEASUREMENT + i, true);
104 // Set gain for electrode measurement channel
105 ba_eeg_manager_set_channel_gain(manager1, BA_EEG_CHANNEL_ID_ELECTRODE_MEASUREMENT + i, BA_GAIN_MODE_X8);
106 }
107
108 // Enable sample number channel
109 ba_eeg_manager_set_channel_enabled(manager1, BA_EEG_CHANNEL_ID_SAMPLE_NUMBER, true);
110 // Enable streaming channel
111 ba_eeg_manager_set_channel_enabled(manager1, BA_EEG_CHANNEL_ID_STREAMING, true);
112
113 // Load the configuration
114 ba_eeg_manager_load_config(manager1, NULL, NULL);
115
116 // Define the callback function for handling EEG data chunks
117 ba_callback_chunk my_callback = chunk_callback;
118
119 // Set the callback function for handling EEG data chunks
120 ba_eeg_manager_set_callback_chunk(manager1, my_callback, manager1);
121
122 // Start the EEG data streaming
123
124 printf("start stream returned %d\n", ba_eeg_manager_start_stream(manager1, NULL, NULL));
125
126 printf("stream_start\n");
127
128 // Stop the EEG data streaming after 5 seconds
129 for (size_t i = 0; i < RUNTIME; i++)
130 {
131 printf("sec: %d started\n", i);
132 sleep_ms(1000 * 1);
133 }
134 ba_eeg_manager_stop_stream(manager1, NULL, NULL);
135 printf("stream_stop\n");
136
137 ba_eeg_manager_disconnect(manager1); // Disconnect from the EEG device
138 ba_core_close(); // Close the core library
139 printf("Core closed.\n"); // Print a message indicating the core has been
140 // closed
141
142 return status; // Return the status code
143}