Comparar commits
10 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| d6335257e1 | |||
| aea599a7dd | |||
| 031861d2ed | |||
| 6fd9ddf01b | |||
| fe2abac07b | |||
| 2528d56ac9 | |||
| 18b137b498 | |||
| 470ee81928 | |||
| 3c46100e1d | |||
| 2c0b2e37d2 |
@@ -3,11 +3,20 @@ node_js:
|
||||
- "4.0"
|
||||
- "4.1"
|
||||
- "4.2"
|
||||
- "4.3"
|
||||
- "4.4"
|
||||
- "4.5"
|
||||
- "4.6"
|
||||
- "5.11.0"
|
||||
- "6.0"
|
||||
- "6.1"
|
||||
- "6.2"
|
||||
- "6.3"
|
||||
- "6.4"
|
||||
- "6.5"
|
||||
- "6.6"
|
||||
- "6.7"
|
||||
- "6.8"
|
||||
install:
|
||||
- npm install --all
|
||||
script:
|
||||
|
||||
+6
-1
@@ -895,6 +895,7 @@ Send the command to tell the board to start the syncing protocol. Must be connec
|
||||
timeRoundTrip: 0, // Simply timeSyncSetPacket - timeSyncSent.
|
||||
timeTransmission: 0, // Estimated time it took for time sync set packet to be sent from Board to Driver.
|
||||
timeOffset: 0, // The map (or translation) from boardTime to module time.
|
||||
timeOffsetMaster: 0, // The map (or translation) from boardTime to module time averaged over time syncs.
|
||||
valid: false // If there was an error in the process, valid will be false and no time sync was done. It's important to resolve this so we can perform multiple promise syncs as show in the example below.
|
||||
}
|
||||
```
|
||||
@@ -1040,13 +1041,17 @@ ourBoard.write('o');
|
||||
|
||||
Emitted when the serial connection to the board is closed.
|
||||
|
||||
### <a name="event-close"></a> .on('droppedPacket', callback)
|
||||
|
||||
Emitted when a packet (or packets) are dropped. Returns an array.
|
||||
|
||||
### <a name="event-error"></a> .on('error', callback)
|
||||
|
||||
Emitted when there is an on the serial port.
|
||||
|
||||
### <a name="event-impedance-array"></a> .on('impedanceArray', callback)
|
||||
|
||||
Emitted when there is a new impedanceArray available.
|
||||
Emitted when there is a new impedanceArray available. Returns an array.
|
||||
|
||||
### <a name="event-query"></a> .on('query', callback)
|
||||
|
||||
|
||||
@@ -1,3 +1,32 @@
|
||||
# 1.3.3
|
||||
|
||||
### New Features
|
||||
|
||||
* Add `timeOffsetMaster` to object emitted when bad time sync.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed log statement on impedance setting function
|
||||
* Remove event emitter with time sync on reject of sync clock full
|
||||
|
||||
# 1.3.2
|
||||
|
||||
### Enhancements
|
||||
|
||||
* Added master time offset `timeOffsetMaster` to `syncObj` which is a running average across sync attempts.
|
||||
|
||||
# 1.3.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed bug where `connected` and `streaming` were not set in constructor
|
||||
|
||||
# 1.3.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Add dropped packet detection, new event `droppedPacket` can be added to get an array of dropped packet numbers in the case of the dropped packet event.
|
||||
|
||||
# 1.2.3
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "timesync",
|
||||
"version": "1.0.0",
|
||||
"description": "Time sync example",
|
||||
"main": "timeSync.js",
|
||||
"scripts": {
|
||||
"start": "node timeSync.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"time",
|
||||
"sync"
|
||||
],
|
||||
"author": "AJ Keller",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"openbci": "^1.3.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* This is an example of time syncing every second for one minute. Used with a
|
||||
* real board.
|
||||
* To run:
|
||||
* change directory to this file `cd examples/timeSync`
|
||||
* do `npm install`
|
||||
* then `npm start`
|
||||
*/
|
||||
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
|
||||
var ourBoard = new OpenBCIBoard({});
|
||||
|
||||
const resyncPeriodMin = 5; // re sync every five minutes
|
||||
const secondsInMinute = 60;
|
||||
var sampleRate = 250; // Default to 250, ALWAYS verify with a call to `.sampleRate()` after 'ready' event!
|
||||
var timeSyncPossible = false;
|
||||
|
||||
ourBoard.autoFindOpenBCIBoard().then(portName => {
|
||||
if(portName) {
|
||||
/**
|
||||
* Connect to the board with portName
|
||||
* i.e. ourBoard.connect(portName).....
|
||||
*/
|
||||
// Call to connect
|
||||
ourBoard.connect(portName).then(() => {
|
||||
console.log(`connected`);
|
||||
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`connect: ${err}`);
|
||||
});
|
||||
} else {
|
||||
/**Unable to auto find OpenBCI board*/
|
||||
}
|
||||
});
|
||||
|
||||
var readyFunc = () => {
|
||||
// Get the sample rate after 'ready'
|
||||
sampleRate = ourBoard.sampleRate();
|
||||
// Find out if you can even time sync, you must be using v2 and this is only accurate after a `.softReset()` call which is called internally on `.connect()`. We parse the `.softReset()` response for the presence of firmware version 2 properties.
|
||||
timeSyncPossible = ourBoard.usingVersionTwoFirmware();
|
||||
|
||||
if (timeSyncPossible) {
|
||||
ourBoard.streamStart()
|
||||
.catch(err => {
|
||||
console.log(`stream start: ${err}`);
|
||||
});
|
||||
} else {
|
||||
killFunc();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var killFunc = () => {
|
||||
ourBoard.disconnect()
|
||||
.then(() => {
|
||||
process.kill();
|
||||
});
|
||||
}
|
||||
|
||||
var sampleFunc = sample => {
|
||||
// Resynchronize every every second
|
||||
if (sample._count % (sampleRate * 1) === 0) {
|
||||
ourBoard.syncClocksFull()
|
||||
.then(syncObj => {
|
||||
// Sync was successful
|
||||
if (syncObj.valid) {
|
||||
// Log the object to check it out!
|
||||
console.log(`timeOffset`,syncObj.timeOffsetMaster);
|
||||
} else {
|
||||
// Retry it
|
||||
console.log(`Was not able to sync... retry!`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (sample.timeStamp) { // true after the first successful sync
|
||||
if (sample.timeStamp < 10 * 60 * 60 * 1000) { // Less than 10 hours
|
||||
console.log(`Bad time sync ${sample.timeStamp}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop after one minute
|
||||
if (sample._count > sampleRate * 60) {
|
||||
killFunc();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Subscribe to your functions
|
||||
ourBoard.on('ready',readyFunc);
|
||||
ourBoard.on('sample',sampleFunc);
|
||||
+26
-6
@@ -145,6 +145,9 @@ function OpenBCIFactory() {
|
||||
this.accelArray = [0,0,0]; // X, Y, Z
|
||||
this.channelSettingsArray = k.channelSettingsArrayInit(k.numberOfChannelsForBoardType(this.options.boardType));
|
||||
this.writeOutArray = new Array(100);
|
||||
// Booleans
|
||||
this.connected = false;
|
||||
this.streaming = false;
|
||||
// Buffers
|
||||
this.buffer = null;
|
||||
this.masterBuffer = masterBufferMaker();
|
||||
@@ -173,6 +176,7 @@ function OpenBCIFactory() {
|
||||
this._lowerChannelsSampleObject = null;
|
||||
this.sync = {
|
||||
curSyncObj: null,
|
||||
eventEmitter: null,
|
||||
objArray: [],
|
||||
sntpActive: false,
|
||||
timeOffsetMaster: 0,
|
||||
@@ -185,9 +189,10 @@ function OpenBCIFactory() {
|
||||
this.curParsingMode = k.OBCIParsingReset;
|
||||
this.commandsToWrite = 0;
|
||||
this.impedanceArray = openBCISample.impedanceArray(k.numberOfChannelsForBoardType(this.options.boardType));
|
||||
this.writeOutDelay = k.OBCIWriteIntervalDelayMSShort;
|
||||
this.previousSampleNumber = -1;
|
||||
this.sampleCount = 0;
|
||||
this.timeOfPacketArrival = 0;
|
||||
this.writeOutDelay = k.OBCIWriteIntervalDelayMSShort;
|
||||
// Strings
|
||||
|
||||
// NTP
|
||||
@@ -1323,7 +1328,6 @@ function OpenBCIFactory() {
|
||||
if (this.options.verbose) console.log('pInput: ' + pInput + ' nInput: ' + nInput);
|
||||
// Get impedance settings to send the board
|
||||
k.getImpedanceSetter(channelNumber,pInput,nInput).then((commandsArray) => {
|
||||
console.log(commandsArray);
|
||||
this.write(commandsArray);
|
||||
//delayInMS += commandsArray.length * k.OBCIWriteIntervalDelayMSLong;
|
||||
delayInMS += this.commandsToWrite * k.OBCIWriteIntervalDelayMSShort; // Account for commands waiting to be sent in the write buffer
|
||||
@@ -1560,10 +1564,11 @@ function OpenBCIFactory() {
|
||||
if (!this.usingVersionTwoFirmware()) reject('Time sync not implemented on v1 firmware, please update to v2');
|
||||
setTimeout(() => {
|
||||
return reject('syncClocksFull timeout after 500ms with no sync');
|
||||
}, 1000); // Should not take more than 1s to sync up
|
||||
this.once('synced',syncObj => {
|
||||
}, 500); // Should not take more than 1s to sync up
|
||||
this.sync.eventEmitter = syncObj => {
|
||||
return resolve(syncObj);
|
||||
});
|
||||
};
|
||||
this.once('synced', this.sync.eventEmitter);
|
||||
this.sync.curSyncObj = openBCISample.newSyncObject();
|
||||
this.sync.curSyncObj.timeSyncSent = this.time();
|
||||
this.curParsingMode = k.OBCIParsingTimeSyncSent;
|
||||
@@ -1735,6 +1740,11 @@ function OpenBCIFactory() {
|
||||
OpenBCIBoard.prototype._processQualifiedPacket = function(rawDataPacketBuffer) {
|
||||
if (!rawDataPacketBuffer) return;
|
||||
if (rawDataPacketBuffer.byteLength !== k.OBCIPacketSize) return;
|
||||
var missedPacketArray = openBCISample.droppedPacketCheck(this.previousSampleNumber, rawDataPacketBuffer[k.OBCIPacketPositionSampleNumber]);
|
||||
if (missedPacketArray) {
|
||||
this.emit('droppedPacket', missedPacketArray);
|
||||
}
|
||||
this.previousSampleNumber = rawDataPacketBuffer[k.OBCIPacketPositionSampleNumber];
|
||||
var packetType = openBCISample.getRawPacketType(rawDataPacketBuffer[k.OBCIPacketPositionStopByte]);
|
||||
switch (packetType) {
|
||||
case k.OBCIStreamPacketStandardAccel:
|
||||
@@ -1844,7 +1854,9 @@ function OpenBCIFactory() {
|
||||
// Fix the curParsingMode back to normal
|
||||
this.curParsingMode = k.OBCIParsingNormal;
|
||||
// Emit the bad sync object for fun
|
||||
this.emit('synced',openBCISample.newSyncObject());
|
||||
var badObject = openBCISample.newSyncObject();
|
||||
badObject.timeOffsetMaster = this.sync.timeOffsetMaster;
|
||||
this.emit('synced', badObject);
|
||||
// Set back to null
|
||||
this.sync.curSyncObj = null;
|
||||
// Return will exit this method with the err
|
||||
@@ -1924,6 +1936,8 @@ function OpenBCIFactory() {
|
||||
this.sync.timeOffsetMaster = this.sync.curSyncObj.timeOffset;
|
||||
}
|
||||
|
||||
this.sync.curSyncObj.timeOffsetMaster = this.sync.timeOffsetMaster;
|
||||
|
||||
if (this.options.verbose) {
|
||||
console.log(`Master offset ${this.sync.timeOffsetMaster} ms`);
|
||||
}
|
||||
@@ -1940,6 +1954,12 @@ function OpenBCIFactory() {
|
||||
return resolve(rawPacket);
|
||||
})
|
||||
.catch(err => {
|
||||
// Emit the bad sync object for fun
|
||||
var badObject = openBCISample.newSyncObject();
|
||||
badObject.timeOffsetMaster = this.sync.timeOffsetMaster;
|
||||
this.emit('synced', badObject);
|
||||
// Set back to null
|
||||
this.sync.curSyncObj = null;
|
||||
console.log('Error in _processPacketTimeSyncSet', err)
|
||||
return reject(err);
|
||||
});
|
||||
|
||||
@@ -199,6 +199,9 @@ const OBCISimulatorLineNoiseNone = 'None';
|
||||
const OBCISampleRate125 = 125;
|
||||
const OBCISampleRate250 = 250;
|
||||
|
||||
/** Max sample number */
|
||||
const OBCISampleNumberMax = 255;
|
||||
|
||||
/** Packet Size */
|
||||
const OBCIPacketSize = 33;
|
||||
|
||||
@@ -729,6 +732,8 @@ module.exports = {
|
||||
/** Possible Sample Rates */
|
||||
OBCISampleRate125,
|
||||
OBCISampleRate250,
|
||||
/** Max sample number */
|
||||
OBCISampleNumberMax,
|
||||
/** Packet Size */
|
||||
OBCIPacketSize,
|
||||
/** Notable Bytes */
|
||||
|
||||
+43
-6
@@ -522,7 +522,42 @@ var sampleModule = {
|
||||
isTimeSyncSetConfirmationInBuffer,
|
||||
makeTailByteFromPacketType,
|
||||
isStopByte,
|
||||
newSyncObject
|
||||
newSyncObject,
|
||||
/**
|
||||
* @description Checks to make sure the previous sample number is one less
|
||||
* then the new sample number. Takes into account sample numbers wrapping
|
||||
* around at 255.
|
||||
* @param `previousSampleNumber` {Number} - An integer number of the previous
|
||||
* sample number.
|
||||
* @param `newSampleNumber` {Number} - An integer number of the new sample
|
||||
* number.
|
||||
* @returns {Array} - Returns null if there is no dropped packets, otherwise,
|
||||
* or on a missed packet, an array of their packet numbers is returned.
|
||||
*/
|
||||
droppedPacketCheck: (previousSampleNumber, newSampleNumber) => {
|
||||
if (previousSampleNumber === k.OBCISampleNumberMax && newSampleNumber === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (newSampleNumber - previousSampleNumber === 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var missedPacketArray = [];
|
||||
|
||||
if (previousSampleNumber > newSampleNumber) {
|
||||
var numMised = k.OBCISampleNumberMax - previousSampleNumber;
|
||||
for (var i = 0; i < numMised; i++) {
|
||||
missedPacketArray.push(previousSampleNumber + i + 1);
|
||||
}
|
||||
previousSampleNumber = -1;
|
||||
}
|
||||
|
||||
for (var i = 1; i < (newSampleNumber - previousSampleNumber); i++) {
|
||||
missedPacketArray.push(previousSampleNumber + i);
|
||||
}
|
||||
return missedPacketArray;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = sampleModule;
|
||||
@@ -551,6 +586,7 @@ function newSyncObject() {
|
||||
timeRoundTrip: 0,
|
||||
timeTransmission: 0,
|
||||
timeOffset: 0,
|
||||
timeOffsetMaster: 0,
|
||||
valid: false
|
||||
}
|
||||
}
|
||||
@@ -671,7 +707,6 @@ function parsePacketTimeSyncedAccel(dataBuf,channelSettingsArray,boardOffsetTime
|
||||
return new Promise((resolve, reject) => {
|
||||
// The sample object we are going to build
|
||||
var sampleObject = {};
|
||||
|
||||
if (dataBuf.byteLength != k.OBCIPacketSize) reject("Error [parsePacketTimeSyncedAccel]: input buffer must be " + k.OBCIPacketSize + " bytes!");
|
||||
|
||||
// Get the sample number
|
||||
@@ -767,10 +802,12 @@ function getFromTimePacketTime(dataBuf) {
|
||||
// Ths packet has 'A0','00'....,'00','00','FF','FF','FF','FF','C3' where the 'FF's are times
|
||||
const lastBytePosition = k.OBCIPacketSize - 1; // This is 33, but 0 indexed would be 32 minus 1 for the stop byte and another two for the aux channel or the
|
||||
return new Promise((resolve, reject) => {
|
||||
if (dataBuf.byteLength != k.OBCIPacketSize) reject("Error [getFromTimePacketTime]: input buffer must be " + k.OBCIPacketSize + " bytes!");
|
||||
|
||||
// Grab the time from the packet
|
||||
resolve(dataBuf.readUInt32BE(lastBytePosition - k.OBCIStreamPacketTimeByteSize));
|
||||
if (dataBuf.byteLength != k.OBCIPacketSize) {
|
||||
reject("Error [getFromTimePacketTime]: input buffer must be " + k.OBCIPacketSize + " bytes!");
|
||||
} else {
|
||||
// Grab the time from the packet
|
||||
resolve(dataBuf.readUInt32BE(lastBytePosition - k.OBCIStreamPacketTimeByteSize));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openbci",
|
||||
"version": "1.2.3",
|
||||
"version": "1.3.3",
|
||||
"description": "The official Node.js SDK for the OpenBCI Biosensor Board.",
|
||||
"main": "openBCIBoard",
|
||||
"scripts": {
|
||||
|
||||
@@ -765,6 +765,11 @@ describe('OpenBCIConstants', function() {
|
||||
assert.equal(250, k.OBCISampleRate250);
|
||||
});
|
||||
});
|
||||
describe('Max sample number',function() {
|
||||
it('should be 255',function () {
|
||||
assert.equal(255, k.OBCISampleNumberMax);
|
||||
});
|
||||
});
|
||||
describe("Radio Channel Limits", function() {
|
||||
it("should get the right channel number max",function () {
|
||||
expect(k.OBCIRadioChannelMax).to.be.equal(25);
|
||||
|
||||
@@ -5,9 +5,9 @@ var assert = require('assert');
|
||||
var openBCISample = require('../openBCISample');
|
||||
var sinon = require('sinon');
|
||||
var chai = require('chai'),
|
||||
expect = chai.expect,
|
||||
should = chai.should(),
|
||||
expect = chai.expect;
|
||||
expect = chai.expect,
|
||||
assert = chai.assert;
|
||||
|
||||
var chaiAsPromised = require("chai-as-promised");
|
||||
var sinonChai = require("sinon-chai");
|
||||
@@ -1352,6 +1352,9 @@ describe('openBCISample',function() {
|
||||
it("should have property timeOffset",function() {
|
||||
expect(syncObj).to.have.property("timeOffset",0);
|
||||
});
|
||||
it("should have property timeOffsetMaster",function() {
|
||||
expect(syncObj).to.have.property("timeOffsetMaster",0);
|
||||
});
|
||||
it("should have property timeRoundTrip",function() {
|
||||
expect(syncObj).to.have.property("timeRoundTrip",0);
|
||||
});
|
||||
@@ -1373,7 +1376,41 @@ describe('openBCISample',function() {
|
||||
it("should have property boardTime",function() {
|
||||
expect(syncObj).to.have.property("boardTime",0);
|
||||
});
|
||||
})
|
||||
});
|
||||
describe('#droppedPacketCheck',function() {
|
||||
it("should return an array of missed packet numbers",function() {
|
||||
previous = 0;
|
||||
current = previous + 2;
|
||||
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [1], "dropped one packet");
|
||||
|
||||
previous = 0;
|
||||
current = previous + 4;
|
||||
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [1,2,3], "dropped three packets");
|
||||
|
||||
previous = 255;
|
||||
current = 2;
|
||||
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [0,1], "dropped two packets on wrap edge!");
|
||||
|
||||
previous = 254;
|
||||
current = 2;
|
||||
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [255,0,1], "dropped three packets on wrap!");
|
||||
|
||||
previous = 250;
|
||||
current = 1;
|
||||
assert.sameMembers(openBCISample.droppedPacketCheck(previous, current), [251,252,253,254,255,0], "dropped a bunch of packets on wrap!");
|
||||
|
||||
});
|
||||
it("should roll over when 255 was previous and current is 0", function() {
|
||||
previous = 255;
|
||||
current = 0;
|
||||
expect(openBCISample.droppedPacketCheck(previous, current)).to.be.null;
|
||||
});
|
||||
it("should return null when previous is one less then new sample number", function() {
|
||||
previous = 0;
|
||||
current = previous + 1;
|
||||
expect(openBCISample.droppedPacketCheck(previous, current)).to.be.null;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
+190
-15
@@ -82,6 +82,8 @@ describe('openbci-sdk',function() {
|
||||
expect(board.options.verbose).to.be.false;
|
||||
expect(board.sampleRate()).to.equal(250);
|
||||
expect(board.numberOfChannels()).to.equal(8);
|
||||
expect(board.connected).to.be.false;
|
||||
expect(board.streaming).to.be.false;
|
||||
});
|
||||
it('should be able to set ganglion mode', () => {
|
||||
var board = new openBCIBoard.OpenBCIBoard({
|
||||
@@ -294,6 +296,16 @@ describe('openbci-sdk',function() {
|
||||
(ourBoard.impedanceTest.onChannel).should.equal(0);
|
||||
(ourBoard.impedanceTest.sampleNumber).should.equal(0);
|
||||
});
|
||||
it('configures sync object correctly', function() {
|
||||
ourBoard = new openBCIBoard.OpenBCIBoard();
|
||||
expect(ourBoard.sync.curSyncObj).to.be.null;
|
||||
expect(ourBoard.sync.eventEmitter).to.be.null;
|
||||
expect(ourBoard.sync.objArray.length).to.equal(0);
|
||||
(ourBoard.sync.sntpActive).should.equal(false);
|
||||
(ourBoard.sync.timeOffsetMaster).should.equal(0);
|
||||
(ourBoard.sync.timeOffsetAvg).should.equal(0);
|
||||
expect(ourBoard.sync.timeOffsetArray.length).to.equal(0);
|
||||
});
|
||||
it('configures impedance array with the correct amount of channels for default', function() {
|
||||
ourBoard = new openBCIBoard.OpenBCIBoard();
|
||||
(ourBoard.impedanceArray.length).should.equal(8);
|
||||
@@ -1010,6 +1022,39 @@ describe('openbci-sdk',function() {
|
||||
funcSpyTimeSyncedAccel.should.not.have.been.called;
|
||||
funcSpyTimeSyncedRawAux.should.not.have.been.called;
|
||||
});
|
||||
it("should emit a dropped packet on dropped packet",function(done) {
|
||||
// Set to default state
|
||||
ourBoard.previousSampleNumber = -1;
|
||||
var sampleNumber0 = openBCISample.samplePacket(0);
|
||||
ourBoard.once('droppedPacket',() => {
|
||||
done();
|
||||
});
|
||||
var sampleNumber2 = openBCISample.samplePacket(2);
|
||||
// Call the function under test
|
||||
ourBoard._processDataBuffer(sampleNumber0);
|
||||
ourBoard._processDataBuffer(sampleNumber2);
|
||||
});
|
||||
it("should emit a dropped packet on dropped packet with edge",function(done) {
|
||||
// Set to default state
|
||||
var count = 0;
|
||||
ourBoard.previousSampleNumber = 253;
|
||||
var buf1 = openBCISample.samplePacket(254);
|
||||
var countFunc = arr => {
|
||||
count++;
|
||||
};
|
||||
ourBoard.on('droppedPacket', countFunc);
|
||||
var buf2 = openBCISample.samplePacket(0);
|
||||
var buf3 = openBCISample.samplePacket(1);
|
||||
// Call the function under test
|
||||
ourBoard._processDataBuffer(buf1);
|
||||
ourBoard._processDataBuffer(buf2);
|
||||
ourBoard._processDataBuffer(buf3);
|
||||
setTimeout(() => {
|
||||
ourBoard.removeListener('droppedPacket', countFunc);
|
||||
expect(count).to.equal(1);
|
||||
done();
|
||||
}, 10)
|
||||
});
|
||||
});
|
||||
|
||||
describe("#_processPacketTimeSyncSet", function() {
|
||||
@@ -1050,19 +1095,64 @@ describe('openbci-sdk',function() {
|
||||
.catch(function(err) {
|
||||
expect(ourBoard.curParsingMode).to.equal(k.OBCIParsingNormal);
|
||||
expect(ourBoard.sync.curSyncObj).to.be.null;
|
||||
expect(ourBoard.sync.eventEmitter).to.be.null;
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should emit sycned event with valid false", function(done) {
|
||||
var timeSetPacketArrived = ourBoard.time();
|
||||
var expectedTimeSyncOffsetMaster = 72;
|
||||
ourBoard.curParsingMode = k.OBCIParsingTimeSyncSent;
|
||||
ourBoard.sync.curSyncObj = openBCISample.newSyncObject();
|
||||
ourBoard.sync.timeOffsetMaster = expectedTimeSyncOffsetMaster;
|
||||
ourBoard.once('synced',obj => {
|
||||
expect(obj.valid).to.be.false;
|
||||
expect(obj.timeOffsetMaster).to.equal(expectedTimeSyncOffsetMaster);
|
||||
done();
|
||||
})
|
||||
});
|
||||
ourBoard._processPacketTimeSyncSet(timeSyncSetPacket,timeSetPacketArrived);
|
||||
});
|
||||
it("should reset when bad raw packet", function(done) {
|
||||
var timeSetPacketArrived = ourBoard.time();
|
||||
var badPacket;
|
||||
if (k.getVersionNumber(process.version) >= 6) {
|
||||
// from introduced in node version 6.x.x
|
||||
badPacket = Buffer.from(timeSyncSetPacket.slice(0,30));
|
||||
} else {
|
||||
badPacket = new Buffer(timeSyncSetPacket.slice(0,30));
|
||||
}
|
||||
ourBoard.sync.curSyncObj = openBCISample.newSyncObject();
|
||||
ourBoard._processPacketTimeSyncSet(badPacket,timeSetPacketArrived)
|
||||
.then(() => {
|
||||
done("failed to get rejected");
|
||||
})
|
||||
.catch(function(err) {
|
||||
expect(ourBoard.curParsingMode).to.equal(k.OBCIParsingNormal);
|
||||
expect(ourBoard.sync.curSyncObj).to.be.null;
|
||||
expect(ourBoard.sync.eventEmitter).to.be.null;
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("should emit bad synced object bad raw packet", function(done) {
|
||||
var timeSetPacketArrived = ourBoard.time();
|
||||
var expectedTimeSyncOffsetMaster = 72;
|
||||
var badPacket;
|
||||
if (k.getVersionNumber(process.version) >= 6) {
|
||||
// from introduced in node version 6.x.x
|
||||
badPacket = Buffer.from(timeSyncSetPacket.slice(0,30));
|
||||
} else {
|
||||
badPacket = new Buffer(timeSyncSetPacket.slice(0,30));
|
||||
}
|
||||
ourBoard.curParsingMode = k.OBCIParsingTimeSyncSent;
|
||||
ourBoard.sync.curSyncObj = openBCISample.newSyncObject();
|
||||
ourBoard.sync.timeOffsetMaster = expectedTimeSyncOffsetMaster;
|
||||
ourBoard.once('synced',obj => {
|
||||
expect(obj.valid).to.be.false;
|
||||
expect(obj.timeOffsetMaster).to.equal(expectedTimeSyncOffsetMaster);
|
||||
done();
|
||||
});
|
||||
ourBoard._processPacketTimeSyncSet(badPacket,timeSetPacketArrived);
|
||||
});
|
||||
it("should calculate round trip time as the difference between time sent and time set packet arrived",function(done) {
|
||||
var timeSetPacketArrived = ourBoard.time();
|
||||
var expectedRoundTripTime = 20; //ms
|
||||
@@ -1519,7 +1609,7 @@ describe('openbci-sdk',function() {
|
||||
// Pretend that half of buf1 got sent in the first serial flush
|
||||
// and that the last half of it will arrive a lil later
|
||||
var splitPoint = 15;
|
||||
if (process.version > 6) {
|
||||
if (k.getVersionNumber(process.version) >= 6) {
|
||||
// from introduced in node version 6.x.x
|
||||
ourBoard.buffer = Buffer.from(buf1.slice(0,splitPoint));
|
||||
} else {
|
||||
@@ -1558,7 +1648,7 @@ describe('openbci-sdk',function() {
|
||||
|
||||
ourBoard["buffer"] = null;
|
||||
var bufFirstHalf, bufLastHalf;
|
||||
if (process.version > 6) {
|
||||
if (k.getVersionNumber(process.version) >= 6) {
|
||||
// from introduced in node version 6.x.x
|
||||
bufFirstHalf = Buffer.from(buf3.slice(0,splitPoint));
|
||||
bufLastHalf = Buffer.from(buf3.slice(splitPoint));
|
||||
@@ -2846,7 +2936,7 @@ describe('#daisy', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#sync', function() {
|
||||
describe('#syncWhileStreaming', function() {
|
||||
var ourBoard;
|
||||
this.timeout(4000);
|
||||
before(function (done) {
|
||||
@@ -2908,43 +2998,128 @@ describe('#sync', function() {
|
||||
it('can sync while streaming', done => {
|
||||
var syncAfterSamples = 50;
|
||||
var notSynced = true;
|
||||
var syncFunc = obj => {
|
||||
ourBoard.removeListener('sample',samp);
|
||||
done();
|
||||
};
|
||||
var samp = sample => {
|
||||
if (sample.sampleNumber >= syncAfterSamples && notSynced) {
|
||||
notSynced = false;
|
||||
// Call the first one
|
||||
ourBoard.syncClocks().catch(err => done);
|
||||
ourBoard.syncClocks()
|
||||
.catch((err) => {
|
||||
ourBoard.removeListener('sample',samp);
|
||||
ourBoard.removeListener('synced',syncFunc);
|
||||
done();
|
||||
});
|
||||
}
|
||||
};
|
||||
ourBoard.on('sample',samp);
|
||||
// Attached the emitted
|
||||
ourBoard.once('synced',obj => {
|
||||
console.log('syhnc obj', obj);
|
||||
ourBoard.removeListener('sample',samp);
|
||||
done();
|
||||
});
|
||||
ourBoard.once('synced', syncFunc);
|
||||
});
|
||||
});
|
||||
describe('#syncClocksFull', function() {
|
||||
it('can run a full clock sync', done => {
|
||||
var notSynced = true;
|
||||
var sampleFun = sample => {
|
||||
console.log('sample',sample);
|
||||
|
||||
if (notSynced) {
|
||||
notSynced = false;
|
||||
// Call the first one
|
||||
ourBoard.syncClocksFull()
|
||||
.then(syncObj => {
|
||||
console.log(syncObj);
|
||||
if (syncObj.valid) {
|
||||
ourBoard.removeListener('sample',sampleFun);
|
||||
done();
|
||||
} else {
|
||||
ourBoard.removeListener('sample',sampleFun);
|
||||
done("Not able to sync");
|
||||
}
|
||||
}).catch(err => done);
|
||||
}).catch((err) => {
|
||||
ourBoard.removeListener('sample',sampleFun);
|
||||
done();
|
||||
});
|
||||
}
|
||||
};
|
||||
ourBoard.on('sample',sampleFun);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#syncErrors', function() {
|
||||
var ourBoard;
|
||||
this.timeout(4000);
|
||||
before(function (done) {
|
||||
ourBoard = new openBCIBoard.OpenBCIBoard({
|
||||
verbose:true,
|
||||
simulatorFirmwareVersion: 'v2'
|
||||
});
|
||||
var useSim = () => {
|
||||
ourBoard.simulatorEnable()
|
||||
.then(() => {
|
||||
return ourBoard.connect(k.OBCISimulatorPortName);
|
||||
})
|
||||
.then(() => {
|
||||
return ourBoard.softReset();
|
||||
})
|
||||
.catch(err => console.log(err));
|
||||
};
|
||||
ourBoard.autoFindOpenBCIBoard()
|
||||
.then(portName => {
|
||||
return setTimeout(() => {
|
||||
console.log('Issuing connect');
|
||||
ourBoard.connect(portName);
|
||||
},500);
|
||||
})
|
||||
.catch((err) => {
|
||||
useSim();
|
||||
})
|
||||
.then(() => {
|
||||
//console.log('connected');
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('Error: ' + err);
|
||||
});
|
||||
|
||||
|
||||
ourBoard.once('ready', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
after(function(done) {
|
||||
if (ourBoard.connected) {
|
||||
ourBoard.disconnect().then(() => {
|
||||
done();
|
||||
}).catch(() => done);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
afterEach(() => {
|
||||
this.buffer = null;
|
||||
});
|
||||
describe('#syncClocksFull', function() {
|
||||
it('should reject syncClocksFull request because of timeout', done => {
|
||||
var notSynced = true;
|
||||
var sampleFun = sample => {
|
||||
if (notSynced) {
|
||||
notSynced = false;
|
||||
// Call the first one
|
||||
ourBoard.syncClocksFull()
|
||||
.then(syncObj => {
|
||||
done("Should not be able to sync");
|
||||
}).catch((err) => {
|
||||
ourBoard.removeListener('sample',sampleFun);
|
||||
done();
|
||||
});
|
||||
ourBoard.streamStop();
|
||||
}
|
||||
};
|
||||
ourBoard.streamStart()
|
||||
.catch(err => {
|
||||
ourBoard.removeListener('sample',sampleFun);
|
||||
done('coulnd not start stime sync')
|
||||
});
|
||||
ourBoard.on('sample',sampleFun);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário