Comparar commits
130 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 6cf5e993ed | |||
| 6cbf99e635 | |||
| 9bd1121ab8 | |||
| 7d878f1a16 | |||
| ba4370793c | |||
| e88922c106 | |||
| a43c52fdec | |||
| 5cf97383b9 | |||
| d51c8f80d4 | |||
| 0a1f3de1a7 | |||
| e68f85d5b3 | |||
| 9c51fd673e | |||
| 2cf1a46994 | |||
| 77f7946790 | |||
| 9bd83aaf15 | |||
| 22f5ddbcef | |||
| 918451ebcb | |||
| a03250502c | |||
| 265e89284c | |||
| 0cd2e57f96 | |||
| 4a58dcb36a | |||
| 82a3fc3ced | |||
| 23e8364185 | |||
| e21160fa4d | |||
| 6d3813c4e1 | |||
| d8342879cf | |||
| 3322e9ca5c | |||
| 5f0085ddb3 | |||
| a005c8b711 | |||
| 49d0a5376f | |||
| de22e725d5 | |||
| 74cd163bd5 | |||
| 9fd53d2bec | |||
| da8e407e84 | |||
| d624b1d387 | |||
| f861563326 | |||
| 083df5a109 | |||
| aa5e42575a | |||
| cd482558bb | |||
| fa5890d5ad | |||
| 3df7d3170c | |||
| 46edd477a5 | |||
| c36e9d6126 | |||
| ccd2983cc9 | |||
| 08a575cc9c | |||
| 83223cb50a | |||
| dbd9987d5e | |||
| 2832fcb6b2 | |||
| 61a2971275 | |||
| cc177e200d | |||
| 12429398ca | |||
| de3604f3b8 | |||
| 6f6ffe7ad8 | |||
| f4cd6b3a65 | |||
| 443ee211ad | |||
| bfc0fe62a1 | |||
| 4d7d4eb5d8 | |||
| f948ec25f2 | |||
| 78b830e5c0 | |||
| 63a15cb950 | |||
| f5bf4db9a0 | |||
| 117c4411da | |||
| 927f6c1596 | |||
| 81af1098ed | |||
| a8fa5bab02 | |||
| 982688008a | |||
| cbbecc8b37 | |||
| 4080fe0d1b | |||
| 9e745331eb | |||
| b1c8b81aa1 | |||
| de6e1ab353 | |||
| cd108bd29a | |||
| 79b46ecb53 | |||
| f8a47560b8 | |||
| 03ed89b516 | |||
| bc436a7e1f | |||
| 2108ae2a75 | |||
| 70689548a1 | |||
| 701bc75a1f | |||
| cce4f930ef | |||
| 737f40e51e | |||
| f00988716a | |||
| 7e7eb8f549 | |||
| 8383070639 | |||
| b24d682e49 | |||
| b36a7b3409 | |||
| cfa8f4bdc8 | |||
| ee66c49ff0 | |||
| abfb37a38e | |||
| 48be1a01db | |||
| 8bbc011ead | |||
| cc839b3b32 | |||
| e2cd5d1dd7 | |||
| 682074dff7 | |||
| 0af11eabe5 | |||
| 31eea736dd | |||
| 8cafa3f7ff | |||
| 971787720e | |||
| c267cca924 | |||
| 3a90e5ab96 | |||
| a18e17c7ca | |||
| 5da869f059 | |||
| e32ec71c47 | |||
| 5ee44ae531 | |||
| b7f8c135b9 | |||
| 8aa69a18dd | |||
| 617e111812 | |||
| d8c74d5b30 | |||
| aaf9f08c24 | |||
| 37c622fdf4 | |||
| 1d9927a7d7 | |||
| 1eda6df549 | |||
| 88f973d349 | |||
| afcf1de6e2 | |||
| caeeaf7dbd | |||
| 6474391d1e | |||
| 169422e77e | |||
| 21438f5a37 | |||
| 2f5a31e481 | |||
| 04f6fbae14 | |||
| 8a22f3f11b | |||
| 3ab00cfaf5 | |||
| 29b713b7f1 | |||
| 74339c126b | |||
| 465b3cc3a5 | |||
| 920eab9ed1 | |||
| 3a6d87ca90 | |||
| 6a0e1c609f | |||
| cd7d388e69 | |||
| 0ef2add033 |
+1
-1
@@ -33,10 +33,10 @@ public
|
||||
|
||||
# Test output files
|
||||
myOutput.txt
|
||||
hardwareVoltageOutputAll.txt
|
||||
|
||||
# Local npm builds for testing end in .tgz
|
||||
*.tgz
|
||||
|
||||
# For git
|
||||
*.orig
|
||||
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "4.0"
|
||||
- "4.1"
|
||||
- "4.2"
|
||||
- "5.11.0"
|
||||
- "6.0"
|
||||
- "6.1"
|
||||
- "6.2"
|
||||
- "6.3"
|
||||
install:
|
||||
- npm install --all
|
||||
script:
|
||||
|
||||
+578
-106
@@ -1,13 +1,59 @@
|
||||
[](https://waffle.io/OpenBCI/openbci-js-sdk)
|
||||
[](https://gitter.im/OpenBCI/openbci-js-sdk?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/OpenBCI/openbci-js-sdk)
|
||||
[](https://codecov.io/github/OpenBCI/openbci-js-sdk?branch=master)
|
||||
[](https://waffle.io/OpenBCI/OpenBCI_NodeJS)
|
||||
[](https://gitter.im/OpenBCI/OpenBCI_NodeJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/OpenBCI/OpenBCI_NodeJS)
|
||||
[](https://codecov.io/gh/OpenBCI/OpenBCI_NodeJS)
|
||||
|
||||
# openbci-sdk
|
||||
# OpenBCI Node.js SDK
|
||||
|
||||
An NPM module for OpenBCI ~ written with love by [Push The World!](www.pushtheworldllc.com)
|
||||
A Node.js module for OpenBCI ~ written with love by [Push The World!](http://www.pushtheworldllc.com)
|
||||
|
||||
## Working with the Module
|
||||
We are proud to support all functionality of the OpenBCI 8 and 16 Channel boards and are actively developing and maintaining this module.
|
||||
|
||||
The purpose of this module is to **get connected** and **start streaming** as fast as possible.
|
||||
|
||||
## TL;DR
|
||||
|
||||
#### Install via npm:
|
||||
|
||||
```
|
||||
npm install openbci
|
||||
```
|
||||
|
||||
#### Get connected and start streaming
|
||||
|
||||
```js
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.connect(portName)
|
||||
.then(function() {
|
||||
ourBoard.on('ready',function() {
|
||||
ourBoard.streamStart();
|
||||
ourBoard.on('sample',function(sample) {
|
||||
/** Work with sample */
|
||||
for (var i = 0; i < ourBoard.numberOfChannels(); i++) {
|
||||
console.log("Channel " + (i + 1) + ": " + sample.channelData[i].toFixed(8) + " Volts.");
|
||||
// prints to the console
|
||||
// "Channel 1: 0.00001987 Volts."
|
||||
// "Channel 2: 0.00002255 Volts."
|
||||
// ...
|
||||
// "Channel 8: -0.00001875 Volts."
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
```
|
||||
|
||||
Want to know if the module really works? Check out some projects and organizations using it:
|
||||
|
||||
* [_OpenEXP_](https://github.com/openexp/OpenEXP): an open-source desktop app for running experiments and collecting behavioral and physiological data.
|
||||
* [_Thinker_](http://www.pushtheworldllc.com/#!thinker/uc1fn): a project building the world's first brainwave-word database.
|
||||
* [_NeuroJS_](https://github.com/NeuroJS): a community dedicated to Neuroscience research using JavaScript, they have several great examples.
|
||||
|
||||
Still not satisfied it works?? Check out this [detailed report](http://s132342840.onlinehome.us/pushtheworld/files/voltageVerificationTestPlanAndResults.pdf) that scientifically validates the output voltages of this module.
|
||||
|
||||
How are you still doubting and not using this already? Fine, go look at some of the [400 **_automatic_** tests](https://codecov.io/github/OpenBCI/openbci-js-sdk?branch=master) written for it!
|
||||
|
||||
## General Overview
|
||||
|
||||
Initialization
|
||||
--------------
|
||||
@@ -15,14 +61,15 @@ Initialization
|
||||
Initializing the board:
|
||||
|
||||
```js
|
||||
var OpenBCIBoard = require('openbci-sdk');
|
||||
var OpenBCIBoard = require('openbci');
|
||||
var ourBoard = new OpenBCIBoard.OpenBCIBoard();
|
||||
```
|
||||
|
||||
For initializing with options, such as verbose print outs:
|
||||
|
||||
```js
|
||||
var ourBoard = require('openbci-sdk').OpenBCIBoard({
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard({
|
||||
verbose: true
|
||||
});
|
||||
```
|
||||
@@ -30,39 +77,37 @@ var ourBoard = require('openbci-sdk').OpenBCIBoard({
|
||||
Or if you don't have a board and want to use synthetic data:
|
||||
|
||||
```js
|
||||
var ourBoard = require('openbci-sdk').OpenBCIBoard({
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard({
|
||||
simulate: true
|
||||
});
|
||||
```
|
||||
|
||||
Auto-finding boards
|
||||
-------------------
|
||||
You must have the OpenBCI board connected to the PC before trying to automatically find it.
|
||||
|
||||
If a port is not automatically found, then call `.listPorts()` to get a list of all serial ports this would be a good place to present a drop down picker list to the user, so they may manually select the serial port name.
|
||||
|
||||
Another useful way to start the simulator:
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
ourBoard.autoFindOpenBCIBoard().then(portName => {
|
||||
if(portName) {
|
||||
/**
|
||||
* Connect to the board with portName
|
||||
* i.e. ourBoard.connect(portName).....
|
||||
*/
|
||||
} else {
|
||||
/**Unable to auto find OpenBCI board*/
|
||||
}
|
||||
});
|
||||
var openBCIBoard = require('openbci');
|
||||
var k = openBCIBoard.OpenBCIConstants;
|
||||
var ourBoard = openBCIBoard.OpenBCIBoard();
|
||||
ourBoard.connect(k.OBCISimulatorPortName) // This will set `simulate` to true
|
||||
.then(function(boardSerial) {
|
||||
ourBoard.on('ready',function() {
|
||||
/** Start streaming, reading registers, what ever your heart desires */
|
||||
});
|
||||
}).catch(function(err) {
|
||||
/** Handle connection errors */
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
'ready' event
|
||||
------------
|
||||
|
||||
You MUST wait for the 'ready' event to be emitted before streaming/talking with the board. The ready happens asynchronously
|
||||
You MUST wait for the 'ready' event to be emitted before streaming/talking with the board. The ready happens asynchronously
|
||||
so installing the 'sample' listener and writing before the ready event might result in... nothing at all.
|
||||
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.connect(portName).then(function(boardSerial) {
|
||||
ourBoard.on('ready',function() {
|
||||
/** Start streaming, reading registers, what ever your heart desires */
|
||||
@@ -74,15 +119,18 @@ ourBoard.connect(portName).then(function(boardSerial) {
|
||||
|
||||
Sample properties:
|
||||
------------------
|
||||
* `startByte` (`Number` should be `0xA0`)
|
||||
* `sampleNumber` (a `Number` between 0-255)
|
||||
* `startByte` (`Number` should be `0xA0`)
|
||||
* `sampleNumber` (a `Number` between 0-255)
|
||||
* `channelData` (channel data indexed at 0 filled with floating point `Numbers` in Volts)
|
||||
* `auxData` (aux data indexed starting at 0 [0,1,2] filled with floating point `Numbers`)
|
||||
* `stopByte` (`Number` should be `0xC0`)
|
||||
* `accelData` (`Array` with X, Y, Z accelerometer values when new data available)
|
||||
* `auxData` (`Buffer` filled with either 2 bytes (if time synced) or 6 bytes (not time synced))
|
||||
* `stopByte` (`Number` should be `0xCx` where x is 0-15 in hex)
|
||||
* `boardTime` (`Number` the raw board time)
|
||||
* `timeStamp` (`Number` the `boardTime` plus the NTP calculated offset)
|
||||
|
||||
The power of this module is in using the sample emitter, to be provided with samples to do with as you wish.
|
||||
|
||||
You can also start the simulator by sending `.connect(portName)` with `portName` equal to `'/dev/tty.openBCISimulator'`.
|
||||
You can also start the simulator by sending `.connect(portName)` with `portName` equal to `'OpenBCISimulator'`.
|
||||
|
||||
To get a 'sample' event, you need to:
|
||||
-------------------------------------
|
||||
@@ -91,8 +139,9 @@ To get a 'sample' event, you need to:
|
||||
3. In callback for 'ready' emitter, call `streamStart()`
|
||||
4. Install the 'sample' event emitter
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
ourBoard.connect(portName).then(function(boardSerial) {
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.connect(portName).then(function() {
|
||||
ourBoard.on('ready',function() {
|
||||
ourBoard.streamStart();
|
||||
ourBoard.on('sample',function(sample) {
|
||||
@@ -105,17 +154,107 @@ ourBoard.connect(portName).then(function(boardSerial) {
|
||||
```
|
||||
Close the connection with `.streamStop()` and disconnect with `.disconnect()`
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
var ourBoard = new require('openbci').OpenBCIBoard();
|
||||
ourBoard.streamStop().then(ourBoard.disconnect());
|
||||
```
|
||||
|
||||
Time Syncing
|
||||
------------
|
||||
You must be using OpenBCI firmware version 2 in order to do time syncing. After you `.connect()` and send a `.softReset()`, you can call `.usingVersionTwoFirmware()` to get a boolean response as to if you are using `v1` or `v2`.
|
||||
|
||||
Now using firmware `v2`, the fun begins! We synchronize the Board's clock with the module's time. In firmware `v2` we leverage samples with time stamps and _ACKs_ from the Dongle to form a time synchronization strategy. Time syncing has been verified to +/- 4ms and a test report is on the way. We are still working on the synchronize of this module and an NTP server, this is an open call for any NTP experts out there! With a global NTP server you could use several different devices and all sync to the same time server. That way you can really do some serious cloud computing!
|
||||
|
||||
Keep your resync interval above 50ms. While it's important to resync every couple minutes due to drifting of clocks, please do not try to sync without getting the last sync event! We can only support one sync operation at a time!
|
||||
|
||||
Using local computer time:
|
||||
```js
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard,
|
||||
ourBoard = new OpenBCIBoard({
|
||||
verbose:true
|
||||
});
|
||||
|
||||
const resyncPeriodMin = 5; // re sync every five minutes
|
||||
const secondsInMinute = 60;
|
||||
var sampleRate = k.OBCISampleRate250; // Default to 250, ALWAYS verify with a call to `sampleRate` after `ready` event!
|
||||
var timeSyncPossible = false;
|
||||
|
||||
// Call to connect
|
||||
ourBoard.connect(portName).then(() => {
|
||||
ourBoard.on('ready',() => {
|
||||
// Get the sample rate after 'ready' event!
|
||||
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();
|
||||
|
||||
ourBoard.streamStart()
|
||||
.then(() => {
|
||||
/** Start streaming command sent to board. */
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`stream start: ${err}`);
|
||||
})
|
||||
});
|
||||
|
||||
// PTW recommends sample driven
|
||||
ourBoard.on('sample',sample => {
|
||||
// Resynchronize every every 5 minutes
|
||||
if (sample._count % (sampleRate * resyncPeriodMin * secondsInMinute) === 0) {
|
||||
ourBoard.syncClocksFull()
|
||||
.then(syncObj => {
|
||||
// Sync was successful
|
||||
if (syncObj.valid) {
|
||||
// Log the object to check it out!
|
||||
console.log(`syncObj`,syncObj);
|
||||
|
||||
// Sync was not successful
|
||||
} else {
|
||||
// Retry it
|
||||
console.log(`Was not able to sync, please retry?`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (sample.timeStamp) { // true after the first sync
|
||||
console.log(`NTP Time Stamp ${sample.timeStamp}`);
|
||||
}
|
||||
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`connect: ${err}`);
|
||||
});
|
||||
```
|
||||
|
||||
Auto-finding boards
|
||||
-------------------
|
||||
You must have the OpenBCI board connected to the PC before trying to automatically find it.
|
||||
|
||||
If a port is not automatically found, then call `.listPorts()` to get a list of all serial ports this would be a good place to present a drop down picker list to the user, so they may manually select the serial port name.
|
||||
|
||||
```js
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.autoFindOpenBCIBoard().then(portName => {
|
||||
if(portName) {
|
||||
/**
|
||||
* Connect to the board with portName
|
||||
* i.e. ourBoard.connect(portName).....
|
||||
*/
|
||||
} else {
|
||||
/**Unable to auto find OpenBCI board*/
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Note: `.autoFindOpenBCIBoard()` will return the name of the Simulator if you instantiate with option `simulate: true`.
|
||||
|
||||
Auto Test - (Using impedance to determine signal quality)
|
||||
---------------------------------------------------------
|
||||
Measuring impedance is a vital tool in ensuring great data is collected.
|
||||
Measuring impedance is a vital tool in ensuring great data is collected.
|
||||
|
||||
**_IMPORTANT!_** Measuring impedance takes time, so *only test what you must*
|
||||
|
||||
Your OpenBCI board will have electrodes hooked up to either a P input, N input or in some cases both inputs.
|
||||
Your OpenBCI board will have electrodes hooked up to either a P input, N input or in some cases both inputs.
|
||||
|
||||
To test specific inputs of channels:
|
||||
|
||||
@@ -135,7 +274,8 @@ Where there are the same number of elements as channels and each element can be
|
||||
|
||||
Without further ado, here is an example:
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.connect(portName).then(function(boardSerial) {
|
||||
ourBoard.on('ready',function() {
|
||||
ourBoard.streamStart();
|
||||
@@ -146,7 +286,7 @@ ourBoard.connect(portName).then(function(boardSerial) {
|
||||
});
|
||||
}).catch(function(err) {
|
||||
/** Handle connection errors */
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
But wait! What is this `impedanceArray`? An Array of Objects, for each object:
|
||||
@@ -154,13 +294,11 @@ But wait! What is this `impedanceArray`? An Array of Objects, for each object:
|
||||
[{
|
||||
channel: 1,
|
||||
P: {
|
||||
data: [],
|
||||
average: -1,
|
||||
raw: -1,
|
||||
text: 'init'
|
||||
},
|
||||
N: {
|
||||
data: [],
|
||||
average: -1,
|
||||
raw: -1,
|
||||
text: 'init'
|
||||
}
|
||||
},
|
||||
@@ -173,8 +311,7 @@ Where:
|
||||
|
||||
* *channel* is the channel number (`impedanceArray[0]` is channel 1, `impedanceArray[6]` is channel 7)
|
||||
* *P* is the P input data (Note: P is capitalized)
|
||||
* *data* is an array of raw impedances values that were recorded over 250ms
|
||||
* *average* is an average impedance value taken from `data` array. To get this value we remove outliers from the `data` array and average the cleaned data.
|
||||
* *raw* is an impedance value resulting from the Goertzel algorithm.
|
||||
* *text* is a text interpretation of the `average`
|
||||
* **Good** impedance is < 5k Ohms
|
||||
* **Ok** impedance is 5 to 10k Ohms
|
||||
@@ -182,7 +319,7 @@ Where:
|
||||
* **None** impedance is > 1M Ohms
|
||||
* *N* is the N input data (Note: N is capitalized) (see above for what N object consists of)
|
||||
|
||||
To run an impedance test on all imputs:
|
||||
To run an impedance test on all inputs, one channel at a time:
|
||||
|
||||
1. Connect to board
|
||||
2. Start streaming
|
||||
@@ -194,7 +331,8 @@ To run an impedance test on all imputs:
|
||||
For example:
|
||||
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.connect(portName).then(function(boardSerial) {
|
||||
ourBoard.streamStart();
|
||||
ourBoard.on('impedanceArray', impedanceArray => {
|
||||
@@ -218,26 +356,40 @@ Create new instance of an OpenBCI board.
|
||||
|
||||
Board optional configurations.
|
||||
|
||||
* `boardType` Specifies type of OpenBCI board (3 possible boards)
|
||||
* `baudRate` {Number} - Baud Rate, defaults to 115200. Manipulating this is allowed if firmware on board has been previously configured.
|
||||
* `boardType` {String} - Specifies type of OpenBCI board (3 possible boards)
|
||||
* `default` - 8 Channel OpenBCI board (Default)
|
||||
* `daisy` - 8 Channel board with Daisy Module
|
||||
(NOTE: THIS IS IN-OP AT THIS TIME DUE TO NO ACCESS TO ACCESSORY BOARD)
|
||||
* `daisy` - 8 Channel board with Daisy Module - 16 Channels
|
||||
* `ganglion` - 4 Channel board
|
||||
(NOTE: THIS IS IN-OP TIL RELEASE OF GANGLION BOARD 07/2016)
|
||||
* `baudRate` Baud Rate, defaults to 115200. Manipulating this is allowed if firmware on board has been previously configured.
|
||||
* `verbose` To output more messages to the command line.
|
||||
* `simulate` Full functionality, just synthetic data.
|
||||
* `simulatorSampleRate` - The sample rate to use for the simulator (Default is `250`)
|
||||
(NOTE: THIS IS IN-OP TIL RELEASE OF GANGLION BOARD 08/2016)
|
||||
* `simulate` {Boolean} - Full functionality, just mock data. Must attach Daisy module by setting `simulatorDaisyModuleAttached` to `true` in order to get 16 channels. (Default `false`)
|
||||
* `simulatorBoardFailure` {Boolean} - Simulates board communications failure. This occurs when the RFduino on the board is not polling the RFduino on the dongle. (Default `false`)
|
||||
* `simulatorDaisyModuleAttached` {Boolean} - Simulates a daisy module being attached to the OpenBCI board. This is useful if you want to test how your application reacts to a user requesting 16 channels but there is no daisy module actually attached, or vice versa, where there is a daisy module attached and the user only wants to use 8 channels. (Default `false`)
|
||||
* `simulatorFirmwareVersion` {String} - Allows the simulator to use firmware version 2 features. (2 Possible Options)
|
||||
* `v1` - Firmware Version 1 (Default)
|
||||
* `v2` - Firmware Version 2
|
||||
* `simulatorHasAccelerometer` - {Boolean} - Sets simulator to send packets with accelerometer data. (Default `true`)
|
||||
* `simulatorInjectAlpha` - {Boolean} - Inject a 10Hz alpha wave in Channels 1 and 2 (Default `true`)
|
||||
* `simulatorInjectLineNoise` {String} - Injects line noise on channels. (3 Possible Options)
|
||||
* `60Hz` - 60Hz line noise (Default) [America]
|
||||
* `50Hz` - 50Hz line noise [Europe]
|
||||
* `None` - Do not inject line noise.
|
||||
* `simulatorSampleRate` {Number} - The sample rate to use for the simulator. Simulator will set to 125 if `simulatorDaisyModuleAttached` is set `true`. However, setting this option overrides that setting and this sample rate will be used. (Default is `250`)
|
||||
* `simulatorSerialPortFailure` {Boolean} - Simulates not being able to open a serial connection. Most likely due to a OpenBCI dongle not being plugged in.
|
||||
* `sntpTimeSync` - {Boolean} Syncs the module up with an SNTP time server and uses that as single source of truth instead of local computer time. If you are running experiments on your local computer, keep this `false`. (Default `false`)
|
||||
* `sntpTimeSyncHost` - {String} The sntp server to use, can be either sntp or ntp (Defaults `pool.ntp.org`).
|
||||
* `sntpTimeSyncPort` - {Number} The port to access the sntp server (Defaults `123`)
|
||||
* `verbose` {Boolean} - Print out useful debugging events (Default `false`)
|
||||
|
||||
**Note, we have added support for either all lowercase OR camelcase of the options, use whichever style you prefer.**
|
||||
**Note, we have added support for either all lowercase OR camel case for the options, use whichever style you prefer.**
|
||||
|
||||
### .autoFindOpenBCIBoard()
|
||||
|
||||
Automatically find an OpenBCI board.
|
||||
Automatically find an OpenBCI board.
|
||||
|
||||
**Note: This will always return an Array of `COM` ports on Windows**
|
||||
|
||||
**_Returns_** a promise, fulfilled with a `portName` such as `/dev/tty.*` on Mac/Linux.
|
||||
**_Returns_** a promise, fulfilled with a `portName` such as `/dev/tty.*` on Mac/Linux or `OpenBCISimulator` if `this.options.simulate === true`.
|
||||
|
||||
### .channelOff(channelNumber)
|
||||
|
||||
@@ -245,7 +397,7 @@ Turn off a specified channel
|
||||
|
||||
**_channelNumber_**
|
||||
|
||||
A number (1-16) specifying which channel you want to turn off.
|
||||
A number (1-16) specifying which channel you want to turn off.
|
||||
|
||||
**_Returns_** a promise, fulfilled if the command was sent to the write queue.
|
||||
|
||||
@@ -255,7 +407,7 @@ Turn on a specified channel
|
||||
|
||||
**_channelNumber_**
|
||||
|
||||
A number (1-16) specifying which channel you want to turn on.
|
||||
A number (1-16) specifying which channel you want to turn on.
|
||||
|
||||
**_Returns_** a promise, fulfilled if the command was sent to the write queue.
|
||||
|
||||
@@ -267,19 +419,19 @@ Send a channel setting command to the board.
|
||||
|
||||
Determines which channel to set. It's a 'Number' (1-16)
|
||||
|
||||
**_powerDown_**
|
||||
**_powerDown_**
|
||||
|
||||
Powers the channel up or down. It's a 'Bool' where `true` turns the channel off and `false` turns the channel on (default)
|
||||
|
||||
**_gain_**
|
||||
|
||||
|
||||
Sets the gain for the channel. It's a 'Number' that is either (1,2,4,6,8,12,24(default))
|
||||
|
||||
**_inputType_**
|
||||
|
||||
|
||||
**_inputType_**
|
||||
|
||||
Selects the ADC channel input source. It's a 'String' that **MUST** be one of the following: "normal", "shorted", "biasMethod" , "mvdd" , "temp" , "testsig", "biasDrp", "biasDrn".
|
||||
|
||||
**_bias_**
|
||||
**_bias_**
|
||||
|
||||
Selects if the channel shall include the channel input in bias generation. It's a 'Bool' where `true` includes the channel in bias (default) or `false` it removes it from bias.
|
||||
|
||||
@@ -288,7 +440,7 @@ Selects if the channel shall include the channel input in bias generation. It's
|
||||
Select to connect (`true`) this channel's P input to the SRB2 pin. This closes a switch between P input and SRB2 for the given channel, and allows the P input to also remain connected to the ADC. It's a 'Bool' where `true` connects this input to SRB2 (default) or `false` which disconnect this input from SRB2.
|
||||
|
||||
**_srb1_**
|
||||
|
||||
|
||||
Select to connect (`true`) all channels' N inputs to SRB1. This effects all pins, and disconnects all N inputs from the ADC. It's a 'Bool' where `true` connects all N inputs to SRB1 and `false` disconnects all N inputs from SRB1 (default).
|
||||
|
||||
**_Returns_** a promise fulfilled if proper commands sent to the write queue, rejects on bad input or no board.
|
||||
@@ -307,7 +459,7 @@ The essential precursor method to be called initially to establish a serial conn
|
||||
|
||||
The system path of the OpenBCI board serial port to open. For example, `/dev/tty` on Mac/Linux or `COM1` on Windows.
|
||||
|
||||
**_Returns_** a promise, fulfilled by a successful serial connection to the board The promise will be rejected at any time if the serial port has an 'error' or 'close' event emitted.
|
||||
**_Returns_** a promise, fulfilled by a successful serial connection to the board.
|
||||
|
||||
### .debugSession()
|
||||
|
||||
@@ -315,7 +467,7 @@ Calls all `.printPacketsBad()`, `.printPacketsRead()`, `.printBytesIn()`
|
||||
|
||||
### .disconnect()
|
||||
|
||||
Closes the serial port opened by `.connect()`
|
||||
Closes the serial port opened by `.connect()`. Waits for stop streaming command to be sent if currently streaming.
|
||||
|
||||
**_Returns_** a promise, fulfilled by a successful close of the serial port object, rejected otherwise.
|
||||
|
||||
@@ -323,7 +475,7 @@ Closes the serial port opened by `.connect()`
|
||||
|
||||
Gets the specified channelSettings register data from printRegisterSettings call.
|
||||
|
||||
**_channelNumber_**
|
||||
**_channelNumber_**
|
||||
|
||||
A number specifying which channel you want to get data on. Only 1-8 at this time.
|
||||
|
||||
@@ -343,10 +495,10 @@ Don't forget to install the `impedanceArray` emitter to receive the impendances!
|
||||
|
||||
### .impedanceTestChannels(arrayOfCommands)
|
||||
|
||||
**_arrayOfCommands_**
|
||||
**_arrayOfCommands_**
|
||||
|
||||
The array of configurations where there are the same number of elements as channels and each element can be either:
|
||||
|
||||
|
||||
* `p` or `P` (only test P input)
|
||||
* `n` or `N` (only test N input)
|
||||
* `b` or `B` (test both inputs) (takes 66% longer to run then previous two `p` or `n`)
|
||||
@@ -368,9 +520,10 @@ A Number, specifies which channel you want to test.
|
||||
|
||||
**_Returns_** a promise that resolves a single channel impedance object.
|
||||
|
||||
Example:
|
||||
**Example**
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.connect(portName).then(function(boardSerial) {
|
||||
ourBoard.on('ready',function() {
|
||||
ourBoard.streamStart();
|
||||
@@ -382,20 +535,18 @@ ourBoard.connect(portName).then(function(boardSerial) {
|
||||
});
|
||||
}).catch(function(err) {
|
||||
/** Handle connection errors */
|
||||
});
|
||||
});
|
||||
```
|
||||
Where an impedance for this method call would look like:
|
||||
```js
|
||||
{
|
||||
channel: 1,
|
||||
P: {
|
||||
data: [3456.324,2204.5,...],
|
||||
average: 2394.45,
|
||||
raw: 2394.45,
|
||||
text: 'good'
|
||||
},
|
||||
N: {
|
||||
data: [5436.324,9404.5,...],
|
||||
average: 7694.45,
|
||||
raw: 7694.45,
|
||||
text: 'ok'
|
||||
}
|
||||
}
|
||||
@@ -411,9 +562,10 @@ A Number, specifies which channel you want to test.
|
||||
|
||||
**_Returns_** a promise that resolves a single channel impedance object.
|
||||
|
||||
Example:
|
||||
**Example**
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.connect(portName).then(function(boardSerial) {
|
||||
ourBoard.on('ready',function() {
|
||||
ourBoard.streamStart();
|
||||
@@ -425,20 +577,18 @@ ourBoard.connect(portName).then(function(boardSerial) {
|
||||
});
|
||||
}).catch(function(err) {
|
||||
/** Handle connection errors */
|
||||
});
|
||||
});
|
||||
```
|
||||
Where an impedance for this method call would look like:
|
||||
```js
|
||||
{
|
||||
channel: 1,
|
||||
P: {
|
||||
data: [3456.324,2204.5,...],
|
||||
average: 2394.45,
|
||||
raw: 2394.45,
|
||||
text: 'good'
|
||||
},
|
||||
N: {
|
||||
data: [],
|
||||
average: -1,
|
||||
raw: -1,
|
||||
text: 'init'
|
||||
}
|
||||
}
|
||||
@@ -454,9 +604,10 @@ A Number, specifies which channel you want to test.
|
||||
|
||||
**_Returns_** a promise that resolves a single channel impedance object.
|
||||
|
||||
Example:
|
||||
**Example**
|
||||
```js
|
||||
var ourBoard = new require('openbci-sdk').OpenBCIBoard();
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
ourBoard.connect(portName).then(function(boardSerial) {
|
||||
ourBoard.on('ready',function() {
|
||||
ourBoard.streamStart();
|
||||
@@ -468,25 +619,35 @@ ourBoard.connect(portName).then(function(boardSerial) {
|
||||
});
|
||||
}).catch(function(err) {
|
||||
/** Handle connection errors */
|
||||
});
|
||||
});
|
||||
```
|
||||
Where an impedance for this method call would look like:
|
||||
```js
|
||||
{
|
||||
channel: 1,
|
||||
P: {
|
||||
data: [],
|
||||
average: -1,
|
||||
raw: -1,
|
||||
text: 'init'
|
||||
},
|
||||
N: {
|
||||
data: [5436.324,9404.5,...],
|
||||
average: 7694.45,
|
||||
raw: 7694.45,
|
||||
text: 'ok'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### .impedanceTestContinuousStart()
|
||||
|
||||
Sends command to turn on impedances for all channels and continuously calculate their impedances.
|
||||
|
||||
**_Returns_** a promise, that fulfills when all the commands are sent to the internal write buffer
|
||||
|
||||
### .impedanceTestContinuousStop()
|
||||
|
||||
Sends command to turn off impedances for all channels and stop continuously calculate their impedances.
|
||||
|
||||
**_Returns_** a promise, that fulfills when all the commands are sent to the internal write buffer
|
||||
|
||||
### .listPorts()
|
||||
|
||||
List available ports so the user can choose a device when not automatically found.
|
||||
@@ -519,6 +680,78 @@ Prints all register settings for the ADS1299 and the LIS3DH on the OpenBCI board
|
||||
|
||||
**_Returns_** a promise, fulfilled if the command was sent to the write queue.
|
||||
|
||||
### .radioBaudRateSet(speed)
|
||||
|
||||
Used to set the OpenBCI Host (Dongle) baud rate. With the RFduino configuration, the Dongle is the Host and the Board is the Device. Only the Device can initiate a communication between the two entities. There exists a detrimental error where if the Host is interrupted by the radio during a Serial write, then all hell breaks loose. So this is an effort to eliminate that problem by increasing the rate at which serial data is sent from the Host to the Serial driver. The rate can either be set to default or fast. Further the function should reject if currently streaming. Lastly and more important, if the board is not running the new firmware then this functionality does not exist and thus this method will reject. If the board is using firmware 2+ then this function should resolve the new baud rate after closing the current serial port and reopening one.
|
||||
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_speed_**
|
||||
|
||||
{String} - The baud rate that to switch to. Can be either `default` (115200) or `fast` (230400).
|
||||
|
||||
**_Returns_** {Promise} - Resolves a {Number} that is the new baud rate, rejects on error.
|
||||
|
||||
### .radioChannelGet()
|
||||
|
||||
Used to query the OpenBCI system for it's radio channel number. The function will reject if not connected to the serial port of the dongle. Further the function should reject if currently streaming. Lastly and more important, if the board is not running the new firmware then this functionality does not exist and thus this method will reject. If the board is using firmware 2+ then this function should resolve an Object. See `returns` below.
|
||||
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_Returns_** {Promise} - Resolve an object with keys `channelNumber` which is a Number and `err` which contains an error in the condition that there system is experiencing board communications failure.
|
||||
|
||||
### .radioChannelSet(channelNumber)
|
||||
|
||||
Used to set the system radio channel number. The function will reject if not connected to the serial port of the dongle. Further the function should reject if currently streaming. Lastly and more important, if the board is not running the new firmware then this functionality does not exist and thus this method will reject. If the board is using firmware 2+ then this function should resolve.
|
||||
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_channelNumber_**
|
||||
|
||||
{Number} - The channel number you want to set to, 1-25.
|
||||
|
||||
**_Returns_** {Promise} - Resolves with the new channel number, rejects with err.
|
||||
|
||||
### .radioChannelSetHostOverride(channelNumber)
|
||||
|
||||
Used to set the ONLY the radio dongle Host channel number. This will fix your radio system if your dongle and board are not on the right channel and bring down your radio system if you take your dongle and board are not on the same channel. Use with caution! The function will reject if not connected to the serial port of the dongle. Further the function should reject if currently streaming. Lastly and more important, if the board is not running the new firmware then this functionality does not exist and thus this method will reject. If the board is using firmware 2+ then this function should resolve.
|
||||
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_channelNumber_**
|
||||
|
||||
{Number} - The channel number you want to set to, 1-25.
|
||||
|
||||
**_Returns_** {Promise} - Resolves with the new channel number, rejects with err.
|
||||
|
||||
### .radioPollTimeGet()
|
||||
|
||||
Used to query the OpenBCI system for it's device's poll time. The function will reject if not connected to the serial port of the dongle. Further the function should reject if currently streaming. Lastly and more important, if the board is not running the new firmware then this functionality does not exist and thus this method will reject. If the board is using firmware 2+ then this function should resolve the poll time when fulfilled. It's important to note that if the board is not on, this function will always be rejected with a failure message.
|
||||
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_Returns_** {Promise} - Resolves with the new poll time, rejects with err.
|
||||
|
||||
### .radioPollTimeSet(pollTime)
|
||||
|
||||
Used to set the OpenBCI poll time. With the RFduino configuration, the Dongle is the Host and the Board is the Device. Only the Device can initiate a communication between the two entities. Therefore this sets the interval at which the Device polls the Host for new information. Further the function should reject if currently streaming. Lastly and more important, if the board is not running the new firmware then this functionality does not exist and thus this method will reject. If the board is using firmware 2+ then this function should resolve.
|
||||
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_pollTime_**
|
||||
|
||||
{Number} - The poll time you want to set to, 0-255.
|
||||
|
||||
**_Returns_** {Promise} - Resolves with the new channel number, rejects with err.
|
||||
|
||||
### .radioSystemStatusGet()
|
||||
|
||||
Used to ask the Host if it's radio system is up. This is useful to quickly determine if you are in fact ready to start trying to connect and such. The function will reject if not connected to the serial port of the dongle. Further the function should reject if currently streaming. Lastly and more important, if the board is not running the new firmware then this functionality does not exist and thus this method will reject. If the board is using firmware +v2.0.0 and the radios are both on the same channel and powered, then this will resolve true.
|
||||
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_Returns_** {Promise} - Resolves true if both radios are powered and on the same channel; false otherwise.
|
||||
|
||||
### .sampleRate()
|
||||
|
||||
Get the current sample rate.
|
||||
@@ -527,7 +760,35 @@ Get the current sample rate.
|
||||
|
||||
**_Returns_** a number, the current sample rate.
|
||||
|
||||
### .simulatorStart()
|
||||
### .sdStart(recordingDuration)
|
||||
|
||||
Start logging to the SD card. If you are not streaming when you send this command, then you should expect to get a success or failure message followed by and end of transmission `$$$`.
|
||||
|
||||
**_recordingDuration_**
|
||||
|
||||
The duration you want to log SD information for. Opens a new SD file to write into. Limited to:
|
||||
|
||||
* `14sec` - 14 seconds
|
||||
* `5min` - 5 minutes
|
||||
* `15min` - 15 minutes
|
||||
* `30min` - 30 minutes
|
||||
* `1hour` - 1 hour
|
||||
* `2hour` - 2 hour
|
||||
* `4hour` - 4 hour
|
||||
* `12hour` - 12 hour
|
||||
* `24hour` - 24 hour
|
||||
|
||||
**Note: You must have the proper type of SD card inserted into the board for logging to work.**
|
||||
|
||||
**_Returns_** resolves if the command was added to the write queue.
|
||||
|
||||
### .sdStop()
|
||||
|
||||
Stop logging to the SD card and close any open file. If you are not streaming when you send this command, then you should expect to get a success or failure message followed by and end of transmission `$$$`. The success message contains a lot of useful information about what happened when writing to the SD card.
|
||||
|
||||
**_Returns_** resolves if the command was added to the write queue.
|
||||
|
||||
### .simulatorEnable()
|
||||
|
||||
To enter simulate mode. Must call `.connect()` after.
|
||||
|
||||
@@ -535,14 +796,34 @@ To enter simulate mode. Must call `.connect()` after.
|
||||
|
||||
**_Returns_** a promise, fulfilled if able to enter simulate mode, reject if not.
|
||||
|
||||
### .simulatorStop()
|
||||
### .simulatorDisable()
|
||||
|
||||
To leave simulate mode.
|
||||
To leave simulate mode.
|
||||
|
||||
**Note, must be called after the constructor.**
|
||||
|
||||
**_Returns_** a promise, fulfilled if able to stop simulate mode, reject if not.
|
||||
|
||||
### .sntp
|
||||
|
||||
Extends the popular STNP package on [npmjs](https://www.npmjs.com/package/sntp)
|
||||
|
||||
### .sntpGetOffset()
|
||||
|
||||
Stateful method for querying the current offset only when the last one is too old. (defaults to daily)
|
||||
|
||||
**_Returns_** a promise with the time offset
|
||||
|
||||
### .sntpStart()
|
||||
|
||||
This starts the SNTP server and gets it to remain in sync with the SNTP server.
|
||||
|
||||
**_Returns_** a promise if the module was able to sync with NTP server.
|
||||
|
||||
### .sntpStop()
|
||||
|
||||
Stops the SNTP from updating
|
||||
|
||||
### .softReset()
|
||||
|
||||
Sends a soft reset command to the board.
|
||||
@@ -553,7 +834,7 @@ Sends a soft reset command to the board.
|
||||
|
||||
### .streamStart()
|
||||
|
||||
Sends a start streaming command to the board.
|
||||
Sends a start streaming command to the board.
|
||||
|
||||
**Note, You must have called and fulfilled `.connect()` AND observed a `'ready'` emitter before calling this method.**
|
||||
|
||||
@@ -561,17 +842,149 @@ Sends a start streaming command to the board.
|
||||
|
||||
### .streamStop()
|
||||
|
||||
Sends a stop streaming command to the board.
|
||||
Sends a stop streaming command to the board.
|
||||
|
||||
**Note, You must have called and fulfilled `.connect()` AND observed a `'ready'` emitter before calling this method.**
|
||||
|
||||
**_Returns_** a promise, fulfilled if the command was sent to the write queue, rejected if unable.
|
||||
|
||||
### .write(data)
|
||||
### .syncClocks()
|
||||
|
||||
Send commands to the board. Due to the OpenBCI board firmware, a 10ms spacing **must** be observed between every command sent to the board. This method handles the timing and spacing between characters by adding characters to a global write queue and pulling from it every 10ms.
|
||||
Send the command to tell the board to start the syncing protocol. Must be connected, streaming and using version +2 firmware.
|
||||
|
||||
**_dataToWrite_**
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_Returns_** {Promise} resolves if the command was sent to the write queue, rejects if unable.
|
||||
|
||||
### .syncClocksFull()
|
||||
|
||||
Send the command to tell the board to start the syncing protocol. Must be connected, streaming and using v2 firmware. Uses the `synced` event to ensure multiple syncs don't overlap.
|
||||
|
||||
**Note, this functionality requires OpenBCI Firmware Version 2.0**
|
||||
|
||||
**_Returns_** {Promise} resolves if `synced` event is emitted, rejects if not connected or using firmware v2. Resolves with a synced object:
|
||||
```javascript
|
||||
{
|
||||
boardTime: 0, // The time contained in the time sync set packet.
|
||||
correctedTransmissionTime: false, // If the confirmation and the set packet arrive in the same serial flush we have big problem! This will be true in this case. See source code for full explanation.
|
||||
timeSyncSent: 0, // The time the `<` was sent to the Dongle.
|
||||
timeSyncSentConfirmation: 0, // The time the `<` was sent to the Board; It's really the time `,` was received from the Dongle.
|
||||
timeSyncSetPacket: 0, // The time the set packet was received from the Board.
|
||||
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.
|
||||
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.
|
||||
}
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
Syncing multiple times to base the offset of the average of the four syncs.
|
||||
|
||||
```javascript
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard,
|
||||
ourBoard = new OpenBCIBoard({
|
||||
verbose:true
|
||||
});
|
||||
|
||||
var portName = /* INSERT PORT NAME HERE */;
|
||||
var samples = []; // Array to store time synced samples into
|
||||
var timeSyncActivated = false;
|
||||
|
||||
ourBoard.connect(portName)
|
||||
.then(() => {
|
||||
ourBoard.on('ready',() => {
|
||||
ourBoard.streamStart()
|
||||
.then(() => {
|
||||
/** Could also call `.syncClocksFull()` here */
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`Error starting stream ${err}`);
|
||||
})
|
||||
});
|
||||
ourBoard.on('sample',sample => {
|
||||
/** If we are not synced, then do that! */
|
||||
if (timeSyncActivated === false) {
|
||||
timeSyncActivated = true;
|
||||
ourBoard.syncClocksFull()
|
||||
.then(syncObj => {
|
||||
if (syncObj.valid) {
|
||||
console.log('1st sync done');
|
||||
}
|
||||
return ourBoard.syncClocksFull();
|
||||
})
|
||||
.then(syncObj => {
|
||||
if (syncObj.valid) {
|
||||
console.log('2nd sync done');
|
||||
}
|
||||
return ourBoard.syncClocksFull();
|
||||
})
|
||||
.then(syncObj => {
|
||||
if (syncObj.valid) {
|
||||
console.log('3rd sync done');
|
||||
}
|
||||
return ourBoard.syncClocksFull();
|
||||
})
|
||||
.then(syncObj => {
|
||||
if (syncObj.valid) {
|
||||
console.log('4th sync done');
|
||||
|
||||
}
|
||||
/* Do awesome time syncing stuff */
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`sync err ${err}`);
|
||||
});
|
||||
}
|
||||
if (startLoggingSamples && sample.hasOwnProperty("timeStamp") && sample.hasOwnProperty("boardTime")) {
|
||||
/** If you only want to log samples with time stamps */
|
||||
samples.push(sample);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`connect ${err}`);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
### .testSignal(signal)
|
||||
|
||||
Apply the internal test signal to all channels.
|
||||
|
||||
**_signal_**
|
||||
|
||||
A String indicating which test signal to apply
|
||||
|
||||
* `dc` - Connect to DC signal
|
||||
* `ground` - Connect to internal GND (VDD - VSS)
|
||||
* `pulse1xFast` - Connect to test signal 1x Amplitude, fast pulse
|
||||
* `pulse1xSlow` - Connect to test signal 1x Amplitude, slow pulse
|
||||
* `pulse2xFast` - Connect to test signal 2x Amplitude, fast pulse
|
||||
* `pulse2xFast` - Connect to test signal 2x Amplitude, slow pulse
|
||||
* `none` - Reset to default
|
||||
|
||||
**_Returns_** a promise, if the commands were sent to write buffer.
|
||||
|
||||
### .time()
|
||||
|
||||
Uses `._sntpNow()` time when sntpTimeSync specified in options, or else use Date.now() for time.
|
||||
|
||||
**_Returns_** time since UNIX epoch in ms.
|
||||
|
||||
### .usingVersionTwoFirmware()
|
||||
|
||||
Convenience method to determine if you can use firmware v2.x.x capabilities.
|
||||
|
||||
**Note, should be called after a `.softReset()` because we can parse the output of that to determine if we are using firmware version 2.**
|
||||
|
||||
**_Returns_** a boolean, true if using firmware version 2 or greater.
|
||||
|
||||
### .write(dataToWrite)
|
||||
|
||||
Send commands to the board. Due to the OpenBCI board firmware 1.0, a 10ms spacing **must** be observed between every command sent to the board. This method handles the timing and spacing between characters by adding characters to a global write queue and pulling from it every 10ms. If you are using firmware version +2.0 then you no spacing will be used.
|
||||
|
||||
**_dataToWrite_**
|
||||
|
||||
Either a single character or an Array of characters
|
||||
|
||||
@@ -591,7 +1004,7 @@ Sends an array of bytes
|
||||
ourBoard.write(['x','0','1','0','0','0','0','0','0','X']);
|
||||
```
|
||||
|
||||
Taking full advantage of the write queue. The following would be sent at t = 0, 10ms, 20ms, 30ms
|
||||
Taking full advantage of the write queue. The following would be sent at t = 0, 10ms, 20ms, 30ms
|
||||
```js
|
||||
ourBoard.write('t');
|
||||
ourBoard.write('a');
|
||||
@@ -629,7 +1042,7 @@ Emitted when the board is in a ready to start streaming state.
|
||||
|
||||
Emitted when there is a new sample available.
|
||||
|
||||
## Properties
|
||||
## Properties
|
||||
|
||||
### connected
|
||||
|
||||
@@ -639,6 +1052,65 @@ A bool, true if connected to an OpenBCI board, false if not.
|
||||
|
||||
A bool, true if streaming data from an OpenBCI board, false if not.
|
||||
|
||||
## Useful Constants
|
||||
|
||||
To use the constants file simply:
|
||||
```js
|
||||
var openBCIBoard = require('openbci');
|
||||
var k = openBCIBoard.OpenBCIConstants;
|
||||
|
||||
console.log(k.OBCISimulatorPortName); // prints OpenBCISimulator to the console.
|
||||
```
|
||||
|
||||
### .OBCISimulatorPortName
|
||||
|
||||
The name of the simulator port.
|
||||
|
||||
## Interfacing With Other Tools
|
||||
|
||||
### LabStreamingLayer
|
||||
|
||||
[LabStreamingLayer](https://github.com/sccn/labstreaminglayer) by SCCN is a stream management tool designed to time-synchronize multiple data streams, potentially from different sources, over a LAN network with millisecond accuracy (given configuration).
|
||||
|
||||
For example, a VR display device running a Unity simulation may, using the [LSL4Unity](https://github.com/xfleckx/LSL4Unity) library, emit string markers into LSL corresponding to events of interest (For the P300 ERP, this event would be the onset of an attended, unusual noise in a pattern of commonplace ones). The computer doing data collection via the OpenBCI_NodeJS library (potentially with 4ms accuracy) would then output into an LSL stream the EEG and AUX data. LSL can then synchronize the two clocks relative to each other before inputting into a different program or toolkit, like [BCILAB](https://github.com/sccn/BCILAB) for analysis to trigger responses in the Unity display.
|
||||
|
||||
This requires OpenBCI_NodeJS exporting data into LSL. Currently, there does not exist a pre-built NodeJS module for LSL, though LSL comes with tools that could possibly allow creation of one. In the meantime, the simpler route is to use a concurrent python script (driven by NodeJS module [python-shell](https://www.npmjs.com/package/python-shell)) to handoff the data to LSL for you, like so:
|
||||
|
||||
In your NodeJS code, before initializing/connecting to the OpenBCIBoard:
|
||||
```js
|
||||
// Construct LSL Handoff Python Shell
|
||||
var PythonShell = require('python-shell');
|
||||
var lsloutlet = new PythonShell('LslHandoff.py');
|
||||
|
||||
lsloutlet.on('message', function(message){
|
||||
console.log('LslOutlet: ' + message);
|
||||
});
|
||||
console.log('Python Shell Created for LSLHandoff');
|
||||
```
|
||||
|
||||
In your NodeJS code, when reading samples:
|
||||
```js
|
||||
st = sample.channelData.join(' ')
|
||||
//getTime returns milliseconds since midnight 1970/01/01
|
||||
var s = ''+ sample.timeStamp + ': '+ st
|
||||
lsloutlet.send(s)
|
||||
```
|
||||
|
||||
in LSLHandoff.py:
|
||||
```py
|
||||
from pylsl import StreamInfo, StreamOutlet
|
||||
info = StreamInfo('OpenBCI_EEG', 'EEG', 8, 250, 'float32', '[RANDOM NUMBER HERE]')
|
||||
outlet = StreamOutlet(info)
|
||||
while True:
|
||||
strSample = raw_input().split(': ',1)
|
||||
sample = map(float, strSample[1].split(' '))
|
||||
stamp = float(strSample[0])
|
||||
|
||||
outlet.push_sample(sample, stamp)
|
||||
print('Pushed Sample At: ' + strSample[0])
|
||||
```
|
||||
AUX data would be done the same way in a separate LSL stream.
|
||||
|
||||
## Dev Notes
|
||||
Running
|
||||
-------
|
||||
@@ -662,4 +1134,4 @@ npm test
|
||||
6. Submit a pull request :D
|
||||
|
||||
## License
|
||||
MIT
|
||||
MIT
|
||||
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
# 1.2.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Add tutorial/sample code for interfacing the module with lab streaming layer.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Fixed time synced accel to work OpenBCI_32bit_Library release candidate 5 and newer.
|
||||
|
||||
# 1.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Add function `.time()` which should be used in time syncing
|
||||
* Add function `.syncClocksFull()` which should be used for immediate consecutive time syncs
|
||||
* Synced object can be emitted on `synced` event. Check `valid` property for if the sync was done
|
||||
* Add detailed description of object returned on `synced` event to README.md
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Changed option named `timeSync` to `sntpTimeSync`
|
||||
* Removed function called `.sntpNow()` because it was replaced by `.time()`
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Time sync working
|
||||
* Module could not work with local time
|
||||
|
||||
# 1.0.1
|
||||
|
||||
### New Features
|
||||
|
||||
* Add time sync tutorial in `README.md`
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed bug in simulator that lead to samples being all zeros.
|
||||
* Fixed time sync sent confirmation bug that led to bad time values.
|
||||
|
||||
# 1.0.0
|
||||
|
||||
The second major release for the OpenBCI Node.js SDK brings major changes, improvements and stability, on top of a push to increase automated test coverage.
|
||||
|
||||
### New Features
|
||||
|
||||
* NPM Module now called `openbci` instead of `openbci-sdk`
|
||||
* Firmware version 2.0 support.
|
||||
* Clock synchronization between OpenBCI board and this driver
|
||||
* `.info` property which contains verified board information parsed from the OpenBCI's `softReset()` response.
|
||||
* `eot` event that is emitted when a user sends a command that results in an EOT ("$$$") being sent from the board
|
||||
* Daisy (16 channel) support
|
||||
* Simulator overhaul, it completely mocks the board. Can now simulate board failure, where the board stops talking to the dongle. Can also mock a serial port failure.
|
||||
* `error` and `close` events from serialport now emtted events users can subscribe to.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* NPM package is not called `openbci-sdk` anymore, now called `openbci`
|
||||
* Accelerometer data now goes into `.accelData` array instead of `.auxData` array.
|
||||
* In openBCISample.js
|
||||
* `parseRawPacket()` is now called `parseRawPacketStandard()`
|
||||
* `ready` event only triggered after soft reset. `eot` event emitted in all other conditions resulting in the board sending EOT ("$$$")
|
||||
* Must use camel case on the OpenBCISimulator object.
|
||||
* Renamed constructor options for readability:
|
||||
* `simulatorAlpha` to `simulatorInjectAlpha`
|
||||
* `simulatorLineNoise` to `simulatorInjectLineNoise`
|
||||
* `connect()` no longer rejects on `close` or `error` event from the serialport.
|
||||
|
||||
# 0.3.9
|
||||
|
||||
### Enhancements
|
||||
|
||||
* Add tests for parsing raw packets
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Removed `got here` log from `.streamStart()`
|
||||
* Validate stop byte before emitting `rawDataPacket`
|
||||
|
||||
# 0.3.8
|
||||
|
||||
### Bug Fixes
|
||||
* Fixed readme.md
|
||||
|
||||
# 0.3.7
|
||||
|
||||
### New Features
|
||||
|
||||
* Upgrade dependencies
|
||||
* Update Travis
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `.numberOfChannels()` now uses the info object, which is set in the constructor and on the return message from `.softReset()`
|
||||
* `.sampleRate()` now uses the info object, which is set in the constructor and on the return message from `.softReset()`
|
||||
|
||||
# 0.3.6
|
||||
|
||||
### New Features
|
||||
|
||||
* Simulator now has accelerometer data
|
||||
|
||||
# 0.3.5
|
||||
|
||||
### New Features
|
||||
|
||||
* SD card support! Now logging to an SD card is easier than ever.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Sample rate does not return correct sample rate for custom rate on simulator. #58
|
||||
|
||||
# 0.3.4
|
||||
|
||||
### New Features
|
||||
|
||||
* Simulator made to look more like brainwave data to the user. Implemented a 1/f filter. Defaults to injecting 60Hz line noise with two channels of alpha (10Hz) boost.
|
||||
|
||||
### Github Issues Addressed
|
||||
|
||||
* [https://github.com/OpenBCI/openbci-js-sdk/issues/44](#44)
|
||||
|
||||
# 0.3.3
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `rawDataPacket` not being emitted
|
||||
|
||||
# 0.3.2
|
||||
|
||||
### Work In Progress
|
||||
|
||||
* SNTP Time Synchronization
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* updates to README.me and comments to change ntp to sntp, because the two are similar, but not the same and we do not want to be misleading
|
||||
* Extended [Stnp](https://www.npmjs.com/package/sntp) to main openBCIBoard.js
|
||||
* Add `.sntpNow()` function to get ntp time.
|
||||
|
||||
# 0.3.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Bumped serialport version
|
||||
|
||||
# 0.3.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Test Signals with ADS1299 using `.testSignal()`
|
||||
* Continuous impedance testing, where each sample gets an `impedances` object that is an array of impedances for each
|
||||
channel.
|
||||
* OpenBCI Radio Test File
|
||||
* Added Sntp npm module with helper functions
|
||||
* Removed stopByte and startByte from sampleObjects
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Changed simulator name to `OpenBCISimulator`
|
||||
* Changed name of function `simulatorOn` to `simulatorEnable`
|
||||
* Changed name of function `simulatorOff` to `simulatorDisable`
|
||||
|
||||
### Work In Progress
|
||||
|
||||
* NTP Time Synchronization
|
||||
* Goertzel algorithm to get voltage for impedance calculation
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Impedance calculations
|
||||
* Readme updates
|
||||
* Serial buffer had the chance to become permanently unaligned, optimized and completely transformed and refactored the way bytes are processed.
|
||||
* Changes to gain of channels not working correctly.
|
||||
* Node 5 compatibility
|
||||
|
||||
### Github Issues Addressed
|
||||
|
||||
* #25, #26, #27, #29, #30, #31, #33, #34
|
||||
+1327
-263
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+737
-414
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+1110
-156
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+271
-28
@@ -6,21 +6,25 @@ var stream = require('stream');
|
||||
|
||||
var openBCISample = require('./openBCISample');
|
||||
var k = openBCISample.k;
|
||||
var now = require('performance-now');
|
||||
|
||||
|
||||
function OpenBCISimulatorFactory() {
|
||||
var factory = this;
|
||||
|
||||
|
||||
|
||||
var _options = {
|
||||
samplerate: 250,
|
||||
accel: true,
|
||||
alpha: true,
|
||||
boardFailure:false,
|
||||
daisy: false,
|
||||
drift: 0,
|
||||
firmwareVersion: k.OBCIFirmwareV1,
|
||||
lineNoise: '60Hz',
|
||||
sampleRate: 250,
|
||||
serialPortFailure:false,
|
||||
verbose: false
|
||||
};
|
||||
|
||||
|
||||
|
||||
function OpenBCISimulator(portName, options) {
|
||||
options = (typeof options !== 'function') && options || {};
|
||||
var opts = {};
|
||||
@@ -28,31 +32,62 @@ function OpenBCISimulatorFactory() {
|
||||
stream.Stream.call(this);
|
||||
|
||||
/** Configuring Options */
|
||||
opts.sampleRate = options.sampleRate || options.samplerate || _options.samplerate;
|
||||
if (options.accel === false) {
|
||||
opts.accel = false;
|
||||
} else {
|
||||
opts.accel = _options.accel;
|
||||
}
|
||||
if (options.alpha === false) {
|
||||
opts.alpha = false;
|
||||
} else {
|
||||
opts.alpha = _options.alpha;
|
||||
}
|
||||
opts.boardFailure = options.boardFailure || _options.boardFailure;
|
||||
opts.daisy = options.daisy || _options.daisy;
|
||||
opts.drift = options.drift || _options.drift;
|
||||
opts.firmwareVersion = options.firmwareVersion || _options.firmwareVersion;
|
||||
opts.lineNoise = options.lineNoise || _options.lineNoise;
|
||||
if (options.sampleRate) {
|
||||
opts.sampleRate = options.sampleRate;
|
||||
} else {
|
||||
opts.sampleRate = k.OBCISampleRate250;
|
||||
}
|
||||
opts.serialPortFailure = options.serialPortFailure || _options.serialPortFailure;
|
||||
opts.verbose = options.verbose || _options.verbose;
|
||||
|
||||
this.options = opts;
|
||||
|
||||
// Bools
|
||||
this.connected = false;
|
||||
this.sd = {
|
||||
active:false,
|
||||
startTime: 0
|
||||
};
|
||||
this.streaming = false;
|
||||
this.synced = false;
|
||||
this.sendSyncSetPacket = false;
|
||||
// Buffers
|
||||
this.buffer = new Buffer(500);
|
||||
// Numbers
|
||||
this.channelNumber = 1;
|
||||
this.hostChannelNumber = this.channelNumber;
|
||||
this.pollTime = 80;
|
||||
this.sampleNumber = -1; // So the first sample is 0
|
||||
// Objects
|
||||
this.sampleGenerator = openBCISample.randomSample(k.OBCINumberOfChannelsDefault, this.options.sampleRate, this.options.alpha, this.options.lineNoise);
|
||||
this.time = {
|
||||
current: 0,
|
||||
start: now(),
|
||||
loop: null
|
||||
};
|
||||
// Strings
|
||||
this.portName = portName || k.OBCISimulatorPortName;
|
||||
|
||||
// Call 'open'
|
||||
if (this.options.verbose) console.log(`Port name: ${portName}`);
|
||||
setTimeout(() => {
|
||||
console.log('Port name: ' + portName);
|
||||
if (portName === k.OBCISimulatorPortName) {
|
||||
this.emit('open');
|
||||
this.connected = true;
|
||||
} else {
|
||||
var err = new Error('Serialport not open.');
|
||||
this.emit('error',err);
|
||||
}
|
||||
this.emit('open');
|
||||
this.connected = true;
|
||||
}, 200);
|
||||
|
||||
}
|
||||
@@ -66,13 +101,65 @@ function OpenBCISimulatorFactory() {
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype.write = function(data,callback) {
|
||||
if (data[0] === k.OBCIStreamStart) {
|
||||
if (!this.stream) this._startStream();
|
||||
} else if (data[0] === k.OBCIStreamStop) {
|
||||
if (this.stream) clearInterval(this.stream); // Stops the stream
|
||||
} else if (data[0] === k.OBCIMiscSoftReset) {
|
||||
if (this.stream) clearInterval(this.stream);
|
||||
this.emit('data', new Buffer('OpenBCI Board Simulator\nPush The World V-0.2\n$$$'));
|
||||
switch (data[0]) {
|
||||
case k.OBCIRadioKey:
|
||||
this._processPrivateRadioMessage(data);
|
||||
break;
|
||||
case k.OBCIStreamStart:
|
||||
if (!this.stream) this._startStream();
|
||||
this.streaming = true;
|
||||
break;
|
||||
case k.OBCIStreamStop:
|
||||
if (this.stream) clearInterval(this.stream); // Stops the stream
|
||||
this.streaming = false;
|
||||
break;
|
||||
case k.OBCIMiscSoftReset:
|
||||
if (this.stream) clearInterval(this.stream);
|
||||
this.streaming = false;
|
||||
this.emit('data', new Buffer(`OpenBCI V3 Simulator\nOn Board ADS1299 Device ID: 0x12345\n${this.options.daisy ? "On Daisy ADS1299 Device ID: 0xFFFFF\n" : ""}LIS3DH Device ID: 0x38422\n${this.options.firmware === k.OBCIFirmwareV2 ? "Firmware: v2.0.0\n" : ""}$$$`));
|
||||
break;
|
||||
case k.OBCISDLogForHour1:
|
||||
case k.OBCISDLogForHour2:
|
||||
case k.OBCISDLogForHour4:
|
||||
case k.OBCISDLogForHour12:
|
||||
case k.OBCISDLogForHour24:
|
||||
case k.OBCISDLogForMin5:
|
||||
case k.OBCISDLogForMin15:
|
||||
case k.OBCISDLogForMin30:
|
||||
case k.OBCISDLogForSec14:
|
||||
// If we are not streaming, then do verbose output
|
||||
if (!this.streaming) {
|
||||
this.emit('data', new Buffer('Wiring is correct and a card is present.\nCorresponding SD file OBCI_69.TXT\n$$$'));
|
||||
}
|
||||
this.sd.active = true;
|
||||
this.sd.startTime = now();
|
||||
break;
|
||||
case k.OBCISDLogStop:
|
||||
if (!this.streaming) {
|
||||
if (this.SDLogActive) {
|
||||
this.emit('data', new Buffer(`Total Elapsed Time: ${now() - this.sd.startTime} ms\n`));
|
||||
this.emit('data', new Buffer(`Max write time: ${Math.random()*500} us\n`));
|
||||
this.emit('data', new Buffer(`Min write time: ${Math.random()*200} us\n`));
|
||||
this.emit('data', new Buffer(`Overruns: 0\n`));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this.emit('data', new Buffer('No open file to close\n'));
|
||||
this._printEOT();
|
||||
}
|
||||
}
|
||||
this.SDLogActive = false;
|
||||
break;
|
||||
case k.OBCISyncTimeSet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
this.synced = true;
|
||||
setTimeout(() => {
|
||||
this.emit('data', new Buffer(k.OBCISyncTimeSent));
|
||||
this._syncUp();
|
||||
}, 10);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/** Handle Callback */
|
||||
@@ -83,7 +170,6 @@ function OpenBCISimulatorFactory() {
|
||||
|
||||
OpenBCISimulator.prototype.drain = function(callback) {
|
||||
callback();
|
||||
//if (this.options.verbose) console.log('drain');
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype.close = function(callback) {
|
||||
@@ -91,7 +177,6 @@ function OpenBCISimulatorFactory() {
|
||||
this.emit('close');
|
||||
}
|
||||
this.connected = false;
|
||||
//if (this.options.verbose) console.log('close');
|
||||
callback();
|
||||
};
|
||||
|
||||
@@ -100,10 +185,31 @@ function OpenBCISimulatorFactory() {
|
||||
|
||||
if (intervalInMS < 2) intervalInMS = 2;
|
||||
|
||||
var generateSample = openBCISample.randomSample(k.OBCINumberOfChannelsDefault, k.OBCISampleRate250);
|
||||
|
||||
var getNewPacket = sampNumber => {
|
||||
return openBCISample.convertSampleToPacket(generateSample(sampNumber));
|
||||
if (this.options.accel) {
|
||||
if (this.synced) {
|
||||
if (this.sendSyncSetPacket) {
|
||||
this.sendSyncSetPacket = false;
|
||||
return openBCISample.convertSampleToPacketAccelTimeSyncSet(this.sampleGenerator(sampNumber),now().toFixed(0));
|
||||
} else {
|
||||
return openBCISample.convertSampleToPacketAccelTimeSynced(this.sampleGenerator(sampNumber),now().toFixed(0));
|
||||
}
|
||||
} else {
|
||||
return openBCISample.convertSampleToPacketStandard(this.sampleGenerator(sampNumber));
|
||||
}
|
||||
} else {
|
||||
if (this.synced) {
|
||||
if (this.sendSyncSetPacket) {
|
||||
this.sendSyncSetPacket = false;
|
||||
return openBCISample.convertSampleToPacketRawAuxTimeSyncSet(this.sampleGenerator(sampNumber),now().toFixed(0),new Buffer([0,0,0,0,0,0]));
|
||||
} else {
|
||||
return openBCISample.convertSampleToPacketRawAuxTimeSynced(this.sampleGenerator(sampNumber),now().toFixed(0),new Buffer([0,0,0,0,0,0]));
|
||||
}
|
||||
} else {
|
||||
return openBCISample.convertSampleToPacketRawAux(this.sampleGenerator(sampNumber),new Buffer([0,0,0,0,0,0]));
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
this.stream = setInterval(() => {
|
||||
@@ -112,10 +218,147 @@ function OpenBCISimulatorFactory() {
|
||||
}, intervalInMS);
|
||||
};
|
||||
|
||||
factory.OpenBCISimulator = OpenBCISimulator;
|
||||
OpenBCISimulator.prototype._syncUp = function() {
|
||||
setTimeout(() => {
|
||||
this.sendSyncSetPacket = true;
|
||||
}, 12); // 3 packets later
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._printEOT = function () {
|
||||
this.emit('data', new Buffer("$$$"));
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._printFailure = function () {
|
||||
this.emit('data', new Buffer("Failure: "));
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._printSuccess = function () {
|
||||
this.emit('data', new Buffer("Success: "));
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._printValidatedCommsTimeout = function () {
|
||||
this._printFailure();
|
||||
this.emit('data', new Buffer("Communications timeout - Device failed to poll Host"));
|
||||
this._printEOT();
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._processPrivateRadioMessage = function(dataBuffer) {
|
||||
switch (dataBuffer[1]) {
|
||||
case k.OBCIRadioCmdChannelGet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
this._printSuccess();
|
||||
this.emit('data', new Buffer(`Host and Device on Channel Number ${this.channelNumber}`));
|
||||
this.emit('data', new Buffer([this.channelNumber]));
|
||||
this._printEOT();
|
||||
} else if (!this.serialPortFailure) {
|
||||
this._printFailure();
|
||||
this.emit('data', new Buffer(`Host on Channel Number ${this.channelNumber}`));
|
||||
this.emit('data', new Buffer([this.channelNumber]));
|
||||
this._printEOT();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdChannelSet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
if (dataBuffer[2] < k.OBCIRadioChannelMax) {
|
||||
this.channelNumber = dataBuffer[2];
|
||||
this.hostChannelNumber = this.channelNumber;
|
||||
this._printSuccess();
|
||||
this.emit('data', new Buffer(`Channel Number ${this.channelNumber}`));
|
||||
this.emit('data', new Buffer([this.channelNumber]));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printFailure();
|
||||
this.emit('data', new Buffer("Verify channel number is less than 25"));
|
||||
this._printEOT();
|
||||
}
|
||||
} else if (!this.serialPortFailure) {
|
||||
this._printValidatedCommsTimeout();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdChannelSetOverride:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (dataBuffer[2] < k.OBCIRadioChannelMax) {
|
||||
if (dataBuffer[2] === this.channelNumber) {
|
||||
this.options.boardFailure = false;
|
||||
} else {
|
||||
this.options.boardFailure = true;
|
||||
}
|
||||
this.hostChannelNumber = dataBuffer[2];
|
||||
this._printSuccess();
|
||||
this.emit('data', new Buffer(`Host override - Channel Number ${this.hostChannelNumber}`));
|
||||
this.emit('data', new Buffer([this.hostChannelNumber]));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printFailure();
|
||||
this.emit('data', new Buffer("Verify channel number is less than 25"));
|
||||
this._printEOT();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdPollTimeGet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
this._printSuccess();
|
||||
this.emit('data', new Buffer(`Poll Time ${this.pollTime}`));
|
||||
this.emit('data', new Buffer([this.pollTime]));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printValidatedCommsTimeout();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdPollTimeSet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
this.pollTime = dataBuffer[2];
|
||||
this._printSuccess();
|
||||
this.emit('data', new Buffer(`Poll Time ${this.pollTime}`));
|
||||
this.emit('data', new Buffer([this.pollTime]));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printValidatedCommsTimeout();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdBaudRateSetDefault:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
this._printSuccess();
|
||||
this.emit('data', new Buffer("Switch your baud rate to 115200"));
|
||||
this.emit('data', new Buffer([0x24,0x24,0x24,0xFF])); // The board really does this
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdBaudRateSetFast:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
this._printSuccess();
|
||||
this.emit('data', new Buffer("Switch your baud rate to 230400"));
|
||||
this.emit('data', new Buffer([0x24,0x24,0x24,0xFF])); // The board really does this
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdSystemStatus:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
this._printSuccess();
|
||||
this.emit('data', new Buffer("System is Up"));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printFailure();
|
||||
this.emit('data', new Buffer("System is Down"));
|
||||
this._printEOT();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
factory.OpenBCISimulator = OpenBCISimulator;
|
||||
}
|
||||
|
||||
util.inherits(OpenBCISimulatorFactory, EventEmitter);
|
||||
|
||||
module.exports = new OpenBCISimulatorFactory();
|
||||
module.exports = new OpenBCISimulatorFactory();
|
||||
|
||||
+13
-10
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "openbci-sdk",
|
||||
"version": "0.2.0",
|
||||
"description": "A fully NodeJS based API for the OpenBCI board connecting to the hardware directly over serial",
|
||||
"name": "openbci",
|
||||
"version": "1.2.0",
|
||||
"description": "The official Node.js SDK for the OpenBCI Biosensor Board.",
|
||||
"main": "openBCIBoard",
|
||||
"scripts": {
|
||||
"start": "node index",
|
||||
@@ -15,11 +15,13 @@
|
||||
"author": "AJ Keller <aj@pushtheworld.us> (www.openbci.com)",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal": "^1.0.0",
|
||||
"gaussian": "^1.0.0",
|
||||
"istanbul": "^0.4.2",
|
||||
"outliers": "0.0.3",
|
||||
"scientific-statistics": "^0.2.7",
|
||||
"serialport": "^2.0.2"
|
||||
"mathjs": "^3.3.0",
|
||||
"performance-now": "^0.2.0",
|
||||
"serialport": "3.1.2",
|
||||
"sntp": "^2.0.0",
|
||||
"streamsearch": "^0.1.2"
|
||||
},
|
||||
"directories": {
|
||||
"test": "test"
|
||||
@@ -28,6 +30,7 @@
|
||||
"chai": "^3.4.1",
|
||||
"chai-as-promised": "^5.2.0",
|
||||
"codecov": "^1.0.1",
|
||||
"istanbul": "^0.4.4",
|
||||
"mocha": "^2.3.4",
|
||||
"sandboxed-module": "^2.0.3",
|
||||
"sinon": "^1.17.2",
|
||||
@@ -35,12 +38,12 @@
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/openbci/openbci-js-sdk.git"
|
||||
"url": "git+https://github.com/openbci/openbci_nodejs.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/openbci/openbci-js-sdk/issues"
|
||||
"url": "https://github.com/openbci/openbci_nodejs/issues"
|
||||
},
|
||||
"homepage": "https://github.com/openbci/openbci-js-sdk#readme",
|
||||
"homepage": "https://github.com/openbci/openbci_nodejs#readme",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
/**
|
||||
* Created by AJ Keller
|
||||
* Date: 12/23/15
|
||||
* Purpose: To unit test the OpenBCIBoard file
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var OpenBCIBoard = require('../openBCIBoard');
|
||||
var OpenBCISample = OpenBCIBoard.OpenBCISample;
|
||||
var k = OpenBCIBoard.OpenBCIConstants;
|
||||
var chai = require('chai')
|
||||
, expect = chai.expect
|
||||
, should = chai.should();
|
||||
var chaiAsPromised = require("chai-as-promised");
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
|
||||
var sampleSelf = function() {
|
||||
return {
|
||||
masterBuffer: {
|
||||
buffer: new Buffer(3300),
|
||||
positionRead:0,
|
||||
positionWrite:0,
|
||||
packetsIn:0,
|
||||
packetsRead:0,
|
||||
looseBytes:0
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var sampleData;
|
||||
var bciBoard;
|
||||
|
||||
var samplePacket = function () {
|
||||
var byteSample = 0x45;
|
||||
var buffy = new Buffer([0xA0,byteSample,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0,8,0,0,0,1,0,2,0xC0]);
|
||||
return buffy;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
describe('OpenBCIBoard',function() {
|
||||
describe('#_bufMerger',function() {
|
||||
beforeEach(function() {
|
||||
bciBoard = new OpenBCIBoard.OpenBCIBoard();
|
||||
sampleData = [];
|
||||
(function(){
|
||||
for(var i = 0;i < 100;i++) {
|
||||
var sample = samplePacket();
|
||||
sample.sampleNumber = i;
|
||||
sampleData[i] = sample;
|
||||
}
|
||||
}());
|
||||
});
|
||||
it('should write the buffer to the empty master buffer', function() {
|
||||
bciBoard._bufMerger(sampleData[0]);
|
||||
|
||||
// test to see if buffers match
|
||||
assert.equal(0,sampleData[0].compare(bciBoard.masterBuffer.buffer.slice(0, k.OBCIPacketSize)));
|
||||
// test to make sure the write position was moved
|
||||
assert.equal(k.OBCIPacketSize, bciBoard.masterBuffer.positionWrite);
|
||||
// test to make sure we read in the right number of packets
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,1);
|
||||
// test to make sure there are no loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,0);
|
||||
});
|
||||
it('should write the tiny buffer to the empty master buffer, but not record a packet in', function() {
|
||||
var tinyBufferSize = 10; //tiny because its smaller than a packet
|
||||
var tinyBuffer = sampleData[0].slice(0,tinyBufferSize);
|
||||
|
||||
bciBoard._bufMerger(tinyBuffer);
|
||||
|
||||
// test to see if buffers match
|
||||
assert.equal(0,tinyBuffer.compare(bciBoard.masterBuffer.buffer.slice(0, tinyBufferSize)));
|
||||
// test to make sure the write position was moved
|
||||
assert.equal(tinyBufferSize, bciBoard.masterBuffer.positionWrite);
|
||||
// test to make sure we read in the right number of packets
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,0);
|
||||
// test to make sure there are 10 loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,tinyBufferSize);
|
||||
});
|
||||
it('should write the multi packet plus loose byte buffer to the empty master buffer', function() {
|
||||
var tinyBufferSize = 10; //tiny because its smaller than a packet
|
||||
var tinyBuffer = sampleData[0].slice(0,tinyBufferSize);
|
||||
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2],tinyBuffer];
|
||||
var totalLength = k.OBCIPacketSize * 3 + tinyBufferSize;
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer);
|
||||
|
||||
// test to see if buffers match
|
||||
assert.equal(0,multiPacketBuffer.compare(bciBoard.masterBuffer.buffer.slice(0, totalLength)));
|
||||
// test to make sure the write position was moved
|
||||
assert.equal(totalLength, bciBoard.masterBuffer.positionWrite);
|
||||
// test to make sure we read in the right number of packets (shall be three)
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,3);
|
||||
// test to make sure there are 10 loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,tinyBufferSize);
|
||||
});
|
||||
it('should use looseBytes in to write the multi packet to the master buffer and record an extra packet in', function() {
|
||||
var tinyBufferSize = 10; //tiny because its smaller than a packet
|
||||
var tinyBuffer = sampleData[0].slice(0,tinyBufferSize);
|
||||
|
||||
var hackedBufferSize = k.OBCIPacketSize - tinyBufferSize;
|
||||
var hackedBuffer = sampleData[0].slice(tinyBufferSize);
|
||||
|
||||
bciBoard.masterBuffer.looseBytes = tinyBufferSize;
|
||||
|
||||
var buffers = [hackedBuffer,sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3 + hackedBufferSize;
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer);
|
||||
|
||||
// test to see if buffers match
|
||||
assert.equal(0,multiPacketBuffer.compare(bciBoard.masterBuffer.buffer.slice(0, totalLength)));
|
||||
// test to make sure the write position was moved
|
||||
assert.equal(totalLength, bciBoard.masterBuffer.positionWrite);
|
||||
// test to make sure we read in the right number of packets (shall be three)
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,4);
|
||||
// test to make sure there are 10 loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,0);
|
||||
});
|
||||
it('should write in the position of the masterBufferPositionWrite', function() {
|
||||
var originalWritePosition = 69;
|
||||
bciBoard.masterBuffer.positionWrite = originalWritePosition;
|
||||
|
||||
bciBoard._bufMerger(sampleData[0]);
|
||||
|
||||
// test to see if the master buffer contains the correct data
|
||||
assert.equal(0,sampleData[0].compare(bciBoard.masterBuffer.buffer.slice(originalWritePosition, originalWritePosition + k.OBCIPacketSize)));
|
||||
// test to see if the write position was moved properly
|
||||
assert.equal(bciBoard.masterBuffer.positionWrite,originalWritePosition + k.OBCIPacketSize);
|
||||
// test to make sure we read in the right number of packets
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,1);
|
||||
// test to make sure there are no loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,0);
|
||||
});
|
||||
it('should wrap the input buffer around the master buffer',function() {
|
||||
var spaceRemaingInMasterBuffer = 15;
|
||||
var originalWritePosition = k.OBCIMasterBufferSize - spaceRemaingInMasterBuffer;
|
||||
|
||||
bciBoard.masterBuffer.positionWrite = originalWritePosition;
|
||||
|
||||
bciBoard._bufMerger(sampleData[0]);
|
||||
|
||||
// test to see that the end of master buffer contains half of sample
|
||||
assert.equal(0,sampleData[0].slice(0,spaceRemaingInMasterBuffer).compare(bciBoard.masterBuffer.buffer.slice(originalWritePosition)));
|
||||
// test to see that the beginning of master buffer contains the second half of sampleData[0]
|
||||
assert.equal(0,sampleData[0].slice(spaceRemaingInMasterBuffer).compare(bciBoard.masterBuffer.buffer.slice(0,sampleData[0].byteLength - spaceRemaingInMasterBuffer)));
|
||||
// test to make sure the write position was moved correctly
|
||||
assert.equal(bciBoard.masterBuffer.positionWrite,sampleData[0].byteLength - spaceRemaingInMasterBuffer);
|
||||
// test to make sure we read in the right number of packets
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,1);
|
||||
// test to make sure there are no loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,0);
|
||||
});
|
||||
});
|
||||
describe('#_bufPacketStripper', function() {
|
||||
beforeEach(function() {
|
||||
bciBoard = new OpenBCIBoard.OpenBCIBoard();
|
||||
sampleData = [];
|
||||
(function(){
|
||||
for(var i = 0;i < 100;i++) {
|
||||
var sample = samplePacket();
|
||||
sample.sampleNumber = i;
|
||||
sampleData[i] = sample;
|
||||
}
|
||||
}());
|
||||
});
|
||||
it('should remove a packet from the master buffer', function() {
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3;
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
//console.log(multiPacketBuffer);
|
||||
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer);
|
||||
|
||||
// run through three iterations of stripping packets
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var rawPacket = bciBoard._bufPacketStripper();
|
||||
var sample = OpenBCISample.convertPacketToSample(rawPacket);
|
||||
//console.log(OpenBCISample.debugPrettyPrint(sample));
|
||||
//console.log('Sample ' + i + ' has sample number ' + sample.sampleNumber);
|
||||
assert.equal(sample.sampleNumber,69);
|
||||
}
|
||||
});
|
||||
it('should remove a packet from the master buffer, even at wrap..', function() {
|
||||
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3;
|
||||
|
||||
bciBoard.masterBuffer.positionWrite = k.OBCIMasterBufferSize - 10;
|
||||
bciBoard.masterBuffer.positionRead = bciBoard.masterBuffer.positionWrite;
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer);
|
||||
|
||||
// run through three iterations of stripping packets
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var rawPacket = bciBoard._bufPacketStripper();
|
||||
var sample = OpenBCISample.convertPacketToSample(rawPacket);
|
||||
assert(sample.sampleNumber,i);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('#_bufAlign',function() {
|
||||
beforeEach(function() {
|
||||
bciBoard = new OpenBCIBoard.OpenBCIBoard();
|
||||
sampleData = [];
|
||||
(function(){
|
||||
for(var i = 0;i < 100;i++) {
|
||||
var sample = samplePacket();
|
||||
sample.sampleNumber = i;
|
||||
sampleData[i] = sample;
|
||||
}
|
||||
}());
|
||||
});
|
||||
it('should fix a buffer', function() {
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3;
|
||||
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
//console.log(multiPacketBuffer);
|
||||
|
||||
var bytesToHackOffSample = 10;
|
||||
var expectedNewPositionRead = k.OBCIPacketSize - bytesToHackOffSample;
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer.slice(10,totalLength));
|
||||
|
||||
bciBoard._bufAlign();
|
||||
|
||||
assert(expectedNewPositionRead,bciBoard.masterBuffer.positionRead);
|
||||
|
||||
});
|
||||
it('should wrap & then fix a buffer', function() {
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3;
|
||||
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
var bytesFromEndOfBuffer = 5;
|
||||
|
||||
bciBoard.masterBuffer.positionRead = k.OBCIMasterBufferSize - bytesFromEndOfBuffer;
|
||||
|
||||
var bytesToHackOffSample = 10;
|
||||
var expectedNewPositionRead = bytesToHackOffSample - bytesFromEndOfBuffer;
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer.slice(10,totalLength));
|
||||
|
||||
bciBoard._bufAlign();
|
||||
|
||||
assert(expectedNewPositionRead,bciBoard.masterBuffer.positionRead);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function debugPrintBufferCompare(buf1,buf2) {
|
||||
console.log('Comparing:\n\tBuffer 1\n\t\t' + buf1.toString('hex') + '\n\tBuffer 2\n\t\t' + buf2.toString('hex'));
|
||||
|
||||
}
|
||||
+223
-31
@@ -291,6 +291,20 @@ describe('OpenBCIConstants', function() {
|
||||
assert.equal('1', k.OBCIChannelImpedanceTestSignalApplied);
|
||||
});
|
||||
});
|
||||
describe('Time Sync Stuff',function() {
|
||||
it('Can get proper array size',function() {
|
||||
assert.equal(10, k.OBCITimeSyncArraySize);
|
||||
});
|
||||
it('Get correct time sync with conf',function() {
|
||||
assert.equal(0.9, k.OBCITimeSyncMultiplierWithSyncConf);
|
||||
});
|
||||
it('Get correct time sync without conf',function() {
|
||||
assert.equal(0.75, k.OBCITimeSyncMultiplierWithoutSyncConf);
|
||||
});
|
||||
it('Get correct time sync transmission threshold',function() {
|
||||
assert.equal(10, k.OBCITimeSyncThresholdTransFailureMS);
|
||||
});
|
||||
});
|
||||
describe('SD card Commands',function() {
|
||||
it('logs for 1 hour', function() {
|
||||
assert.equal('G', k.OBCISDLogForHour1);
|
||||
@@ -323,6 +337,86 @@ describe('OpenBCIConstants', function() {
|
||||
assert.equal('j', k.OBCISDLogStop);
|
||||
});
|
||||
});
|
||||
describe('SD card string Commands',function() {
|
||||
it('logs for 1 hour', function() {
|
||||
assert.equal('1hour', k.OBCIStringSDHour1);
|
||||
});
|
||||
it('logs for 2 hours', function() {
|
||||
assert.equal('2hour', k.OBCIStringSDHour2);
|
||||
});
|
||||
it('logs for 4 hours', function() {
|
||||
assert.equal('4hour', k.OBCIStringSDHour4);
|
||||
});
|
||||
it('logs for 12 hours', function() {
|
||||
assert.equal('12hour', k.OBCIStringSDHour12);
|
||||
});
|
||||
it('logs for 24 hours', function() {
|
||||
assert.equal('24hour', k.OBCIStringSDHour24);
|
||||
});
|
||||
it('logs for 5 minutes', function() {
|
||||
assert.equal('5min', k.OBCIStringSDMin5);
|
||||
});
|
||||
it('logs for 15 minutes', function() {
|
||||
assert.equal('15min', k.OBCIStringSDMin15);
|
||||
});
|
||||
it('logs for 30 minutes', function() {
|
||||
assert.equal('30min', k.OBCIStringSDMin30);
|
||||
});
|
||||
it('logs for 14 seconds', function() {
|
||||
assert.equal('14sec', k.OBCIStringSDSec14);
|
||||
});
|
||||
});
|
||||
describe('#sdSettingForString',function() {
|
||||
it('correct command for 1 hour', function() {
|
||||
var expectation = k.OBCISDLogForHour1;
|
||||
var result = k.sdSettingForString('1hour');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('correct command for 2 hour', function() {
|
||||
var expectation = k.OBCISDLogForHour2;
|
||||
var result = k.sdSettingForString('2hour');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('correct command for 4 hour', function() {
|
||||
var expectation = k.OBCISDLogForHour4;
|
||||
var result = k.sdSettingForString('4hour');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('correct command for 12 hour', function() {
|
||||
var expectation = k.OBCISDLogForHour12;
|
||||
var result = k.sdSettingForString('12hour');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('correct command for 24 hour', function() {
|
||||
var expectation = k.OBCISDLogForHour24;
|
||||
var result = k.sdSettingForString('24hour');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('correct command for 5 min', function() {
|
||||
var expectation = k.OBCISDLogForMin5;
|
||||
var result = k.sdSettingForString('5min');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('correct command for 15 min', function() {
|
||||
var expectation = k.OBCISDLogForMin15;
|
||||
var result = k.sdSettingForString('15min');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('correct command for 30 min', function() {
|
||||
var expectation = k.OBCISDLogForMin30;
|
||||
var result = k.sdSettingForString('30min');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('correct command for 14 seconds', function() {
|
||||
var expectation = k.OBCISDLogForSec14;
|
||||
var result = k.sdSettingForString('14sec');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Invalid command request', function() {
|
||||
var result = k.sdSettingForString('taco');
|
||||
return expect(result).to.be.rejected;
|
||||
});
|
||||
});
|
||||
describe('Stream Data Commands',function() {
|
||||
it('starts',function () {
|
||||
assert.equal('b', k.OBCIStreamStart);
|
||||
@@ -355,6 +449,45 @@ describe('OpenBCIConstants', function() {
|
||||
assert.equal('f', k.OBCIFilterEnable);
|
||||
});
|
||||
});
|
||||
describe('Stream packet types/codes',function() {
|
||||
it('Standard with Accel',function () {
|
||||
assert.equal(0, k.OBCIStreamPacketStandardAccel);
|
||||
});
|
||||
it('Standard with Raw Aux',function () {
|
||||
assert.equal(1, k.OBCIStreamPacketStandardRawAux);
|
||||
});
|
||||
it('User Defined Packet',function () {
|
||||
assert.equal(2, k.OBCIStreamPacketUserDefinedType);
|
||||
});
|
||||
it('Time Sync Set with accel',function () {
|
||||
assert.equal(3, k.OBCIStreamPacketAccelTimeSyncSet);
|
||||
});
|
||||
it('Time Synced with Accel',function () {
|
||||
assert.equal(4, k.OBCIStreamPacketAccelTimeSynced);
|
||||
});
|
||||
it('Time Sync set with Raw Aux',function () {
|
||||
assert.equal(5, k.OBCIStreamPacketRawAuxTimeSyncSet);
|
||||
});
|
||||
it('Time Synced with Raw Aux',function () {
|
||||
assert.equal(6, k.OBCIStreamPacketRawAuxTimeSynced);
|
||||
});
|
||||
});
|
||||
describe('Time synced with accel packet',function() {
|
||||
it('X axis',function () {
|
||||
assert.equal(7, k.OBCIAccelAxisX);
|
||||
});
|
||||
it('Y axis',function () {
|
||||
assert.equal(8, k.OBCIAccelAxisY);
|
||||
});
|
||||
it('Z axis',function () {
|
||||
assert.equal(9, k.OBCIAccelAxisZ);
|
||||
});
|
||||
});
|
||||
describe('Time sync useful numbers',function() {
|
||||
it('Time from the board is 4 bytes',function () {
|
||||
assert.equal(4, k.OBCIStreamPacketTimeByteSize);
|
||||
});
|
||||
});
|
||||
describe('should return the right command for each channel', function(){
|
||||
it('Channel 1', function() {
|
||||
var expectation = '1';
|
||||
@@ -534,78 +667,78 @@ describe('OpenBCIConstants', function() {
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 2', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = '@';
|
||||
var result = k.commandChannelOn(2);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 3', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = '#';
|
||||
var result = k.commandChannelOn(3);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 4', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = '$';
|
||||
var result = k.commandChannelOn(4);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 5', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = '%';
|
||||
var result = k.commandChannelOn(5);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 6', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = '^';
|
||||
var result = k.commandChannelOn(6);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 7', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = '&';
|
||||
var result = k.commandChannelOn(7);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 8', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = '*';
|
||||
var result = k.commandChannelOn(8);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 9', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = 'Q';
|
||||
var result = k.commandChannelOn(9);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 10', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = 'W';
|
||||
var result = k.commandChannelOn(10);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 11', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = 'E';
|
||||
var result = k.commandChannelOn(11);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 12', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = 'R';
|
||||
var result = k.commandChannelOn(12);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 13', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = 'T';
|
||||
var result = k.commandChannelOn(13);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 14', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = 'Y';
|
||||
var result = k.commandChannelOn(14);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 15', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = 'U';
|
||||
var result = k.commandChannelOn(15);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Channel 16', function() {
|
||||
var expectation = '!';
|
||||
var result = k.commandChannelOn(1);
|
||||
var expectation = 'I';
|
||||
var result = k.commandChannelOn(16);
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Invalid channel request', function() {
|
||||
@@ -632,6 +765,20 @@ describe('OpenBCIConstants', function() {
|
||||
assert.equal(250, k.OBCISampleRate250);
|
||||
});
|
||||
});
|
||||
describe("Radio Channel Limits", function() {
|
||||
it("should get the right channel number max",function () {
|
||||
expect(k.OBCIRadioChannelMax).to.be.equal(25);
|
||||
});
|
||||
it("should get the right channel number min",function () {
|
||||
expect(k.OBCIRadioChannelMin).to.be.equal(0);
|
||||
});
|
||||
it("should get the right poll time max",function () {
|
||||
expect(k.OBCIRadioPollTimeMax).to.be.equal(255);
|
||||
});
|
||||
it("should get the right poll time min",function () {
|
||||
expect(k.OBCIRadioPollTimeMin).to.be.equal(0);
|
||||
});
|
||||
});
|
||||
describe('#getChannelSetter', function() {
|
||||
//'channel 1, power on, gain 24, inputType normal, bias include, srb2 connect, srb1 dissconnect'
|
||||
describe('channel input selection works', function() {
|
||||
@@ -896,6 +1043,51 @@ describe('OpenBCIConstants', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#getTestSignalCommand', function() {
|
||||
it('ground', function() {
|
||||
var expectation = '0';
|
||||
var result = k.getTestSignalCommand('ground');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('dc', function() {
|
||||
var expectation = 'p';
|
||||
var result = k.getTestSignalCommand('dc');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Pulse 1x Fast', function() {
|
||||
var expectation = '=';
|
||||
var result = k.getTestSignalCommand('pulse1xFast');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Pulse 1x Slow', function() {
|
||||
var expectation = '-';
|
||||
var result = k.getTestSignalCommand('pulse1xSlow');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Pulse 2x Fast', function() {
|
||||
var expectation = ']';
|
||||
var result = k.getTestSignalCommand('pulse2xFast');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('Pulse 2x Slow', function() {
|
||||
var expectation = '[';
|
||||
var result = k.getTestSignalCommand('pulse2xSlow');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
it('none', function() {
|
||||
var expectation = 'd';
|
||||
var result = k.getTestSignalCommand('none');
|
||||
return expect(result).to.eventually.equal(expectation);
|
||||
});
|
||||
});
|
||||
describe('#getVersionNumber', function() {
|
||||
it('should get the major version number from a github standard version string',() => {
|
||||
var expectedVersion = 6;
|
||||
var inputStringVersion = 'v6.0.0';
|
||||
|
||||
expect(k.getVersionNumber(inputStringVersion)).to.equal(expectedVersion);
|
||||
});
|
||||
});
|
||||
describe('#getImpedanceSetter', function() {
|
||||
describe('channel input selection works', function () {
|
||||
it('channel 2', function (done) {
|
||||
@@ -999,4 +1191,4 @@ describe('OpenBCIConstants', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+1217
-137
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,622 @@
|
||||
var sinon = require('sinon');
|
||||
var chai = require('chai'),
|
||||
should = chai.should(),
|
||||
expect = chai.expect,
|
||||
openBCIBoard = require('../openBCIBoard'),
|
||||
openBCISample = openBCIBoard.OpenBCISample,
|
||||
k = openBCISample.k;
|
||||
|
||||
var chaiAsPromised = require("chai-as-promised");
|
||||
var sinonChai = require("sinon-chai");
|
||||
chai.use(chaiAsPromised);
|
||||
chai.use(sinonChai);
|
||||
var bufferEqual = require('buffer-equal');
|
||||
var fs = require('fs');
|
||||
//var wstream = fs.createWriteStream('myOutput.txt');
|
||||
|
||||
|
||||
describe('#impedanceTesting', function() {
|
||||
var ourBoard;
|
||||
this.timeout(20000);
|
||||
|
||||
before(function(done) {
|
||||
ourBoard = new openBCIBoard.OpenBCIBoard({
|
||||
verbose: true
|
||||
});
|
||||
var useSim = () => {
|
||||
ourBoard.simulatorEnable().then(() => {
|
||||
return ourBoard.connect(k.OBCISimulatorPortName);
|
||||
});
|
||||
};
|
||||
ourBoard.autoFindOpenBCIBoard()
|
||||
.then(portName => {
|
||||
return ourBoard.connect(portName);
|
||||
})
|
||||
.catch((err) => {
|
||||
useSim();
|
||||
})
|
||||
.then(() => {
|
||||
console.log('connected');
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('Error: '+ err);
|
||||
});
|
||||
|
||||
|
||||
ourBoard.once('ready',() => {
|
||||
ourBoard.streamStart()
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 100); // give some time for the stream command to be sent
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
after(done => {
|
||||
if(ourBoard["connected"]) {
|
||||
ourBoard.disconnect()
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(err => {
|
||||
done(err);
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
describe('#impedanceTestAllChannels', function () {
|
||||
var impedanceArray = [];
|
||||
|
||||
before(function(done) {
|
||||
ourBoard.once('impedanceArray', arr => {
|
||||
impedanceArray = arr;
|
||||
console.log(impedanceArray);
|
||||
done();
|
||||
});
|
||||
ourBoard.impedanceTestAllChannels();
|
||||
});
|
||||
describe('#channel1',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[0].channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[0].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[0].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[0].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[0].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel2',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[1].channel.should.be.equal(2);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[1].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[1].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[1].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[1].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel3',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[2].channel.should.be.equal(3);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[2].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[2].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[2].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[2].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel4',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[3].channel.should.be.equal(4);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[3].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[3].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[3].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[3].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel5',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[4].channel.should.be.equal(5);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[4].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[4].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[4].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[4].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel6',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[5].channel.should.be.equal(6);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[5].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[5].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[5].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[5].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel7',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[6].channel.should.be.equal(7);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[6].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[6].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[6].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[6].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel8',function() {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[7].channel.should.be.equal(8);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[7].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function () {
|
||||
impedanceArray[7].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[7].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function () {
|
||||
impedanceArray[7].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannelsRejects', function() {
|
||||
it('rejects when it does not get an array', function(done) {
|
||||
ourBoard.impedanceTestChannels('taco').should.be.rejected.and.notify(done);
|
||||
});
|
||||
|
||||
it('rejects when it array length does not match number of channels', function(done) {
|
||||
ourBoard.impedanceTestChannels(['-','N','n','p','P','p','b']).should.be.rejected.and.notify(done);
|
||||
});
|
||||
|
||||
});
|
||||
describe('#impedanceTestChannels', function () {
|
||||
var impedanceArray = [];
|
||||
|
||||
before(function(done) {
|
||||
ourBoard.once('impedanceArray', arr => {
|
||||
impedanceArray = arr;
|
||||
done();
|
||||
});
|
||||
ourBoard.impedanceArray[0] = openBCISample.impedanceObject(1);
|
||||
ourBoard.impedanceTestChannels(['-','N','n','p','P','p','b','B']).catch(err => done(err));
|
||||
});
|
||||
describe('#channel1',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[0].channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[0].P.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[0].P.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[0].N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[0].N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel2',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[1].channel.should.be.equal(2);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[1].P.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[1].P.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[1].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[1].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel3',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[2].channel.should.be.equal(3);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[2].P.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[2].P.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[2].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[2].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel4',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[3].channel.should.be.equal(4);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[3].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[3].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[3].N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[3].N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel5',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[4].channel.should.be.equal(5);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[4].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[4].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[4].N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[4].N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel6',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[5].channel.should.be.equal(6);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[5].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[5].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[5].N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[5].N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel7',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceArray[6].channel.should.be.equal(7);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[6].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[6].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceArray[6].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceArray[6].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel8',function() {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[7].channel.should.be.equal(8);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[7].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function () {
|
||||
impedanceArray[7].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[7].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function () {
|
||||
impedanceArray[7].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannel', function () {
|
||||
var impedanceObject = {};
|
||||
|
||||
before(function(done) {
|
||||
ourBoard.impedanceTestChannel(1)
|
||||
.then(impdObj => {
|
||||
impedanceObject = impdObj;
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
describe('#channel1',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceObject.channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceObject.P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceObject.P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceObject.N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceObject.N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannelInputP', function () {
|
||||
var impedanceObject = {};
|
||||
|
||||
before(function(done) {
|
||||
ourBoard.impedanceTestChannelInputP(1)
|
||||
.then(impdObj => {
|
||||
impedanceObject = impdObj;
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
describe('#channel1',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceObject.channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceObject.P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceObject.P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceObject.N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceObject.N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannelInputN', function () {
|
||||
|
||||
var impedanceObject = {};
|
||||
//wstream = fs.createWriteStream('hardwareVoltageOutputAll.txt');
|
||||
|
||||
before(function(done) {
|
||||
|
||||
console.log('7');
|
||||
|
||||
ourBoard.on('sample',sample => {
|
||||
//console.log('8');
|
||||
//OpenBCISample.debugPrettyPrint(sample);
|
||||
// good to start impedance testing..
|
||||
});
|
||||
|
||||
ourBoard.impedanceTestChannelInputN(1)
|
||||
.then(impdObj => {
|
||||
impedanceObject = impdObj;
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 1000);
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
describe('#channel1',function() {
|
||||
it('has valid channel number', function() {
|
||||
impedanceObject.channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceObject.P.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceObject.P.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function() {
|
||||
it('got raw impedance value',function() {
|
||||
impedanceObject.N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it('text is not \'init\'', function() {
|
||||
impedanceObject.N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestContinuousStXX', function () {
|
||||
|
||||
var impedanceArray = [];
|
||||
|
||||
before(function(done) {
|
||||
ourBoard.impedanceTestContinuousStart()
|
||||
.then(done).catch(err => done(err));
|
||||
|
||||
});
|
||||
|
||||
after(function(done) {
|
||||
ourBoard.impedanceTestContinuousStop()
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('prints 10 impedance arrays', function(done) {
|
||||
var count = 1;
|
||||
|
||||
var listener = impedanceArray => {
|
||||
//console.log('\nImpedance Array: ' + count);
|
||||
//console.log(impedanceArray);
|
||||
count++;
|
||||
if (count > 10) {
|
||||
ourBoard.removeListener('impedanceArray', listener);
|
||||
done();
|
||||
}
|
||||
};
|
||||
ourBoard.on('impedanceArray', listener);
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
describe('#_impedanceTestSetChannel', function () {
|
||||
it('reject with invalid channel', function(done) {
|
||||
ourBoard._impedanceTestSetChannel(0,false,false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
});
|
||||
describe('#_impedanceTestCalculateChannel', function () {
|
||||
it('reject with low invalid channel', function(done) {
|
||||
ourBoard._impedanceTestCalculateChannel(0,false,false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with high invalid channel', function(done) {
|
||||
ourBoard._impedanceTestCalculateChannel(69,false,false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with invalid data type pInput', function(done) {
|
||||
ourBoard._impedanceTestCalculateChannel(1,'taco',false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with invalid data type nInput', function(done) {
|
||||
ourBoard._impedanceTestCalculateChannel(1,false,'taco').should.be.rejected.and.notify(done);
|
||||
});
|
||||
});
|
||||
describe('#_impedanceTestFinalizeChannel', function () {
|
||||
it('reject with low invalid channel', function(done) {
|
||||
ourBoard._impedanceTestFinalizeChannel(0,false,false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with high invalid channel', function(done) {
|
||||
ourBoard._impedanceTestFinalizeChannel(69,false,false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with invalid data type pInput', function(done) {
|
||||
ourBoard._impedanceTestFinalizeChannel(1,'taco',false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with invalid data type nInput', function(done) {
|
||||
ourBoard._impedanceTestFinalizeChannel(1,false,'taco').should.be.rejected.and.notify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
//'use strict';
|
||||
//
|
||||
//var sinon = require('sinon');
|
||||
//var chai = require('chai');
|
||||
//var expect = chai.expect;
|
||||
//
|
||||
//var MockedOpenBCIBoard = require('../test_mocks/openbci-hardware');
|
||||
//var openBCIBoard = MockedOpenBCIBoard.openBCIBoard;
|
||||
//var hardware = MockedOpenBCIBoard.hardware;
|
||||
//
|
||||
//describe('openBCIBoard', function () {
|
||||
// var sandbox;
|
||||
//
|
||||
// beforeEach(function (){
|
||||
// sandbox = sinon.sandbox.create();
|
||||
//
|
||||
// // Create a board for fun and profit
|
||||
// hardware.reset();
|
||||
// hardware.createBoard();
|
||||
// });
|
||||
//
|
||||
// afterEach(function () {
|
||||
// sandbox.restore();
|
||||
// });
|
||||
//
|
||||
//});
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,710 @@
|
||||
var sinon = require('sinon'),
|
||||
chai = require('chai'),
|
||||
should = chai.should(),
|
||||
expect = chai.expect,
|
||||
openBCISimulator = require('../openBCISimulator'),
|
||||
openBCISample = require('../openBCISample'),
|
||||
k = openBCISample.k;
|
||||
|
||||
var chaiAsPromised = require("chai-as-promised");
|
||||
var sinonChai = require("sinon-chai");
|
||||
chai.use(chaiAsPromised);
|
||||
chai.use(sinonChai);
|
||||
var bufferEqual = require('buffer-equal');
|
||||
var fs = require('fs');
|
||||
|
||||
describe('openBCISimulator',function() {
|
||||
this.timeout(4000);
|
||||
var portName = k.OBCISimulatorPortName;
|
||||
describe('#constructor', function () {
|
||||
var simulator;
|
||||
afterEach(() => {
|
||||
simulator = null;
|
||||
});
|
||||
after(done => {
|
||||
setTimeout(() => {
|
||||
// Since there is a conditional timeout, it's important to wait to start the next test till this ends for sure
|
||||
done();
|
||||
}, 200); // The same amount of time in the simulator
|
||||
});
|
||||
it('constructs with the correct default options', function() {
|
||||
simulator = new openBCISimulator.OpenBCISimulator();
|
||||
expect(simulator.options.accel).to.be.true;
|
||||
expect(simulator.options.alpha).to.be.true;
|
||||
expect(simulator.options.boardFailure).to.be.false;
|
||||
expect(simulator.options.daisy).to.be.false;
|
||||
expect(simulator.options.drift).to.equal(0);
|
||||
expect(simulator.options.firmwareVersion).to.equal(k.OBCIFirmwareV1);
|
||||
expect(simulator.options.lineNoise).to.equal(k.OBCISimulatorLineNoiseHz60);
|
||||
expect(simulator.options.sampleRate).to.equal(k.OBCISampleRate250);
|
||||
expect(simulator.options.serialPortFailure).to.be.false;
|
||||
expect(simulator.options.verbose).to.be.false;
|
||||
});
|
||||
it('should be able to get into daisy mode',function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
daisy: true
|
||||
});
|
||||
expect(simulator.options.daisy).to.be.true;
|
||||
});
|
||||
it('should set the correct sample rate in daisy mode, if no sampleRate is provided',function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
daisy: true
|
||||
});
|
||||
expect(simulator.options.sampleRate).to.equal(250); // produce samples at same rate
|
||||
});
|
||||
it('should use provided sample rate even if daisy is true',function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
daisy: true,
|
||||
sampleRate: 20
|
||||
});
|
||||
expect(simulator.options.daisy).to.be.true;
|
||||
expect(simulator.options.sampleRate).to.equal(20);
|
||||
});
|
||||
it('should be able to put into firmware version 2', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
firmwareVersion: 'v2'
|
||||
});
|
||||
expect(simulator.options.firmwareVersion).to.equal(k.OBCIFirmwareV2);
|
||||
});
|
||||
it('should be able to simulate board failure',function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
boardFailure: true
|
||||
});
|
||||
expect(simulator.options.boardFailure).to.be.true;
|
||||
});
|
||||
it('should be able to simulate serial port failure',function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
serialPortFailure: true
|
||||
});
|
||||
expect(simulator.options.serialPortFailure).to.be.true;
|
||||
});
|
||||
it('can turn 50Hz line noise on', function() {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
lineNoise: '50Hz'
|
||||
});
|
||||
(simulator.options.lineNoise).should.equal(k.OBCISimulatorLineNoiseHz50);
|
||||
});
|
||||
it('can turn no line noise on', function() {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
lineNoise: 'None'
|
||||
});
|
||||
(simulator.options.lineNoise).should.equal(k.OBCISimulatorLineNoiseNone);
|
||||
});
|
||||
it('should not inject alpha if desired', function() {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
alpha: false
|
||||
});
|
||||
expect(simulator.options.alpha).to.be.false;
|
||||
});
|
||||
it('should be able to not use the accel', function() {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
accel: false
|
||||
});
|
||||
expect(simulator.options.accel).to.be.false;
|
||||
});
|
||||
it('should be able to set positive drift', function() {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
drift: 1
|
||||
});
|
||||
expect(simulator.options.drift).to.be.greaterThan(0);
|
||||
});
|
||||
it('should be able to set negative drift', function() {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName,{
|
||||
drift: -1
|
||||
});
|
||||
expect(simulator.options.drift).to.be.lessThan(0);
|
||||
});
|
||||
});
|
||||
describe("_startStream", function() {
|
||||
it('should return a packet with sample data in it', function(done) {
|
||||
var simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName);
|
||||
var sampleCounter = 0;
|
||||
var sampleTestSize = 5;
|
||||
|
||||
var newDataFunc = data => {
|
||||
if (sampleCounter > sampleTestSize) {
|
||||
simulator.write(new Buffer([k.OBCIStreamStop]));
|
||||
simulator.removeListener('data',newDataFunc);
|
||||
openBCISample.parseRawPacketStandard(data,k.channelSettingsArrayInit(k.OBCINumberOfChannelsDefault),true)
|
||||
.then(sampleObject => {
|
||||
sampleObject.channelData.forEach((channelValue, index) => {
|
||||
expect(channelValue).to.not.equal(0);
|
||||
});
|
||||
simulator = null;
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
sampleCounter++;
|
||||
}
|
||||
}
|
||||
simulator.on('data',newDataFunc);
|
||||
simulator._startStream();
|
||||
});
|
||||
it('should return a sync set packet with accel',function(done) {
|
||||
var simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName);
|
||||
var sampleCounter = 0;
|
||||
var sampleTestSize = 5;
|
||||
|
||||
var newDataFunc = data => {
|
||||
if (sampleCounter === 0) {
|
||||
// Ensure everything is switched on for this test
|
||||
simulator.options.accel = true;
|
||||
simulator.synced = true;
|
||||
simulator.sendSyncSetPacket = true;
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketStandardAccel));
|
||||
} else if (sampleCounter === 1) {
|
||||
// Now this data should be the time sync up packet
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketAccelTimeSyncSet));
|
||||
// Expect flag to be down
|
||||
expect(simulator.sendSyncSetPacket).to.be.false;
|
||||
} else if (sampleCounter >= sampleTestSize) {
|
||||
simulator.write(new Buffer([k.OBCIStreamStop]));
|
||||
simulator.removeListener('data',newDataFunc);
|
||||
simulator = null;
|
||||
done();
|
||||
} else {
|
||||
// Now this data should be the time sync up packet
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketAccelTimeSynced));
|
||||
}
|
||||
sampleCounter++;
|
||||
}
|
||||
|
||||
simulator.on('data',newDataFunc);
|
||||
simulator._startStream();
|
||||
});
|
||||
it('should return a sync set packet with raw aux',function(done) {
|
||||
var simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName,{
|
||||
accel: false
|
||||
});
|
||||
var sampleCounter = 0;
|
||||
var sampleTestSize = 5;
|
||||
|
||||
var newDataFunc = data => {
|
||||
if (sampleCounter === 0) {
|
||||
// Ensure everything is switched on for this test
|
||||
simulator.synced = true;
|
||||
simulator.sendSyncSetPacket = true;
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketStandardRawAux));
|
||||
} else if (sampleCounter === 1) {
|
||||
// Now this data should be the time sync up packet
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketRawAuxTimeSyncSet));
|
||||
// Expect flag to be down
|
||||
expect(simulator.sendSyncSetPacket).to.be.false;
|
||||
} else if (sampleCounter >= sampleTestSize) {
|
||||
simulator.write(new Buffer([k.OBCIStreamStop]));
|
||||
simulator.removeListener('data',newDataFunc);
|
||||
simulator = null;
|
||||
done();
|
||||
} else {
|
||||
// Now this data should be the time sync up packet
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketRawAuxTimeSynced));
|
||||
}
|
||||
sampleCounter++;
|
||||
}
|
||||
|
||||
simulator.on('data',newDataFunc);
|
||||
simulator._startStream();
|
||||
});
|
||||
});
|
||||
describe("firmwareVersion1",function () {
|
||||
|
||||
});
|
||||
describe("firmwareVersion2",function () {
|
||||
var simulator;
|
||||
beforeEach(() => {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName,{
|
||||
firmwareVersion: 'v2'
|
||||
});
|
||||
});
|
||||
afterEach(() => {
|
||||
simulator = null;
|
||||
});
|
||||
describe('_processPrivateRadioMessage',function () {
|
||||
describe('OBCIRadioCmdChannelGet',function () {
|
||||
it('should emit success if firmware version 2', done => {
|
||||
simulator.channelNumber = 0;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(0);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdChannelGet]));
|
||||
});
|
||||
it('should emit failure if board failure and host channel number', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
simulator.channelNumber = 9;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
expect(buf[buf.length - 4]).to.equal(9);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdChannelGet]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdChannelSet',function () {
|
||||
it('should set the channel number if in bounds', done => {
|
||||
var newChanNum = 20;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(newChanNum);
|
||||
expect(simulator.channelNumber).to.equal(newChanNum);
|
||||
expect(simulator.hostChannelNumber).to.equal(newChanNum);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdChannelSet,newChanNum]));
|
||||
});
|
||||
it('should not set the channel number if out of bounds', done => {
|
||||
var newChanNum = 26;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdChannelSet,newChanNum]));
|
||||
});
|
||||
it('should emit failure if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdChannelSet,7]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdChannelSetOverride',function () {
|
||||
it('should change just the hosts channel number and not the systems channel number and force a board comms failure', done => {
|
||||
var systemChannelNumber = 0;
|
||||
var newHostChannelNumber = 1;
|
||||
simulator.channelNumber = systemChannelNumber;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(newHostChannelNumber);
|
||||
expect(simulator.options.boardFailure).to.be.true;
|
||||
expect(simulator.channelNumber).to.equal(systemChannelNumber);
|
||||
expect(simulator.hostChannelNumber).to.equal(newHostChannelNumber);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdChannelSetOverride,newHostChannelNumber]));
|
||||
});
|
||||
it('should change just the hosts channel number and not the systems channel number and fix a board failure', done => {
|
||||
var systemChannelNumber = 0;
|
||||
var oldHostChannelNumber = 1;
|
||||
simulator.channelNumber = systemChannelNumber;
|
||||
simulator.hostChannelNumber = oldHostChannelNumber;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(systemChannelNumber);
|
||||
expect(simulator.options.boardFailure).to.be.false;
|
||||
expect(simulator.channelNumber).to.equal(systemChannelNumber);
|
||||
expect(simulator.hostChannelNumber).to.equal(systemChannelNumber);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdChannelSetOverride,systemChannelNumber]));
|
||||
});
|
||||
it('should not set the channel number if out of bounds', done => {
|
||||
var newChanNum = 26;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdChannelSetOverride,newChanNum]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdPollTimeGet',function () {
|
||||
it('should emit success if firmware version 2 with poll time', done => {
|
||||
var expectedPollTime = 80;
|
||||
simulator.pollTime = expectedPollTime;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(expectedPollTime);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdPollTimeGet]));
|
||||
});
|
||||
it('should emit failure if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdPollTimeGet]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdPollTimeSet',function () {
|
||||
it('should set the poll time if in bounds', done => {
|
||||
var newPollTime = 20;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(newPollTime);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdPollTimeSet,newPollTime]));
|
||||
});
|
||||
it('should emit failure if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdPollTimeSet,7]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdBaudRateSetDefault',function () {
|
||||
it('should emit success if firmware version 2 with proper baud rate', done => {
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
var eotBuf = new Buffer('$$$');
|
||||
var newBaudRateBuf;
|
||||
for (var i = buf.length; i > 3; i--) {
|
||||
if (bufferEqual(buf.slice(i - 3, i),eotBuf)) {
|
||||
newBaudRateBuf = buf.slice(i - 9, i - 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
var newBaudRateNum = Number(newBaudRateBuf.toString());
|
||||
expect(newBaudRateNum).to.equal(k.OBCIRadioBaudRateDefault);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdBaudRateSetDefault]));
|
||||
});
|
||||
it('should emit success if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdBaudRateSetDefault]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdBaudRateSetFast',function () {
|
||||
it('should emit success if firmware version 2 with proper baud rate', done => {
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
var eotBuf = new Buffer("$$$");
|
||||
var newBaudRateBuf;
|
||||
for (var i = buf.length; i > 3; i--) {
|
||||
if (bufferEqual(buf.slice(i - 3, i),eotBuf)) {
|
||||
newBaudRateBuf = buf.slice(i - 9, i - 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
var newBaudRateNum = Number(newBaudRateBuf.toString());
|
||||
expect(newBaudRateNum).to.equal(k.OBCIRadioBaudRateFast);
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdBaudRateSetFast]));
|
||||
});
|
||||
it('should emit success if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdBaudRateSetFast]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdSystemStatus',function () {
|
||||
it('should emit success if firmware version 2', done => {
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdSystemStatus]));
|
||||
});
|
||||
it('should emit failure if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf,data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data',dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data',dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey,k.OBCIRadioCmdSystemStatus]));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("boardFailure",function () {
|
||||
|
||||
});
|
||||
|
||||
describe("#sync",function () {
|
||||
this.timeout(2000);
|
||||
var simulator;
|
||||
beforeEach(function(done) {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
firmwareVersion: 'v2'
|
||||
});
|
||||
simulator.once('open',() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
afterEach(function() {
|
||||
simulator = null;
|
||||
});
|
||||
it("should emit the time sync sent command", function(done) {
|
||||
simulator.once('data',data => {
|
||||
expect(openBCISample.isTimeSyncSetConfirmationInBuffer(data)).to.be.true;
|
||||
done();
|
||||
});
|
||||
simulator.write(k.OBCISyncTimeSet, (err, msg) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
it("should set synced to true", function(done) {
|
||||
simulator.synced = false;
|
||||
var newData = data => {
|
||||
expect(simulator.synced).to.be.true;
|
||||
simulator.removeListener('data', newData);
|
||||
done();
|
||||
};
|
||||
|
||||
simulator.on('data', data => {
|
||||
newData(data);
|
||||
});
|
||||
|
||||
simulator.write(k.OBCISyncTimeSet, (err, msg) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
it("should emit a time sync set packet followed by a time synced accel packet after sync up call", function(done) {
|
||||
simulator.synced = false;
|
||||
var emitCounter = 0;
|
||||
var maxPacketsBetweenSetPacket = 5;
|
||||
var newData = data => {
|
||||
if (emitCounter === 0) { // the time sync packet is emitted here
|
||||
// Make a call to start streaming
|
||||
simulator.write(k.OBCIStreamStart, err => {
|
||||
if (err) done(err);
|
||||
});
|
||||
} else if (emitCounter < maxPacketsBetweenSetPacket) {
|
||||
if (openBCISample.getRawPacketType(data[k.OBCIPacketPositionStopByte]) === k.OBCIStreamPacketAccelTimeSyncSet) {
|
||||
simulator.removeListener('data', newData);
|
||||
simulator.write(k.OBCIStreamStop, err => {
|
||||
if (err) done(err);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
expect(openBCISample.getRawPacketType(data[k.OBCIPacketPositionStopByte])).to.equal(k.OBCIStreamPacketAccelTimeSynced);
|
||||
|
||||
}
|
||||
} else {
|
||||
done("Failed to get set packet in time")
|
||||
}
|
||||
emitCounter++;
|
||||
};
|
||||
|
||||
simulator.on('data', newData);
|
||||
|
||||
simulator.write(k.OBCISyncTimeSet, (err, msg) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
it("should emit a time sync set raw aux, then time synced raw aux packet after sync up call", function(done) {
|
||||
simulator.synced = false;
|
||||
simulator.options.accel = false;
|
||||
var emitCounter = 0;
|
||||
var maxPacketsBetweenSetPacket = 5;
|
||||
var newData = data => {
|
||||
if (emitCounter === 0) { // the time sync packet is emitted here
|
||||
// Make a call to start streaming
|
||||
simulator.write(k.OBCIStreamStart, err => {
|
||||
if (err) done(err);
|
||||
});
|
||||
} else if (emitCounter < maxPacketsBetweenSetPacket) {
|
||||
if (openBCISample.getRawPacketType(data[k.OBCIPacketPositionStopByte]) === k.OBCIStreamPacketRawAuxTimeSyncSet) {
|
||||
simulator.removeListener('data', newData);
|
||||
simulator.write(k.OBCIStreamStop, err => {
|
||||
if (err) done(err);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
expect(openBCISample.getRawPacketType(data[k.OBCIPacketPositionStopByte])).to.equal(k.OBCIStreamPacketRawAuxTimeSynced);
|
||||
}
|
||||
} else {
|
||||
done("Failed to get set packet in time")
|
||||
}
|
||||
|
||||
emitCounter++;
|
||||
};
|
||||
|
||||
simulator.on('data', newData);
|
||||
|
||||
simulator.write(k.OBCISyncTimeSet, (err, msg) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
Referência em uma Nova Issue
Bloquear um usuário