@@ -23,6 +23,7 @@ function OpenBCIFactory () {
2323 simulate : false ,
2424 simulatorBoardFailure : false ,
2525 simulatorDaisyModuleAttached : false ,
26+ simulatorDaisyModuleCanBeAttached : true ,
2627 simulatorFirmwareVersion : [ k . OBCIFirmwareV1 , k . OBCIFirmwareV2 ] ,
2728 simulatorFragmentation : [ k . OBCISimulatorFragmentationNone , k . OBCISimulatorFragmentationRandom , k . OBCISimulatorFragmentationFullBuffers , k . OBCISimulatorFragmentationOneByOne ] ,
2829 simulatorLatencyTime : 16 ,
@@ -41,80 +42,84 @@ function OpenBCIFactory () {
4142 } ;
4243
4344 /**
44- * @description The initialization method to call first, before any other method.
45- * @param options (optional) - Board optional configurations.
46- * - `baudRate` {Number} - Baud Rate, defaults to 115200. Manipulating this is allowed if
47- * firmware on board has been previously configured.
48- *
49- * - `boardType` {String} - Specifies type of OpenBCI board.
50- * 3 Possible Boards:
51- * `default` - 8 Channel OpenBCI board (Default)
52- * `daisy` - 8 Channel OpenBCI board with Daisy Module. Total of 16 channels.
53- * `ganglion` - 4 Channel board
54- * (NOTE: THIS IS IN-OP TIL RELEASE OF GANGLION BOARD 07/2016)
55- *
56- * - `simulate` {Boolean} - Full functionality, just mock data. Must attach Daisy module by setting
57- * `simulatorDaisyModuleAttached` to `true` in order to get 16 channels. (Default `false`)
58- *
59- * - `simulatorBoardFailure` {Boolean} - Simulates board communications failure. This occurs when the RFduino on
60- * the board is not polling the RFduino on the dongle. (Default `false`)
61- *
62- * - `simulatorDaisyModuleAttached` {Boolean} - Simulates a daisy module being attached to the OpenBCI board.
63- * This is useful if you want to test how your application reacts to a user requesting 16 channels
64- * but there is no daisy module actually attached, or vice versa, where there is a daisy module
65- * attached and the user only wants to use 8 channels. (Default `false`)
66- *
67- * - `simulatorFirmwareVersion` {String} - Allows simulator to be started with firmware version 2 features
68- * 2 Possible Options:
69- * `v1` - Firmware Version 1 (Default)
70- * `v2` - Firmware Version 2
71- *
72- * - `simulatorFragmentation` {String} - Specifies how to break packets to simulate fragmentation, which
73- * occurs commonly in real devices. It is recommended to test code with this enabled.
74- * 4 Possible Options:
75- * `none` - do not fragment packets; output complete chunks immediately when produced (Default)
76- * `random` - output random small chunks of data interspersed with full buffers
77- * `fullBuffers` - allow buffers to fill up until the latency timer has expired
78- * `oneByOne` - output each byte separately
79- *
80- * - `simulatorLatencyTime` {Number} - The time in milliseconds to wait before sending partially full buffers,
81- if `simulatorFragmentation` is specified. (Default `16`)
82- *
83- * - `simulatorBufferSize` {Number} - The size of a full buffer of data, if `simulatorFragmentation` is
84- * specified. (Default `4096`)
85- *
86- * - `simulatorHasAccelerometer` - {Boolean} - Sets simulator to send packets with accelerometer data. (Default `true`)
87- *
88- * - `simulatorInjectAlpha` - {Boolean} - Inject a 10Hz alpha wave in Channels 1 and 2 (Default `true`)
89- *
90- * - `simulatorInjectLineNoise` {String} - Injects line noise on channels.
91- * 3 Possible Options:
92- * `60Hz` - 60Hz line noise (Default) [America]
93- * `50Hz` - 50Hz line noise [Europe]
94- * `none` - Do not inject line noise.
95- *
96- * - `simulatorSampleRate` {Number} - The sample rate to use for the simulator. Simulator will set to 125 if
97- * `simulatorDaisyModuleAttached` is set `true`. However, setting this option overrides that
98- * setting and this sample rate will be used. (Default is `250`)
99- *
100- * - `simulatorSerialPortFailure` {Boolean} - Simulates not being able to open a serial connection. Most likely
101- * due to a OpenBCI dongle not being plugged in.
102- *
103- * - `sntpTimeSync` - {Boolean} Syncs the module up with an SNTP time server and uses that as single source
104- * of truth instead of local computer time. If you are running experiements on your local
105- * computer, keep this `false`. (Default `false`)
106- *
107- * - `sntpTimeSyncHost` - {String} The ntp server to use, can be either sntp or ntp. (Defaults `pool.ntp.org`).
108- *
109- * - `sntpTimeSyncPort` - {Number} The port to access the ntp server. (Defaults `123`)
110- *
111- * - `verbose` {Boolean} - Print out useful debugging events. (Default `false`)
112- *
113- * - `debug` {Boolean} - Print out a raw dump of bytes sent and received. (Default `false`)
114- *
115- * @constructor
116- * @author AJ Keller (@pushtheworldllc)
117- */
45+ * @description The initialization method to call first, before any other method.
46+ * @param options (optional) - Board optional configurations.
47+ * - `baudRate` {Number} - Baud Rate, defaults to 115200. Manipulating this is allowed if
48+ * firmware on board has been previously configured.
49+ *
50+ * - `boardType` {String} - Specifies type of OpenBCI board.
51+ * 3 Possible Boards:
52+ * `default` - 8 Channel OpenBCI board (Default)
53+ * `daisy` - 8 Channel OpenBCI board with Daisy Module. Total of 16 channels.
54+ * `ganglion` - 4 Channel board
55+ * (NOTE: THIS IS IN-OP TIL RELEASE OF GANGLION BOARD 07/2016)
56+ *
57+ * - `simulate` {Boolean} - Full functionality, just mock data. Must attach Daisy module by setting
58+ * `simulatorDaisyModuleAttached` to `true` in order to get 16 channels. (Default `false`)
59+ *
60+ * - `simulatorBoardFailure` {Boolean} - Simulates board communications failure. This occurs when the RFduino on
61+ * the board is not polling the RFduino on the dongle. (Default `false`)
62+ *
63+ * - `simulatorDaisyModuleAttached` {Boolean} - Simulates a daisy module being attached to the OpenBCI board.
64+ * This is useful if you want to test how your application reacts to a user requesting 16 channels
65+ * but there is no daisy module actually attached, or vice versa, where there is a daisy module
66+ * attached and the user only wants to use 8 channels. (Default `false`)
67+ *
68+ * - `simulatorDaisyModuleCanBeAttached` {Boolean} - Allows the simulation of the a hot swapped daisy board.
69+ * For example: You coule simulate if the board has only detected 8 channels and the user requested
70+ * 16 channels. (Default `true`)
71+ *
72+ * - `simulatorFirmwareVersion` {String} - Allows simulator to be started with firmware version 2 features
73+ * 2 Possible Options:
74+ * `v1` - Firmware Version 1 (Default)
75+ * `v2` - Firmware Version 2
76+ *
77+ * - `simulatorFragmentation` {String} - Specifies how to break packets to simulate fragmentation, which
78+ * occurs commonly in real devices. It is recommended to test code with this enabled.
79+ * 4 Possible Options:
80+ * `none` - do not fragment packets; output complete chunks immediately when produced (Default)
81+ * `random` - output random small chunks of data interspersed with full buffers
82+ * `fullBuffers` - allow buffers to fill up until the latency timer has expired
83+ * `oneByOne` - output each byte separately
84+ *
85+ * - `simulatorLatencyTime` {Number} - The time in milliseconds to wait before sending partially full buffers,
86+ * if `simulatorFragmentation` is specified. (Default `16`)
87+ *
88+ * - `simulatorBufferSize` {Number} - The size of a full buffer of data, if `simulatorFragmentation` is
89+ * specified. (Default `4096`)
90+ *
91+ * - `simulatorHasAccelerometer` - {Boolean} - Sets simulator to send packets with accelerometer data. (Default `true`)
92+ *
93+ * - `simulatorInjectAlpha` - {Boolean} - Inject a 10Hz alpha wave in Channels 1 and 2 (Default `true`)
94+ *
95+ * - `simulatorInjectLineNoise` {String} - Injects line noise on channels.
96+ * 3 Possible Options:
97+ * `60Hz` - 60Hz line noise (Default) [America]
98+ * `50Hz` - 50Hz line noise [Europe]
99+ * `none` - Do not inject line noise.
100+ *
101+ * - `simulatorSampleRate` {Number} - The sample rate to use for the simulator. Simulator will set to 125 if
102+ * `simulatorDaisyModuleAttached` is set `true`. However, setting this option overrides that
103+ * setting and this sample rate will be used. (Default is `250`)
104+ *
105+ * - `simulatorSerialPortFailure` {Boolean} - Simulates not being able to open a serial connection. Most likely
106+ * due to a OpenBCI dongle not being plugged in.
107+ *
108+ * - `sntpTimeSync` - {Boolean} Syncs the module up with an SNTP time server and uses that as single source
109+ * of truth instead of local computer time. If you are running experiements on your local
110+ * computer, keep this `false`. (Default `false`)
111+ *
112+ * - `sntpTimeSyncHost` - {String} The ntp server to use, can be either sntp or ntp. (Defaults `pool.ntp.org`).
113+ *
114+ * - `sntpTimeSyncPort` - {Number} The port to access the ntp server. (Defaults `123`)
115+ *
116+ * - `verbose` {Boolean} - Print out useful debugging events. (Default `false`)
117+ *
118+ * - `debug` {Boolean} - Print out a raw dump of bytes sent and received. (Default `false`)
119+ *
120+ * @constructor
121+ * @author AJ Keller (@pushtheworldllc)
122+ */
118123 function OpenBCIBoard ( options ) {
119124 options = ( typeof options !== 'function' ) && options || { } ;
120125 var opts = { } ;
@@ -206,6 +211,7 @@ function OpenBCIFactory () {
206211 this . timeOfPacketArrival = 0 ;
207212 this . writeOutDelay = k . OBCIWriteIntervalDelayMSShort ;
208213 // Strings
214+ this . portName = null ;
209215
210216 // NTP
211217 if ( this . options . sntpTimeSync ) {
@@ -254,6 +260,7 @@ function OpenBCIFactory () {
254260 alpha : this . options . simulatorInjectAlpha ,
255261 boardFailure : this . options . simulatorBoardFailure ,
256262 daisy : this . options . simulatorDaisyModuleAttached ,
263+ daisyCanBeAttached : this . options . simulatorDaisyModuleCanBeAttached ,
257264 drift : this . options . simulatorInternalClockDrift ,
258265 firmwareVersion : this . options . simulatorFirmwareVersion ,
259266 fragmentation : this . options . simulatorFragmentation ,
@@ -378,14 +385,24 @@ function OpenBCIFactory () {
378385 return this . serial . isOpen ( ) ;
379386 } ;
380387
388+
381389 /**
382390 * @description Checks if the board is currently sending samples.
383391 * @returns {boolean } - True if streaming.
384392 */
393+ OpenBCIBoard . prototype . isSimulating = function ( ) {
394+ return this . options . simulate ;
395+ } ;
396+
397+ /**
398+ * @description Checks if the board is currently sending samples.
399+ * @returns {boolean } - True if streaming.
400+ */
385401 OpenBCIBoard . prototype . isStreaming = function ( ) {
386402 return this . _streaming ;
387403 } ;
388404
405+
389406 /**
390407 * @description Sends a start streaming command to the board.
391408 * @returns {Promise } indicating if the signal was able to be sent.
@@ -1012,6 +1029,14 @@ function OpenBCIFactory () {
10121029 } ) ;
10131030 } ;
10141031
1032+ /**
1033+ * Get the board type.
1034+ * @return boardType: string
1035+ */
1036+ OpenBCIBoard . prototype . getBoardType = function ( ) {
1037+ return this . info . boardType ;
1038+ } ;
1039+
10151040 /**
10161041 * Get the core info object.
10171042 * @return {{boardType: string, sampleRate: number, firmware: string, numberOfChannels: number, missedPackets: number} }
@@ -1025,7 +1050,7 @@ function OpenBCIFactory () {
10251050 * @param boardType {String}
10261051 * `default` or `daisy`. Defaults to `default`.
10271052 */
1028- OpenBCIBoard . prototype . setInfoForBoardType = function ( boardType ) {
1053+ OpenBCIBoard . prototype . overrideInfoForBoardType = function ( boardType ) {
10291054 switch ( boardType ) {
10301055 case k . OBCIBoardDaisy :
10311056 this . info . boardType = k . OBCIBoardDaisy ;
@@ -1043,20 +1068,60 @@ function OpenBCIFactory () {
10431068
10441069 /**
10451070 * Used to set the max number of channels on the Cyton board.
1046- * @param numberOfChannels {number }
1047- * Either 8 or 16
1071+ * @param boardType {String }
1072+ * Either `default` or `daisy`
10481073 * @return {Promise }
10491074 */
1050- OpenBCIBoard . prototype . setMaxChannels = function ( numberOfChannels ) {
1051- if ( numberOfChannels === k . OBCINumberOfChannelsDefault ) {
1052- this . curParsingMode = k . OBCIParsingEOT ;
1053- return this . write ( k . OBCIChannelMaxNumber8 ) ;
1054- } else if ( numberOfChannels === k . OBCINumberOfChannelsDaisy ) {
1055- this . curParsingMode = k . OBCIParsingEOT ;
1056- return this . write ( k . OBCIChannelMaxNumber16 ) ;
1057- } else {
1058- return Promise . reject ( 'invalid number of channels' ) ;
1059- }
1075+ OpenBCIBoard . prototype . hardSetBoardType = function ( boardType ) {
1076+ if ( this . isStreaming ( ) ) return Promise . reject ( 'Must not be streaming!' ) ;
1077+ return new Promise ( ( resolve , reject ) => {
1078+ const eotFunc = ( data ) => {
1079+ switch ( data . slice ( 0 , data . length - k . OBCIParseEOT . length ) . toString ( ) ) {
1080+ case k . OBCIChannelMaxNumber8NoDaisyToRemove :
1081+ this . overrideInfoForBoardType ( k . OBCIBoardDefault ) ;
1082+ resolve ( 'no daisy to remove' ) ;
1083+ break ;
1084+ case k . OBCIChannelMaxNumber8SuccessDaisyRemoved :
1085+ this . overrideInfoForBoardType ( k . OBCIBoardDefault ) ;
1086+ resolve ( 'daisy removed' ) ;
1087+ break ;
1088+ case k . OBCIChannelMaxNumber16DaisyAlreadyAttached :
1089+ this . overrideInfoForBoardType ( k . OBCIBoardDaisy ) ;
1090+ resolve ( 'daisy already attached' ) ;
1091+ break ;
1092+ case k . OBCIChannelMaxNumber16DaisyAttached :
1093+ this . overrideInfoForBoardType ( k . OBCIBoardDaisy ) ;
1094+ resolve ( 'daisy attached' ) ;
1095+ break ;
1096+ case k . OBCIChannelMaxNumber16NoDaisyAttached :
1097+ this . overrideInfoForBoardType ( k . OBCIBoardDefault ) ;
1098+ reject ( 'unable to attach daisy' ) ;
1099+ break ;
1100+ default :
1101+ reject ( Error ( 'invalid return, board may not be configured correctly.' ) ) ;
1102+ break ;
1103+ }
1104+ } ;
1105+ if ( boardType === k . OBCIBoardDefault ) {
1106+ this . curParsingMode = k . OBCIParsingEOT ;
1107+ this . once ( k . OBCIEmitterEot , eotFunc ) ;
1108+ this . write ( k . OBCIChannelMaxNumber8 )
1109+ . catch ( ( err ) => {
1110+ this . removeListener ( k . OBCIEmitterEot , eotFunc ) ;
1111+ reject ( err ) ;
1112+ } ) ;
1113+ } else if ( boardType === k . OBCIBoardDaisy ) {
1114+ this . curParsingMode = k . OBCIParsingEOT ;
1115+ this . once ( k . OBCIEmitterEot , eotFunc ) ;
1116+ this . write ( k . OBCIChannelMaxNumber16 )
1117+ . catch ( ( err ) => {
1118+ this . removeListener ( k . OBCIEmitterEot , eotFunc ) ;
1119+ reject ( err ) ;
1120+ } ) ;
1121+ } else {
1122+ reject ( 'invalid board type' ) ;
1123+ }
1124+ } ) ;
10601125 } ;
10611126
10621127 /**
@@ -1854,9 +1919,9 @@ function OpenBCIFactory () {
18541919 */
18551920 OpenBCIBoard . prototype . _processParseBufferForReset = function ( dataBuffer ) {
18561921 if ( openBCISample . countADSPresent ( dataBuffer ) === 2 ) {
1857- this . setInfoForBoardType ( k . OBCIBoardDaisy ) ;
1922+ this . overrideInfoForBoardType ( k . OBCIBoardDaisy ) ;
18581923 } else {
1859- this . setInfoForBoardType ( k . OBCIBoardDefault ) ;
1924+ this . overrideInfoForBoardType ( k . OBCIBoardDefault ) ;
18601925 }
18611926
18621927 if ( openBCISample . findV2Firmware ( dataBuffer ) ) {
0 commit comments