Skip to content

Commit bc1a47f

Browse files
authored
improve timestamps for wifi shield (#42)
* improve timestamps for wifi shield Signed-off-by: Andrey Parfenov <[email protected]>
1 parent 7e543f1 commit bc1a47f

File tree

11 files changed

+550
-240
lines changed

11 files changed

+550
-240
lines changed

CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,25 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
107107
else (CMAKE_SIZEOF_VOID_P EQUAL 8)
108108
MESSAGE ("32 bits compiler detected")
109109
SET (PLATFORM_ACH "X86")
110-
SET (BOARD_CONTROLLER_NAME "BoardController32")
111-
SET (DATA_HANDLER_NAME "DataHandler32")
112-
SET (BRAINFLOW_CPP_BINDING_NAME "Brainflow32")
113110
# for linux and apple we dont add 32bit library to packages, so there can not be a conflict between libs
114111
# to dont write code like if(32 bits) if(64 bits) in bindings and keep the ability to use them if brainflow was built from src
115112
# use the same name for 32 and 64 bits
116113
if (APPLE)
114+
SET (BOARD_CONTROLLER_NAME "BoardController")
115+
SET (DATA_HANDLER_NAME "DataHandler")
116+
SET (BRAINFLOW_CPP_BINDING_NAME "Brainflow")
117117
SET (BOARD_CONTROLLER_COMPILED_NAME "libBoardController.dylib")
118118
SET (DATA_HANDLER_COMPILED_NAME "libDataHandler.dylib")
119119
elseif (UNIX)
120+
SET (BOARD_CONTROLLER_NAME "BoardController")
121+
SET (DATA_HANDLER_NAME "DataHandler")
122+
SET (BRAINFLOW_CPP_BINDING_NAME "Brainflow")
120123
SET (BOARD_CONTROLLER_COMPILED_NAME "libBoardController.so")
121124
SET (DATA_HANDLER_COMPILED_NAME "libDataHandler.so")
122125
else ()
126+
SET (BOARD_CONTROLLER_NAME "BoardController32")
127+
SET (DATA_HANDLER_NAME "DataHandler32")
128+
SET (BRAINFLOW_CPP_BINDING_NAME "Brainflow32")
123129
SET (BOARD_CONTROLLER_COMPILED_NAME "BoardController32.dll")
124130
SET (DATA_HANDLER_COMPILED_NAME "DataHandler32.dll")
125131
SET (NEUROSDK_LIB_NAME "neurosdk-x86")

brainflow_boards.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,16 @@
7777
"name": "GanglionWifi",
7878
"sampling_rate": 1600,
7979
"package_num_channel" : 0,
80-
"timestamp_channel" : 18,
81-
"num_rows" : 19,
80+
"timestamp_channel" : 23,
81+
"num_rows" : 24,
8282
"eeg_channels" : [1, 2, 3, 4],
8383
"emg_channels" : [1, 2, 3, 4],
8484
"ecg_channels" : [1, 2, 3, 4],
8585
"eog_channels" : [1, 2, 3, 4],
8686
"accel_channels" : [5, 6, 7],
8787
"analog_channels" : [15, 16, 17],
88-
"other_channels": [8, 9, 10, 11, 12, 13, 14]
88+
"other_channels": [8, 9, 10, 11, 12, 13, 14],
89+
"resistance_channels": [18, 19, 20, 21, 22]
8990
},
9091
"5" : {
9192
"name": "CytonWifi",

src/board_controller/openbci/cyton_daisy_wifi.cpp

Lines changed: 122 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#include "custom_cast.h"
33
#include "timestamp.h"
44

5+
#ifndef _WIN32
6+
#include <errno.h>
7+
#endif
58

69
#define START_BYTE 0xA0
710
#define END_BYTE_STANDARD 0xC0
@@ -38,148 +41,154 @@ void CytonDaisyWifi::read_thread ()
3841
Byte 33: 0xCX where X is 0-F in hex
3942
*/
4043
int res;
41-
unsigned char b[OpenBCIWifiShieldBoard::transaction_size];
44+
unsigned char b[OpenBCIWifiShieldBoard::package_size];
4245
double accel[3] = {0.};
4346
while (keep_alive)
4447
{
45-
res = server_socket->recv (b, OpenBCIWifiShieldBoard::transaction_size);
46-
if (res != OpenBCIWifiShieldBoard::transaction_size)
48+
res = server_socket->recv (b, OpenBCIWifiShieldBoard::package_size);
49+
if (res != OpenBCIWifiShieldBoard::package_size)
4750
{
51+
safe_logger (spdlog::level::warn, "recv result: {}", res);
52+
if (res == -1)
53+
{
54+
#ifdef _WIN32
55+
safe_logger (spdlog::level::warn, "WSAGetLastError is {}", WSAGetLastError ());
56+
#else
57+
safe_logger (spdlog::level::warn, "errno {} message {}", errno, strerror (errno));
58+
#endif
59+
}
60+
4861
continue;
4962
}
63+
5064
double package[30] = {0.};
5165
bool first_sample = false;
52-
for (int cur_package = 0;
53-
cur_package < OpenBCIWifiShieldBoard::num_packages_per_transaction; cur_package++)
66+
if (b[0] != START_BYTE)
67+
{
68+
break; // drop entire transaction for daisy
69+
}
70+
unsigned char *bytes = b + 1; // for better consistency between plain cyton and wifi, in
71+
// plain cyton index is shifted by 1
72+
73+
if ((bytes[31] < END_BYTE_STANDARD) || (bytes[31] > END_BYTE_MAX))
74+
{
75+
safe_logger (spdlog::level::warn, "Wrong end byte {}", bytes[31]);
76+
continue;
77+
}
78+
79+
// place unprocessed bytes to other_channels for all modes
80+
if ((bytes[0] % 2 == 0) && (first_sample))
5481
{
55-
int offset = cur_package * OpenBCIWifiShieldBoard::package_size;
56-
if (b[0 + offset] != START_BYTE)
82+
// eeg
83+
for (int i = 0; i < 8; i++)
5784
{
58-
break; // drop entire transaction for daisy
85+
package[i + 9] = eeg_scale * cast_24bit_to_int32 (bytes + 1 + 3 * i);
5986
}
60-
unsigned char *bytes = b + 1; // for better consistency between plain cyton and wifi, in
61-
// plain cyton index is shifted by 1
62-
63-
if ((bytes[31 + offset] < END_BYTE_STANDARD) || (bytes[31 + offset] > END_BYTE_MAX))
87+
// need to average other_channels
88+
package[21] += (double)bytes[25];
89+
package[22] += (double)bytes[28];
90+
package[23] += (double)bytes[27];
91+
package[24] += (double)bytes[28];
92+
package[25] += (double)bytes[29];
93+
package[26] += (double)bytes[30];
94+
package[21] /= 2.0;
95+
package[22] /= 2.0;
96+
package[23] /= 2.0;
97+
package[24] /= 2.0;
98+
package[25] /= 2.0;
99+
package[26] /= 2.0;
100+
package[20] = (double)bytes[31];
101+
}
102+
else
103+
{
104+
first_sample = true;
105+
package[0] = (double)bytes[0];
106+
// eeg
107+
for (int i = 0; i < 8; i++)
64108
{
65-
safe_logger (spdlog::level::warn, "Wrong end byte {}", bytes[31 + offset]);
66-
continue;
109+
package[i + 1] = eeg_scale * cast_24bit_to_int32 (bytes + 1 + 3 * i);
67110
}
111+
// other_channels
112+
package[21] = (double)bytes[25];
113+
package[22] = (double)bytes[26];
114+
package[23] = (double)bytes[27];
115+
package[24] = (double)bytes[28];
116+
package[25] = (double)bytes[29];
117+
package[26] = (double)bytes[30];
118+
}
119+
120+
// place processed accel data
121+
if (bytes[31] == END_BYTE_STANDARD)
122+
{
123+
int32_t accel_temp[3] = {0};
124+
accel_temp[0] = cast_16bit_to_int32 (bytes + 25);
125+
accel_temp[1] = cast_16bit_to_int32 (bytes + 27);
126+
accel_temp[2] = cast_16bit_to_int32 (bytes + 29);
68127

69-
// place unprocessed bytes to other_channels for all modes
70-
if ((bytes[0 + offset] % 2 == 0) && (first_sample))
128+
if ((bytes[0] % 2 == 0) && (first_sample))
71129
{
72-
// eeg
73-
for (int i = 0; i < 8; i++)
130+
// need to average accel data
131+
if (accel_temp[0] != 0)
74132
{
75-
package[i + 9] = eeg_scale * cast_24bit_to_int32 (bytes + 1 + 3 * i + offset);
133+
accel[0] += accel_scale * accel_temp[0];
134+
accel[1] += accel_scale * accel_temp[1];
135+
accel[2] += accel_scale * accel_temp[2];
136+
137+
accel[0] /= 2.f;
138+
accel[1] /= 2.f;
139+
accel[2] /= 2.f;
76140
}
77-
// need to average other_channels
78-
package[21] += (double)bytes[25 + offset];
79-
package[22] += (double)bytes[28 + offset];
80-
package[23] += (double)bytes[27 + offset];
81-
package[24] += (double)bytes[28 + offset];
82-
package[25] += (double)bytes[29 + offset];
83-
package[26] += (double)bytes[30 + offset];
84-
package[21] /= 2.0;
85-
package[22] /= 2.0;
86-
package[23] /= 2.0;
87-
package[24] /= 2.0;
88-
package[25] /= 2.0;
89-
package[26] /= 2.0;
90-
package[20] = (double)bytes[31 + offset];
141+
142+
package[20] = (double)bytes[31];
91143
}
92144
else
93145
{
94146
first_sample = true;
95-
package[0] = (double)bytes[0 + offset];
96-
// eeg
97-
for (int i = 0; i < 8; i++)
98-
{
99-
package[i + 1] = eeg_scale * cast_24bit_to_int32 (bytes + 1 + 3 * i + offset);
100-
}
101-
// other_channels
102-
package[21] = (double)bytes[25 + offset];
103-
package[22] = (double)bytes[26 + offset];
104-
package[23] = (double)bytes[27 + offset];
105-
package[24] = (double)bytes[28 + offset];
106-
package[25] = (double)bytes[29 + offset];
107-
package[26] = (double)bytes[30 + offset];
108-
}
109-
110-
// place processed accel data
111-
if (bytes[31 + offset] == END_BYTE_STANDARD)
112-
{
113-
int32_t accel_temp[3] = {0};
114-
accel_temp[0] = cast_16bit_to_int32 (bytes + 25 + offset);
115-
accel_temp[1] = cast_16bit_to_int32 (bytes + 27 + offset);
116-
accel_temp[2] = cast_16bit_to_int32 (bytes + 29 + offset);
117-
118-
if ((bytes[0 + offset] % 2 == 0) && (first_sample))
119-
{
120-
// need to average accel data
121-
if (accel_temp[0] != 0)
122-
{
123-
accel[0] += accel_scale * accel_temp[0];
124-
accel[1] += accel_scale * accel_temp[1];
125-
accel[2] += accel_scale * accel_temp[2];
147+
package[0] = (double)bytes[0];
126148

127-
accel[0] /= 2.f;
128-
accel[1] /= 2.f;
129-
accel[2] /= 2.f;
130-
}
131-
132-
package[20] = (double)bytes[31 + offset];
133-
}
134-
else
149+
// accel
150+
if (accel_temp[0] != 0)
135151
{
136-
first_sample = true;
137-
package[0] = (double)bytes[0 + offset];
138-
139-
// accel
140-
if (accel_temp[0] != 0)
141-
{
142-
accel[0] = accel_scale * accel_temp[0];
143-
accel[1] = accel_scale * accel_temp[1];
144-
accel[2] = accel_scale * accel_temp[2];
145-
}
152+
accel[0] = accel_scale * accel_temp[0];
153+
accel[1] = accel_scale * accel_temp[1];
154+
accel[2] = accel_scale * accel_temp[2];
146155
}
147-
148-
package[17] = accel[0];
149-
package[18] = accel[1];
150-
package[19] = accel[2];
151156
}
152-
// place processed analog data
153-
if (bytes[31 + offset] == END_BYTE_ANALOG)
157+
158+
package[17] = accel[0];
159+
package[18] = accel[1];
160+
package[19] = accel[2];
161+
}
162+
// place processed analog data
163+
if (bytes[31] == END_BYTE_ANALOG)
164+
{
165+
if ((bytes[0] % 2 == 0) && (first_sample))
154166
{
155-
if ((bytes[0 + offset] % 2 == 0) && (first_sample))
156-
{
157-
// need to average analog data
158-
package[27] += cast_16bit_to_int32 (bytes + 25 + offset);
159-
package[28] += cast_16bit_to_int32 (bytes + 27 + offset);
160-
package[29] += cast_16bit_to_int32 (bytes + 29 + offset);
161-
package[27] /= 2.0f;
162-
package[28] /= 2.0f;
163-
package[29] /= 2.0f;
164-
package[20] = (double)bytes[31 + offset]; // cyton end byte
165-
}
166-
else
167-
{
168-
first_sample = true;
169-
package[0] = (double)bytes[0 + offset];
170-
// analog
171-
package[27] = cast_16bit_to_int32 (bytes + 25 + offset);
172-
package[28] = cast_16bit_to_int32 (bytes + 27 + offset);
173-
package[29] = cast_16bit_to_int32 (bytes + 29 + offset);
174-
}
167+
// need to average analog data
168+
package[27] += cast_16bit_to_int32 (bytes + 25);
169+
package[28] += cast_16bit_to_int32 (bytes + 27);
170+
package[29] += cast_16bit_to_int32 (bytes + 29);
171+
package[27] /= 2.0f;
172+
package[28] /= 2.0f;
173+
package[29] /= 2.0f;
174+
package[20] = (double)bytes[31]; // cyton end byte
175175
}
176-
// commit package
177-
if ((bytes[0 + offset] % 2 == 0) && (first_sample))
176+
else
178177
{
179-
double timestamp = get_timestamp ();
180-
db->add_data (timestamp, package);
181-
streamer->stream_data (package, 30, timestamp);
178+
first_sample = true;
179+
package[0] = (double)bytes[0];
180+
// analog
181+
package[27] = cast_16bit_to_int32 (bytes + 25);
182+
package[28] = cast_16bit_to_int32 (bytes + 27);
183+
package[29] = cast_16bit_to_int32 (bytes + 29);
182184
}
183185
}
186+
// commit package
187+
if ((bytes[0] % 2 == 0) && (first_sample))
188+
{
189+
double timestamp = get_timestamp ();
190+
db->add_data (timestamp, package);
191+
streamer->stream_data (package, 30, timestamp);
192+
}
184193
}
185194
}

0 commit comments

Comments
 (0)