@@ -48,7 +48,7 @@ void OpenBCI_Ganglion::initialize() {
4848 Serial.begin (115200 );
4949 } else {
5050 Serial.begin (9600 );
51- SimbleeBLE.advertisementData = " Ganglion 1 " ;
51+ SimbleeBLE.advertisementData = " Ganglion" ;
5252 SimbleeBLE.begin ();
5353 SimbleeBLE.txPowerLevel = +4 ;
5454 }
@@ -60,14 +60,14 @@ void OpenBCI_Ganglion::initialize() {
6060void OpenBCI_Ganglion::makeUniqueId () {
6161 uint64_t id = getDeviceId ();
6262 String stringy = String (getDeviceIdLow (), HEX );
63- advdata[11 ] = (uint8_t )stringy.charAt (0 );
64- advdata[12 ] = (uint8_t )stringy.charAt (1 );
65- advdata[13 ] = (uint8_t )stringy.charAt (2 );
66- advdata[14 ] = (uint8_t )stringy.charAt (3 );
63+ advdata[16 ] = (uint8_t )stringy.charAt (0 );
64+ advdata[17 ] = (uint8_t )stringy.charAt (1 );
65+ advdata[18 ] = (uint8_t )stringy.charAt (2 );
66+ advdata[19 ] = (uint8_t )stringy.charAt (3 );
6767 SimbleeBLE.manufacturerName = " openbci.com" ;
6868 SimbleeBLE.modelNumber = " Ganglion" ;
6969 SimbleeBLE.hardwareRevision = " 1.0.1" ;
70- SimbleeBLE.softwareRevision = " 2 .0.1 " ;
70+ SimbleeBLE.softwareRevision = " 3 .0.0 " ;
7171}
7272
7373void OpenBCI_Ganglion::blinkLED () {
@@ -149,7 +149,10 @@ boolean OpenBCI_Ganglion::startRunning(void) {
149149
150150void OpenBCI_Ganglion::processData () {
151151 MCP_dataReady = false ;
152- if (sampleCounter >= 201 ){ sampleCounter = 0 ; }
152+ if (sampleCounter > 200 ){
153+ sampleCounter = 0 ;
154+ ringBufferLevel = 0 ;
155+ }
153156 if (wifi.present && wifi.tx ) {
154157 if (useAccel){
155158 wifi.storeByteBufTx (PCKT_END | PACKET_TYPE_ACCEL );
@@ -171,25 +174,19 @@ void OpenBCI_Ganglion::processData() {
171174 return ;
172175 }
173176
174- if (sampleCounter == 0 ) {
175- buildRawPacket (); // assemble raw packet on sampleCounter roll-over
176- sendRawPacket (); // send raw sample packet
177+ if (useAccel == true ){
178+ if (accelOnEdge == true ){
179+ accelOnEdge = false ;
180+ if (sampleCounter%2 == 0 ){ compressData19 (); return ; }
181+ }
182+ compressData18 (); // compress deltas and send on even samples
177183 } else {
178- if (useAccel == true ){
179- if (accelOnEdge == true ){
180- accelOnEdge = false ;
181- if (sampleCounter%2 == 0 ){ compressData19 (); return ; }
182- }
183- compressData18 (); // compress deltas and send on even samples
184- } else {
185- if (accelOffEdge == true ){
186- accelOffEdge = false ;
187- if (sampleCounter%2 == 0 ){ compressData18 (); return ; }
188- }
189- compressData19 (); // compress deltas and send on even samples
184+ if (accelOffEdge == true ){
185+ accelOffEdge = false ;
186+ if (sampleCounter%2 == 0 ){ compressData18 (); return ; }
190187 }
188+ compressData19 (); // compress deltas and send on even samples
191189 }
192-
193190}
194191
195192boolean OpenBCI_Ganglion::stopRunning (void ) {
@@ -202,8 +199,6 @@ boolean OpenBCI_Ganglion::stopRunning(void) {
202199 return is_running;
203200}
204201
205-
206-
207202int OpenBCI_Ganglion::changeChannelState_maintainRunningState (int chan, int start) {
208203 boolean was_running_when_called = is_running;
209204 // must stop running to turn channel on/off
@@ -252,76 +247,57 @@ void OpenBCI_Ganglion::incrementSyntheticChannelData() {
252247 }
253248}
254249
255- void OpenBCI_Ganglion::buildRawPacket () {
256- int byteCounter = 0 ;
257- ringBufferLevel = 0 ;
258- for (int i = 0 ; i < 4 ; i++) {
259- for (int j = 16 ; j >= 0 ; j -= 8 ) { // fill the raw data array for streaming
260- compression_ring[ringBufferLevel][byteCounter] = ((channelData[i] >> j) & 0xFF );
261- byteCounter++;
262- }
263- lastChannelData[i] = channelData[i]; // keep track of the previous value
264- }
265- }
266-
267-
268- void OpenBCI_Ganglion::sendRawPacket () {
269- radioBuffer[0 ] = ringBufferLevel;
270- for (int i = 0 ; i < 12 ; i++) {
271- radioBuffer[i + 1 ] = compression_ring[ringBufferLevel][i];
250+ /*
251+ Send two samples in one packet by truncating the data to the MSBs.
252+ Each sample is a signed 24 bit integer, but is stored in a 32 bit integer.
253+ This means that only the 32nd (sign) and 1st-23rd bits have data.
254+ Truncate the 24 bit integer to 18 bits by removing the 6 LSBs.
255+ Move the sign bit to the new LSB place.
256+ Now the sample is in bits 1-18 where the first bit is the sign bit.
257+ Align the 2 samples x 4 channel x 18 bit samples into 18 bytes.
258+ */
259+ void OpenBCI_Ganglion::compressData18 ()
260+ {
261+ bool even = (sampleCounter % 2 ) == 0 ;
262+ for (int i = 0 ; i < 4 ; i++)
263+ {
264+ bitWrite (channelData[i], 6 , (bitRead (channelData[i], 31 ))); // Store the sign bit in bit 6
265+ channelData[i] = channelData[i] >> 6 ; // Then align the data to bits 1-18
272266 }
273- for (char c = 0 ; c < 7 ; c++) {
274- radioBuffer[c + 13 ] = c + ' A' ; // padding
267+ if (even)
268+ {
269+ // Pack even samples first
270+ compression_ring[ringBufferLevel][0 ] = ((channelData[0 ] & 0x0003FC00 ) >> 10 );
271+ compression_ring[ringBufferLevel][1 ] = ((channelData[0 ] & 0x000003FC ) >> 2 );
272+ compression_ring[ringBufferLevel][2 ] = ((channelData[0 ] & 0x00000003 ) << 6 );
273+ compression_ring[ringBufferLevel][2 ] |= ((channelData[1 ] & 0x0003F000 ) >> 12 );
274+ compression_ring[ringBufferLevel][3 ] = ((channelData[1 ] & 0x00000FF0 ) >> 4 );
275+ compression_ring[ringBufferLevel][4 ] = ((channelData[1 ] & 0x0000000F ) << 4 );
276+ compression_ring[ringBufferLevel][4 ] |= ((channelData[2 ] & 0x0003C000 ) >> 14 );
277+ compression_ring[ringBufferLevel][5 ] = ((channelData[2 ] & 0x00003FC0 ) >> 6 );
278+ compression_ring[ringBufferLevel][6 ] = ((channelData[2 ] & 0x0000003F ) << 2 );
279+ compression_ring[ringBufferLevel][6 ] |= ((channelData[3 ] & 0x00030000 ) >> 16 );
280+ compression_ring[ringBufferLevel][7 ] = ((channelData[3 ] & 0x0000FF00 ) >> 8 );
281+ compression_ring[ringBufferLevel][8 ] = ((channelData[3 ] & 0x000000FF ));
275282 }
276- ringBufferLevel++;
283+ else
284+ {
285+ // Pack odd samples second
286+ compression_ring[ringBufferLevel][9 ] = ((channelData[0 ] & 0x0003FC00 ) >> 10 );
287+ compression_ring[ringBufferLevel][10 ] = ((channelData[0 ] & 0x000003FC ) >> 2 );
288+ compression_ring[ringBufferLevel][11 ] = ((channelData[0 ] & 0x00000003 ) << 6 );
289+ compression_ring[ringBufferLevel][11 ] |= ((channelData[1 ] & 0x0003F000 ) >> 12 );
290+ compression_ring[ringBufferLevel][12 ] = ((channelData[1 ] & 0x00000FF0 ) >> 4 );
291+ compression_ring[ringBufferLevel][13 ] = ((channelData[1 ] & 0x0000000F ) << 4 );
292+ compression_ring[ringBufferLevel][13 ] |= ((channelData[2 ] & 0x0003C000 ) >> 14 );
293+ compression_ring[ringBufferLevel][14 ] = ((channelData[2 ] & 0x00003FC0 ) >> 6 );
294+ compression_ring[ringBufferLevel][15 ] = ((channelData[2 ] & 0x0000003F ) << 2 );
295+ compression_ring[ringBufferLevel][16 ] |= ((channelData[3 ] & 0x00030000 ) >> 16 );
296+ compression_ring[ringBufferLevel][16 ] = ((channelData[3 ] & 0x0000FF00 ) >> 8 );
297+ compression_ring[ringBufferLevel][17 ] = ((channelData[3 ] & 0x000000FF ));
277298
278- if (BLEconnected) {
279- SimbleeBLE.send (radioBuffer, 20 );
280- }
281- }
282- /*
283- send two samples in one packet by compressing the data
284- first, take the delta between the current sample and the last sample
285- then, retain the sign of the delta by moving it to bit 0
286- then, only send the LSBs
287- this function crams the data into a BLE packet
288- */
289- void OpenBCI_Ganglion::compressData18 () {
290- int deltas[4 ];
291- int even = sampleCounter % 2 ;
292- for (int i = 0 ; i < 4 ; i++) {
293- deltas[i] = lastChannelData[i] - channelData[i]; // subtract new from old
294- lastChannelData[i] = channelData[i]; // keep track of the previous value
295- bitWrite (deltas[i], 0 , (bitRead (deltas[i], 31 ))); // store the sign bit in bit0
296- }
297- if (even == 1 ) { // pack odd samples first
298- compression_ring[ringBufferLevel][0 ] = ((deltas[0 ] & 0x0003FC00 ) >> 10 );
299- compression_ring[ringBufferLevel][1 ] = ((deltas[0 ] & 0x000003FC ) >> 2 );
300- compression_ring[ringBufferLevel][2 ] = ((deltas[0 ] & 0x00000003 ) << 6 );
301- compression_ring[ringBufferLevel][2 ] |= ((deltas[1 ] & 0x0003F000 ) >> 12 );
302- compression_ring[ringBufferLevel][3 ] = ((deltas[1 ] & 0x00000FF0 ) >> 4 );
303- compression_ring[ringBufferLevel][4 ] = ((deltas[1 ] & 0x0000000F ) << 4 );
304- compression_ring[ringBufferLevel][4 ] |= ((deltas[2 ] & 0x0003C000 ) >> 14 );
305- compression_ring[ringBufferLevel][5 ] = ((deltas[2 ] & 0x00003FC0 ) >> 6 );
306- compression_ring[ringBufferLevel][6 ] = ((deltas[2 ] & 0x0000003F ) << 2 );
307- compression_ring[ringBufferLevel][6 ] |= ((deltas[3 ] & 0x00030000 ) >> 16 );
308- compression_ring[ringBufferLevel][7 ] = ((deltas[3 ] & 0x0000FF00 ) >> 8 );
309- compression_ring[ringBufferLevel][8 ] = (deltas[3 ] & 0x000000FF );
310- } else { // pack even samples second
311- compression_ring[ringBufferLevel][9 ] = ((deltas[0 ] & 0x0003FC00 ) >> 10 );
312- compression_ring[ringBufferLevel][10 ] = ((deltas[0 ] & 0x000003FC ) >> 2 );
313- compression_ring[ringBufferLevel][11 ] = ((deltas[0 ] & 0x00000003 ) << 6 );
314- compression_ring[ringBufferLevel][11 ] |= ((deltas[1 ] & 0x0003F000 ) >> 12 );
315- compression_ring[ringBufferLevel][12 ] = ((deltas[1 ] & 0x00000FF0 ) >> 4 );
316- compression_ring[ringBufferLevel][13 ] = ((deltas[1 ] & 0x0000000F ) << 4 );
317- compression_ring[ringBufferLevel][13 ] |= ((deltas[2 ] & 0x0003C000 ) >> 14 );
318- compression_ring[ringBufferLevel][14 ] = ((deltas[2 ] & 0x00003FC0 ) >> 6 );
319- compression_ring[ringBufferLevel][15 ] = ((deltas[2 ] & 0x0000003F ) << 2 );
320- compression_ring[ringBufferLevel][15 ] |= ((deltas[3 ] & 0x00030000 ) >> 16 );
321- compression_ring[ringBufferLevel][16 ] = ((deltas[3 ] & 0x0000FF00 ) >> 8 );
322- compression_ring[ringBufferLevel][17 ] = (deltas[3 ] & 0x000000FF );
323-
324- sendCompressedPacket18 (); // send on the even packet
299+ // Send on the even packet
300+ sendCompressedPacket18 ();
325301 }
326302}
327303
@@ -346,49 +322,62 @@ void OpenBCI_Ganglion::sendCompressedPacket18() {
346322}
347323
348324
349- void OpenBCI_Ganglion::compressData19 () {
350- int deltas[4 ];
351- int even = sampleCounter % 2 ;
352- for (int i = 0 ; i < 4 ; i++) {
353- deltas[i] = lastChannelData[i] - channelData[i]; // subtract new from old
354- lastChannelData[i] = channelData[i]; // keep track of the previous value
355- bitWrite (deltas[i], 0 , (bitRead (deltas[i], 31 ))); // store the sign bit in bit0
356- }
357- if (even == 1 ) { // pack odd samples first
358- compression_ring[ringBufferLevel][0 ] = ((deltas[0 ] & 0x0007F800 ) >> 11 );
359- compression_ring[ringBufferLevel][1 ] = ((deltas[0 ] & 0x000007F8 ) >> 3 );
360- compression_ring[ringBufferLevel][2 ] = ((deltas[0 ] & 0x00000007 ) << 5 );
361- compression_ring[ringBufferLevel][2 ] |= ((deltas[1 ] & 0x0007C000 ) >> 14 );
362- compression_ring[ringBufferLevel][3 ] = ((deltas[1 ] & 0x00003FC0 ) >> 6 );
363- compression_ring[ringBufferLevel][4 ] = ((deltas[1 ] & 0x0000003F ) << 2 );
364- compression_ring[ringBufferLevel][4 ] |= ((deltas[2 ] & 0x00060000 ) >> 17 );
365- compression_ring[ringBufferLevel][5 ] = ((deltas[2 ] & 0x0001FE00 ) >> 9 );
366- compression_ring[ringBufferLevel][6 ] = ((deltas[2 ] & 0x000001FE ) >> 1 );
367- compression_ring[ringBufferLevel][7 ] = ((deltas[2 ] & 00000001 ) << 7 );
368- compression_ring[ringBufferLevel][7 ] |= ((deltas[3 ] & 0x0007F000 ) >> 12 );
369- compression_ring[ringBufferLevel][8 ] = ((deltas[3 ] & 0x00000FF0 ) >> 4 );
370- compression_ring[ringBufferLevel][9 ] = ((deltas[3 ] & 0x0000000F ) << 4 );
371- } else { // pack even samples second
372- compression_ring[ringBufferLevel][9 ] |= ((deltas[0 ] & 0x00078000 ) >> 15 );
373- compression_ring[ringBufferLevel][10 ] = ((deltas[0 ] & 0x00007F80 ) >> 7 );
374- compression_ring[ringBufferLevel][11 ] = ((deltas[0 ] & 0x0000007F ) << 1 );
375- compression_ring[ringBufferLevel][11 ] |= ((deltas[1 ] & 0x00040000 ) >> 18 );
376- compression_ring[ringBufferLevel][12 ] = ((deltas[1 ] & 0x0003FC00 ) >> 10 );
377- compression_ring[ringBufferLevel][13 ] = ((deltas[1 ] & 0x000003FC ) >> 2 );
378- compression_ring[ringBufferLevel][14 ] = ((deltas[1 ] & 0x00000003 ) << 6 );
379- compression_ring[ringBufferLevel][14 ] |= ((deltas[2 ] & 0x0007E000 ) >> 13 );
380- compression_ring[ringBufferLevel][15 ] = ((deltas[2 ] & 0x00001FE0 ) >> 5 );
381- compression_ring[ringBufferLevel][16 ] = ((deltas[2 ] & 0x0000001F ) << 3 );
382- compression_ring[ringBufferLevel][16 ] |= ((deltas[3 ] & 0x00070000 ) >> 16 );
383- compression_ring[ringBufferLevel][17 ] = ((deltas[3 ] & 0x0000FF00 ) >> 8 );
384- compression_ring[ringBufferLevel][18 ] = (deltas[3 ] & 0x000000FF );
385-
386- sendCompressedPacket19 (); // send on the even packet
325+ /*
326+ Send two samples in one packet by truncating the data to the MSBs.
327+ Each sample is a signed 24 bit integer, but is stored in a 32 bit integer.
328+ This means that only the 32nd (sign) and 1st-23rd bits have data.
329+ Truncate the 24 bit integer to 19 bits by removing the 5 LSBs.
330+ Move the sign bit to the new LSB place.
331+ Now the sample is in bits 1-19 where the first bit is the sign bit.
332+ Align the 2 samples x 4 channel x 19 bit samples into 19 bytes.
333+ */
334+ void OpenBCI_Ganglion::compressData19 ()
335+ {
336+ bool even = (sampleCounter % 2 ) == 0 ;
337+ for (int i = 0 ; i < 4 ; i++)
338+ {
339+ bitWrite (channelData[i], 5 , (bitRead (channelData[i], 31 ))); // Store the sign bit in bit 5
340+ channelData[i] = channelData[i] >> 5 ; // Then align the data to bits 1-19
341+ }
342+ if (even)
343+ {
344+ // Pack even samples first
345+ compression_ring[ringBufferLevel][0 ] = ((channelData[0 ] & 0x0007F800 ) >> 11 );
346+ compression_ring[ringBufferLevel][1 ] = ((channelData[0 ] & 0x000007F8 ) >> 3 );
347+ compression_ring[ringBufferLevel][2 ] = ((channelData[0 ] & 0x00000007 ) << 5 );
348+ compression_ring[ringBufferLevel][2 ] |= ((channelData[1 ] & 0x0007C000 ) >> 14 );
349+ compression_ring[ringBufferLevel][3 ] = ((channelData[1 ] & 0x00003FC0 ) >> 6 );
350+ compression_ring[ringBufferLevel][4 ] = ((channelData[1 ] & 0x0000003F ) << 2 );
351+ compression_ring[ringBufferLevel][4 ] |= ((channelData[2 ] & 0x00060000 ) >> 17 );
352+ compression_ring[ringBufferLevel][5 ] = ((channelData[2 ] & 0x0001FE00 ) >> 9 );
353+ compression_ring[ringBufferLevel][6 ] = ((channelData[2 ] & 0x000001FE ) >> 1 );
354+ compression_ring[ringBufferLevel][7 ] = ((channelData[2 ] & 0x00000001 ) << 7 );
355+ compression_ring[ringBufferLevel][7 ] |= ((channelData[3 ] & 0x0007F000 ) >> 12 );
356+ compression_ring[ringBufferLevel][8 ] = ((channelData[3 ] & 0x00000FF0 ) >> 4 );
357+ compression_ring[ringBufferLevel][9 ] = ((channelData[3 ] & 0x0000000F ) << 4 );
358+ }
359+ else
360+ {
361+ // Pack odd samples second
362+ compression_ring[ringBufferLevel][9 ] |= ((channelData[0 ] & 0x00078000 ) >> 15 );
363+ compression_ring[ringBufferLevel][10 ] = ((channelData[0 ] & 0x00007F80 ) >> 7 );
364+ compression_ring[ringBufferLevel][11 ] = ((channelData[0 ] & 0x0000007F ) << 1 );
365+ compression_ring[ringBufferLevel][11 ] |= ((channelData[1 ] & 0x00040000 ) >> 18 );
366+ compression_ring[ringBufferLevel][12 ] = ((channelData[1 ] & 0x0003FC00 ) >> 10 );
367+ compression_ring[ringBufferLevel][13 ] = ((channelData[1 ] & 0x000003FC ) >> 2 );
368+ compression_ring[ringBufferLevel][14 ] = ((channelData[1 ] & 0x00000003 ) << 6 );
369+ compression_ring[ringBufferLevel][14 ] |= ((channelData[2 ] & 0x0007E000 ) >> 13 );
370+ compression_ring[ringBufferLevel][15 ] = ((channelData[2 ] & 0x00001FE0 ) >> 5 );
371+ compression_ring[ringBufferLevel][16 ] = ((channelData[2 ] & 0x0000001F ) << 3 );
372+ compression_ring[ringBufferLevel][16 ] |= ((channelData[3 ] & 0x00070000 ) >> 16 );
373+ compression_ring[ringBufferLevel][17 ] = ((channelData[3 ] & 0x0000FF00 ) >> 8 );
374+ compression_ring[ringBufferLevel][18 ] = ((channelData[3 ] & 0x000000FF ));
375+
376+ // Send on the even packet
377+ sendCompressedPacket19 ();
387378 }
388379}
389380
390-
391-
392381void OpenBCI_Ganglion::sendCompressedPacket19 () {
393382 radioBuffer[0 ] = ringBufferLevel + 100 ;
394383 for (int i = 0 ; i < 19 ; i++) {
0 commit comments