1+ /**
2+ * This is an example from the readme.md
3+ * On windows you should run with PowerShell not git bash.
4+ * Install
5+ * [nodejs](https://nodejs.org/en/)
6+ *
7+ * To run:
8+ * change directory to this file `cd examples/debug`
9+ * do `npm install`
10+ * then `npm start`
11+ */
12+ var OpenBCIBoard = require ( 'openbci' ) . OpenBCIBoard ;
13+ var port_pub = 'tcp://127.0.0.1:3004' ;
14+ var zmq = require ( 'zmq-prebuilt' ) ;
15+ var socket = zmq . socket ( 'pair' ) ;
16+ var simulate = true ; // Sends synthetic data
17+ var debug = false ; // Pretty print any bytes in and out... it's amazing...
18+ var verbose = true ; // Adds verbosity to functions
19+
20+ var ourBoard = new OpenBCIBoard ( {
21+ simulate : simulate ,
22+ simulatorFirmwareVersion : 'v2' ,
23+ debug : debug ,
24+ verbose : verbose
25+ } ) ;
26+
27+ var sampleRate = 250 ; // Default to 250, ALWAYS verify with a call to `.sampleRate()` after 'ready' event!
28+ var timeSyncPossible = false ;
29+ var resyncPeriodMin = 1 ;
30+ var secondsInMinute = 60 ;
31+ var resyncPeriod = ourBoard . sampleRate ( ) * resyncPeriodMin * secondsInMinute ;
32+
33+ ourBoard . autoFindOpenBCIBoard ( ) . then ( portName => {
34+ if ( portName ) {
35+ /**
36+ * Connect to the board with portName
37+ * i.e. ourBoard.connect(portName).....
38+ */
39+ // Call to connect
40+ ourBoard . connect ( portName )
41+ . then ( ( ) => {
42+ ourBoard . on ( 'ready' , ( ) => {
43+
44+ // Get the sample rate after 'ready'
45+ sampleRate = ourBoard . sampleRate ( ) ;
46+ // 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.
47+ timeSyncPossible = ourBoard . usingVersionTwoFirmware ( ) ;
48+
49+ if ( timeSyncPossible ) {
50+ ourBoard . streamStart ( )
51+ . catch ( err => {
52+ console . log ( `stream start: ${ err } ` ) ;
53+ } ) ;
54+ } else {
55+ console . log ( 'not able to time sync' ) ;
56+ }
57+ } )
58+ } )
59+ . catch ( err => {
60+ console . log ( `connect: ${ err } ` ) ;
61+ } ) ;
62+ } else {
63+ /** Unable to auto find OpenBCI board */
64+ console . log ( 'Unable to auto find OpenBCI board' ) ;
65+ }
66+ } ) ;
67+
68+ var sampleFunc = sample => {
69+ if ( sample . _count % resyncPeriod === 0 ) {
70+ ourBoard . syncClocksFull ( )
71+ . then ( syncObj => {
72+ // Sync was successful
73+ if ( syncObj . valid ) {
74+ // Log the object to check it out!
75+ console . log ( `timeOffset` , syncObj . timeOffsetMaster ) ;
76+ } else {
77+ // Retry it
78+ console . log ( `Was not able to sync... retry!` ) ;
79+ }
80+ } ) ;
81+ }
82+
83+ if ( sample . timeStamp ) { // true after the first successful sync
84+ if ( sample . timeStamp < 10 * 60 * 60 * 1000 ) { // Less than 10 hours
85+ console . log ( `Bad time sync ${ sample . timeStamp } ` ) ;
86+ } else {
87+ sendToPython ( {
88+ action : 'process' ,
89+ command : 'sample' ,
90+ message : sample
91+ } ) ;
92+ }
93+ }
94+ } ;
95+
96+ // Subscribe to your functions
97+ ourBoard . on ( 'sample' , sampleFunc ) ;
98+
99+ // ZMQ fun
100+
101+ socket . bind ( port_pub , function ( err ) {
102+ if ( err ) throw err ;
103+ console . log ( `bound to ${ port_pub } ` ) ;
104+ } ) ;
105+
106+ /**
107+ * Used to send a message to the Python process.
108+ * @param {Object } interProcessObject The standard inter-process object.
109+ * @return {None }
110+ */
111+ var sendToPython = ( interProcessObject , verbose ) => {
112+ if ( verbose ) {
113+ console . log ( `<- out ${ JSON . stringify ( interProcessObject ) } ` ) ;
114+ }
115+ if ( socket ) {
116+ socket . send ( JSON . stringify ( interProcessObject ) ) ;
117+ }
118+ } ;
119+
120+ var receiveFromPython = ( raw_data ) => {
121+ try {
122+ let body = JSON . parse ( raw_data ) ; // five because `resp `
123+ processInterfaceObject ( body ) ;
124+ } catch ( err ) {
125+ console . log ( 'in -> ' + 'bad json' ) ;
126+ }
127+ } ;
128+
129+ socket . on ( 'message' , receiveFromPython ) ;
130+
131+ var sendStatus = ( ) => {
132+ sendToPython ( { 'action' : 'active' , 'message' : 'ready' , 'command' : 'status' } , true ) ;
133+ } ;
134+
135+ sendStatus ( ) ;
136+
137+ /**
138+ * Process an incoming message
139+ * @param {String } body A stringify JSON object that shall be parsed.
140+ * @return {None }
141+ */
142+ var processInterfaceObject = ( body ) => {
143+ switch ( body . command ) {
144+ case 'status' :
145+ processStatus ( body ) ;
146+ break ;
147+ default :
148+ unrecognizedCommand ( body ) ;
149+ break ;
150+ }
151+ } ;
152+
153+ /**
154+ * Used to process a status related command from TCP IPC.
155+ * @param {Object } body
156+ * @return {None }
157+ */
158+ var processStatus = ( body ) => {
159+ switch ( body . action ) {
160+ case 'started' :
161+ console . log ( `python started @ ${ body . message } ms` ) ;
162+ break ;
163+ case 'alive' :
164+ console . log ( `python duplex communication test completed @ ${ body . message } ms` ) ;
165+ break ;
166+ default :
167+ unrecognizedCommand ( body ) ;
168+ break ;
169+ }
170+ } ;
171+
172+ function unrecognizedCommand ( body ) {
173+ console . log ( `unrecognizedCommand ${ body } ` ) ;
174+ }
175+
176+ function exitHandler ( options , err ) {
177+ if ( options . cleanup ) {
178+ if ( verbose ) console . log ( 'clean' ) ;
179+ /** Do additional clean up here */
180+ }
181+ if ( err ) console . log ( err . stack ) ;
182+ if ( options . exit ) {
183+ if ( verbose ) console . log ( 'exit' ) ;
184+ ourBoard . disconnect ( ) . catch ( console . log ) ;
185+ }
186+ }
187+
188+ if ( process . platform === "win32" ) {
189+ const rl = require ( "readline" ) . createInterface ( {
190+ input : process . stdin ,
191+ output : process . stdout
192+ } ) ;
193+
194+ rl . on ( "SIGINT" , function ( ) {
195+ process . emit ( "SIGINT" ) ;
196+ } ) ;
197+ }
198+
199+ // do something when app is closing
200+ process . on ( 'exit' , exitHandler . bind ( null , {
201+ cleanup : true
202+ } ) ) ;
203+
204+ // catches ctrl+c event
205+ process . on ( 'SIGINT' , exitHandler . bind ( null , {
206+ exit : true
207+ } ) ) ;
208+
209+ // catches uncaught exceptions
210+ process . on ( 'uncaughtException' , exitHandler . bind ( null , {
211+ exit : true
212+ } ) ) ;
0 commit comments