You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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`.
164
164
165
-
Now using firmware `v2`, the fun begins! What we set out to do was synchronize not only the board to this modules clock, but also with a global NTP server, so that you could use several different devices and all sync to the same global server. That way you can really do some serious cloud computing!
165
+
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 different time stamps and unique new features to calculate a time sync 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 serveryou could use several different devices and all sync to the same time server. That way you can really do some serious cloud computing!
166
166
167
+
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!
168
+
169
+
Using local computer time:
167
170
```js
168
171
var OpenBCIBoard =require('openbci').OpenBCIBoard,
169
172
ourBoard =newOpenBCIBoard({
170
-
verbose:true,
171
-
timeSync:true// Sync up with NTP servers in constructor
173
+
verbose:true
172
174
});
173
175
176
+
constresyncPeriodMin=5; // re sync every five minutes
177
+
constsecondsInMinute=60;
178
+
var sampleRate =k.OBCISampleRate250; // Default to 250, ALWAYS verify with a call to `sampleRate` after `ready` event!
179
+
var timeSyncPossible =false;
180
+
174
181
// Call to connect
175
182
ourBoard.connect(portName).then(() => {
176
183
ourBoard.on('ready',() => {
184
+
// Get the sample rate after 'ready' event!
185
+
sampleRate =ourBoard.sampleRate();
186
+
// 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.
* `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`)
353
378
* `simulatorSerialPortFailure` {Boolean} - Simulates not being able to open a serial connection. Most likely due to a OpenBCI dongle not being plugged in.
354
-
* `timeSync` - {Boolean} Syncs the module up with an SNTP time server. Syncs the board on startup with the SNTP time. Adds a time stamp to the AUX channels.
379
+
* `sntpTimeSync` - {Boolean} Syncs the module up with an SNTP time server and uses that as single source of truth instead of local computer time. (Default `true`)
380
+
* `sntpTimeSyncHost` - {String} The sntp server to use, can be either sntp or ntp (Defaults `pool.ntp.org`).
381
+
* `sntpTimeSyncPort` - {Number} The port to access the sntp server (Defaults `123`)
355
382
* `verbose` {Boolean} - Print out useful debugging events
356
383
357
384
**Note, we have added support for either all lowercase OR camel case for the options, use whichever style you prefer.**
@@ -493,7 +520,7 @@ A Number, specifies which channel you want to test.
493
520
494
521
**_Returns_** a promise that resolves a single channel impedance object.
495
522
496
-
Example:
523
+
**Example**
497
524
```js
498
525
var OpenBCIBoard =require('openbci').OpenBCIBoard;
499
526
var ourBoard =newOpenBCIBoard();
@@ -535,7 +562,7 @@ A Number, specifies which channel you want to test.
535
562
536
563
**_Returns_** a promise that resolves a single channel impedance object.
537
564
538
-
Example:
565
+
**Example**
539
566
```js
540
567
var OpenBCIBoard =require('openbci').OpenBCIBoard;
541
568
var ourBoard =newOpenBCIBoard();
@@ -577,7 +604,7 @@ A Number, specifies which channel you want to test.
577
604
578
605
**_Returns_** a promise that resolves a single channel impedance object.
579
606
580
-
Example:
607
+
**Example**
581
608
```js
582
609
var OpenBCIBoard =require('openbci').OpenBCIBoard;
583
610
var ourBoard =newOpenBCIBoard();
@@ -787,21 +814,9 @@ Stateful method for querying the current offset only when the last one is too ol
787
814
788
815
**_Returns_** a promise with the time offset
789
816
790
-
### .sntpGetServerTime()
791
-
792
-
Get time from the SNTP server. Must have internet connection!
793
-
794
-
**_Returns_** a promise fulfilled with time object
795
-
796
-
### .sntpNow()
797
-
798
-
This function gets SNTP time since Jan 1, 1970, if we call this after a successful `.sntpStart()` this time will be synced, or else we will just get the current computer time, the case if there is no internet.
799
-
800
-
**_Returns_** time since UNIX epoch in ms.
801
-
802
817
### .sntpStart()
803
818
804
-
This starts the SNTP server and gets it to remain in sync with the SNTP server;
819
+
This starts the SNTP server and gets it to remain in sync with the SNTP server.
805
820
806
821
**_Returns_** a promise if the module was able to sync with NTP server.
807
822
@@ -841,6 +856,96 @@ Send the command to tell the board to start the syncing protocol. Must be connec
841
856
842
857
**_Returns_** {Promise} resolves if the command was sent to the write queue, rejects if unable.
843
858
859
+
### .syncClocksFull()
860
+
861
+
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.
862
+
863
+
**Note, this functionality requires OpenBCI Firmware Version 2.0**
864
+
865
+
**_Returns_** {Promise} resolves if `synced` event is emitted, rejects if not connected or using firmware v2. Resolves with a synced object:
866
+
```javascript
867
+
{
868
+
boardTime:0, // The time contained in the time sync set packet.
869
+
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.
870
+
timeSyncSent:0, // The time the `<` was sent to the Dongle.
871
+
timeSyncSentConfirmation:0, // The time the `<` was sent to the Board; It's really the time `,` was received from the Dongle.
872
+
timeSyncSetPacket:0, // The time the set packet was received from the Board.
timeTransmission:0, // Estimated time it took for time sync set packet to be sent from Board to Driver.
875
+
timeOffset:0, // The map (or translation) from boardTime to module time.
876
+
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.
877
+
}
878
+
```
879
+
880
+
**Example**
881
+
882
+
```javascript
883
+
var OpenBCIBoard =require('openbci').OpenBCIBoard,
884
+
ourBoard =newOpenBCIBoard({
885
+
verbose:true
886
+
});
887
+
888
+
var portName =/* INSERT PORT NAME HERE */;
889
+
var samples = []; // Array to store time synced samples into
890
+
var timeSyncActivated =false;
891
+
892
+
ourBoard.connect(portName)
893
+
.then(() => {
894
+
ourBoard.on('ready',() => {
895
+
ourBoard.streamStart()
896
+
.then(() => {
897
+
/** Could also call `.syncClocksFull()` here */
898
+
})
899
+
.catch(err=> {
900
+
console.log(`Error starting stream ${err}`);
901
+
})
902
+
});
903
+
ourBoard.on('sample',sample=> {
904
+
/** If we are not synced, then do that! */
905
+
if (timeSyncActivated ===false) {
906
+
timeSyncActivated =true;
907
+
ourBoard.syncClocksFull()
908
+
.then(syncObj=> {
909
+
if (syncObj.valid) {
910
+
console.log('1st sync done');
911
+
}
912
+
returnourBoard.syncClocksFull();
913
+
})
914
+
.then(syncObj=> {
915
+
if (syncObj.valid) {
916
+
console.log('2nd sync done');
917
+
}
918
+
returnourBoard.syncClocksFull();
919
+
})
920
+
.then(syncObj=> {
921
+
if (syncObj.valid) {
922
+
console.log('3rd sync done');
923
+
}
924
+
returnourBoard.syncClocksFull();
925
+
})
926
+
.then(syncObj=> {
927
+
if (syncObj.valid) {
928
+
console.log('4th sync done');
929
+
930
+
}
931
+
/* Do awesome time syncing stuff */
932
+
})
933
+
.catch(err=> {
934
+
console.log(`sync err ${err}`);
935
+
});
936
+
}
937
+
if (startLoggingSamples &&sample.hasOwnProperty("timeStamp") &&sample.hasOwnProperty("boardTime")) {
938
+
/** If you only want to log samples with time stamps */
939
+
samples.push(sample);
940
+
}
941
+
});
942
+
})
943
+
.catch(err=> {
944
+
console.log(`connect ${err}`);
945
+
});
946
+
947
+
```
948
+
844
949
### .testSignal(signal)
845
950
846
951
Apply the internal test signal to all channels.
@@ -859,6 +964,12 @@ A String indicating which test signal to apply
859
964
860
965
**_Returns_** a promise, if the commands were sent to write buffer.
861
966
967
+
### .time()
968
+
969
+
Uses `._sntpNow()` time when sntpTimeSync specified in options, or else use Date.now() for time.
970
+
971
+
**_Returns_** time since UNIX epoch in ms.
972
+
862
973
### .usingVersionTwoFirmware()
863
974
864
975
Convenience method to determine if you can use firmware v2.x.x capabilities.
0 commit comments