├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── ROADMAP.md ├── examples ├── browser │ ├── index.html │ └── index.js └── node │ └── index.js ├── images └── node_icon2.png ├── package.json ├── src ├── constants.js ├── debug.js ├── index.js └── utilities.js ├── test ├── bluebirdChecks.js ├── openBCIConstants-test.js ├── openBCIUtilities-test.js └── timingEventsAsPromises.js └── webpack.config.js /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["semistandard"], 3 | "plugins": [ 4 | "chai-friendly" 5 | ], 6 | "rules": { 7 | "no-unused-expressions": 0, 8 | "chai-friendly/no-unused-expressions": 2 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # node-waf configuration 27 | .lock-wscript 28 | 29 | # Compiled binary addons (http://nodejs.org/api/addons.html) 30 | build/Release 31 | 32 | # Dependency directories 33 | node_modules 34 | jspm_packages 35 | 36 | # Optional npm cache directory 37 | .npm 38 | 39 | # Optional eslint cache 40 | .eslintcache 41 | 42 | # Optional REPL history 43 | .node_repl_history 44 | 45 | # Output of 'npm pack' 46 | *.tgz 47 | 48 | # Yarn Integrity file 49 | .yarn-integrity 50 | 51 | # Webstorm 52 | .idea 53 | .idea/*.xml 54 | .DS_Store 55 | 56 | dist 57 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | test_mocks/ 3 | 4 | # MIRRORED FROM .gitignore PLEASE MAINTAIN 5 | logs 6 | *.log 7 | pids 8 | *.pid 9 | *.seed 10 | lib-cov 11 | coverage 12 | .grunt 13 | .lock-wscript 14 | build/Release 15 | node_modules 16 | .idea 17 | .DS_Store 18 | public 19 | myOutput.txt 20 | *.tgz 21 | openBCISerialFormat 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.8.4" 4 | - "6" 5 | - "7" 6 | - "8" 7 | - "9" 8 | install: 9 | - npm install --all 10 | script: 11 | - npm run test 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # v1.0.0 2 | 3 | ### Breaking Changes 4 | 5 | - Name of package is now @openbci/cyton 6 | 7 | # v0.3.6 8 | 9 | ### Bug Fixes 10 | 11 | - Fix bug where parseGanglion could result in a concat of non-buffer types 12 | 13 | # v0.3.5 14 | 15 | ### Bug Fixes 16 | 17 | - Fix bug where `getFirmware` failed for patch or minor versions over 9 (aka double digits) 18 | 19 | # v0.3.4 20 | 21 | ### Bug Fixes 22 | 23 | - Protect and ensure buffer returned for raw data packets 24 | 25 | # v0.3.3 26 | 27 | ### Enhancements 28 | 29 | - Add raw of version to `getFirmware` 30 | - Bump mathjs to 4.0.0 to resolve insecurity 31 | 32 | # v0.3.1 33 | 34 | ### Enhancements 35 | 36 | - Removed `lodash` from dependencies to reduce bundle size (thanks @alexcastillo!!) 37 | 38 | # v0.3.0 39 | 40 | You can now use this module in the browser!! Huge should out to @alexcastillo for help with making with refactoring the project! 41 | 42 | ### Breaking Changes 43 | 44 | - Removed simulator file back into cyton repo 45 | - Removed `safe-buffer` in place of `buffer` 46 | - Removed support for node version 5 and below 47 | - `Utilities` changed to to `utilities` 48 | - `Constants` is now `constants` 49 | - Inidividual functions can now be importated from the utilities module. 50 | 51 | # v0.2.7 52 | 53 | ### Bug Fixes 54 | 55 | - No `stopByte` property for daisy samples. Added tests. 56 | 57 | # v0.2.6 58 | 59 | ### Bug Fixes 60 | 61 | - Accel data with counts did not work for cyton with daisy over wifi. 62 | 63 | # v0.2.5 64 | 65 | ### Bug Fixes 66 | 67 | - Had incorrect ganglion accel multiplication factor of 32mg per count but was really 16mg per count 68 | - `newSample` and `newSampleNoScale` in utility file did not have `valid` is `true` property. 69 | 70 | # v0.2.4 71 | 72 | ### New Features 73 | 74 | - Add new constants for emitter 75 | 76 | ### Bug Fixes 77 | 78 | - Fix bug where ganglion sample channel data when scale was false produced array of 8 values instead of 4 79 | 80 | # v0.2.3 81 | 82 | ### New Features 83 | 84 | - Add function for parsing an impedance object `.parsePacketImpedance()` 85 | 86 | # v0.2.2 87 | 88 | ### Bug Fixes 89 | 90 | - Fix wrap around bug in extractRawBLEDataPackets 91 | 92 | # v0.2.1 93 | 94 | ### Bug Fixes 95 | 96 | - Accel data with counts did not work for cyton with daisy. Also fixed up some test errors with the effected functions. 97 | 98 | ### New Features 99 | 100 | - Add features for `openbci-ganglion` 101 | 102 | # v0.2.0 103 | 104 | ### New Feature 105 | 106 | - With scale option false, `.parsePacketStandardAccel()` `.parsePacketTimeSyncedAccel()` will now return array called will now return `accelDataCounts` property with un-scaled data. 107 | 108 | # v0.1.5 109 | 110 | ### Bug Fixes 111 | 112 | - Was missing errors in constants used by ganglion and other ble projects. 113 | - Fixed getChannelData functions to support 2 channel cytons 114 | 115 | # v0.1.4 116 | 117 | ### Bug Fixes 118 | 119 | - E-patch on new function added 0.1.3 120 | 121 | # v0.1.3 122 | 123 | ### New Features 124 | 125 | - A bunch of functions to support synchronization of channel settings with cyton. Will be used by both the Wifi and the Cyton node modules. 126 | 127 | # v0.1.2 128 | 129 | ### Bug Fixes 130 | 131 | - Send counts did not work for daisy. 132 | - Sample output was inconsistent 133 | - Fixed `timeStamp` to `timestamp` this was pr #147 (thanks @alexdevmotion) 134 | 135 | # v0.1.1 136 | 137 | ### Bug Fixes 138 | 139 | - Send counts did not work for daisy. 140 | 141 | # v0.1.0 142 | 143 | ### New Functions 144 | 145 | - Add function `getFirmware(dataBuffer)` to utilities 146 | 147 | ### Breaking Changes 148 | 149 | - Removed function called `findV2Firmware()` because it's useless with v3.0.0 firmware 150 | 151 | # v0.0.10 152 | 153 | ### New Function 154 | 155 | - Add `boardTypeForNumberOfChannels()` to Constants 156 | 157 | # v0.0.9 158 | 159 | ### New Features 160 | 161 | - Add impedance calculation functions from cyton 162 | - The simulator from OpenBCI_NodeJS has been ripped out and place into this library! Woo. 163 | 164 | # v0.0.8 165 | 166 | ### New Features 167 | 168 | - Sample object now has property `valid` of type `boolean`, `false` when error parseing packet, `true` otherwise. On `false` there will be another property called `error` of type `string` which contains an error message. 169 | 170 | # v0.0.7 171 | 172 | ### Continuous Integration 173 | 174 | - Add `npm run test-lint` to add linting to travis.yml 175 | 176 | ### Bug Fixes 177 | 178 | - Last sample number was confusing to use with `transformRawDataPacketsToSample` 179 | 180 | ### New Features 181 | 182 | - In openBCIUtilities.js add function `transformRawDataPacketToSample` to parse a single raw data packet 183 | - In openBCIConstants.js add function `rawDataToSampleObjectDefault(numChannels)` which should be used by drivers to create the object that is passed through each call to `transformRawDataPacketsToSample` 184 | 185 | # v0.0.6 186 | 187 | ### Bug Fixes 188 | 189 | - Could not use 'daisy' with sample rate setter. 190 | 191 | ### New Features 192 | 193 | - Add function in utilities for making daisy packets. 194 | - Add code to `getChannelDataArray` for ganglion and daisy data being routed over wifi 195 | - Create idea of protocols i.e. `BLE`, `Wifi`, and `Serial` 196 | 197 | ### Breaking changes 198 | 199 | - `getChannelDataArray` now takes object as only arg. 200 | 201 | # v0.0.5 202 | 203 | ### Bug Fixes 204 | 205 | - When not scaling outputs `channelDataCounts` instead of `channelData` 206 | 207 | # v0.0.4 208 | 209 | ### Bug Fixes 210 | 211 | - Fix bug where samples were not properly being extracted 212 | 213 | # v0.0.2 214 | 215 | ### Breaking Changes 216 | 217 | - Renamed `Sample` to `Utilities` in `index.js` 218 | - Renamed openBCIUtilities.js to openBCIUtilities.js 219 | - Renamed openBCIUtilities-test.js to openBCIUtilities-test.js 220 | 221 | ### New Features 222 | 223 | - Added a function in the sample module that parses a raw buffer of OpenBCI data, extracts raw data packets and returns the buffer with just the raw data packets removed. Allowing the user to process other data that is not a raw data. 224 | 225 | # v0.0.1 226 | 227 | Initial release 228 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # OpenBCI JavaScript Utilities Library Code of Conduct 2 | 3 | ## Purpose 4 | 5 | It is our hope that any one is able to contribute to OpenBCI JavaScript Utilities Library regardless of their background. Thus, we hope to provide a safe, welcoming, and warmly geeky environment for everybody, regardless of gender, sexual orientation, ability, ethnicity, socioeconomic status, and religion (or lack thereof). 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment 10 | include: 11 | 12 | * Using welcoming and inclusive language 13 | * Being respectful of differing viewpoints and experiences 14 | * Gracefully accepting constructive criticism 15 | * Focusing on what is best for the community 16 | * Showing empathy towards other community members 17 | 18 | Examples of unacceptable behavior by participants include: 19 | 20 | * The use of sexualized language or imagery and unwelcome sexual attention or 21 | advances 22 | * Trolling, insulting/derogatory comments, and personal or political attacks 23 | * Public or private harassment 24 | * Publishing others' private information, such as a physical or electronic 25 | address, without explicit permission 26 | * Other conduct which could reasonably be considered inappropriate in a 27 | professional setting 28 | 29 | ## Our Responsibilities 30 | 31 | Project maintainers are responsible for clarifying the standards of acceptable 32 | behavior and are expected to take appropriate and fair corrective action in 33 | response to any instances of unacceptable behavior. 34 | 35 | Project maintainers have the right and responsibility to remove, edit, or 36 | reject comments, commits, code, wiki edits, issues, and other contributions 37 | that are not aligned to this Code of Conduct, or to ban temporarily or 38 | permanently any contributor for other behaviors that they deem inappropriate, 39 | threatening, offensive, or harmful. 40 | 41 | ## Scope 42 | 43 | This Code of Conduct applies both within project spaces and in public spaces 44 | when an individual is representing the project or its community. Examples of 45 | representing a project or community include using an official project e-mail 46 | address, posting via an official social media account, or acting as an appointed 47 | representative at an online or offline event. Representation of a project may be 48 | further defined and clarified by project maintainers. 49 | 50 | ## Enforcement 51 | 52 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 53 | reported by contacting the project team at [info@pushtheworld.us](mailto:info@pushtheworld.us). All 54 | complaints will be reviewed and investigated and will result in a response that 55 | is deemed necessary and appropriate to the circumstances. The project team is 56 | obligated to maintain confidentiality with regard to the reporter of an incident. 57 | Further details of specific enforcement policies may be posted separately. 58 | 59 | Project maintainers who do not follow or enforce the Code of Conduct in good 60 | faith may face temporary or permanent repercussions as determined by other 61 | members of the project's leadership. 62 | 63 | ## Attribution 64 | 65 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 66 | available at [http://contributor-covenant.org/version/1/4][version] 67 | 68 | [homepage]: http://contributor-covenant.org 69 | [version]: http://contributor-covenant.org/version/1/4/ 70 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | :tada::clinking_glasses: First off, thanks for taking the time to contribute! :tada::clinking_glasses: 4 | 5 | Contributions are always welcome, no matter how small. 6 | 7 | The following is a small set of guidelines for how to contribute to the project 8 | 9 | ## Where to start 10 | 11 | ### Code of Conduct 12 | This project adheres to the Contributor Covenant [Code of Conduct](CODE_OF_CONDUCT.md). 13 | By participating you are expected to adhere to these expectations. Please report unacceptable behaviour to [info@pushtheworld.us](mailto:info@pushtheworld.us) 14 | 15 | ### Contributing on Github 16 | 17 | If you're new to Git and want to learn how to fork this repo, make your own additions, and include those additions in the master version of this project, check out this [great tutorial](http://blog.davidecoppola.com/2016/11/howto-contribute-to-open-source-project-on-github/). 18 | 19 | ### Community 20 | 21 | This project is maintained by the [OpenBCI](www.openbci.com) and [NeuroTechX](www.neurotechx.com) community. Join the NeuroTechX Slack to check out our #devices channel, where discussions about OpenBCI takes place. 22 | 23 | ## How can I contribute? 24 | 25 | This is currently a small, humble project so our contribution process is rather casual. Take a look at our [GitHub Projects board to see](https://github.com/NeuroTechX/eeg-101/projects) to see all the features we are currently working on. If there's a feature you'd be interested in building, go ahead! Let us know on the #interactive-tutorial channel on [the NeuroTechX Slack](http://neurotechx.herokuapp.com/) and we'll support you as much as we can. When you're finished submit a pull request to the master branch referencing the specific issue you addressed. 26 | 27 | If you find a bug, or have a suggestion on how to improve the project, just fill out a [Github issue](../../issues) 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 OpenBCI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **THIS REPOSITORY HAS BEEN DEPRECATED AND IS NO LONGER IN ACTIVE DEVELOPMENT.** 2 | 3 | # OpenBCI JavaScript Utilities Library 4 | 5 |

6 | banner 7 |

8 |

9 | Provide a stable javascript library for OpenBCI 10 |

11 | 12 | [![Build Status](https://travis-ci.org/OpenBCI/OpenBCI_JavaScript_Utilities.svg?branch=master)](https://travis-ci.org/OpenBCI/OpenBCI_JavaScript_Utilities) 13 | [![codecov](https://codecov.io/gh/OpenBCI/OpenBCI_Javascript_Utilities/branch/master/graph/badge.svg)](https://codecov.io/gh/OpenBCI/OpenBCI_Javascript_Utilities) 14 | [![Dependency Status](https://david-dm.org/OpenBCI/OpenBCI_Javascript_Utilities.svg)](https://david-dm.org/OpenBCI/OpenBCI_Javascript_Utilities) 15 | [![npm](https://img.shields.io/npm/dm/openbci-utilities.svg?maxAge=2592000)](http://npmjs.com/package/openbci-utilities) 16 | [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat-square)](https://github.com/Flet/semistandard) 17 | 18 | ## Welcome! 19 | 20 | First and foremost, Welcome! :tada: Willkommen! :confetti_ball: Bienvenue! :balloon::balloon::balloon: 21 | 22 | Thank you for visiting the OpenBCI JavaScript Utilities Library repository. 23 | 24 | This document (the README file) is a hub to give you some information about the project. Jump straight to one of the sections below, or just scroll down to find out more. 25 | 26 | - [What are we doing? (And why?)](#what-are-we-doing) 27 | - [Who are we?](#who-are-we) 28 | - [What do we need?](#what-do-we-need) 29 | - [How can you get involved?](#get-involved) 30 | - [Get in touch](#contact-us) 31 | - [Find out more](#find-out-more) 32 | - [Understand the jargon](#glossary) 33 | 34 | ## What are we doing? 35 | 36 | ### The problem 37 | 38 | - The first javascript libraries for OpenBCI was the [NodeJS Cyton SDK][link_nodejs], then the [NodeJS Ganglion SDK][link_nodejs_ganglion], then the [NodeJS for WiFi][link_nodejs_wifi], each with their own interfaces, serial, bluetooth, and wifi respectively. 39 | - The ganglion's raw data is incredibly complex and must be decompressed and carefully parsed, in less words, it takes time to learn to parse this stream 40 | - People want to use the [Ganglion][link_shop_ganglion] in the web browser 41 | 42 | So, if even developers are interested in working with [OpenBCI][link_shop_openbci] devices with javascript, they have a huge burden to overcome before they can parse the data. 43 | 44 | ### The solution 45 | 46 | The OpenBCI JavaScript Utilities Library will: 47 | 48 | - Provide a nice cozy home to all the horror of parsing raw binary byte streams 49 | - Use automated testing extensively and don't let untested code be released! 50 | - Work in the browser and NodeJS! 51 | - Be able to parse ganglion and cyton data. 52 | - Store a constants file so every module agrees on names of keys and such 53 | 54 | Using a single unified JavaScript library solves the challenges of parsing raw brainwave data. Our main goal is to **_provide a stable javascript library for OpenBCI_** 55 | 56 | ## Who are we? 57 | 58 | The main code writer of the OpenBCI JavaScript Utilities Library is [AJ Keller][link_aj_keller]. This code all started in the OpenBCI NodeJS SDK for Cyton. Many people contributed, if not directly, but by advice or instructions drawn on a coffee table to calculate impedance. A lot of people who use this library never have any idea about it! Every user of the OpenBCI GUI is heavily dependent on this code base for all data acquisition from the Cyton, Ganglion and WiFi shield! 59 | 60 | ## What do we need? 61 | 62 | **You**! In whatever way you can help. 63 | 64 | We need expertise in programming, user experience, software sustainability, documentation and technical writing and project management. 65 | 66 | We'd love your feedback along the way. 67 | 68 | Our primary goal is to provide a stable javascript library for OpenBCI, and we're excited to support the professional development of any and all of our contributors. If you're looking to learn to code, try out working collaboratively, or translate you skills to the digital domain, we're here to help. 69 | 70 | ## Get involved 71 | 72 | If you think you can help in any of the areas listed above (and we bet you can) or in any of the many areas that we haven't yet thought of (and here we're _sure_ you can) then please check out our [contributors' guidelines](CONTRIBUTING.md) and our [roadmap](ROADMAP.md). 73 | 74 | Please note that it's very important to us that we maintain a positive and supportive environment for everyone who wants to participate. When you join us we ask that you follow our [code of conduct](CODE_OF_CONDUCT.md) in all interactions both on and offline. 75 | 76 | ## Contact us 77 | 78 | If you want to report a problem or suggest an enhancement we'd love for you to [open an issue](../../issues) at this github repository because then we can get right on it. But you can also contact [AJ][link_aj_keller] by email (pushtheworldllc AT gmail DOT com) or on [twitter](https://twitter.com/aj-ptw). 79 | 80 | ## Find out more 81 | 82 | You might be interested in: 83 | 84 | - What is [OpenBCI][link_openbci]? 85 | 86 | And of course, you'll want to know our: 87 | 88 | - [Contributors' guidelines](CONTRIBUTING.md) 89 | - [Roadmap](ROADMAP.md) 90 | 91 | ## Thank you 92 | 93 | Thank you so much (Danke schön! Merci beaucoup!) for visiting the project and we do hope that you'll join us on this amazing journey to make programming with OpenBCI fun and easy. 94 | 95 | # Documentation 96 | 97 | ### Table of Contents: 98 | 99 | --- 100 | 101 | 1. [Installation](#install) 102 | 2. [Usage](#usage) 103 | 3. [Developing](#developing) 104 | 4. [Testing](#developing-testing) 105 | 5. [Contribute](#contribute) 106 | 6. [License](#license) 107 | 108 | ## Installation: 109 | 110 | ``` 111 | npm install @openbci/utilities 112 | ``` 113 | 114 | ## Usage: 115 | 116 | ### In NodeJS 117 | 118 | ```node 119 | const { constants, debug, utilities } = require("openbci-utilities"); 120 | 121 | console.log("OpenBCIUtilities", OpenBCIUtilities); 122 | ``` 123 | 124 | ### In Web Browser 125 | 126 | **index.html** 127 | 128 | ```html 129 | 130 | 131 | 132 | 133 | 137 | 138 | OpenBCI Utilities 139 | 140 | 141 |
See data in the console
142 | 143 | 144 | 145 | 146 | ``` 147 | 148 | **index.js** 149 | 150 | ```javascript 151 | console.log(OpenBCIUtilities); 152 | ``` 153 | 154 | ## Developing: 155 | 156 | ### Running: 157 | 158 | ``` 159 | npm install 160 | ``` 161 | 162 | ### Testing: 163 | 164 | ``` 165 | npm test 166 | ``` 167 | 168 | ## Contribute: 169 | 170 | 1. Fork it! 171 | 2. Branch off of `development`: `git checkout development` 172 | 3. Create your feature branch: `git checkout -b my-new-feature` 173 | 4. Make changes 174 | 5. If adding a feature, please add test coverage. 175 | 6. Ensure tests all pass. (`npm test`) 176 | 7. Commit your changes: `git commit -m 'Add some feature'` 177 | 8. Push to the branch: `git push origin my-new-feature` 178 | 9. Submit a pull request. Make sure it is based off of the `development` branch when submitting! :D 179 | 180 | ## License: 181 | 182 | MIT 183 | 184 | [link_aj_keller]: https://github.com/aj-ptw 185 | [link_shop_wifi_shield]: https://shop.openbci.com/collections/frontpage/products/wifi-shield?variant=44534009550 186 | [link_shop_ganglion]: https://shop.openbci.com/collections/frontpage/products/pre-order-ganglion-board 187 | [link_shop_cyton]: https://shop.openbci.com/collections/frontpage/products/cyton-biosensing-board-8-channel 188 | [link_shop_cyton_daisy]: https://shop.openbci.com/collections/frontpage/products/cyton-daisy-biosensing-boards-16-channel 189 | [link_nodejs]: https://github.com/OpenBCI/OpenBCI_NodeJS 190 | [link_nodejs_cyton]: https://github.com/OpenBCI/OpenBCI_NodeJS_Cyton 191 | [link_nodejs_ganglion]: https://github.com/OpenBCI/OpenBCI_NodeJS_Ganglion 192 | [link_nodejs_wifi]: https://github.com/OpenBCI/OpenBCI_NodeJS_Wifi 193 | [link_ptw]: https://www.pushtheworldllc.com 194 | [link_openbci]: http://www.openbci.com 195 | [link_mozwow]: http://mozillascience.github.io/working-open-workshop/index.html 196 | [link_wifi_get_streaming]: examples/getStreaming/getStreaming.js 197 | [link_openleaderscohort]: https://medium.com/@MozOpenLeaders 198 | [link_mozsci]: https://science.mozilla.org 199 | -------------------------------------------------------------------------------- /ROADMAP.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | ## OpenBCI JavaScript Utilities Library 4 | 5 | Provide a stable javascript library for OpenBCI 6 | 7 | ## Short term - what we're working on now 8 | 9 | - Unit tests! 10 | - Documentation for public functions 11 | 12 | ## Medium term 13 | 14 | - Examples 15 | -------------------------------------------------------------------------------- /examples/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | OpenBCI Utilities 8 | 9 | 10 |
See data in the console
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/browser/index.js: -------------------------------------------------------------------------------- 1 | console.log(OpenBCIUtilities); // eslint-disable-line 2 | -------------------------------------------------------------------------------- /examples/node/index.js: -------------------------------------------------------------------------------- 1 | const OpenBCIUtilities = require("../.."); 2 | const { constansts, debug, utilities } = require("../.."); 3 | 4 | const { extractRawDataPackets } = require("../../dist/utilities"); 5 | const OpenBCICnstants = require("../../dist/constants"); 6 | const debug2 = require("../../dist/debug"); 7 | 8 | console.log("OpenBCIUtilities", OpenBCIUtilities); 9 | console.log( 10 | "constansts, debug, utilities", 11 | constansts, 12 | debug, 13 | utilities 14 | ); 15 | console.log("extractRawDataPackets", extractRawDataPackets); 16 | console.log("OpenBCICnstants", OpenBCICnstants); 17 | console.log("debug2", debug2); 18 | -------------------------------------------------------------------------------- /images/node_icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openbci-archive/OpenBCI_JavaScript_Utilities/33168c60b530d1549b201150d6ce8bf69ac4dbb1/images/node_icon2.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@openbci/utilities", 3 | "version": "1.0.0", 4 | "description": "The official utility package of Node.js SDK for the OpenBCI Biosensor Boards.", 5 | "main": "dist/openbci-utilities.js", 6 | "module": "src/index.js", 7 | "scripts": { 8 | "build": "webpack", 9 | "start": "webpack-dev-server", 10 | "prepublish": "npm run build", 11 | "test": "npm run test-lint && npm run test-cov", 12 | "test-lint": "semistandard | snazzy", 13 | "test-cov": "istanbul cover ./node_modules/mocha/bin/_mocha -- -R spec && codecov" 14 | }, 15 | "files": [ 16 | "dist" 17 | ], 18 | "keywords": [ 19 | "openbci", 20 | "openbci-node", 21 | "ganglion", 22 | "wifi", 23 | "cyton", 24 | "utilities" 25 | ], 26 | "author": "AJ Keller (www.openbci.com)", 27 | "license": "MIT", 28 | "dependencies": { 29 | "buffer": "^5.0.8", 30 | "buffer-equal": "^1.0.0", 31 | "clone": "^2.0.0", 32 | "gaussian": "^1.0.0", 33 | "mathjs": "^4.0.0", 34 | "performance-now": "^2.1.0", 35 | "streamsearch": "^0.1.2" 36 | }, 37 | "directories": { 38 | "test": "test" 39 | }, 40 | "devDependencies": { 41 | "babel-core": "^6.26.0", 42 | "babel-loader": "^7.1.2", 43 | "bluebird": "3.4.6", 44 | "chai": "^4.0.0", 45 | "chai-as-promised": "^7.1.1", 46 | "codecov": "^2.2.0", 47 | "dirty-chai": "^2.0.1", 48 | "eslint-plugin-chai-friendly": "^0.4.0", 49 | "istanbul": "^0.4.4", 50 | "lodash": "^4.16.6", 51 | "mocha": "^3.0.2", 52 | "sandboxed-module": "^2.0.3", 53 | "semistandard": "^11.0.0", 54 | "sinon": "^2.3.7", 55 | "sinon-chai": "^2.8.0", 56 | "snazzy": "^7.0.0", 57 | "webpack": "^3.8.1", 58 | "webpack-dev-server": "^2.9.3" 59 | }, 60 | "repository": { 61 | "type": "git", 62 | "url": "git+https://github.com/openbci/openbci_nodejs_utilities.git" 63 | }, 64 | "bugs": { 65 | "url": "https://github.com/openbci/openbci_nodejs_utilities/issues" 66 | }, 67 | "homepage": "https://github.com/openbci/openbci_nodejs_utilities#readme", 68 | "engines": { 69 | "node": ">=6" 70 | }, 71 | "semistandard": { 72 | "globals": [ 73 | "describe", 74 | "xdescribe", 75 | "context", 76 | "before", 77 | "beforeEach", 78 | "after", 79 | "afterEach", 80 | "it", 81 | "expect", 82 | "should" 83 | ], 84 | "ignore": [ 85 | "examples/browser", 86 | "examples/node" 87 | ] 88 | }, 89 | "publishConfig": { 90 | "access": "public" 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by ajk on 12/16/15. 3 | * Purpose: This file folds all the constants for the 4 | * OpenBCI Board 5 | */ 6 | 'use strict'; 7 | import { Buffer } from 'buffer/'; 8 | 9 | /** Turning channels off */ 10 | const obciChannelOff1 = '1'; 11 | const obciChannelOff2 = '2'; 12 | const obciChannelOff3 = '3'; 13 | const obciChannelOff4 = '4'; 14 | const obciChannelOff5 = '5'; 15 | const obciChannelOff6 = '6'; 16 | const obciChannelOff7 = '7'; 17 | const obciChannelOff8 = '8'; 18 | const obciChannelOff9 = 'q'; 19 | const obciChannelOff10 = 'w'; 20 | const obciChannelOff11 = 'e'; 21 | const obciChannelOff12 = 'r'; 22 | const obciChannelOff13 = 't'; 23 | const obciChannelOff14 = 'y'; 24 | const obciChannelOff15 = 'u'; 25 | const obciChannelOff16 = 'i'; 26 | 27 | /** Turn channels on */ 28 | const obciChannelOn1 = '!'; 29 | const obciChannelOn2 = '@'; 30 | const obciChannelOn3 = '#'; 31 | const obciChannelOn4 = '$'; 32 | const obciChannelOn5 = '%'; 33 | const obciChannelOn6 = '^'; 34 | const obciChannelOn7 = '&'; 35 | const obciChannelOn8 = '*'; 36 | const obciChannelOn9 = 'Q'; 37 | const obciChannelOn10 = 'W'; 38 | const obciChannelOn11 = 'E'; 39 | const obciChannelOn12 = 'R'; 40 | const obciChannelOn13 = 'T'; 41 | const obciChannelOn14 = 'Y'; 42 | const obciChannelOn15 = 'U'; 43 | const obciChannelOn16 = 'I'; 44 | 45 | /** Test Signal Control Commands 46 | * 1x - Voltage will be 1 * (VREFP - VREFN) / 2.4 mV 47 | * 2x - Voltage will be 2 * (VREFP - VREFN) / 2.4 mV 48 | */ 49 | const obciTestSignalConnectToDC = 'p'; 50 | const obciTestSignalConnectToGround = '0'; 51 | const obciTestSignalConnectToPulse1xFast = '='; 52 | const obciTestSignalConnectToPulse1xSlow = '-'; 53 | const obciTestSignalConnectToPulse2xFast = ']'; 54 | const obciTestSignalConnectToPulse2xSlow = '['; 55 | 56 | /** Channel Setting Commands */ 57 | const obciChannelCmdADCNormal = '0'; 58 | const obciChannelCmdADCShorted = '1'; 59 | const obciChannelCmdADCBiasDRP = '6'; 60 | const obciChannelCmdADCBiasDRN = '7'; 61 | const obciChannelCmdADCBiasMethod = '2'; 62 | const obciChannelCmdADCMVDD = '3'; 63 | const obciChannelCmdADCTemp = '4'; 64 | const obciChannelCmdADCTestSig = '5'; 65 | const obciChannelCmdBiasInclude = '1'; 66 | const obciChannelCmdBiasRemove = '0'; 67 | const obciChannelCmdChannel1 = '1'; 68 | const obciChannelCmdChannel2 = '2'; 69 | const obciChannelCmdChannel3 = '3'; 70 | const obciChannelCmdChannel4 = '4'; 71 | const obciChannelCmdChannel5 = '5'; 72 | const obciChannelCmdChannel6 = '6'; 73 | const obciChannelCmdChannel7 = '7'; 74 | const obciChannelCmdChannel8 = '8'; 75 | const obciChannelCmdChannel9 = 'Q'; 76 | const obciChannelCmdChannel10 = 'W'; 77 | const obciChannelCmdChannel11 = 'E'; 78 | const obciChannelCmdChannel12 = 'R'; 79 | const obciChannelCmdChannel13 = 'T'; 80 | const obciChannelCmdChannel14 = 'Y'; 81 | const obciChannelCmdChannel15 = 'U'; 82 | const obciChannelCmdChannel16 = 'I'; 83 | const obciChannelCmdGain1 = '0'; 84 | const obciChannelCmdGain2 = '1'; 85 | const obciChannelCmdGain4 = '2'; 86 | const obciChannelCmdGain6 = '3'; 87 | const obciChannelCmdGain8 = '4'; 88 | const obciChannelCmdGain12 = '5'; 89 | const obciChannelCmdGain24 = '6'; 90 | const obciChannelCmdLatch = 'X'; 91 | const obciChannelCmdPowerOff = '1'; 92 | const obciChannelCmdPowerOn = '0'; 93 | const obciChannelCmdSet = 'x'; 94 | const obciChannelCmdSRB1Connect = '1'; 95 | const obciChannelCmdSRB1Diconnect = '0'; 96 | const obciChannelCmdSRB2Connect = '1'; 97 | const obciChannelCmdSRB2Diconnect = '0'; 98 | 99 | /** Channel Setting Helper Strings */ 100 | const obciStringADCNormal = 'normal'; 101 | const obciStringADCShorted = 'shorted'; 102 | const obciStringADCBiasMethod = 'biasMethod'; 103 | const obciStringADCMvdd = 'mvdd'; 104 | const obciStringADCTemp = 'temp'; 105 | const obciStringADCTestSig = 'testSig'; 106 | const obciStringADCBiasDrp = 'biasDrp'; 107 | const obciStringADCBiasDrn = 'biasDrn'; 108 | 109 | /** Default Channel Settings */ 110 | const obciChannelDefaultAllSet = 'd'; 111 | const obciChannelDefaultAllGet = 'D'; 112 | 113 | /** LeadOff Impedance Commands */ 114 | const obciChannelImpedanceLatch = 'Z'; 115 | const obciChannelImpedanceSet = 'z'; 116 | const obciChannelImpedanceTestSignalApplied = '1'; 117 | const obciChannelImpedanceTestSignalAppliedNot = '0'; 118 | 119 | /** SD card Commands */ 120 | const obciSDLogForHour1 = 'G'; 121 | const obciSDLogForHour2 = 'H'; 122 | const obciSDLogForHour4 = 'J'; 123 | const obciSDLogForHour12 = 'K'; 124 | const obciSDLogForHour24 = 'L'; 125 | const obciSDLogForMin5 = 'A'; 126 | const obciSDLogForMin15 = 'S'; 127 | const obciSDLogForMin30 = 'F'; 128 | const obciSDLogForSec14 = 'a'; 129 | const obciSDLogStop = 'j'; 130 | 131 | /** SD Card String Commands */ 132 | const obciStringSDHour1 = '1hour'; 133 | const obciStringSDHour2 = '2hour'; 134 | const obciStringSDHour4 = '4hour'; 135 | const obciStringSDHour12 = '12hour'; 136 | const obciStringSDHour24 = '24hour'; 137 | const obciStringSDMin5 = '5min'; 138 | const obciStringSDMin15 = '15min'; 139 | const obciStringSDMin30 = '30min'; 140 | const obciStringSDSec14 = '14sec'; 141 | 142 | /** Stream Data Commands */ 143 | const obciStreamStart = 'b'; 144 | const obciStreamStop = 's'; 145 | 146 | /** Miscellaneous */ 147 | const obciMiscQueryRegisterSettings = '?'; 148 | const obciMiscQueryRegisterSettingsChannel1 = 'CH1SET'; 149 | const obciMiscQueryRegisterSettingsChannel2 = 'CH2SET'; 150 | const obciMiscQueryRegisterSettingsChannel3 = 'CH3SET'; 151 | const obciMiscQueryRegisterSettingsChannel4 = 'CH4SET'; 152 | const obciMiscQueryRegisterSettingsChannel5 = 'CH5SET'; 153 | const obciMiscQueryRegisterSettingsChannel6 = 'CH6SET'; 154 | const obciMiscQueryRegisterSettingsChannel7 = 'CH7SET'; 155 | const obciMiscQueryRegisterSettingsChannel8 = 'CH8SET'; 156 | const obciMiscSoftReset = 'v'; 157 | 158 | /** 16 Channel Commands */ 159 | const obciChannelMaxNumber8 = 'c'; 160 | const obciChannelMaxNumber16 = 'C'; 161 | const obciChannelMaxNumber8NoDaisyToRemove = ''; 162 | const obciChannelMaxNumber8SuccessDaisyRemoved = 'daisy removed'; 163 | const obciChannelMaxNumber16DaisyAlreadyAttached = '16'; 164 | const obciChannelMaxNumber16DaisyAttached = 'daisy attached16'; 165 | const obciChannelMaxNumber16NoDaisyAttached = 'no daisy to attach!8'; 166 | 167 | /** 60Hz line filter */ 168 | const obciFilterDisable = 'g'; 169 | const obciFilterEnable = 'f'; 170 | 171 | /** Triggers */ 172 | const obciTrigger = '`'; 173 | 174 | /** Sync Clocks */ 175 | const obciSyncTimeSet = '<'; 176 | const obciSyncTimeSent = ','; 177 | 178 | /** Set board mode */ 179 | const obciBoardModeSet = '/'; 180 | const obciBoardModeCmdDefault = '0'; 181 | const obciBoardModeCmdDebug = '1'; 182 | const obciBoardModeCmdAnalog = '2'; 183 | const obciBoardModeCmdDigital = '3'; 184 | const obciBoardModeCmdGetCur = '/'; 185 | const obciBoardModeAnalog = 'analog'; 186 | const obciBoardModeDefault = 'default'; 187 | const obciBoardModeDebug = 'debug'; 188 | const obciBoardModeDigital = 'digital'; 189 | 190 | /** Set sample rate */ 191 | const obciSampleRateSet = '~'; 192 | const obciSampleRateCmdCyton16000 = '0'; 193 | const obciSampleRateCmdCyton8000 = '1'; 194 | const obciSampleRateCmdCyton4000 = '2'; 195 | const obciSampleRateCmdCyton2000 = '3'; 196 | const obciSampleRateCmdCyton1000 = '4'; 197 | const obciSampleRateCmdCyton500 = '5'; 198 | const obciSampleRateCmdCyton250 = '6'; 199 | const obciSampleRateCmdGang25600 = '0'; 200 | const obciSampleRateCmdGang12800 = '1'; 201 | const obciSampleRateCmdGang6400 = '2'; 202 | const obciSampleRateCmdGang3200 = '3'; 203 | const obciSampleRateCmdGang1600 = '4'; 204 | const obciSampleRateCmdGang800 = '5'; 205 | const obciSampleRateCmdGang400 = '6'; 206 | const obciSampleRateCmdGang200 = '7'; 207 | const obciSampleRateCmdaGetCur = '~'; 208 | 209 | /** Accel enable/disable commands */ 210 | const obciAccelStart = 'n'; 211 | const obciAccelStop = 'N'; 212 | 213 | /** Wifi Stuff */ 214 | const obciWifiAttach = '{'; 215 | const obciWifiRemove = '}'; 216 | const obciWifiReset = ';'; 217 | const obciWifiStatus = ':'; 218 | 219 | /** Radio Key */ 220 | const obciRadioKey = 0xF0; 221 | /** Radio Commands */ 222 | const obciRadioCmdChannelGet = 0x00; 223 | const obciRadioCmdChannelSet = 0x01; 224 | const obciRadioCmdChannelSetOverride = 0x02; 225 | const obciRadioCmdPollTimeGet = 0x03; 226 | const obciRadioCmdPollTimeSet = 0x04; 227 | const obciRadioCmdBaudRateSetDefault = 0x05; 228 | const obciRadioCmdBaudRateSetFast = 0x06; 229 | const obciRadioCmdSystemStatus = 0x07; 230 | 231 | /** Possible number of channels */ 232 | const obciNumberOfChannelsCyton = 8; 233 | const obciNumberOfChannelsCytonBLE = 2; 234 | const obciNumberOfChannelsDaisy = 16; 235 | const obciNumberOfChannelsDefault = obciNumberOfChannelsCyton; 236 | const obciNumberOfChannelsGanglion = 4; 237 | 238 | /** Possible OpenBCI board types */ 239 | const obciBoardCyton = 'cyton'; 240 | const obciBoardCytonBLE = 'cytonBLE'; 241 | const obciBoardDaisy = 'daisy'; 242 | const obciBoardDefault = 'default'; 243 | const obciBoardGanglion = 'ganglion'; 244 | const obciBoardNone = 'none'; 245 | 246 | /** Possible Simulator Line Noise injections */ 247 | const obciSimulatorLineNoiseHz60 = '60Hz'; 248 | const obciSimulatorLineNoiseHz50 = '50Hz'; 249 | const obciSimulatorLineNoiseNone = 'none'; 250 | 251 | /** Possible Simulator Fragmentation modes */ 252 | const obciSimulatorFragmentationRandom = 'random'; 253 | const obciSimulatorFragmentationFullBuffers = 'fullBuffers'; 254 | const obciSimulatorFragmentationOneByOne = 'oneByOne'; 255 | const obciSimulatorFragmentationNone = 'none'; 256 | 257 | /** Possible Sample Rates */ 258 | const obciSampleRate1000 = 1000; 259 | const obciSampleRate125 = 125; 260 | const obciSampleRate12800 = 12800; 261 | const obciSampleRate1600 = 1600; 262 | const obciSampleRate16000 = 16000; 263 | const obciSampleRate200 = 200; 264 | const obciSampleRate2000 = 2000; 265 | const obciSampleRate250 = 250; 266 | const obciSampleRate25600 = 25600; 267 | const obciSampleRate3200 = 3200; 268 | const obciSampleRate400 = 400; 269 | const obciSampleRate4000 = 4000; 270 | const obciSampleRate500 = 500; 271 | const obciSampleRate6400 = 6400; 272 | const obciSampleRate800 = 800; 273 | const obciSampleRate8000 = 8000; 274 | 275 | /** Max sample number */ 276 | const obciSampleNumberMax = 255; 277 | 278 | /** Packet Size */ 279 | const obciPacketSize = 33; 280 | const obciPacketSizeBLECyton = 20; 281 | const obciPacketSizeBLERaw = 12; 282 | 283 | /** OpenBCI V3 Standard Packet Positions */ 284 | /** 285 | * 0:[startByte] | 1:[sampleNumber] | 2:[Channel-1.1] | 3:[Channel-1.2] | 4:[Channel-1.3] | 5:[Channel-2.1] | 6:[Channel-2.2] | 7:[Channel-2.3] | 8:[Channel-3.1] | 9:[Channel-3.2] | 10:[Channel-3.3] | 11:[Channel-4.1] | 12:[Channel-4.2] | 13:[Channel-4.3] | 14:[Channel-5.1] | 15:[Channel-5.2] | 16:[Channel-5.3] | 17:[Channel-6.1] | 18:[Channel-6.2] | 19:[Channel-6.3] | 20:[Channel-7.1] | 21:[Channel-7.2] | 22:[Channel-7.3] | 23:[Channel-8.1] | 24:[Channel-8.2] | 25:[Channel-8.3] | 26:[Aux-1.1] | 27:[Aux-1.2] | 28:[Aux-2.1] | 29:[Aux-2.2] | 30:[Aux-3.1] | 31:[Aux-3.2] | 32:StopByte 286 | */ 287 | const obciPacketPositionChannelDataStart = 2; // 0:startByte | 1:sampleNumber | [2:4] | [5:7] | [8:10] | [11:13] | [14:16] | [17:19] | [21:23] | [24:26] 288 | const obciPacketPositionChannelDataStop = 25; // 24 bytes for channel data 289 | const obciPacketPositionSampleNumber = 1; 290 | const obciPacketPositionStartByte = 0; // first byte 291 | const obciPacketPositionStopByte = 32; // [32] 292 | const obciPacketPositionStartAux = 26; // [26,27]:Aux 1 | [28,29]:Aux 2 | [30,31]:Aux 3 293 | const obciPacketPositionStopAux = 31; // - - - [30,31]:Aux 3 | 32: Stop byte 294 | const obciPacketPositionTimeSyncAuxStart = 26; 295 | const obciPacketPositionTimeSyncAuxStop = 28; 296 | const obciPacketPositionTimeSyncTimeStart = 28; 297 | const obciPacketPositionTimeSyncTimeStop = 32; 298 | 299 | /** Notable Bytes */ 300 | const obciByteStart = 0xA0; 301 | const obciByteStop = 0xC0; 302 | 303 | /** Errors */ 304 | const errorInvalidByteLength = 'Invalid Packet Byte Length'; 305 | const errorInvalidByteStart = 'Invalid Start Byte'; 306 | const errorInvalidByteStop = 'Invalid Stop Byte'; 307 | const errorInvalidData = 'Invalid data - try again'; 308 | const errorInvalidType = 'Invalid type - check comments for input type'; 309 | const errorMissingRegisterSetting = 'Missing register setting'; 310 | const errorMissingRequiredProperty = 'Missing property in JSON'; 311 | const errorNobleAlreadyScanning = 'Scan already under way'; 312 | const errorNobleNotAlreadyScanning = 'No scan started'; 313 | const errorNobleNotInPoweredOnState = 'Please turn blue tooth on.'; 314 | const errorTimeSyncIsNull = "'this.sync.curSyncObj' must not be null"; 315 | const errorTimeSyncNoComma = 'Missed the time sync sent confirmation. Try sync again'; 316 | const errorUndefinedOrNullInput = 'Undefined or Null Input'; 317 | 318 | /** Max Master Buffer Size */ 319 | const obciMasterBufferSize = 4096; 320 | 321 | /** Impedance Calculation Variables */ 322 | const obciLeadOffDriveInAmps = 0.000000006; 323 | const obciLeadOffFrequencyHz = 31.5; 324 | 325 | /** Command send delay */ 326 | const obciWriteIntervalDelayMSLong = 50; 327 | const obciWriteIntervalDelayMSNone = 0; 328 | const obciWriteIntervalDelayMSShort = 10; 329 | 330 | /** Impedance */ 331 | const obciImpedanceTextBad = 'bad'; 332 | const obciImpedanceTextNone = 'none'; 333 | const obciImpedanceTextGood = 'good'; 334 | const obciImpedanceTextInit = 'init'; 335 | const obciImpedanceTextOk = 'ok'; 336 | 337 | const obciImpedanceThresholdGoodMin = 0; 338 | const obciImpedanceThresholdGoodMax = 5000; 339 | const obciImpedanceThresholdOkMin = 5001; 340 | const obciImpedanceThresholdOkMax = 10000; 341 | const obciImpedanceThresholdBadMin = 10001; 342 | const obciImpedanceThresholdBadMax = 1000000; 343 | 344 | const obciImpedanceSeriesResistor = 2200; // There is a 2.2 k Ohm series resistor that must be subtracted 345 | 346 | /** Simulator */ 347 | const obciSimulatorPortName = 'OpenBCISimulator'; 348 | 349 | /** 350 | * Stream packet types/codes 351 | */ 352 | const obciStreamPacketStandardAccel = 0; // 0000 353 | const obciStreamPacketStandardRawAux = 1; // 0001 354 | const obciStreamPacketUserDefinedType = 2; // 0010 355 | const obciStreamPacketAccelTimeSyncSet = 3; // 0011 356 | const obciStreamPacketAccelTimeSynced = 4; // 0100 357 | const obciStreamPacketRawAuxTimeSyncSet = 5; // 0101 358 | const obciStreamPacketRawAuxTimeSynced = 6; // 0110 359 | const obciStreamPacketImpedance = 7; // 0111 360 | 361 | /** Time from board */ 362 | const obciStreamPacketTimeByteSize = 4; 363 | 364 | /** Time synced with accel packet */ 365 | const obciAccelAxisX = 7; 366 | const obciAccelAxisY = 8; 367 | const obciAccelAxisZ = 9; 368 | 369 | /** Firmware version indicator */ 370 | const obciFirmwareV1 = 'v1'; 371 | const obciFirmwareV2 = 'v2'; 372 | const obciFirmwareV3 = 'v3'; 373 | 374 | /** Parse */ 375 | const obciParseDaisy = 'Daisy'; 376 | const obciParseFirmware = 'v2'; 377 | const obciParseFailure = 'Failure'; 378 | const obciParseEOT = '$$$'; 379 | const obciParseSuccess = 'Success'; 380 | 381 | /** Used in parsing incoming serial data */ 382 | const obciParsingChannelSettings = 2; 383 | const obciParsingEOT = 4; 384 | const obciParsingNormal = 3; 385 | const obciParsingReset = 0; 386 | const obciParsingTimeSyncSent = 1; 387 | 388 | /** Timeouts */ 389 | const obciTimeoutProcessBytes = 500; // 0.5 seconds 390 | 391 | /** Simulator Board Configurations */ 392 | const obciSimulatorRawAux = 'rawAux'; 393 | const obciSimulatorStandard = 'standard'; 394 | 395 | /** OpenBCI Radio Limits */ 396 | const obciRadioChannelMax = 25; 397 | const obciRadioChannelMin = 1; 398 | const obciRadioPollTimeMax = 255; 399 | const obciRadioPollTimeMin = 0; 400 | 401 | /** Time sync stuff */ 402 | const obciTimeSyncArraySize = 10; 403 | const obciTimeSyncMultiplierWithSyncConf = 0.9; 404 | const obciTimeSyncMultiplierWithoutSyncConf = 0.75; 405 | const obciTimeSyncThresholdTransFailureMS = 10; // ms 406 | 407 | /** Baud Rates */ 408 | const obciRadioBaudRateDefault = 115200; 409 | const obciRadioBaudRateDefaultStr = 'default'; 410 | const obciRadioBaudRateFast = 230400; 411 | const obciRadioBaudRateFastStr = 'fast'; 412 | 413 | /** Emitters */ 414 | const obciEmitterAccelerometer = 'accelerometer'; 415 | const obciEmitterBlePoweredUp = 'blePoweredOn'; 416 | const obciEmitterClose = 'close'; 417 | const obciEmitterDroppedPacket = 'droppedPacket'; 418 | const obciEmitterEot = 'eot'; 419 | const obciEmitterError = 'error'; 420 | const obciEmitterGanglionFound = 'ganglionFound'; 421 | const obciEmitterHardSet = 'hardSet'; 422 | const obciEmitterImpedance = 'impedance'; 423 | const obciEmitterImpedanceArray = 'impedanceArray'; 424 | const obciEmitterMessage = 'message'; 425 | const obciEmitterQuery = 'query'; 426 | const obciEmitterRawDataPacket = 'rawDataPacket'; 427 | const obciEmitterReady = 'ready'; 428 | const obciEmitterRFduino = 'rfduino'; 429 | const obciEmitterSample = 'sample'; 430 | const obciEmitterScanStopped = 'scanStopped'; 431 | const obciEmitterSynced = 'synced'; 432 | const obciEmitterWifiShield = 'wifiShield'; 433 | 434 | /** Accel packets */ 435 | const obciGanglionAccelAxisX = 1; 436 | const obciGanglionAccelAxisY = 2; 437 | const obciGanglionAccelAxisZ = 3; 438 | 439 | /** Accel scale factor */ 440 | const obciGanglionAccelScaleFactor = 0.016; // mG per count 441 | 442 | /** Ganglion */ 443 | const obciGanglionBleSearchTime = 20000; // ms 444 | const obciGanglionByteIdUncompressed = 0; 445 | const obciGanglionByteId18Bit = { 446 | max: 100, 447 | min: 1 448 | }; 449 | const obciGanglionByteId19Bit = { 450 | max: 200, 451 | min: 101 452 | }; 453 | const obciGanglionByteIdImpedanceChannel1 = 201; 454 | const obciGanglionByteIdImpedanceChannel2 = 202; 455 | const obciGanglionByteIdImpedanceChannel3 = 203; 456 | const obciGanglionByteIdImpedanceChannel4 = 204; 457 | const obciGanglionByteIdImpedanceChannelReference = 205; 458 | const obciGanglionByteIdMultiPacket = 206; 459 | const obciGanglionByteIdMultiPacketStop = 207; 460 | const obciGanglionPacketSize = 20; 461 | const obciGanglionSamplesPerPacket = 2; 462 | const obciGanglionPacket18Bit = { 463 | auxByte: 20, 464 | byteId: 0, 465 | dataStart: 1, 466 | dataStop: 19 467 | }; 468 | const obciGanglionPacket19Bit = { 469 | byteId: 0, 470 | dataStart: 1, 471 | dataStop: 20 472 | }; 473 | const obciGanglionMCP3912Gain = 51.0; // assumed gain setting for MCP3912. NEEDS TO BE ADJUSTABLE JM 474 | const obciGanglionMCP3912Vref = 1.2; // reference voltage for ADC in MCP3912 set in hardware 475 | const obciGanglionPrefix = 'Ganglion'; 476 | const obciGanglionSyntheticDataEnable = 't'; 477 | const obciGanglionSyntheticDataDisable = 'T'; 478 | const obciGanglionImpedanceStart = 'z'; 479 | const obciGanglionImpedanceStop = 'Z'; 480 | const obciGanglionScaleFactorPerCountVolts = obciGanglionMCP3912Vref / (8388607.0 * obciGanglionMCP3912Gain * 1.5); 481 | 482 | /** Simblee */ 483 | const simbleeUuidService = 'fe84'; 484 | const simbleeUuidReceive = '2d30c082f39f4ce6923f3484ea480596'; 485 | const simbleeUuidSend = '2d30c083f39f4ce6923f3484ea480596'; 486 | const simbleeUuidDisconnect = '2d30c084f39f4ce6923f3484ea480596'; 487 | 488 | /** RFduino BLE UUID */ 489 | const rfduinoUuidService = '2220'; 490 | const rfduinoUuidReceive = '2221'; 491 | const rfduinoUuidSend = '2222'; 492 | const rfduinoUuidSendTwo = '2223'; 493 | 494 | /** Cyton BLE */ 495 | const obciCytonBLESamplesPerPacket = 3; 496 | 497 | /** Noble */ 498 | const obciNobleEmitterPeripheralConnect = 'connect'; 499 | const obciNobleEmitterPeripheralDisconnect = 'disconnect'; 500 | const obciNobleEmitterPeripheralDiscover = 'discover'; 501 | const obciNobleEmitterPeripheralServicesDiscover = 'servicesDiscover'; 502 | const obciNobleEmitterServiceCharacteristicsDiscover = 'characteristicsDiscover'; 503 | const obciNobleEmitterServiceRead = 'read'; 504 | const obciNobleEmitterDiscover = 'discover'; 505 | const obciNobleEmitterScanStart = 'scanStart'; 506 | const obciNobleEmitterScanStop = 'scanStop'; 507 | const obciNobleEmitterStateChange = 'stateChange'; 508 | const obciNobleStatePoweredOn = 'poweredOn'; 509 | 510 | /** Protocols */ 511 | const obciProtocolBLE = 'ble'; 512 | const obciProtocolSerial = 'serial'; 513 | const obciProtocolWifi = 'wifi'; 514 | 515 | /** Register Query on Cyton */ 516 | const obciRegisterQueryAccelerometerFirmwareV1 = '\nLIS3DH Registers\n0x07.0\n0x08.0\n0x09.0\n0x0A.0\n0x0B.0\n0x0C.0\n0x0D.0\n0x0E.0\n0x0F.33\n\n0x1F.0\n0x20.8\n0x21.0\n0x22.0\n0x23.18\n0x24.0\n0x25.0\n0x26.0\n0x27.0\n0x28.0\n0x29.0\n0x2A.0\n0x2B.0\n0x2C.0\n0x2D.0\n0x2E.0\n0x2F.20\n0x30.0\n0x31.0\n0x32.0\n0x33.0\n\n0x38.0\n0x39.0\n0x3A.0\n0x3B.0\n0x3C.0\n0x3D.0\n'; 517 | const obciRegisterQueryAccelerometerFirmwareV3 = '\nLIS3DH Registers\n0x07 00\n0x08 00\n0x09 00\n0x0A 00\n0x0B 00\n0x0C 00\n0x0D 00\n0x0E 00\n0x0F 33\n\n0x1F 00\n0x20 08\n0x21 00\n0x22 00\n0x23 18\n0x24 00\n0x25 00\n0x26 00\n0x27 00\n0x28 00\n0x29 00\n0x2A 00\n0x2B 00\n0x2C 00\n0x2D 00\n0x2E 00\n0x2F 20\n0x30 00\n0x31 00\n0x32 00\n0x33 00\n\n0x38 00\n0x39 00\n0x3A 00\n0x3B 00\n0x3C 00\n0x3D 00\n'; 518 | const obciRegisterQueryCyton = '\nBoard ADS Registers\nADS_ID, 00, 3E, 0, 0, 1, 1, 1, 1, 1, 0\nCONFIG1, 01, 96, 1, 0, 0, 1, 0, 1, 1, 0\nCONFIG2, 02, C0, 1, 1, 0, 0, 0, 0, 0, 0\nCONFIG3, 03, EC, 1, 1, 1, 0, 1, 1, 0, 0\nLOFF, 04, 02, 0, 0, 0, 0, 0, 0, 1, 0\nCH1SET, 05, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH2SET, 06, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH3SET, 07, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH4SET, 08, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH5SET, 09, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH6SET, 0A, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH7SET, 0B, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH8SET, 0C, 68, 0, 1, 1, 0, 1, 0, 0, 0\nBIAS_SENSP, 0D, FF, 1, 1, 1, 1, 1, 1, 1, 1\nBIAS_SENSN, 0E, FF, 1, 1, 1, 1, 1, 1, 1, 1\nLOFF_SENSP, 0F, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_SENSN, 10, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_FLIP, 11, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_STATP, 12, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_STATN, 13, 00, 0, 0, 0, 0, 0, 0, 0, 0\nGPIO, 14, 0F, 0, 0, 0, 0, 1, 1, 1, 1\nMISC1, 15, 00, 0, 0, 0, 0, 0, 0, 0, 0\nMISC2, 16, 00, 0, 0, 0, 0, 0, 0, 0, 0\nCONFIG4, 17, 00, 0, 0, 0, 0, 0, 0, 0, 0\n'; 519 | const obciRegisterQueryCytonDaisy = '\nDaisy ADS Registers\nADS_ID, 00, 3E, 0, 0, 1, 1, 1, 1, 1, 0\nCONFIG1, 01, 96, 1, 0, 0, 1, 0, 1, 1, 0\nCONFIG2, 02, C0, 1, 1, 0, 0, 0, 0, 0, 0\nCONFIG3, 03, EC, 1, 1, 1, 0, 1, 1, 0, 0\nLOFF, 04, 02, 0, 0, 0, 0, 0, 0, 1, 0\nCH1SET, 05, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH2SET, 06, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH3SET, 07, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH4SET, 08, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH5SET, 09, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH6SET, 0A, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH7SET, 0B, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH8SET, 0C, 68, 0, 1, 1, 0, 1, 0, 0, 0\nBIAS_SENSP, 0D, FF, 1, 1, 1, 1, 1, 1, 1, 1\nBIAS_SENSN, 0E, FF, 1, 1, 1, 1, 1, 1, 1, 1\nLOFF_SENSP, 0F, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_SENSN, 10, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_FLIP, 11, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_STATP, 12, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_STATN, 13, 00, 0, 0, 0, 0, 0, 0, 0, 0\nGPIO, 14, 0F, 0, 0, 0, 0, 1, 1, 1, 1\nMISC1, 15, 00, 0, 0, 0, 0, 0, 0, 0, 0\nMISC2, 16, 00, 0, 0, 0, 0, 0, 0, 0, 0\nCONFIG4, 17, 00, 0, 0, 0, 0, 0, 0, 0, 0\n'; 520 | const obciRegisterQueryNameMISC1 = 'MISC1'; 521 | const obciRegisterQueryNameBIASSENSP = 'BIAS_SENSP'; 522 | const obciRegisterQueryNameCHnSET = ['CH1SET', 'CH2SET', 'CH3SET', 'CH4SET', 'CH5SET', 'CH6SET', 'CH7SET', 'CH8SET']; 523 | const obciRegisterQuerySizeCytonFirmwareV1 = obciRegisterQueryCyton.length + obciRegisterQueryAccelerometerFirmwareV1.length; 524 | const obciRegisterQuerySizeCytonDaisyFirmwareV1 = obciRegisterQueryCyton.length + obciRegisterQueryCytonDaisy.length + obciRegisterQueryAccelerometerFirmwareV1.length; 525 | const obciRegisterQuerySizeCytonFirmwareV3 = obciRegisterQueryCyton.length + obciRegisterQueryAccelerometerFirmwareV3.length; 526 | const obciRegisterQuerySizeCytonDaisyFirmwareV3 = obciRegisterQueryCyton.length + obciRegisterQueryCytonDaisy.length + obciRegisterQueryAccelerometerFirmwareV3.length; 527 | 528 | const constantsModule = { 529 | /** Turning channels off */ 530 | OBCIChannelOff1: obciChannelOff1, 531 | OBCIChannelOff2: obciChannelOff2, 532 | OBCIChannelOff3: obciChannelOff3, 533 | OBCIChannelOff4: obciChannelOff4, 534 | OBCIChannelOff5: obciChannelOff5, 535 | OBCIChannelOff6: obciChannelOff6, 536 | OBCIChannelOff7: obciChannelOff7, 537 | OBCIChannelOff8: obciChannelOff8, 538 | OBCIChannelOff9: obciChannelOff9, 539 | OBCIChannelOff10: obciChannelOff10, 540 | OBCIChannelOff11: obciChannelOff11, 541 | OBCIChannelOff12: obciChannelOff12, 542 | OBCIChannelOff13: obciChannelOff13, 543 | OBCIChannelOff14: obciChannelOff14, 544 | OBCIChannelOff15: obciChannelOff15, 545 | OBCIChannelOff16: obciChannelOff16, 546 | /** 547 | * Purpose: To get the proper command to turn a channel off 548 | * @param channelNumber - A number (1-16) of the desired channel 549 | * @returns {Promise} 550 | */ 551 | commandChannelOff: function (channelNumber) { 552 | return new Promise(function (resolve, reject) { 553 | switch (channelNumber) { 554 | case 1: 555 | resolve(obciChannelOff1); 556 | break; 557 | case 2: 558 | resolve(obciChannelOff2); 559 | break; 560 | case 3: 561 | resolve(obciChannelOff3); 562 | break; 563 | case 4: 564 | resolve(obciChannelOff4); 565 | break; 566 | case 5: 567 | resolve(obciChannelOff5); 568 | break; 569 | case 6: 570 | resolve(obciChannelOff6); 571 | break; 572 | case 7: 573 | resolve(obciChannelOff7); 574 | break; 575 | case 8: 576 | resolve(obciChannelOff8); 577 | break; 578 | case 9: 579 | resolve(obciChannelOff9); 580 | break; 581 | case 10: 582 | resolve(obciChannelOff10); 583 | break; 584 | case 11: 585 | resolve(obciChannelOff11); 586 | break; 587 | case 12: 588 | resolve(obciChannelOff12); 589 | break; 590 | case 13: 591 | resolve(obciChannelOff13); 592 | break; 593 | case 14: 594 | resolve(obciChannelOff14); 595 | break; 596 | case 15: 597 | resolve(obciChannelOff15); 598 | break; 599 | case 16: 600 | resolve(obciChannelOff16); 601 | break; 602 | default: 603 | reject(Error('Error [commandChannelOff]: Invalid Channel Number')); 604 | break; 605 | } 606 | }); 607 | }, 608 | /** Turning channels on */ 609 | OBCIChannelOn1: obciChannelOn1, 610 | OBCIChannelOn2: obciChannelOn2, 611 | OBCIChannelOn3: obciChannelOn3, 612 | OBCIChannelOn4: obciChannelOn4, 613 | OBCIChannelOn5: obciChannelOn5, 614 | OBCIChannelOn6: obciChannelOn6, 615 | OBCIChannelOn7: obciChannelOn7, 616 | OBCIChannelOn8: obciChannelOn8, 617 | OBCIChannelOn9: obciChannelOn9, 618 | OBCIChannelOn10: obciChannelOn10, 619 | OBCIChannelOn11: obciChannelOn11, 620 | OBCIChannelOn12: obciChannelOn12, 621 | OBCIChannelOn13: obciChannelOn13, 622 | OBCIChannelOn14: obciChannelOn14, 623 | OBCIChannelOn15: obciChannelOn15, 624 | OBCIChannelOn16: obciChannelOn16, 625 | commandChannelOn: function (channelNumber) { 626 | return new Promise(function (resolve, reject) { 627 | switch (channelNumber) { 628 | case 1: 629 | resolve(obciChannelOn1); 630 | break; 631 | case 2: 632 | resolve(obciChannelOn2); 633 | break; 634 | case 3: 635 | resolve(obciChannelOn3); 636 | break; 637 | case 4: 638 | resolve(obciChannelOn4); 639 | break; 640 | case 5: 641 | resolve(obciChannelOn5); 642 | break; 643 | case 6: 644 | resolve(obciChannelOn6); 645 | break; 646 | case 7: 647 | resolve(obciChannelOn7); 648 | break; 649 | case 8: 650 | resolve(obciChannelOn8); 651 | break; 652 | case 9: 653 | resolve(obciChannelOn9); 654 | break; 655 | case 10: 656 | resolve(obciChannelOn10); 657 | break; 658 | case 11: 659 | resolve(obciChannelOn11); 660 | break; 661 | case 12: 662 | resolve(obciChannelOn12); 663 | break; 664 | case 13: 665 | resolve(obciChannelOn13); 666 | break; 667 | case 14: 668 | resolve(obciChannelOn14); 669 | break; 670 | case 15: 671 | resolve(obciChannelOn15); 672 | break; 673 | case 16: 674 | resolve(obciChannelOn16); 675 | break; 676 | default: 677 | reject(Error('Error [commandChannelOn]: Invalid Channel Number')); 678 | break; 679 | } 680 | }); 681 | }, 682 | /** Test Signal Control Commands */ 683 | OBCITestSignalConnectToDC: obciTestSignalConnectToDC, 684 | OBCITestSignalConnectToGround: obciTestSignalConnectToGround, 685 | OBCITestSignalConnectToPulse1xFast: obciTestSignalConnectToPulse1xFast, 686 | OBCITestSignalConnectToPulse1xSlow: obciTestSignalConnectToPulse1xSlow, 687 | OBCITestSignalConnectToPulse2xFast: obciTestSignalConnectToPulse2xFast, 688 | OBCITestSignalConnectToPulse2xSlow: obciTestSignalConnectToPulse2xSlow, 689 | getTestSignalCommand: (signal) => { 690 | return new Promise((resolve, reject) => { 691 | switch (signal) { 692 | case 'dc': 693 | resolve(obciTestSignalConnectToDC); 694 | break; 695 | case 'ground': 696 | resolve(obciTestSignalConnectToGround); 697 | break; 698 | case 'pulse1xFast': 699 | resolve(obciTestSignalConnectToPulse1xFast); 700 | break; 701 | case 'pulse1xSlow': 702 | resolve(obciTestSignalConnectToPulse1xSlow); 703 | break; 704 | case 'pulse2xFast': 705 | resolve(obciTestSignalConnectToPulse2xFast); 706 | break; 707 | case 'pulse2xSlow': 708 | resolve(obciTestSignalConnectToPulse2xSlow); 709 | break; 710 | case 'none': 711 | resolve(obciChannelDefaultAllSet); 712 | break; 713 | default: 714 | reject(Error('Invalid selection! Check your spelling.')); 715 | break; 716 | } 717 | }); 718 | }, 719 | /** Channel Setting Commands */ 720 | OBCIChannelCmdADCNormal: obciChannelCmdADCNormal, 721 | OBCIChannelCmdADCShorted: obciChannelCmdADCShorted, 722 | OBCIChannelCmdADCBiasDRP: obciChannelCmdADCBiasDRP, 723 | OBCIChannelCmdADCBiasDRN: obciChannelCmdADCBiasDRN, 724 | OBCIChannelCmdADCBiasMethod: obciChannelCmdADCBiasMethod, 725 | OBCIChannelCmdADCMVDD: obciChannelCmdADCMVDD, 726 | OBCIChannelCmdADCTemp: obciChannelCmdADCTemp, 727 | OBCIChannelCmdADCTestSig: obciChannelCmdADCTestSig, 728 | OBCIChannelCmdBiasInclude: obciChannelCmdBiasInclude, 729 | OBCIChannelCmdBiasRemove: obciChannelCmdBiasRemove, 730 | OBCIChannelCmdChannel1: obciChannelCmdChannel1, 731 | OBCIChannelCmdChannel2: obciChannelCmdChannel2, 732 | OBCIChannelCmdChannel3: obciChannelCmdChannel3, 733 | OBCIChannelCmdChannel4: obciChannelCmdChannel4, 734 | OBCIChannelCmdChannel5: obciChannelCmdChannel5, 735 | OBCIChannelCmdChannel6: obciChannelCmdChannel6, 736 | OBCIChannelCmdChannel7: obciChannelCmdChannel7, 737 | OBCIChannelCmdChannel8: obciChannelCmdChannel8, 738 | OBCIChannelCmdChannel9: obciChannelCmdChannel9, 739 | OBCIChannelCmdChannel10: obciChannelCmdChannel10, 740 | OBCIChannelCmdChannel11: obciChannelCmdChannel11, 741 | OBCIChannelCmdChannel12: obciChannelCmdChannel12, 742 | OBCIChannelCmdChannel13: obciChannelCmdChannel13, 743 | OBCIChannelCmdChannel14: obciChannelCmdChannel14, 744 | OBCIChannelCmdChannel15: obciChannelCmdChannel15, 745 | OBCIChannelCmdChannel16: obciChannelCmdChannel16, 746 | commandChannelForCmd, 747 | OBCIChannelCmdGain1: obciChannelCmdGain1, 748 | OBCIChannelCmdGain2: obciChannelCmdGain2, 749 | OBCIChannelCmdGain4: obciChannelCmdGain4, 750 | OBCIChannelCmdGain6: obciChannelCmdGain6, 751 | OBCIChannelCmdGain8: obciChannelCmdGain8, 752 | OBCIChannelCmdGain12: obciChannelCmdGain12, 753 | OBCIChannelCmdGain24: obciChannelCmdGain24, 754 | commandForGain, 755 | gainForCommand, 756 | OBCIChannelCmdLatch: obciChannelCmdLatch, 757 | OBCIChannelCmdPowerOff: obciChannelCmdPowerOff, 758 | OBCIChannelCmdPowerOn: obciChannelCmdPowerOn, 759 | OBCIChannelCmdSet: obciChannelCmdSet, 760 | OBCIChannelCmdSRB1Connect: obciChannelCmdSRB1Connect, 761 | OBCIChannelCmdSRB1Diconnect: obciChannelCmdSRB1Diconnect, 762 | OBCIChannelCmdSRB2Connect: obciChannelCmdSRB2Connect, 763 | OBCIChannelCmdSRB2Diconnect: obciChannelCmdSRB2Diconnect, 764 | /** Channel Settings Object */ 765 | channelSettingsObjectDefault, 766 | /** 767 | * @param numberOfChannels {Number} 768 | * @returns {Array} 769 | */ 770 | channelSettingsArrayInit: (numberOfChannels) => { 771 | var newChannelSettingsArray = []; 772 | for (var i = 0; i < numberOfChannels; i++) { 773 | newChannelSettingsArray.push(channelSettingsObjectDefault(i)); 774 | } 775 | return newChannelSettingsArray; 776 | }, 777 | /** Channel Setting Helper Strings */ 778 | OBCIStringADCNormal: obciStringADCNormal, 779 | OBCIStringADCShorted: obciStringADCShorted, 780 | OBCIStringADCBiasMethod: obciStringADCBiasMethod, 781 | OBCIStringADCMvdd: obciStringADCMvdd, 782 | OBCIStringADCTemp: obciStringADCTemp, 783 | OBCIStringADCTestSig: obciStringADCTestSig, 784 | OBCIStringADCBiasDrp: obciStringADCBiasDrp, 785 | OBCIStringADCBiasDrn: obciStringADCBiasDrn, 786 | /** 787 | * @description To convert a string like 'normal' to the correct command (i.e. '1') 788 | * @param adcString 789 | * @returns {Promise} 790 | * @author AJ Keller (@pushtheworldllc) 791 | */ 792 | commandForADCString, 793 | inputTypeForCommand, 794 | /** Default Channel Settings */ 795 | OBCIChannelDefaultAllSet: obciChannelDefaultAllSet, 796 | OBCIChannelDefaultAllGet: obciChannelDefaultAllGet, 797 | /** LeadOff Impedance Commands */ 798 | OBCIChannelImpedanceLatch: obciChannelImpedanceLatch, 799 | OBCIChannelImpedanceSet: obciChannelImpedanceSet, 800 | OBCIChannelImpedanceTestSignalApplied: obciChannelImpedanceTestSignalApplied, 801 | OBCIChannelImpedanceTestSignalAppliedNot: obciChannelImpedanceTestSignalAppliedNot, 802 | /** SD card Commands */ 803 | OBCISDLogForHour1: obciSDLogForHour1, 804 | OBCISDLogForHour2: obciSDLogForHour2, 805 | OBCISDLogForHour4: obciSDLogForHour4, 806 | OBCISDLogForHour12: obciSDLogForHour12, 807 | OBCISDLogForHour24: obciSDLogForHour24, 808 | OBCISDLogForMin5: obciSDLogForMin5, 809 | OBCISDLogForMin15: obciSDLogForMin15, 810 | OBCISDLogForMin30: obciSDLogForMin30, 811 | OBCISDLogForSec14: obciSDLogForSec14, 812 | OBCISDLogStop: obciSDLogStop, 813 | /** SD Card String Commands */ 814 | OBCIStringSDHour1: obciStringSDHour1, 815 | OBCIStringSDHour2: obciStringSDHour2, 816 | OBCIStringSDHour4: obciStringSDHour4, 817 | OBCIStringSDHour12: obciStringSDHour12, 818 | OBCIStringSDHour24: obciStringSDHour24, 819 | OBCIStringSDMin5: obciStringSDMin5, 820 | OBCIStringSDMin15: obciStringSDMin15, 821 | OBCIStringSDMin30: obciStringSDMin30, 822 | OBCIStringSDSec14: obciStringSDSec14, 823 | /** 824 | * @description Converts a sd string into the proper setting. 825 | * @param stringCommand {String} - The length of time you want to record to the SD for. 826 | * @returns {Promise} The command to send to the Board, returns an error on improper `stringCommand` 827 | */ 828 | sdSettingForString: (stringCommand) => { 829 | return new Promise((resolve, reject) => { 830 | switch (stringCommand) { 831 | case obciStringSDHour1: 832 | resolve(obciSDLogForHour1); 833 | break; 834 | case obciStringSDHour2: 835 | resolve(obciSDLogForHour2); 836 | break; 837 | case obciStringSDHour4: 838 | resolve(obciSDLogForHour4); 839 | break; 840 | case obciStringSDHour12: 841 | resolve(obciSDLogForHour12); 842 | break; 843 | case obciStringSDHour24: 844 | resolve(obciSDLogForHour24); 845 | break; 846 | case obciStringSDMin5: 847 | resolve(obciSDLogForMin5); 848 | break; 849 | case obciStringSDMin15: 850 | resolve(obciSDLogForMin15); 851 | break; 852 | case obciStringSDMin30: 853 | resolve(obciSDLogForMin30); 854 | break; 855 | case obciStringSDSec14: 856 | resolve(obciSDLogForSec14); 857 | break; 858 | default: 859 | reject(Error(TypeError)); 860 | break; 861 | } 862 | }); 863 | }, 864 | /** Stream Data Commands */ 865 | OBCIStreamStart: obciStreamStart, 866 | OBCIStreamStop: obciStreamStop, 867 | /** Accel enable/disable commands */ 868 | OBCIAccelStart: obciAccelStart, 869 | OBCIAccelStop: obciAccelStop, 870 | /** Miscellaneous */ 871 | OBCIMiscQueryRegisterSettings: obciMiscQueryRegisterSettings, 872 | OBCIMiscQueryRegisterSettingsChannel1: obciMiscQueryRegisterSettingsChannel1, 873 | OBCIMiscQueryRegisterSettingsChannel2: obciMiscQueryRegisterSettingsChannel2, 874 | OBCIMiscQueryRegisterSettingsChannel3: obciMiscQueryRegisterSettingsChannel3, 875 | OBCIMiscQueryRegisterSettingsChannel4: obciMiscQueryRegisterSettingsChannel4, 876 | OBCIMiscQueryRegisterSettingsChannel5: obciMiscQueryRegisterSettingsChannel5, 877 | OBCIMiscQueryRegisterSettingsChannel6: obciMiscQueryRegisterSettingsChannel6, 878 | OBCIMiscQueryRegisterSettingsChannel7: obciMiscQueryRegisterSettingsChannel7, 879 | OBCIMiscQueryRegisterSettingsChannel8: obciMiscQueryRegisterSettingsChannel8, 880 | channelSettingsKeyForChannel: channelNumber => { 881 | return new Promise((resolve, reject) => { 882 | switch (channelNumber) { 883 | case 1: 884 | resolve(new Buffer(obciMiscQueryRegisterSettingsChannel1)); 885 | break; 886 | case 2: 887 | resolve(new Buffer(obciMiscQueryRegisterSettingsChannel2)); 888 | break; 889 | case 3: 890 | resolve(new Buffer(obciMiscQueryRegisterSettingsChannel3)); 891 | break; 892 | case 4: 893 | resolve(new Buffer(obciMiscQueryRegisterSettingsChannel4)); 894 | break; 895 | case 5: 896 | resolve(new Buffer(obciMiscQueryRegisterSettingsChannel5)); 897 | break; 898 | case 6: 899 | resolve(new Buffer(obciMiscQueryRegisterSettingsChannel6)); 900 | break; 901 | case 7: 902 | resolve(new Buffer(obciMiscQueryRegisterSettingsChannel7)); 903 | break; 904 | case 8: 905 | resolve(new Buffer(obciMiscQueryRegisterSettingsChannel8)); 906 | break; 907 | default: 908 | reject(Error('Invalid channel number')); 909 | break; 910 | } 911 | }); 912 | }, 913 | OBCIMiscSoftReset: obciMiscSoftReset, 914 | /** 16 Channel Commands */ 915 | OBCIChannelMaxNumber8: obciChannelMaxNumber8, 916 | OBCIChannelMaxNumber16: obciChannelMaxNumber16, 917 | OBCIChannelMaxNumber8NoDaisyToRemove: obciChannelMaxNumber8NoDaisyToRemove, 918 | OBCIChannelMaxNumber8SuccessDaisyRemoved: obciChannelMaxNumber8SuccessDaisyRemoved, 919 | OBCIChannelMaxNumber16DaisyAlreadyAttached: obciChannelMaxNumber16DaisyAlreadyAttached, 920 | OBCIChannelMaxNumber16DaisyAttached: obciChannelMaxNumber16DaisyAttached, 921 | OBCIChannelMaxNumber16NoDaisyAttached: obciChannelMaxNumber16NoDaisyAttached, 922 | /** Filters */ 923 | OBCIFilterDisable: obciFilterDisable, 924 | OBCIFilterEnable: obciFilterEnable, 925 | /** Triggers */ 926 | OBCITrigger: obciTrigger, 927 | /** Possible number of channels */ 928 | OBCINumberOfChannelsCyton: obciNumberOfChannelsCyton, 929 | OBCINumberOfChannelsCytonBLE: obciNumberOfChannelsCytonBLE, 930 | OBCINumberOfChannelsDaisy: obciNumberOfChannelsDaisy, 931 | OBCINumberOfChannelsDefault: obciNumberOfChannelsDefault, 932 | OBCINumberOfChannelsGanglion: obciNumberOfChannelsGanglion, 933 | /** Possible OpenBCI board types */ 934 | OBCIBoardCyton: obciBoardCyton, 935 | OBCIBoardCytonBLE: obciBoardCytonBLE, 936 | OBCIBoardDaisy: obciBoardDaisy, 937 | OBCIBoardDefault: obciBoardDefault, 938 | OBCIBoardGanglion: obciBoardGanglion, 939 | OBCIBoardNone: obciBoardNone, 940 | numberOfChannelsForBoardType: boardType => { 941 | switch (boardType) { 942 | case obciBoardDaisy: 943 | return obciNumberOfChannelsDaisy; 944 | case obciBoardGanglion: 945 | return obciNumberOfChannelsGanglion; 946 | case obciBoardNone: 947 | return 0; 948 | case obciBoardCytonBLE: 949 | return obciNumberOfChannelsCytonBLE; 950 | case obciBoardCyton: 951 | default: 952 | return obciNumberOfChannelsDefault; 953 | } 954 | }, 955 | boardTypeForNumberOfChannels: (numberOfChannels) => { 956 | switch (numberOfChannels) { 957 | case obciNumberOfChannelsDaisy: 958 | return obciBoardDaisy; 959 | case obciNumberOfChannelsGanglion: 960 | return obciBoardGanglion; 961 | case 0: 962 | return obciBoardNone; 963 | case obciNumberOfChannelsCytonBLE: 964 | return obciBoardCytonBLE; 965 | case obciNumberOfChannelsDefault: 966 | default: 967 | return obciBoardCyton; 968 | } 969 | }, 970 | /** Possible Sample Rates */ 971 | OBCISampleRate1000: obciSampleRate1000, 972 | OBCISampleRate125: obciSampleRate125, 973 | OBCISampleRate12800: obciSampleRate12800, 974 | OBCISampleRate1600: obciSampleRate1600, 975 | OBCISampleRate16000: obciSampleRate16000, 976 | OBCISampleRate200: obciSampleRate200, 977 | OBCISampleRate2000: obciSampleRate2000, 978 | OBCISampleRate250: obciSampleRate250, 979 | OBCISampleRate25600: obciSampleRate25600, 980 | OBCISampleRate3200: obciSampleRate3200, 981 | OBCISampleRate400: obciSampleRate400, 982 | OBCISampleRate4000: obciSampleRate4000, 983 | OBCISampleRate500: obciSampleRate500, 984 | OBCISampleRate6400: obciSampleRate6400, 985 | OBCISampleRate800: obciSampleRate800, 986 | OBCISampleRate8000: obciSampleRate8000, 987 | /** Max sample number */ 988 | OBCISampleNumberMax: obciSampleNumberMax, 989 | /** Packet Size */ 990 | OBCIPacketSize: obciPacketSize, 991 | OBCIPacketSizeBLECyton: obciPacketSizeBLECyton, 992 | OBCIPacketSizeBLERaw: obciPacketSizeBLERaw, 993 | /** Notable Bytes */ 994 | OBCIByteStart: obciByteStart, 995 | OBCIByteStop: obciByteStop, 996 | /** Errors */ 997 | OBCIErrorInvalidByteLength: errorInvalidByteLength, 998 | OBCIErrorInvalidByteStart: errorInvalidByteStart, 999 | OBCIErrorInvalidByteStop: errorInvalidByteStop, 1000 | OBCIErrorInvalidData: errorInvalidData, 1001 | OBCIErrorInvalidType: errorInvalidType, 1002 | OBCIErrorMissingRegisterSetting: errorMissingRegisterSetting, 1003 | OBCIErrorMissingRequiredProperty: errorMissingRequiredProperty, 1004 | OBCIErrorNobleAlreadyScanning: errorNobleAlreadyScanning, 1005 | OBCIErrorNobleNotAlreadyScanning: errorNobleNotAlreadyScanning, 1006 | OBCIErrorNobleNotInPoweredOnState: errorNobleNotInPoweredOnState, 1007 | OBCIErrorTimeSyncIsNull: errorTimeSyncIsNull, 1008 | OBCIErrorTimeSyncNoComma: errorTimeSyncNoComma, 1009 | OBCIErrorUndefinedOrNullInput: errorUndefinedOrNullInput, 1010 | /** Max Master Buffer Size */ 1011 | OBCIMasterBufferSize: obciMasterBufferSize, 1012 | /** Impedance Calculation Variables */ 1013 | OBCILeadOffDriveInAmps: obciLeadOffDriveInAmps, 1014 | OBCILeadOffFrequencyHz: obciLeadOffFrequencyHz, 1015 | /** Channel Setter Maker */ 1016 | getChannelSetter: channelSetter, 1017 | /** Impedance Setter Maker */ 1018 | getImpedanceSetter: impedanceSetter, 1019 | /** Sample Rate Setter Maker */ 1020 | getSampleRateSetter: sampleRateSetter, 1021 | /** Board Mode Setter Maker */ 1022 | getBoardModeSetter: boardModeSetter, 1023 | /** Command send delay */ 1024 | OBCIWriteIntervalDelayMSLong: obciWriteIntervalDelayMSLong, 1025 | OBCIWriteIntervalDelayMSNone: obciWriteIntervalDelayMSNone, 1026 | OBCIWriteIntervalDelayMSShort: obciWriteIntervalDelayMSShort, 1027 | /** Sync Clocks */ 1028 | OBCISyncTimeSent: obciSyncTimeSent, 1029 | OBCISyncTimeSet: obciSyncTimeSet, 1030 | /** Radio Key */ 1031 | OBCIRadioKey: obciRadioKey, 1032 | /** Radio Commands */ 1033 | OBCIRadioCmdChannelGet: obciRadioCmdChannelGet, 1034 | OBCIRadioCmdChannelSet: obciRadioCmdChannelSet, 1035 | OBCIRadioCmdChannelSetOverride: obciRadioCmdChannelSetOverride, 1036 | OBCIRadioCmdPollTimeGet: obciRadioCmdPollTimeGet, 1037 | OBCIRadioCmdPollTimeSet: obciRadioCmdPollTimeSet, 1038 | OBCIRadioCmdBaudRateSetDefault: obciRadioCmdBaudRateSetDefault, 1039 | OBCIRadioCmdBaudRateSetFast: obciRadioCmdBaudRateSetFast, 1040 | OBCIRadioCmdSystemStatus: obciRadioCmdSystemStatus, 1041 | /** Impedance */ 1042 | OBCIImpedanceTextBad: obciImpedanceTextBad, 1043 | OBCIImpedanceTextGood: obciImpedanceTextGood, 1044 | OBCIImpedanceTextInit: obciImpedanceTextInit, 1045 | OBCIImpedanceTextOk: obciImpedanceTextOk, 1046 | OBCIImpedanceTextNone: obciImpedanceTextNone, 1047 | OBCIImpedanceThresholdBadMax: obciImpedanceThresholdBadMax, 1048 | OBCIImpedanceSeriesResistor: obciImpedanceSeriesResistor, 1049 | getTextForRawImpedance: (value) => { 1050 | if (value > obciImpedanceThresholdGoodMin && value < obciImpedanceThresholdGoodMax) { 1051 | return obciImpedanceTextGood; 1052 | } else if (value > obciImpedanceThresholdOkMin && value < obciImpedanceThresholdOkMax) { 1053 | return obciImpedanceTextOk; 1054 | } else if (value > obciImpedanceThresholdBadMin && value < obciImpedanceThresholdBadMax) { 1055 | return obciImpedanceTextBad; 1056 | } else { 1057 | return obciImpedanceTextNone; 1058 | } 1059 | }, 1060 | /** Simulator */ 1061 | OBCISimulatorPortName: obciSimulatorPortName, 1062 | /** 1063 | * Stream packet types/codes 1064 | */ 1065 | OBCIStreamPacketStandardAccel: obciStreamPacketStandardAccel, 1066 | OBCIStreamPacketStandardRawAux: obciStreamPacketStandardRawAux, 1067 | OBCIStreamPacketUserDefinedType: obciStreamPacketUserDefinedType, 1068 | OBCIStreamPacketAccelTimeSyncSet: obciStreamPacketAccelTimeSyncSet, 1069 | OBCIStreamPacketAccelTimeSynced: obciStreamPacketAccelTimeSynced, 1070 | OBCIStreamPacketRawAuxTimeSyncSet: obciStreamPacketRawAuxTimeSyncSet, 1071 | OBCIStreamPacketRawAuxTimeSynced: obciStreamPacketRawAuxTimeSynced, 1072 | OBCIStreamPacketImpedance: obciStreamPacketImpedance, 1073 | /** fun funcs */ 1074 | isNumber, 1075 | isBoolean, 1076 | isString, 1077 | isUndefined, 1078 | isNull, 1079 | /** OpenBCI V3 Standard Packet Positions */ 1080 | OBCIPacketPositionStartByte: obciPacketPositionStartByte, 1081 | OBCIPacketPositionStopByte: obciPacketPositionStopByte, 1082 | OBCIPacketPositionStartAux: obciPacketPositionStartAux, 1083 | OBCIPacketPositionStopAux: obciPacketPositionStopAux, 1084 | OBCIPacketPositionChannelDataStart: obciPacketPositionChannelDataStart, 1085 | OBCIPacketPositionChannelDataStop: obciPacketPositionChannelDataStop, 1086 | OBCIPacketPositionSampleNumber: obciPacketPositionSampleNumber, 1087 | OBCIPacketPositionTimeSyncAuxStart: obciPacketPositionTimeSyncAuxStart, 1088 | OBCIPacketPositionTimeSyncAuxStop: obciPacketPositionTimeSyncAuxStop, 1089 | OBCIPacketPositionTimeSyncTimeStart: obciPacketPositionTimeSyncTimeStart, 1090 | OBCIPacketPositionTimeSyncTimeStop: obciPacketPositionTimeSyncTimeStop, 1091 | /** Possible Simulator Line Noise injections */ 1092 | OBCISimulatorLineNoiseHz60: obciSimulatorLineNoiseHz60, 1093 | OBCISimulatorLineNoiseHz50: obciSimulatorLineNoiseHz50, 1094 | OBCISimulatorLineNoiseNone: obciSimulatorLineNoiseNone, 1095 | /** Possible Simulator Fragmentation modes */ 1096 | OBCISimulatorFragmentationRandom: obciSimulatorFragmentationRandom, 1097 | OBCISimulatorFragmentationFullBuffers: obciSimulatorFragmentationFullBuffers, 1098 | OBCISimulatorFragmentationOneByOne: obciSimulatorFragmentationOneByOne, 1099 | OBCISimulatorFragmentationNone: obciSimulatorFragmentationNone, 1100 | /** Firmware version indicator */ 1101 | OBCIFirmwareV1: obciFirmwareV1, 1102 | OBCIFirmwareV2: obciFirmwareV2, 1103 | OBCIFirmwareV3: obciFirmwareV3, 1104 | /** Time synced accel packet */ 1105 | OBCIAccelAxisX: obciAccelAxisX, 1106 | OBCIAccelAxisY: obciAccelAxisY, 1107 | OBCIAccelAxisZ: obciAccelAxisZ, 1108 | /** Time from board */ 1109 | OBCIStreamPacketTimeByteSize: obciStreamPacketTimeByteSize, 1110 | /** Parse */ 1111 | OBCIParseDaisy: obciParseDaisy, 1112 | OBCIParseFailure: obciParseFailure, 1113 | OBCIParseFirmware: obciParseFirmware, 1114 | OBCIParseEOT: obciParseEOT, 1115 | OBCIParseSuccess: obciParseSuccess, 1116 | /** Used in parsing incoming serial data */ 1117 | OBCIParsingChannelSettings: obciParsingChannelSettings, 1118 | OBCIParsingEOT: obciParsingEOT, 1119 | OBCIParsingNormal: obciParsingNormal, 1120 | OBCIParsingReset: obciParsingReset, 1121 | OBCIParsingTimeSyncSent: obciParsingTimeSyncSent, 1122 | /** Timeouts */ 1123 | OBCITimeoutProcessBytes: obciTimeoutProcessBytes, 1124 | /** Simulator Board Configurations */ 1125 | OBCISimulatorRawAux: obciSimulatorRawAux, 1126 | OBCISimulatorStandard: obciSimulatorStandard, 1127 | /** Radio Channel Limits */ 1128 | OBCIRadioChannelMax: obciRadioChannelMax, 1129 | OBCIRadioChannelMin: obciRadioChannelMin, 1130 | OBCIRadioPollTimeMax: obciRadioPollTimeMax, 1131 | OBCIRadioPollTimeMin: obciRadioPollTimeMin, 1132 | /** Time sync stuff */ 1133 | OBCITimeSyncArraySize: obciTimeSyncArraySize, 1134 | OBCITimeSyncMultiplierWithSyncConf: obciTimeSyncMultiplierWithSyncConf, 1135 | OBCITimeSyncMultiplierWithoutSyncConf: obciTimeSyncMultiplierWithoutSyncConf, 1136 | OBCITimeSyncThresholdTransFailureMS: obciTimeSyncThresholdTransFailureMS, 1137 | /** Set board mode */ 1138 | OBCIBoardModeSet: obciBoardModeSet, 1139 | OBCIBoardModeCmdDefault: obciBoardModeCmdDefault, 1140 | OBCIBoardModeCmdDebug: obciBoardModeCmdDebug, 1141 | OBCIBoardModeCmdAnalog: obciBoardModeCmdAnalog, 1142 | OBCIBoardModeCmdDigital: obciBoardModeCmdDigital, 1143 | OBCIBoardModeCmdGetCur: obciBoardModeCmdGetCur, 1144 | OBCIBoardModeAnalog: obciBoardModeAnalog, 1145 | OBCIBoardModeDefault: obciBoardModeDefault, 1146 | OBCIBoardModeDebug: obciBoardModeDebug, 1147 | OBCIBoardModeDigital: obciBoardModeDigital, 1148 | 1149 | /** Set sample rate */ 1150 | OBCISampleRateSet: obciSampleRateSet, 1151 | OBCISampleRateCmdCyton16000: obciSampleRateCmdCyton16000, 1152 | OBCISampleRateCmdCyton8000: obciSampleRateCmdCyton8000, 1153 | OBCISampleRateCmdCyton4000: obciSampleRateCmdCyton4000, 1154 | OBCISampleRateCmdCyton2000: obciSampleRateCmdCyton2000, 1155 | OBCISampleRateCmdCyton1000: obciSampleRateCmdCyton1000, 1156 | OBCISampleRateCmdCyton500: obciSampleRateCmdCyton500, 1157 | OBCISampleRateCmdCyton250: obciSampleRateCmdCyton250, 1158 | OBCISampleRateCmdGang25600: obciSampleRateCmdGang25600, 1159 | OBCISampleRateCmdGang12800: obciSampleRateCmdGang12800, 1160 | OBCISampleRateCmdGang6400: obciSampleRateCmdGang6400, 1161 | OBCISampleRateCmdGang3200: obciSampleRateCmdGang3200, 1162 | OBCISampleRateCmdGang1600: obciSampleRateCmdGang1600, 1163 | OBCISampleRateCmdGang800: obciSampleRateCmdGang800, 1164 | OBCISampleRateCmdGang400: obciSampleRateCmdGang400, 1165 | OBCISampleRateCmdGang200: obciSampleRateCmdGang200, 1166 | OBCISampleRateCmdGetCur: obciSampleRateCmdaGetCur, 1167 | 1168 | /** Wifi Stuff */ 1169 | OBCIWifiAttach: obciWifiAttach, 1170 | OBCIWifiRemove: obciWifiRemove, 1171 | OBCIWifiReset: obciWifiReset, 1172 | OBCIWifiStatus: obciWifiStatus, 1173 | /** Baud Rates */ 1174 | OBCIRadioBaudRateDefault: obciRadioBaudRateDefault, 1175 | OBCIRadioBaudRateDefaultStr: obciRadioBaudRateDefaultStr, 1176 | OBCIRadioBaudRateFast: obciRadioBaudRateFast, 1177 | OBCIRadioBaudRateFastStr: obciRadioBaudRateFastStr, 1178 | /** Emitters */ 1179 | OBCIEmitterAccelerometer: obciEmitterAccelerometer, 1180 | OBCIEmitterBlePoweredUp: obciEmitterBlePoweredUp, 1181 | OBCIEmitterClose: obciEmitterClose, 1182 | OBCIEmitterDroppedPacket: obciEmitterDroppedPacket, 1183 | OBCIEmitterEot: obciEmitterEot, 1184 | OBCIEmitterError: obciEmitterError, 1185 | OBCIEmitterGanglionFound: obciEmitterGanglionFound, 1186 | OBCIEmitterHardSet: obciEmitterHardSet, 1187 | OBCIEmitterImpedance: obciEmitterImpedance, 1188 | OBCIEmitterImpedanceArray: obciEmitterImpedanceArray, 1189 | OBCIEmitterMessage: obciEmitterMessage, 1190 | OBCIEmitterQuery: obciEmitterQuery, 1191 | OBCIEmitterRawDataPacket: obciEmitterRawDataPacket, 1192 | OBCIEmitterReady: obciEmitterReady, 1193 | OBCIEmitterRFduino: obciEmitterRFduino, 1194 | OBCIEmitterSample: obciEmitterSample, 1195 | OBCIEmitterScanStopped: obciEmitterScanStopped, 1196 | OBCIEmitterSynced: obciEmitterSynced, 1197 | OBCIEmitterWifiShield: obciEmitterWifiShield, 1198 | /** Emitters */ 1199 | /** Accel packets */ 1200 | OBCIGanglionAccelAxisX: obciGanglionAccelAxisX, 1201 | OBCIGanglionAccelAxisY: obciGanglionAccelAxisY, 1202 | OBCIGanglionAccelAxisZ: obciGanglionAccelAxisZ, 1203 | /** Ganglion */ 1204 | OBCIGanglionBleSearchTime: obciGanglionBleSearchTime, 1205 | OBCIGanglionByteIdUncompressed: obciGanglionByteIdUncompressed, 1206 | OBCIGanglionByteId18Bit: obciGanglionByteId18Bit, 1207 | OBCIGanglionByteId19Bit: obciGanglionByteId19Bit, 1208 | OBCIGanglionByteIdImpedanceChannel1: obciGanglionByteIdImpedanceChannel1, 1209 | OBCIGanglionByteIdImpedanceChannel2: obciGanglionByteIdImpedanceChannel2, 1210 | OBCIGanglionByteIdImpedanceChannel3: obciGanglionByteIdImpedanceChannel3, 1211 | OBCIGanglionByteIdImpedanceChannel4: obciGanglionByteIdImpedanceChannel4, 1212 | OBCIGanglionByteIdImpedanceChannelReference: obciGanglionByteIdImpedanceChannelReference, 1213 | OBCIGanglionByteIdMultiPacket: obciGanglionByteIdMultiPacket, 1214 | OBCIGanglionByteIdMultiPacketStop: obciGanglionByteIdMultiPacketStop, 1215 | OBCIGanglionMCP3912Gain: obciGanglionMCP3912Gain, // assumed gain setting for MCP3912. NEEDS TO BE ADJUSTABLE JM 1216 | OBCIGanglionMCP3912Vref: obciGanglionMCP3912Vref, // reference voltage for ADC in MCP3912 set in hardware 1217 | OBCIGanglionPacketSize: obciGanglionPacketSize, 1218 | OBCIGanglionPacket18Bit: obciGanglionPacket18Bit, 1219 | OBCIGanglionPacket19Bit: obciGanglionPacket19Bit, 1220 | OBCIGanglionPrefix: obciGanglionPrefix, 1221 | OBCIGanglionSamplesPerPacket: obciGanglionSamplesPerPacket, 1222 | OBCIGanglionSyntheticDataEnable: obciGanglionSyntheticDataEnable, 1223 | OBCIGanglionSyntheticDataDisable: obciGanglionSyntheticDataDisable, 1224 | OBCIGanglionImpedanceStart: obciGanglionImpedanceStart, 1225 | OBCIGanglionImpedanceStop: obciGanglionImpedanceStop, 1226 | OBCIGanglionScaleFactorPerCountVolts: obciGanglionScaleFactorPerCountVolts, 1227 | /** Simblee */ 1228 | SimbleeUuidService: simbleeUuidService, 1229 | SimbleeUuidReceive: simbleeUuidReceive, 1230 | SimbleeUuidSend: simbleeUuidSend, 1231 | SimbleeUuidDisconnect: simbleeUuidDisconnect, 1232 | /** RFduino BLE UUID */ 1233 | RFduinoUuidService: rfduinoUuidService, 1234 | RFduinoUuidReceive: rfduinoUuidReceive, 1235 | RFduinoUuidSend: rfduinoUuidSend, 1236 | RFduinoUuidSendTwo: rfduinoUuidSendTwo, 1237 | /** Cyton BLE */ 1238 | OBCICytonBLESamplesPerPacket: obciCytonBLESamplesPerPacket, 1239 | /** Accel scale factor */ 1240 | OBCIGanglionAccelScaleFactor: obciGanglionAccelScaleFactor, 1241 | /** Noble */ 1242 | OBCINobleEmitterPeripheralConnect: obciNobleEmitterPeripheralConnect, 1243 | OBCINobleEmitterPeripheralDisconnect: obciNobleEmitterPeripheralDisconnect, 1244 | OBCINobleEmitterPeripheralDiscover: obciNobleEmitterPeripheralDiscover, 1245 | OBCINobleEmitterPeripheralServicesDiscover: obciNobleEmitterPeripheralServicesDiscover, 1246 | OBCINobleEmitterServiceCharacteristicsDiscover: obciNobleEmitterServiceCharacteristicsDiscover, 1247 | OBCINobleEmitterServiceRead: obciNobleEmitterServiceRead, 1248 | OBCINobleEmitterDiscover: obciNobleEmitterDiscover, 1249 | OBCINobleEmitterScanStart: obciNobleEmitterScanStart, 1250 | OBCINobleEmitterScanStop: obciNobleEmitterScanStop, 1251 | OBCINobleEmitterStateChange: obciNobleEmitterStateChange, 1252 | OBCINobleStatePoweredOn: obciNobleStatePoweredOn, 1253 | getPeripheralLocalNames, 1254 | getPeripheralWithLocalName, 1255 | getVersionNumber, 1256 | isPeripheralGanglion, 1257 | commandSampleRateForCmdCyton, 1258 | commandSampleRateForCmdGanglion, 1259 | commandBoardModeForMode, 1260 | rawDataToSampleObjectDefault, 1261 | /** Protocols */ 1262 | OBCIProtocolBLE: obciProtocolBLE, 1263 | OBCIProtocolSerial: obciProtocolSerial, 1264 | OBCIProtocolWifi: obciProtocolWifi, 1265 | /** Register Query for Cyton */ 1266 | OBCIRegisterQueryAccelerometerFirmwareV1: obciRegisterQueryAccelerometerFirmwareV1, 1267 | OBCIRegisterQueryAccelerometerFirmwareV3: obciRegisterQueryAccelerometerFirmwareV3, 1268 | OBCIRegisterQueryCyton: obciRegisterQueryCyton, 1269 | OBCIRegisterQueryCytonDaisy: obciRegisterQueryCytonDaisy, 1270 | OBCIRegisterQueryNameMISC1: obciRegisterQueryNameMISC1, 1271 | OBCIRegisterQueryNameBIASSENSP: obciRegisterQueryNameBIASSENSP, 1272 | OBCIRegisterQueryNameCHnSET: obciRegisterQueryNameCHnSET, 1273 | OBCIRegisterQuerySizeCytonFirmwareV1: obciRegisterQuerySizeCytonFirmwareV1, 1274 | OBCIRegisterQuerySizeCytonDaisyFirmwareV1: obciRegisterQuerySizeCytonDaisyFirmwareV1, 1275 | OBCIRegisterQuerySizeCytonFirmwareV3: obciRegisterQuerySizeCytonFirmwareV3, 1276 | OBCIRegisterQuerySizeCytonDaisyFirmwareV3: obciRegisterQuerySizeCytonDaisyFirmwareV3 1277 | }; 1278 | 1279 | /** 1280 | * @description To add a usability abstraction layer above channel setting commands. Due to the 1281 | * extensive and highly specific nature of the channel setting command chain, this 1282 | * will take several different human readable inputs and merge to one array filled 1283 | * with the correct commands, prime for sending directly to the write command. 1284 | * @param channelNumber - Number (1-16) 1285 | * @param powerDown - Bool (true -> OFF, false -> ON (default)) 1286 | * turns the channel on or off 1287 | * @param gain - Number (1,2,4,6,8,12,24(default)) 1288 | * sets the gain for the channel 1289 | * @param inputType - String (normal,shorted,biasMethod,mvdd,temp,testsig,biasDrp,biasDrn) 1290 | * selects the ADC channel input source 1291 | * @param bias - Bool (true -> Include in bias (default), false -> remove from bias) 1292 | * selects to include the channel input in bias generation 1293 | * @param srb2 - Bool (true -> Connect this input to SRB2 (default), 1294 | * false -> Disconnect this input from SRB2) 1295 | * Select to connect (true) this channel's P input to the SRB2 pin. This closes 1296 | * a switch between P input and SRB2 for the given channel, and allows the 1297 | * P input to also remain connected to the ADC. 1298 | * @param srb1 - Bool (true -> connect all N inputs to SRB1, 1299 | * false -> Disconnect all N inputs from SRB1 (default)) 1300 | * Select to connect (true) all channels' N inputs to SRB1. This effects all pins, 1301 | * and disconnects all N inputs from the ADC. 1302 | * @returns {Promise} resolves {commandArray: array of commands to be sent, 1303 | newChannelSettingsObject: an updated channel settings object 1304 | to be stored in openBCIBoard.channelSettingsArray}, 1305 | rejects on bad input or no board 1306 | */ 1307 | function channelSetter (channelNumber, powerDown, gain, inputType, bias, srb2, srb1) { 1308 | // Used to store and assemble the commands 1309 | var cmdPowerDown, 1310 | cmdBias, 1311 | cmdSrb2, 1312 | cmdSrb1; 1313 | 1314 | return new Promise(function (resolve, reject) { 1315 | // Validate the input 1316 | if (!isNumber(channelNumber)) reject(Error("channelNumber must be of type 'number' ")); 1317 | if (!isBoolean(powerDown)) reject(Error("powerDown must be of type 'boolean' ")); 1318 | if (!isNumber(gain)) reject(Error("gain must be of type 'number' ")); 1319 | if (!isString(inputType)) reject(Error("inputType must be of type 'string' ")); 1320 | if (!isBoolean(bias)) reject(Error("bias must be of type 'boolean' ")); 1321 | if (!isBoolean(srb2)) reject(Error("srb1 must be of type 'boolean' ")); 1322 | if (!isBoolean(srb1)) reject(Error("srb2 must be of type 'boolean' ")); 1323 | 1324 | // Set Channel Number 1325 | var p1 = commandChannelForCmd(channelNumber) 1326 | .catch(err => reject(err)); 1327 | 1328 | // Set POWER_DOWN 1329 | cmdPowerDown = powerDown ? obciChannelCmdPowerOff : obciChannelCmdPowerOn; 1330 | 1331 | // Set Gain 1332 | var p2 = commandForGain(gain) 1333 | .catch(err => reject(err)); 1334 | 1335 | // Set ADC string 1336 | var p3 = commandForADCString(inputType) 1337 | .catch(err => reject(err)); 1338 | 1339 | // Set BIAS 1340 | cmdBias = bias ? obciChannelCmdBiasInclude : obciChannelCmdBiasRemove; 1341 | 1342 | // Set SRB2 1343 | cmdSrb2 = srb2 ? obciChannelCmdSRB2Connect : obciChannelCmdSRB2Diconnect; 1344 | 1345 | // Set SRB1 1346 | cmdSrb1 = srb1 ? obciChannelCmdSRB1Connect : obciChannelCmdSRB1Diconnect; 1347 | 1348 | var newChannelSettingsObject = { 1349 | channelNumber: channelNumber, 1350 | powerDown: powerDown, 1351 | gain: gain, 1352 | inputType: inputType, 1353 | bias: bias, 1354 | srb2: srb2, 1355 | srb1: srb1 1356 | }; 1357 | 1358 | Promise.all([p1, p2, p3]).then(function (values) { 1359 | var outputArray = [ 1360 | obciChannelCmdSet, 1361 | values[0], 1362 | cmdPowerDown, 1363 | values[1], 1364 | values[2], 1365 | cmdBias, 1366 | cmdSrb2, 1367 | cmdSrb1, 1368 | obciChannelCmdLatch 1369 | ]; 1370 | resolve({commandArray: outputArray, newChannelSettingsObject: newChannelSettingsObject}); 1371 | }); 1372 | }); 1373 | } 1374 | 1375 | /** 1376 | * @description To build the array of commands to send to the board to measure impedance 1377 | * @param channelNumber 1378 | * @param pInputApplied - Bool (true -> Test Signal Applied, false -> Test Signal Not Applied (default)) 1379 | * applies the test signal to the P input 1380 | * @param nInputApplied - Bool (true -> Test Signal Applied, false -> Test Signal Not Applied (default)) 1381 | * applies the test signal to the N input 1382 | * @returns {Promise} - fulfilled will contain an array of comamnds 1383 | */ 1384 | function impedanceSetter (channelNumber, pInputApplied, nInputApplied) { 1385 | var cmdNInputApplied, 1386 | cmdPInputApplied; 1387 | return new Promise((resolve, reject) => { 1388 | // validate inputs 1389 | if (!isNumber(channelNumber)) reject(Error("channelNumber must be of type 'number' ")); 1390 | if (!isBoolean(pInputApplied)) reject(Error("pInputApplied must be of type 'boolean' ")); 1391 | if (!isBoolean(nInputApplied)) reject(Error("nInputApplied must be of type 'boolean' ")); 1392 | 1393 | // Set pInputApplied 1394 | cmdPInputApplied = pInputApplied ? obciChannelImpedanceTestSignalApplied : obciChannelImpedanceTestSignalAppliedNot; 1395 | 1396 | // Set nInputApplied 1397 | cmdNInputApplied = nInputApplied ? obciChannelImpedanceTestSignalApplied : obciChannelImpedanceTestSignalAppliedNot; 1398 | 1399 | // Set Channel Number 1400 | commandChannelForCmd(channelNumber).then(command => { 1401 | var outputArray = [ 1402 | obciChannelImpedanceSet, 1403 | command, 1404 | cmdPInputApplied, 1405 | cmdNInputApplied, 1406 | obciChannelImpedanceLatch 1407 | ]; 1408 | // console.log(outputArray) 1409 | resolve(outputArray); 1410 | }).catch(err => reject(err)); 1411 | }); 1412 | } 1413 | 1414 | /** 1415 | * @description To build the array of commands to send to the board to set the sample rate 1416 | * @param boardType {String} - The type of board, either cyton or ganglion. Default is Cyton 1417 | * @param sampleRate {Number} - The sample rate you want to set to. Please see docs for possible sample rates. 1418 | * @returns {Promise} - fulfilled will contain an array of commands 1419 | */ 1420 | function sampleRateSetter (boardType, sampleRate) { 1421 | return new Promise((resolve, reject) => { 1422 | // validate inputs 1423 | if (!isString(boardType)) return reject(Error("board type must be of type 'string' ")); 1424 | 1425 | if (!isNumber(sampleRate)) return reject(Error("sampleRate must be of type 'number' ")); 1426 | 1427 | sampleRate = Math.floor(sampleRate); 1428 | 1429 | let func; 1430 | if (boardType === obciBoardCyton || boardType === obciBoardDaisy) { 1431 | func = commandSampleRateForCmdCyton; 1432 | } else if (boardType === obciBoardGanglion) { 1433 | func = commandSampleRateForCmdGanglion; 1434 | } else { 1435 | return reject(Error(`boardType must be either ${obciBoardCyton} or ${obciBoardGanglion}`)); 1436 | } 1437 | 1438 | // Set Channel Number 1439 | func(sampleRate).then(command => { 1440 | var outputArray = [ 1441 | obciSampleRateSet, 1442 | command 1443 | ]; 1444 | // console.log(outputArray) 1445 | resolve(outputArray); 1446 | }).catch(err => reject(err)); 1447 | }); 1448 | } 1449 | 1450 | /** 1451 | * @description To build the array of commands to send to the board t 1452 | * @param boardMode {String} - The type of board mode: 1453 | * `default`: Board will use Accel 1454 | * ` 1455 | * @returns {Promise} - fulfilled will contain an array of commands 1456 | */ 1457 | function boardModeSetter (boardMode) { 1458 | return new Promise((resolve, reject) => { 1459 | // validate inputs 1460 | if (!isString(boardMode)) return reject(Error("board mode must be of type 'string' ")); 1461 | // Set Channel Number 1462 | commandBoardModeForMode(boardMode).then(command => { 1463 | var outputArray = [ 1464 | obciBoardModeSet, 1465 | command 1466 | ]; 1467 | // console.log(outputArray) 1468 | resolve(outputArray); 1469 | }).catch(err => reject(err)); 1470 | }); 1471 | } 1472 | 1473 | function isNumber (input) { 1474 | return (typeof input === 'number'); 1475 | } 1476 | function isBoolean (input) { 1477 | return (typeof input === 'boolean'); 1478 | } 1479 | function isString (input) { 1480 | return (typeof input === 'string'); 1481 | } 1482 | function isUndefined (input) { 1483 | return (typeof input === 'undefined'); 1484 | } 1485 | function isNull (input) { 1486 | return input === null; 1487 | } 1488 | 1489 | function commandForADCString (adcString) { 1490 | return new Promise(function (resolve, reject) { 1491 | switch (adcString) { 1492 | case obciStringADCNormal: 1493 | resolve(obciChannelCmdADCNormal); 1494 | break; 1495 | case obciStringADCShorted: 1496 | resolve(obciChannelCmdADCShorted); 1497 | break; 1498 | case obciStringADCBiasMethod: 1499 | resolve(obciChannelCmdADCBiasMethod); 1500 | break; 1501 | case obciStringADCMvdd: 1502 | resolve(obciChannelCmdADCMVDD); 1503 | break; 1504 | case obciStringADCTemp: 1505 | resolve(obciChannelCmdADCTemp); 1506 | break; 1507 | case obciStringADCTestSig: 1508 | resolve(obciChannelCmdADCTestSig); 1509 | break; 1510 | case obciStringADCBiasDrp: 1511 | resolve(obciChannelCmdADCBiasDRP); 1512 | break; 1513 | case obciStringADCBiasDrn: 1514 | resolve(obciChannelCmdADCBiasDRN); 1515 | break; 1516 | default: 1517 | reject(Error('Invalid ADC string')); 1518 | break; 1519 | } 1520 | }); 1521 | } 1522 | 1523 | /** 1524 | * Returns the input type for the given command 1525 | * @param cmd {Number} The command 1526 | * @returns {String} 1527 | */ 1528 | function inputTypeForCommand (cmd) { 1529 | switch (String(cmd)) { 1530 | case obciChannelCmdADCNormal: 1531 | return obciStringADCNormal; 1532 | case obciChannelCmdADCShorted: 1533 | return obciStringADCShorted; 1534 | case obciChannelCmdADCBiasMethod: 1535 | return obciStringADCBiasMethod; 1536 | case obciChannelCmdADCMVDD: 1537 | return obciStringADCMvdd; 1538 | case obciChannelCmdADCTemp: 1539 | return obciStringADCTemp; 1540 | case obciChannelCmdADCTestSig: 1541 | return obciStringADCTestSig; 1542 | case obciChannelCmdADCBiasDRP: 1543 | return obciStringADCBiasDrp; 1544 | case obciChannelCmdADCBiasDRN: 1545 | return obciStringADCBiasDrn; 1546 | default: 1547 | throw new Error('Invalid input type, must be less than 8'); 1548 | } 1549 | } 1550 | 1551 | function commandForGain (gainSetting) { 1552 | return new Promise(function (resolve, reject) { 1553 | switch (gainSetting) { 1554 | case 1: 1555 | resolve(obciChannelCmdGain1); 1556 | break; 1557 | case 2: 1558 | resolve(obciChannelCmdGain2); 1559 | break; 1560 | case 4: 1561 | resolve(obciChannelCmdGain4); 1562 | break; 1563 | case 6: 1564 | resolve(obciChannelCmdGain6); 1565 | break; 1566 | case 8: 1567 | resolve(obciChannelCmdGain8); 1568 | break; 1569 | case 12: 1570 | resolve(obciChannelCmdGain12); 1571 | break; 1572 | case 24: 1573 | resolve(obciChannelCmdGain24); 1574 | break; 1575 | default: 1576 | reject(Error('Invalid gain setting of ' + gainSetting + ' gain must be (1,2,4,6,8,12,24)')); 1577 | break; 1578 | } 1579 | }); 1580 | } 1581 | 1582 | /** 1583 | * Get the gain 1584 | * @param cmd {Number} 1585 | * @returns {Number} 1586 | */ 1587 | function gainForCommand (cmd) { 1588 | switch (String(cmd)) { 1589 | case obciChannelCmdGain1: 1590 | return 1; 1591 | case obciChannelCmdGain2: 1592 | return 2; 1593 | case obciChannelCmdGain4: 1594 | return 4; 1595 | case obciChannelCmdGain6: 1596 | return 6; 1597 | case obciChannelCmdGain8: 1598 | return 8; 1599 | case obciChannelCmdGain12: 1600 | return 12; 1601 | case obciChannelCmdGain24: 1602 | return 24; 1603 | default: 1604 | throw new Error(`Invalid gain setting of ${cmd} gain must be (0,1,2,3,4,5,6)`); 1605 | } 1606 | } 1607 | 1608 | function commandChannelForCmd (channelNumber) { 1609 | return new Promise(function (resolve, reject) { 1610 | switch (channelNumber) { 1611 | case 1: 1612 | resolve(obciChannelCmdChannel1); 1613 | break; 1614 | case 2: 1615 | resolve(obciChannelCmdChannel2); 1616 | break; 1617 | case 3: 1618 | resolve(obciChannelCmdChannel3); 1619 | break; 1620 | case 4: 1621 | resolve(obciChannelCmdChannel4); 1622 | break; 1623 | case 5: 1624 | resolve(obciChannelCmdChannel5); 1625 | break; 1626 | case 6: 1627 | resolve(obciChannelCmdChannel6); 1628 | break; 1629 | case 7: 1630 | resolve(obciChannelCmdChannel7); 1631 | break; 1632 | case 8: 1633 | resolve(obciChannelCmdChannel8); 1634 | break; 1635 | case 9: 1636 | resolve(obciChannelCmdChannel9); 1637 | break; 1638 | case 10: 1639 | resolve(obciChannelCmdChannel10); 1640 | break; 1641 | case 11: 1642 | resolve(obciChannelCmdChannel11); 1643 | break; 1644 | case 12: 1645 | resolve(obciChannelCmdChannel12); 1646 | break; 1647 | case 13: 1648 | resolve(obciChannelCmdChannel13); 1649 | break; 1650 | case 14: 1651 | resolve(obciChannelCmdChannel14); 1652 | break; 1653 | case 15: 1654 | resolve(obciChannelCmdChannel15); 1655 | break; 1656 | case 16: 1657 | resolve(obciChannelCmdChannel16); 1658 | break; 1659 | default: 1660 | reject(Error('Invalid channel number')); 1661 | break; 1662 | } 1663 | }); 1664 | } 1665 | 1666 | /** 1667 | * @typedef {Object} ChannelSettingsObject - See page 50 of the ads1299.pdf 1668 | * @property {Number} channelNumber - The channel number of this object 1669 | * @property {Boolean} powerDown - Power-down: - This boolean determines the channel power mode for the 1670 | * corresponding channel. `false` for normal operation, channel is on, and `true` for channel 1671 | * power-down, channel is off. (Default is `false`) 1672 | * @property {Number} gain - PGA gain: This number determines the PGA gain setting. Can be either 1, 2, 4, 6, 8, 12, 24 1673 | * (Default is 24) 1674 | * @property {String} inputType - Channel input: This string is used to determine the channel input selection. 1675 | * Can be: 1676 | * 'normal' - Normal electrode input (Default) 1677 | * 'shorted' - Input shorted (for offset or noise measurements) 1678 | * 'biasMethod' - Used in conjunction with BIAS_MEAS bit for BIAS measurements. 1679 | * 'mvdd' - MVDD for supply measurement 1680 | * 'temp' - Temperature sensor 1681 | * 'testsig' - Test signal 1682 | * 'biasDrp' - BIAS_DRP (positive electrode is the driver) 1683 | * 'biasDrn' - BIAS_DRN (negative electrode is the driver) 1684 | * @property {Boolean} bias - BIAS: Is the channel included in the bias? If `true` or yes, this channel has both P 1685 | * and N channels connected to the bias. (Default is `true`) 1686 | * @property {Boolean} srb2 - SRB2 connection: This boolean determines the SRB2 connection for the corresponding 1687 | * channel. `false` for open, not connected to channel, and `true` for closed, connected to the 1688 | * channel. (Default is `true`) 1689 | * @property {Boolean} srb1 - Stimulus, reference, and bias 1: This boolean connects the SRB2 to all 4, 6, or 8 1690 | * channels inverting inputs. `false` when switches open, disconnected, and `true` when switches 1691 | * closed, or connected. (Default is `false`) 1692 | */ 1693 | 1694 | /** 1695 | * Get an object of default board settings. 1696 | * @param channelNumber 1697 | * @returns {ChannelSettingsObject} 1698 | */ 1699 | function channelSettingsObjectDefault (channelNumber) { 1700 | return { 1701 | channelNumber: channelNumber, 1702 | powerDown: false, 1703 | gain: 24, 1704 | inputType: obciStringADCNormal, 1705 | bias: true, 1706 | srb2: true, 1707 | srb1: false 1708 | }; 1709 | } 1710 | 1711 | /** 1712 | * @description RawDataToSample default object creation 1713 | * @param numChannels {Number} - The number of channels 1714 | * @returns {RawDataToSample} - A new object 1715 | */ 1716 | function rawDataToSampleObjectDefault (numChannels) { 1717 | if (numChannels === undefined) numChannels = obciNumberOfChannelsDefault; 1718 | return { 1719 | accelArray: [0, 0, 0], 1720 | channelSettings: constantsModule.channelSettingsArrayInit(numChannels), 1721 | decompressedSamples: decompressedSamplesInit(numChannels), 1722 | lastSampleNumber: 0, 1723 | rawDataPacket: Buffer.alloc(33), 1724 | rawDataPackets: [], 1725 | scale: true, 1726 | sendCounts: false, 1727 | timeOffset: 0, 1728 | verbose: false 1729 | }; 1730 | } 1731 | 1732 | function decompressedSamplesInit (numChannels) { 1733 | let output = []; 1734 | for (let i = 0; i < 3; i++) { 1735 | output.push(new Array(numChannels)); 1736 | } 1737 | return output; 1738 | } 1739 | 1740 | /** 1741 | * Get's the command for sample rate Cyton 1742 | * @param sampleRate {Number} - The desired sample rate 1743 | * @return {Promise} 1744 | */ 1745 | function commandSampleRateForCmdCyton (sampleRate) { 1746 | return new Promise(function (resolve, reject) { 1747 | switch (sampleRate) { 1748 | case obciSampleRate16000: 1749 | resolve(obciSampleRateCmdCyton16000); 1750 | break; 1751 | case obciSampleRate8000: 1752 | resolve(obciSampleRateCmdCyton8000); 1753 | break; 1754 | case obciSampleRate4000: 1755 | resolve(obciSampleRateCmdCyton4000); 1756 | break; 1757 | case obciSampleRate2000: 1758 | resolve(obciSampleRateCmdCyton2000); 1759 | break; 1760 | case obciSampleRate1000: 1761 | resolve(obciSampleRateCmdCyton1000); 1762 | break; 1763 | case obciSampleRate500: 1764 | resolve(obciSampleRateCmdCyton500); 1765 | break; 1766 | case obciSampleRate250: 1767 | resolve(obciSampleRateCmdCyton250); 1768 | break; 1769 | default: 1770 | reject(Error('Invalid sample rate')); 1771 | break; 1772 | } 1773 | }); 1774 | } 1775 | 1776 | /** 1777 | * Get's the command for sample rate Cyton 1778 | * @param sampleRate {Number} - The desired sample rate 1779 | * @return {Promise} 1780 | */ 1781 | function commandSampleRateForCmdGanglion (sampleRate) { 1782 | return new Promise(function (resolve, reject) { 1783 | switch (sampleRate) { 1784 | case obciSampleRate25600: 1785 | resolve(obciSampleRateCmdGang25600); 1786 | break; 1787 | case obciSampleRate12800: 1788 | resolve(obciSampleRateCmdGang12800); 1789 | break; 1790 | case obciSampleRate6400: 1791 | resolve(obciSampleRateCmdGang6400); 1792 | break; 1793 | case obciSampleRate3200: 1794 | resolve(obciSampleRateCmdGang3200); 1795 | break; 1796 | case obciSampleRate1600: 1797 | resolve(obciSampleRateCmdGang1600); 1798 | break; 1799 | case obciSampleRate800: 1800 | resolve(obciSampleRateCmdGang800); 1801 | break; 1802 | case obciSampleRate400: 1803 | resolve(obciSampleRateCmdGang400); 1804 | break; 1805 | case obciSampleRate200: 1806 | resolve(obciSampleRateCmdGang200); 1807 | break; 1808 | default: 1809 | reject(Error('Invalid sample rate')); 1810 | break; 1811 | } 1812 | }); 1813 | } 1814 | 1815 | /** 1816 | * Get's the command for sample rate Cyton 1817 | * @param boardMode {String} - The desired sample rate 1818 | * @return {Promise} 1819 | */ 1820 | function commandBoardModeForMode (boardMode) { 1821 | return new Promise(function (resolve, reject) { 1822 | switch (boardMode) { 1823 | case obciBoardModeDefault: 1824 | resolve(obciBoardModeCmdDefault); 1825 | break; 1826 | case obciBoardModeDebug: 1827 | resolve(obciBoardModeCmdDebug); 1828 | break; 1829 | case obciBoardModeAnalog: 1830 | resolve(obciBoardModeCmdAnalog); 1831 | break; 1832 | case obciBoardModeDigital: 1833 | resolve(obciBoardModeCmdDigital); 1834 | break; 1835 | default: 1836 | reject(Error('Invalid sample rate')); 1837 | break; 1838 | } 1839 | }); 1840 | } 1841 | 1842 | /** 1843 | * @description Get a list of local names from an array of peripherals 1844 | */ 1845 | function getPeripheralLocalNames (pArray) { 1846 | return new Promise((resolve, reject) => { 1847 | var list = []; 1848 | pArray.forEach(perif => { 1849 | list.push(perif.advertisement.localName); 1850 | }); 1851 | if (list.length > 0) { 1852 | return resolve(list); 1853 | } else { 1854 | return reject(Error(`No peripherals discovered with prefix equal to ${obciGanglionPrefix}`)); 1855 | } 1856 | }); 1857 | } 1858 | 1859 | /** 1860 | * @description Get a peripheral with a local name 1861 | * @param `pArray` {Array} - Array of peripherals 1862 | * @param `localName` {String} - The local name of the BLE device. 1863 | */ 1864 | function getPeripheralWithLocalName (pArray, localName) { 1865 | return new Promise((resolve, reject) => { 1866 | if (typeof (pArray) !== 'object') return reject(Error(`pArray must be of type Object`)); 1867 | pArray.forEach(perif => { 1868 | if (perif.advertisement.hasOwnProperty('localName')) { 1869 | if (perif.advertisement.localName === localName) { 1870 | return resolve(perif); 1871 | } 1872 | } 1873 | }); 1874 | return reject(Error(`No peripheral found with localName: ${localName}`)); 1875 | }); 1876 | } 1877 | 1878 | /** 1879 | * @description This function is used to extract the major version from a github 1880 | * version string. 1881 | * @returns {Number} The major version number 1882 | */ 1883 | function getVersionNumber (versionStr) { 1884 | return Number(versionStr[1]); 1885 | } 1886 | 1887 | /** 1888 | * @description Very safely checks to see if the noble peripheral is a 1889 | * ganglion by way of checking the local name property. 1890 | */ 1891 | function isPeripheralGanglion (peripheral) { 1892 | if (peripheral) { 1893 | if (peripheral.hasOwnProperty('advertisement')) { 1894 | if (peripheral.advertisement !== null && peripheral.advertisement.hasOwnProperty('localName')) { 1895 | if (peripheral.advertisement.localName !== undefined && peripheral.advertisement.localName !== null) { 1896 | if (peripheral.advertisement.localName.indexOf(obciGanglionPrefix) > -1) { 1897 | return true; 1898 | } 1899 | } 1900 | } 1901 | } 1902 | } 1903 | return false; 1904 | } 1905 | 1906 | export default constantsModule; 1907 | -------------------------------------------------------------------------------- /src/debug.js: -------------------------------------------------------------------------------- 1 | 2 | import { Buffer } from 'buffer/'; 3 | 4 | /** 5 | * @description Output passed bytes on the console as a hexdump, if enabled 6 | * @param prefix - label to show to the left of bytes 7 | * @param data - bytes to output, a buffer or string 8 | * @private 9 | */ 10 | export default function debugBytes (prefix, data) { 11 | if (typeof data === 'string') data = new Buffer(data); 12 | 13 | console.log('Debug bytes:'); 14 | 15 | for (var j = 0; j < data.length;) { 16 | var hexPart = ''; 17 | var ascPart = ''; 18 | for (var end = Math.min(data.length, j + 16); j < end; ++j) { 19 | var byt = data[j]; 20 | 21 | var hex = ('0' + byt.toString(16)).slice(-2); 22 | hexPart += (((j & 0xf) === 0x8) ? ' ' : ' '); // puts an extra space 8 bytes in 23 | hexPart += hex; 24 | 25 | var asc = (byt >= 0x20 && byt < 0x7f) ? String.fromCharCode(byt) : '.'; 26 | ascPart += asc; 27 | } 28 | 29 | // pad to fixed width for alignment 30 | hexPart = (hexPart + ' ').substring(0, 3 * 17); 31 | 32 | console.log(prefix + ' ' + hexPart + '|' + ascPart + '|'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import constants from './constants'; 2 | import * as debug from './debug'; 3 | import utilities from './utilities'; 4 | 5 | export default { 6 | constants, 7 | debug, 8 | utilities 9 | }; 10 | -------------------------------------------------------------------------------- /test/bluebirdChecks.js: -------------------------------------------------------------------------------- 1 | var timingEventsAsPromises = require('./timingEventsAsPromises'); 2 | exports.BluebirdPromise = require('bluebird'); 3 | exports.PromiseIgnored = global.Promise; 4 | 5 | // Enable bluebird for all promise usage during tests only 6 | // Fails tests for issues bluebird finds 7 | // Exports a function to list all promises (getPendingPromises) 8 | // Exports a function to verify no promises pending within a timeout (noPendingPromises) 9 | 10 | exports.BluebirdPromise.config({ 11 | // TODO: wForgottenReturn is disabled because timingEventsAsPromises triggers it; find a workaround 12 | warnings: { wForgottenReturn: false }, 13 | longStackTraces: true, 14 | monitoring: true, 15 | cancellation: true 16 | }); 17 | 18 | // nextTick conveniently not instrumented by timingEventsAsPromises 19 | exports.BluebirdPromise.setScheduler(process.nextTick); 20 | 21 | // unhandled rejections become test failures 22 | process.on('unhandledRejection', (reason, promise) => { 23 | if (!(reason instanceof Error)) { 24 | reason = new Error('unhandled promise rejection: ' + reason); 25 | } else { 26 | reason.message = 'unhandled promise rejection: ' + reason.message; 27 | } 28 | process.nextTick(() => { throw reason; }); 29 | }); 30 | 31 | // // warnings become test failures 32 | // process.on('warning', (warning) => { 33 | // var error = new Error(warning); 34 | // process.nextTick(() => { throw error; }); 35 | // }); 36 | 37 | // provide access to all currently pending promises 38 | var pendingPromises = {}; 39 | var promiseId = 0; 40 | var nested = 0; 41 | 42 | function promiseCreationHandler (promise) { 43 | // promise created already resolved; ignore 44 | if (!promise.isPending()) return; 45 | 46 | // need to create another promise to get access to the extended stack trace 47 | // nested detects if we are inside our own dummy promise 48 | ++nested; 49 | if (nested === 1) { 50 | // not the dummy promise 51 | promise.___id = ++promiseId; 52 | // store promise details 53 | var error = new Error('Promise ' + promise.___id + ' is still pending'); 54 | var entry = { 55 | promise: promise, 56 | id: promise.___id, 57 | error: error 58 | }; 59 | pendingPromises[promise.___id] = entry; 60 | // extract stack trace by rejecting an error; bluebird fills in expanded stack 61 | exports.BluebirdPromise.reject(error).catch(error => { 62 | entry.error = error; 63 | entry.stack = error.stack; 64 | }); 65 | } else { 66 | promise.___nested = nested; 67 | } 68 | --nested; 69 | } 70 | process.on('promiseCreated', promiseCreationHandler); 71 | 72 | function promiseDoneHandler (promise) { 73 | if (promise.___nested) return; 74 | delete pendingPromises[promise.___id]; 75 | } 76 | process.on('promiseFulfilled', promiseDoneHandler); 77 | process.on('promiseRejected', promiseDoneHandler); 78 | process.on('promiseResolved', promiseDoneHandler); 79 | process.on('promiseCancelled', promiseDoneHandler); 80 | 81 | exports.getPendingPromises = function () { 82 | var ret = []; 83 | for (var promise in pendingPromises) { 84 | ret.push(pendingPromises[promise]); 85 | } 86 | return ret; 87 | }; 88 | 89 | exports.noPendingPromises = function (milliseconds) { 90 | if (!milliseconds) milliseconds = 0; 91 | 92 | return new exports.PromiseIgnored((resolve, reject) => { 93 | function waited100 () { 94 | var promises = exports.getPendingPromises(); 95 | 96 | if (promises.length === 0) { 97 | return resolve(); 98 | } 99 | 100 | if (milliseconds > 0) { 101 | milliseconds -= 100; 102 | return timingEventsAsPromises.setTimeoutIgnored(waited100, 100); 103 | } 104 | 105 | // timed out, but promises remaining: cancel all 106 | 107 | console.log(promises.length + ' promises still pending'); 108 | 109 | promises.forEach(promise => { 110 | promise.promise.cancel(); 111 | }); 112 | 113 | // report one 114 | reject(promises[0].error); 115 | } 116 | 117 | timingEventsAsPromises.setTimeoutIgnored(waited100, 0); 118 | }); 119 | }; 120 | 121 | // now instrument the Promise object itself to always use a simplified version of bluebird 122 | // bluebird is composed inside a bare-bones Promise object providing only the official calls 123 | 124 | global.Promise = function (handler) { 125 | this._promise = new exports.BluebirdPromise(handler); 126 | }; 127 | 128 | // compose class methods 129 | ['all', 'race', 'reject', 'resolve'].forEach(classMethod => { 130 | global.Promise[classMethod] = function () { 131 | return exports.BluebirdPromise[classMethod].apply(exports.BluebirdPromise, [].slice.call(arguments)); 132 | }; 133 | Object.defineProperty(global.Promise[classMethod], 'name', { value: 'Promise.' + classMethod }); 134 | }); 135 | 136 | // compose object methods 137 | ['then', 'catch'].forEach(objectMethod => { 138 | global.Promise.prototype[objectMethod] = function () { 139 | return this._promise[objectMethod].apply(this._promise, [].slice.call(arguments)); 140 | }; 141 | Object.defineProperty(global.Promise.prototype[objectMethod], 'name', { value: 'Promise.' + objectMethod }); 142 | }); 143 | -------------------------------------------------------------------------------- /test/openBCIConstants-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by ajk on 12/16/15. 3 | */ 4 | 'use strict'; 5 | /* global describe, it, afterEach */ 6 | let bluebirdChecks = require('./bluebirdChecks'); 7 | let assert = require('assert'); 8 | let k = require('../dist/constants'); 9 | let chai = require('chai'); 10 | let expect = chai.expect; 11 | let should = chai.should(); // eslint-disable-line no-unused-vars 12 | let chaiAsPromised = require('chai-as-promised'); 13 | chai.use(chaiAsPromised); 14 | 15 | let getListOfPeripheralsOfSize = (perifsToMake) => { 16 | perifsToMake = perifsToMake || 3; 17 | 18 | let output = []; 19 | 20 | for (let i = 0; i < perifsToMake; i++) { 21 | output.push({ 22 | advertisement: { 23 | localName: makeLocalName(i), 24 | txPowerLevel: undefined, 25 | manufacturerData: undefined, 26 | serviceData: [], 27 | serviceUuids: [] 28 | } 29 | }); 30 | } 31 | return output; 32 | }; 33 | 34 | let makeLocalName = (num) => { 35 | let localName = `${k.OBCIGanglionPrefix}-00`; 36 | if (num < 10) { 37 | localName = `${localName}0${num}`; 38 | } else { 39 | localName = `${localName}${num}`; 40 | } 41 | return localName; 42 | }; 43 | 44 | describe('OpenBCIConstants', function () { 45 | afterEach(() => bluebirdChecks.noPendingPromises()); 46 | describe('Turning Channels Off', function () { 47 | it('channel 1', function () { 48 | assert.equal('1', k.OBCIChannelOff1); 49 | }); 50 | it('channel 2', function () { 51 | assert.equal('2', k.OBCIChannelOff2); 52 | }); 53 | it('channel 3', function () { 54 | assert.equal('3', k.OBCIChannelOff3); 55 | }); 56 | it('channel 4', function () { 57 | assert.equal('4', k.OBCIChannelOff4); 58 | }); 59 | it('channel 5', function () { 60 | assert.equal('5', k.OBCIChannelOff5); 61 | }); 62 | it('channel 6', function () { 63 | assert.equal('6', k.OBCIChannelOff6); 64 | }); 65 | it('channel 7', function () { 66 | assert.equal('7', k.OBCIChannelOff7); 67 | }); 68 | it('channel 8', function () { 69 | assert.equal('8', k.OBCIChannelOff8); 70 | }); 71 | it('channel 9', function () { 72 | assert.equal('q', k.OBCIChannelOff9); 73 | }); 74 | it('channel 10', function () { 75 | assert.equal('w', k.OBCIChannelOff10); 76 | }); 77 | it('channel 11', function () { 78 | assert.equal('e', k.OBCIChannelOff11); 79 | }); 80 | it('channel 12', function () { 81 | assert.equal('r', k.OBCIChannelOff12); 82 | }); 83 | it('channel 13', function () { 84 | assert.equal('t', k.OBCIChannelOff13); 85 | }); 86 | it('channel 14', function () { 87 | assert.equal('y', k.OBCIChannelOff14); 88 | }); 89 | it('channel 15', function () { 90 | assert.equal('u', k.OBCIChannelOff15); 91 | }); 92 | it('channel 16', function () { 93 | assert.equal('i', k.OBCIChannelOff16); 94 | }); 95 | }); 96 | describe('Turning Channels On', function () { 97 | it('channel 1', function () { 98 | assert.equal('!', k.OBCIChannelOn1); 99 | }); 100 | it('channel 2', function () { 101 | assert.equal('@', k.OBCIChannelOn2); 102 | }); 103 | it('channel 3', function () { 104 | assert.equal('#', k.OBCIChannelOn3); 105 | }); 106 | it('channel 4', function () { 107 | assert.equal('$', k.OBCIChannelOn4); 108 | }); 109 | it('channel 5', function () { 110 | assert.equal('%', k.OBCIChannelOn5); 111 | }); 112 | it('channel 6', function () { 113 | assert.equal('^', k.OBCIChannelOn6); 114 | }); 115 | it('channel 7', function () { 116 | assert.equal('&', k.OBCIChannelOn7); 117 | }); 118 | it('channel 8', function () { 119 | assert.equal('*', k.OBCIChannelOn8); 120 | }); 121 | it('channel 9', function () { 122 | assert.equal('Q', k.OBCIChannelOn9); 123 | }); 124 | it('channel 10', function () { 125 | assert.equal('W', k.OBCIChannelOn10); 126 | }); 127 | it('channel 11', function () { 128 | assert.equal('E', k.OBCIChannelOn11); 129 | }); 130 | it('channel 12', function () { 131 | assert.equal('R', k.OBCIChannelOn12); 132 | }); 133 | it('channel 13', function () { 134 | assert.equal('T', k.OBCIChannelOn13); 135 | }); 136 | it('channel 14', function () { 137 | assert.equal('Y', k.OBCIChannelOn14); 138 | }); 139 | it('channel 15', function () { 140 | assert.equal('U', k.OBCIChannelOn15); 141 | }); 142 | it('channel 16', function () { 143 | assert.equal('I', k.OBCIChannelOn16); 144 | }); 145 | }); 146 | describe('Test Signal Control Commands', function () { 147 | it('Connect to DC', function () { 148 | assert.equal('p', k.OBCITestSignalConnectToDC); 149 | }); 150 | it('Connect to Ground', function () { 151 | assert.equal('0', k.OBCITestSignalConnectToGround); 152 | }); 153 | it('Connect to Pulse 1x Fast', function () { 154 | assert.equal('=', k.OBCITestSignalConnectToPulse1xFast); 155 | }); 156 | it('Connect to Pulse 1x Slow', function () { 157 | assert.equal('-', k.OBCITestSignalConnectToPulse1xSlow); 158 | }); 159 | it('Connect to Pulse 2x Fast', function () { 160 | assert.equal(']', k.OBCITestSignalConnectToPulse2xFast); 161 | }); 162 | it('Connect to Pulse 2x Slow', function () { 163 | assert.equal('[', k.OBCITestSignalConnectToPulse2xSlow); 164 | }); 165 | }); 166 | describe('Channel Setting Commands', function () { 167 | describe('Channel Selection', function () { 168 | it('Channel 1', function () { 169 | assert.equal('1', k.OBCIChannelCmdChannel1); 170 | }); 171 | it('Channel 2', function () { 172 | assert.equal('2', k.OBCIChannelCmdChannel2); 173 | }); 174 | it('Channel 3', function () { 175 | assert.equal('3', k.OBCIChannelCmdChannel3); 176 | }); 177 | it('Channel 4', function () { 178 | assert.equal('4', k.OBCIChannelCmdChannel4); 179 | }); 180 | it('Channel 5', function () { 181 | assert.equal('5', k.OBCIChannelCmdChannel5); 182 | }); 183 | it('Channel 6', function () { 184 | assert.equal('6', k.OBCIChannelCmdChannel6); 185 | }); 186 | it('Channel 7', function () { 187 | assert.equal('7', k.OBCIChannelCmdChannel7); 188 | }); 189 | it('Channel 8', function () { 190 | assert.equal('8', k.OBCIChannelCmdChannel8); 191 | }); 192 | it('Channel 9', function () { 193 | assert.equal('Q', k.OBCIChannelCmdChannel9); 194 | }); 195 | it('Channel 10', function () { 196 | assert.equal('W', k.OBCIChannelCmdChannel10); 197 | }); 198 | it('Channel 11', function () { 199 | assert.equal('E', k.OBCIChannelCmdChannel11); 200 | }); 201 | it('Channel 12', function () { 202 | assert.equal('R', k.OBCIChannelCmdChannel12); 203 | }); 204 | it('Channel 13', function () { 205 | assert.equal('T', k.OBCIChannelCmdChannel13); 206 | }); 207 | it('Channel 14', function () { 208 | assert.equal('Y', k.OBCIChannelCmdChannel14); 209 | }); 210 | it('Channel 15', function () { 211 | assert.equal('U', k.OBCIChannelCmdChannel15); 212 | }); 213 | it('Channel 16', function () { 214 | assert.equal('I', k.OBCIChannelCmdChannel16); 215 | }); 216 | }); 217 | describe('Power Down', function () { 218 | it('OFF', function () { 219 | assert.equal('1', k.OBCIChannelCmdPowerOff); 220 | }); 221 | it('ON', function () { 222 | assert.equal('0', k.OBCIChannelCmdPowerOn); 223 | }); 224 | }); 225 | describe('Gain Setting', function () { 226 | it('1', function () { 227 | assert.equal('0', k.OBCIChannelCmdGain1); 228 | }); 229 | it('2', function () { 230 | assert.equal('1', k.OBCIChannelCmdGain2); 231 | }); 232 | it('4', function () { 233 | assert.equal('2', k.OBCIChannelCmdGain4); 234 | }); 235 | it('6', function () { 236 | assert.equal('3', k.OBCIChannelCmdGain6); 237 | }); 238 | it('8', function () { 239 | assert.equal('4', k.OBCIChannelCmdGain8); 240 | }); 241 | it('12', function () { 242 | assert.equal('5', k.OBCIChannelCmdGain12); 243 | }); 244 | it('24', function () { 245 | assert.equal('6', k.OBCIChannelCmdGain24); 246 | }); 247 | }); 248 | describe('#commandForGain', function () { 249 | it('gain of 1', function () { 250 | let expectation = '0'; 251 | let result = k.commandForGain(1); 252 | return expect(result).to.eventually.equal(expectation); 253 | }); 254 | it('gain of 2', function () { 255 | let expectation = '1'; 256 | let result = k.commandForGain(2); 257 | return expect(result).to.eventually.equal(expectation); 258 | }); 259 | it('gain of 4', function () { 260 | let expectation = '2'; 261 | let result = k.commandForGain(4); 262 | return expect(result).to.eventually.equal(expectation); 263 | }); 264 | it('gain of 6', function () { 265 | let expectation = '3'; 266 | let result = k.commandForGain(6); 267 | return expect(result).to.eventually.equal(expectation); 268 | }); 269 | it('gain of 8', function () { 270 | let expectation = '4'; 271 | let result = k.commandForGain(8); 272 | return expect(result).to.eventually.equal(expectation); 273 | }); 274 | it('gain of 12', function () { 275 | let expectation = '5'; 276 | let result = k.commandForGain(12); 277 | return expect(result).to.eventually.equal(expectation); 278 | }); 279 | it('gain of 24', function () { 280 | let expectation = '6'; 281 | let result = k.commandForGain(24); 282 | return expect(result).to.eventually.equal(expectation); 283 | }); 284 | it('Invalid command request', function () { 285 | let result = k.commandForGain('taco'); 286 | return expect(result).to.be.rejected; 287 | }); 288 | }); 289 | describe('#gainForCommand', function () { 290 | it('gain of 1', function () { 291 | assert.equal(1, k.gainForCommand(k.OBCIChannelCmdGain1)); 292 | }); 293 | it('gain of 2', function () { 294 | assert.equal(2, k.gainForCommand(k.OBCIChannelCmdGain2)); 295 | }); 296 | it('gain of 4', function () { 297 | assert.equal(4, k.gainForCommand(k.OBCIChannelCmdGain4)); 298 | }); 299 | it('gain of 6', function () { 300 | assert.equal(6, k.gainForCommand(k.OBCIChannelCmdGain6)); 301 | }); 302 | it('gain of 8', function () { 303 | assert.equal(8, k.gainForCommand(k.OBCIChannelCmdGain8)); 304 | }); 305 | it('gain of 12', function () { 306 | assert.equal(12, k.gainForCommand(k.OBCIChannelCmdGain12)); 307 | }); 308 | it('gain of 24', function () { 309 | assert.equal(24, k.gainForCommand(k.OBCIChannelCmdGain24)); 310 | }); 311 | it('Invalid command request', function () { 312 | expect(k.gainForCommand.bind(k, '8')).to.throw(`Invalid gain setting of 8 gain must be (0,1,2,3,4,5,6)`); 313 | }); 314 | }); 315 | describe('#inputTypeForCommand', function () { 316 | it('Normal', function () { 317 | assert.equal(k.OBCIStringADCNormal, k.inputTypeForCommand(0)); 318 | }); 319 | it('Shorted', function () { 320 | assert.equal(k.OBCIStringADCShorted, k.inputTypeForCommand(1)); 321 | }); 322 | it('Bias Method', function () { 323 | assert.equal(k.OBCIStringADCBiasMethod, k.inputTypeForCommand(2)); 324 | }); 325 | it('MVDD', function () { 326 | assert.equal(k.OBCIStringADCMvdd, k.inputTypeForCommand(3)); 327 | }); 328 | it('Temp', function () { 329 | assert.equal(k.OBCIStringADCTemp, k.inputTypeForCommand(4)); 330 | }); 331 | it('Test Signal', function () { 332 | assert.equal(k.OBCIStringADCTestSig, k.inputTypeForCommand(5)); 333 | }); 334 | it('Bias Dr P', function () { 335 | assert.equal(k.OBCIStringADCBiasDrp, k.inputTypeForCommand(6)); 336 | }); 337 | it('Bias Dr N', function () { 338 | assert.equal(k.OBCIStringADCBiasDrn, k.inputTypeForCommand(7)); 339 | }); 340 | it('Invalid command request', function () { 341 | expect(k.inputTypeForCommand.bind(k, '8')).to.throw('Invalid input type, must be less than 8'); 342 | }); 343 | }); 344 | describe('ADC Channel Input Soruce', function () { 345 | it('Normal', function () { 346 | assert.equal('0', k.OBCIChannelCmdADCNormal); 347 | }); 348 | it('Shorted', function () { 349 | assert.equal('1', k.OBCIChannelCmdADCShorted); 350 | }); 351 | it('Bias Method', function () { 352 | assert.equal('2', k.OBCIChannelCmdADCBiasMethod); 353 | }); 354 | it('MVDD', function () { 355 | assert.equal('3', k.OBCIChannelCmdADCMVDD); 356 | }); 357 | it('Temp', function () { 358 | assert.equal('4', k.OBCIChannelCmdADCTemp); 359 | }); 360 | it('Test Signal', function () { 361 | assert.equal('5', k.OBCIChannelCmdADCTestSig); 362 | }); 363 | it('Bias DRP', function () { 364 | assert.equal('6', k.OBCIChannelCmdADCBiasDRP); 365 | }); 366 | it('Bias DRN', function () { 367 | assert.equal('7', k.OBCIChannelCmdADCBiasDRN); 368 | }); 369 | }); 370 | describe('Bias Set', function () { 371 | it('Include in BIAS', function () { 372 | assert.equal('1', k.OBCIChannelCmdBiasInclude); 373 | }); 374 | it('Remove from BIAS', function () { 375 | assert.equal('0', k.OBCIChannelCmdBiasRemove); 376 | }); 377 | }); 378 | describe('SRB2 Set', function () { 379 | it('Disconnect this input from SRB2', function () { 380 | assert.equal('0', k.OBCIChannelCmdSRB2Diconnect); 381 | }); 382 | it('Connect this input to the SRB2', function () { 383 | assert.equal('1', k.OBCIChannelCmdSRB2Connect); 384 | }); 385 | }); 386 | describe('SRB1 Set', function () { 387 | it('Disconnect this input from SRB1', function () { 388 | assert.equal('0', k.OBCIChannelCmdSRB1Diconnect); 389 | }); 390 | it('Connect this input to the SRB1', function () { 391 | assert.equal('1', k.OBCIChannelCmdSRB1Connect); 392 | }); 393 | }); 394 | it('Command to access channel settings', function () { 395 | assert.equal('x', k.OBCIChannelCmdSet); 396 | }); 397 | it('Command to latch', function () { 398 | assert.equal('X', k.OBCIChannelCmdLatch); 399 | }); 400 | }); 401 | describe('Default Channel Settings', function () { 402 | it('Set all channels to default', function () { 403 | assert.equal('d', k.OBCIChannelDefaultAllSet); 404 | }); 405 | it('Get a report of the default settings card', function () { 406 | assert.equal('D', k.OBCIChannelDefaultAllGet); 407 | }); 408 | }); 409 | describe('LeadOff Impedance Commands', function () { 410 | it('Command to access impedance settings', function () { 411 | assert.equal('z', k.OBCIChannelImpedanceSet); 412 | }); 413 | it('Command to latch', function () { 414 | assert.equal('Z', k.OBCIChannelImpedanceLatch); 415 | }); 416 | it('Test signal not applied', function () { 417 | assert.equal('0', k.OBCIChannelImpedanceTestSignalAppliedNot); 418 | }); 419 | it('Test signal applied', function () { 420 | assert.equal('1', k.OBCIChannelImpedanceTestSignalApplied); 421 | }); 422 | }); 423 | describe('Time Sync Stuff', function () { 424 | it('Can get proper array size', function () { 425 | assert.equal(10, k.OBCITimeSyncArraySize); 426 | }); 427 | it('Get correct time sync with conf', function () { 428 | assert.equal(0.9, k.OBCITimeSyncMultiplierWithSyncConf); 429 | }); 430 | it('Get correct time sync without conf', function () { 431 | assert.equal(0.75, k.OBCITimeSyncMultiplierWithoutSyncConf); 432 | }); 433 | it('Get correct time sync transmission threshold', function () { 434 | assert.equal(10, k.OBCITimeSyncThresholdTransFailureMS); 435 | }); 436 | }); 437 | describe('SD card Commands', function () { 438 | it('logs for 1 hour', function () { 439 | assert.equal('G', k.OBCISDLogForHour1); 440 | }); 441 | it('logs for 2 hours', function () { 442 | assert.equal('H', k.OBCISDLogForHour2); 443 | }); 444 | it('logs for 4 hours', function () { 445 | assert.equal('J', k.OBCISDLogForHour4); 446 | }); 447 | it('logs for 12 hours', function () { 448 | assert.equal('K', k.OBCISDLogForHour12); 449 | }); 450 | it('logs for 24 hours', function () { 451 | assert.equal('L', k.OBCISDLogForHour24); 452 | }); 453 | it('logs for 5 minutes', function () { 454 | assert.equal('A', k.OBCISDLogForMin5); 455 | }); 456 | it('logs for 15 minutes', function () { 457 | assert.equal('S', k.OBCISDLogForMin15); 458 | }); 459 | it('logs for 30 minutes', function () { 460 | assert.equal('F', k.OBCISDLogForMin30); 461 | }); 462 | it('logs for 14 seconds', function () { 463 | assert.equal('a', k.OBCISDLogForSec14); 464 | }); 465 | it('stop logging and close the SD file', function () { 466 | assert.equal('j', k.OBCISDLogStop); 467 | }); 468 | }); 469 | describe('SD card string Commands', function () { 470 | it('logs for 1 hour', function () { 471 | assert.equal('1hour', k.OBCIStringSDHour1); 472 | }); 473 | it('logs for 2 hours', function () { 474 | assert.equal('2hour', k.OBCIStringSDHour2); 475 | }); 476 | it('logs for 4 hours', function () { 477 | assert.equal('4hour', k.OBCIStringSDHour4); 478 | }); 479 | it('logs for 12 hours', function () { 480 | assert.equal('12hour', k.OBCIStringSDHour12); 481 | }); 482 | it('logs for 24 hours', function () { 483 | assert.equal('24hour', k.OBCIStringSDHour24); 484 | }); 485 | it('logs for 5 minutes', function () { 486 | assert.equal('5min', k.OBCIStringSDMin5); 487 | }); 488 | it('logs for 15 minutes', function () { 489 | assert.equal('15min', k.OBCIStringSDMin15); 490 | }); 491 | it('logs for 30 minutes', function () { 492 | assert.equal('30min', k.OBCIStringSDMin30); 493 | }); 494 | it('logs for 14 seconds', function () { 495 | assert.equal('14sec', k.OBCIStringSDSec14); 496 | }); 497 | }); 498 | describe('#sdSettingForString', function () { 499 | it('correct command for 1 hour', function () { 500 | let expectation = k.OBCISDLogForHour1; 501 | let result = k.sdSettingForString('1hour'); 502 | return expect(result).to.eventually.equal(expectation); 503 | }); 504 | it('correct command for 2 hour', function () { 505 | let expectation = k.OBCISDLogForHour2; 506 | let result = k.sdSettingForString('2hour'); 507 | return expect(result).to.eventually.equal(expectation); 508 | }); 509 | it('correct command for 4 hour', function () { 510 | let expectation = k.OBCISDLogForHour4; 511 | let result = k.sdSettingForString('4hour'); 512 | return expect(result).to.eventually.equal(expectation); 513 | }); 514 | it('correct command for 12 hour', function () { 515 | let expectation = k.OBCISDLogForHour12; 516 | let result = k.sdSettingForString('12hour'); 517 | return expect(result).to.eventually.equal(expectation); 518 | }); 519 | it('correct command for 24 hour', function () { 520 | let expectation = k.OBCISDLogForHour24; 521 | let result = k.sdSettingForString('24hour'); 522 | return expect(result).to.eventually.equal(expectation); 523 | }); 524 | it('correct command for 5 min', function () { 525 | let expectation = k.OBCISDLogForMin5; 526 | let result = k.sdSettingForString('5min'); 527 | return expect(result).to.eventually.equal(expectation); 528 | }); 529 | it('correct command for 15 min', function () { 530 | let expectation = k.OBCISDLogForMin15; 531 | let result = k.sdSettingForString('15min'); 532 | return expect(result).to.eventually.equal(expectation); 533 | }); 534 | it('correct command for 30 min', function () { 535 | let expectation = k.OBCISDLogForMin30; 536 | let result = k.sdSettingForString('30min'); 537 | return expect(result).to.eventually.equal(expectation); 538 | }); 539 | it('correct command for 14 seconds', function () { 540 | let expectation = k.OBCISDLogForSec14; 541 | let result = k.sdSettingForString('14sec'); 542 | return expect(result).to.eventually.equal(expectation); 543 | }); 544 | it('Invalid command request', function () { 545 | let result = k.sdSettingForString('taco'); 546 | return expect(result).to.be.rejected; 547 | }); 548 | }); 549 | describe('Stream Data Commands', function () { 550 | it('starts', function () { 551 | assert.equal('b', k.OBCIStreamStart); 552 | }); 553 | it('stops', function () { 554 | assert.equal('s', k.OBCIStreamStop); 555 | }); 556 | }); 557 | describe('Accel enable/disable commands', function () { 558 | it('starts', function () { 559 | assert.equal('n', k.OBCIAccelStart); 560 | }); 561 | it('stops', function () { 562 | assert.equal('N', k.OBCIAccelStop); 563 | }); 564 | }); 565 | describe('Accel packet numbers', function () { 566 | it('X axis', function () { 567 | assert.equal(1, k.OBCIGanglionAccelAxisX); 568 | }); 569 | it('Y axis', function () { 570 | assert.equal(2, k.OBCIGanglionAccelAxisY); 571 | }); 572 | it('Z axis', function () { 573 | assert.equal(3, k.OBCIGanglionAccelAxisZ); 574 | }); 575 | }); 576 | describe('Miscellaneous', function () { 577 | it('queries register settings', function () { 578 | assert.equal('?', k.OBCIMiscQueryRegisterSettings); 579 | }); 580 | it('softly resets the board', function () { 581 | assert.equal('v', k.OBCIMiscSoftReset); 582 | }); 583 | }); 584 | describe('Max channel number commands', function () { 585 | it('sets max of 8', function () { 586 | assert.equal('c', k.OBCIChannelMaxNumber8); 587 | }); 588 | it('sets max of 16', function () { 589 | assert.equal('C', k.OBCIChannelMaxNumber16); 590 | }); 591 | it('has correct return messages', function () { 592 | assert.equal('', k.OBCIChannelMaxNumber8NoDaisyToRemove); 593 | assert.equal('daisy removed', k.OBCIChannelMaxNumber8SuccessDaisyRemoved); 594 | assert.equal('16', k.OBCIChannelMaxNumber16DaisyAlreadyAttached); 595 | assert.equal('daisy attached16', k.OBCIChannelMaxNumber16DaisyAttached); 596 | assert.equal('no daisy to attach!8', k.OBCIChannelMaxNumber16NoDaisyAttached); 597 | }); 598 | }); 599 | describe('On board filters', function () { 600 | it('disable', function () { 601 | assert.equal('g', k.OBCIFilterDisable); 602 | }); 603 | it('enable', function () { 604 | assert.equal('f', k.OBCIFilterEnable); 605 | }); 606 | }); 607 | describe('Stream packet types/codes', function () { 608 | it('Standard with Accel', function () { 609 | assert.equal(0, k.OBCIStreamPacketStandardAccel); 610 | }); 611 | it('Standard with Raw Aux', function () { 612 | assert.equal(1, k.OBCIStreamPacketStandardRawAux); 613 | }); 614 | it('User Defined Packet', function () { 615 | assert.equal(2, k.OBCIStreamPacketUserDefinedType); 616 | }); 617 | it('Time Sync Set with accel', function () { 618 | assert.equal(3, k.OBCIStreamPacketAccelTimeSyncSet); 619 | }); 620 | it('Time Synced with Accel', function () { 621 | assert.equal(4, k.OBCIStreamPacketAccelTimeSynced); 622 | }); 623 | it('Time Sync set with Raw Aux', function () { 624 | assert.equal(5, k.OBCIStreamPacketRawAuxTimeSyncSet); 625 | }); 626 | it('Time Synced with Raw Aux', function () { 627 | assert.equal(6, k.OBCIStreamPacketRawAuxTimeSynced); 628 | }); 629 | it('Time Synced with Raw Aux', function () { 630 | assert.equal(7, k.OBCIStreamPacketImpedance); 631 | }); 632 | }); 633 | describe('Time synced with accel packet', function () { 634 | it('X axis', function () { 635 | assert.equal(7, k.OBCIAccelAxisX); 636 | }); 637 | it('Y axis', function () { 638 | assert.equal(8, k.OBCIAccelAxisY); 639 | }); 640 | it('Z axis', function () { 641 | assert.equal(9, k.OBCIAccelAxisZ); 642 | }); 643 | }); 644 | describe('Time sync useful numbers', function () { 645 | it('Time from the board is 4 bytes', function () { 646 | assert.equal(4, k.OBCIStreamPacketTimeByteSize); 647 | }); 648 | }); 649 | describe('should return the right command for each channel', function () { 650 | it('Channel 1', function () { 651 | let expectation = '1'; 652 | let result = k.commandChannelForCmd(1); 653 | return expect(result).to.eventually.equal(expectation); 654 | }); 655 | it('Channel 2', function () { 656 | let expectation = '2'; 657 | let result = k.commandChannelForCmd(2); 658 | return expect(result).to.eventually.equal(expectation); 659 | }); 660 | it('Channel 3', function () { 661 | let expectation = '3'; 662 | let result = k.commandChannelForCmd(3); 663 | return expect(result).to.eventually.equal(expectation); 664 | }); 665 | it('Channel 4', function () { 666 | let expectation = '4'; 667 | let result = k.commandChannelForCmd(4); 668 | return expect(result).to.eventually.equal(expectation); 669 | }); 670 | it('Channel 5', function () { 671 | let expectation = '5'; 672 | let result = k.commandChannelForCmd(5); 673 | return expect(result).to.eventually.equal(expectation); 674 | }); 675 | it('Channel 6', function () { 676 | let expectation = '6'; 677 | let result = k.commandChannelForCmd(6); 678 | return expect(result).to.eventually.equal(expectation); 679 | }); 680 | it('Channel 7', function () { 681 | let expectation = '7'; 682 | let result = k.commandChannelForCmd(7); 683 | return expect(result).to.eventually.equal(expectation); 684 | }); 685 | it('Channel 8', function () { 686 | let expectation = '8'; 687 | let result = k.commandChannelForCmd(8); 688 | return expect(result).to.eventually.equal(expectation); 689 | }); 690 | it('Channel 9', function () { 691 | let expectation = 'Q'; 692 | let result = k.commandChannelForCmd(9); 693 | return expect(result).to.eventually.equal(expectation); 694 | }); 695 | it('Channel 10', function () { 696 | let expectation = 'W'; 697 | let result = k.commandChannelForCmd(10); 698 | return expect(result).to.eventually.equal(expectation); 699 | }); 700 | it('Channel 11', function () { 701 | let expectation = 'E'; 702 | let result = k.commandChannelForCmd(11); 703 | return expect(result).to.eventually.equal(expectation); 704 | }); 705 | it('Channel 12', function () { 706 | let expectation = 'R'; 707 | let result = k.commandChannelForCmd(12); 708 | return expect(result).to.eventually.equal(expectation); 709 | }); 710 | it('Channel 13', function () { 711 | let expectation = 'T'; 712 | let result = k.commandChannelForCmd(13); 713 | return expect(result).to.eventually.equal(expectation); 714 | }); 715 | it('Channel 14', function () { 716 | let expectation = 'Y'; 717 | let result = k.commandChannelForCmd(14); 718 | return expect(result).to.eventually.equal(expectation); 719 | }); 720 | it('Channel 15', function () { 721 | let expectation = 'U'; 722 | let result = k.commandChannelForCmd(15); 723 | return expect(result).to.eventually.equal(expectation); 724 | }); 725 | it('Channel 16', function () { 726 | let expectation = 'I'; 727 | let result = k.commandChannelForCmd(16); 728 | return expect(result).to.eventually.equal(expectation); 729 | }); 730 | it('Invalid channel request', function () { 731 | let result = k.commandChannelForCmd(17); 732 | return expect(result).to.be.rejected; 733 | }); 734 | }); 735 | describe('should return correct channel off command for number', function () { 736 | it('Channel 1', function () { 737 | let expectation = '1'; 738 | let result = k.commandChannelOff(1); 739 | return expect(result).to.eventually.equal(expectation); 740 | }); 741 | it('Channel 2', function () { 742 | let expectation = '2'; 743 | let result = k.commandChannelOff(2); 744 | return expect(result).to.eventually.equal(expectation); 745 | }); 746 | it('Channel 3', function () { 747 | let expectation = '3'; 748 | let result = k.commandChannelOff(3); 749 | return expect(result).to.eventually.equal(expectation); 750 | }); 751 | it('Channel 4', function () { 752 | let expectation = '4'; 753 | let result = k.commandChannelOff(4); 754 | return expect(result).to.eventually.equal(expectation); 755 | }); 756 | it('Channel 5', function () { 757 | let expectation = '5'; 758 | let result = k.commandChannelOff(5); 759 | return expect(result).to.eventually.equal(expectation); 760 | }); 761 | it('Channel 6', function () { 762 | let expectation = '6'; 763 | let result = k.commandChannelOff(6); 764 | return expect(result).to.eventually.equal(expectation); 765 | }); 766 | it('Channel 7', function () { 767 | let expectation = '7'; 768 | let result = k.commandChannelOff(7); 769 | return expect(result).to.eventually.equal(expectation); 770 | }); 771 | it('Channel 8', function () { 772 | let expectation = '8'; 773 | let result = k.commandChannelOff(8); 774 | return expect(result).to.eventually.equal(expectation); 775 | }); 776 | it('Channel 9', function () { 777 | let expectation = 'q'; 778 | let result = k.commandChannelOff(9); 779 | return expect(result).to.eventually.equal(expectation); 780 | }); 781 | it('Channel 10', function () { 782 | let expectation = 'w'; 783 | let result = k.commandChannelOff(10); 784 | return expect(result).to.eventually.equal(expectation); 785 | }); 786 | it('Channel 11', function () { 787 | let expectation = 'e'; 788 | let result = k.commandChannelOff(11); 789 | return expect(result).to.eventually.equal(expectation); 790 | }); 791 | it('Channel 12', function () { 792 | let expectation = 'r'; 793 | let result = k.commandChannelOff(12); 794 | return expect(result).to.eventually.equal(expectation); 795 | }); 796 | it('Channel 13', function () { 797 | let expectation = 't'; 798 | let result = k.commandChannelOff(13); 799 | return expect(result).to.eventually.equal(expectation); 800 | }); 801 | it('Channel 14', function () { 802 | let expectation = 'y'; 803 | let result = k.commandChannelOff(14); 804 | return expect(result).to.eventually.equal(expectation); 805 | }); 806 | it('Channel 15', function () { 807 | let expectation = 'u'; 808 | let result = k.commandChannelOff(15); 809 | return expect(result).to.eventually.equal(expectation); 810 | }); 811 | it('Channel 16', function () { 812 | let expectation = 'i'; 813 | let result = k.commandChannelOff(16); 814 | return expect(result).to.eventually.equal(expectation); 815 | }); 816 | it('Invalid channel request', function () { 817 | let result = k.commandChannelOff(17); 818 | return expect(result).to.be.rejected; 819 | }); 820 | }); 821 | describe('should return the right command for each sample rate for cyton', function () { 822 | it('sample rate 16000', function () { 823 | let expectation = '0'; 824 | let result = k.commandSampleRateForCmdCyton(16000); 825 | return expect(result).to.eventually.equal(expectation); 826 | }); 827 | it('sample rate 8000', function () { 828 | let expectation = '1'; 829 | let result = k.commandSampleRateForCmdCyton(8000); 830 | return expect(result).to.eventually.equal(expectation); 831 | }); 832 | it('sample rate 4000', function () { 833 | let expectation = '2'; 834 | let result = k.commandSampleRateForCmdCyton(4000); 835 | return expect(result).to.eventually.equal(expectation); 836 | }); 837 | it('sample rate 2000', function () { 838 | let expectation = '3'; 839 | let result = k.commandSampleRateForCmdCyton(2000); 840 | return expect(result).to.eventually.equal(expectation); 841 | }); 842 | it('sample rate 1000', function () { 843 | let expectation = '4'; 844 | let result = k.commandSampleRateForCmdCyton(1000); 845 | return expect(result).to.eventually.equal(expectation); 846 | }); 847 | it('sample rate 500', function () { 848 | let expectation = '5'; 849 | let result = k.commandSampleRateForCmdCyton(500); 850 | return expect(result).to.eventually.equal(expectation); 851 | }); 852 | it('sample rate 250', function () { 853 | let expectation = '6'; 854 | let result = k.commandSampleRateForCmdCyton(250); 855 | return expect(result).to.eventually.equal(expectation); 856 | }); 857 | it('Invalid sample rate', function () { 858 | let result = k.commandSampleRateForCmdCyton(17); 859 | return expect(result).to.be.rejected; 860 | }); 861 | it('Invalid sample rate type', function () { 862 | let result = k.commandSampleRateForCmdCyton('taco'); 863 | return expect(result).to.be.rejected; 864 | }); 865 | }); 866 | describe('should return the right command for each sample rate for ganglion', function () { 867 | it('sample rate 25600', function () { 868 | let expectation = '0'; 869 | let result = k.commandSampleRateForCmdGanglion(25600); 870 | return expect(result).to.eventually.equal(expectation); 871 | }); 872 | it('sample rate 12800', function () { 873 | let expectation = '1'; 874 | let result = k.commandSampleRateForCmdGanglion(12800); 875 | return expect(result).to.eventually.equal(expectation); 876 | }); 877 | it('sample rate 6400', function () { 878 | let expectation = '2'; 879 | let result = k.commandSampleRateForCmdGanglion(6400); 880 | return expect(result).to.eventually.equal(expectation); 881 | }); 882 | it('sample rate 3200', function () { 883 | let expectation = '3'; 884 | let result = k.commandSampleRateForCmdGanglion(3200); 885 | return expect(result).to.eventually.equal(expectation); 886 | }); 887 | it('sample rate 1600', function () { 888 | let expectation = '4'; 889 | let result = k.commandSampleRateForCmdGanglion(1600); 890 | return expect(result).to.eventually.equal(expectation); 891 | }); 892 | it('sample rate 800', function () { 893 | let expectation = '5'; 894 | let result = k.commandSampleRateForCmdGanglion(800); 895 | return expect(result).to.eventually.equal(expectation); 896 | }); 897 | it('sample rate 400', function () { 898 | let expectation = '6'; 899 | let result = k.commandSampleRateForCmdGanglion(400); 900 | return expect(result).to.eventually.equal(expectation); 901 | }); 902 | it('sample rate 200', function () { 903 | let expectation = '7'; 904 | let result = k.commandSampleRateForCmdGanglion(200); 905 | return expect(result).to.eventually.equal(expectation); 906 | }); 907 | it('Invalid sample rate', function () { 908 | let result = k.commandSampleRateForCmdGanglion(17); 909 | return expect(result).to.be.rejected; 910 | }); 911 | it('Invalid sample rate type', function () { 912 | let result = k.commandSampleRateForCmdGanglion('taco'); 913 | return expect(result).to.be.rejected; 914 | }); 915 | }); 916 | describe('should return the right command for each board mode', function () { 917 | it('board mode default', function () { 918 | let expectation = '0'; 919 | let result = k.commandBoardModeForMode('default'); 920 | return expect(result).to.eventually.equal(expectation); 921 | }); 922 | it('board mode debug', function () { 923 | let expectation = '1'; 924 | let result = k.commandBoardModeForMode('debug'); 925 | return expect(result).to.eventually.equal(expectation); 926 | }); 927 | it('board mode 2', function () { 928 | let expectation = '2'; 929 | let result = k.commandBoardModeForMode('analog'); 930 | return expect(result).to.eventually.equal(expectation); 931 | }); 932 | it('board mode 3', function () { 933 | let expectation = '3'; 934 | let result = k.commandBoardModeForMode('digital'); 935 | return expect(result).to.eventually.equal(expectation); 936 | }); 937 | it('Invalid board mode', function () { 938 | let result = k.commandBoardModeForMode(10); 939 | return expect(result).to.be.rejected; 940 | }); 941 | it('Invalid board mode', function () { 942 | let result = k.commandBoardModeForMode('taco'); 943 | return expect(result).to.be.rejected; 944 | }); 945 | }); 946 | describe('should return correct channel on command for number', function () { 947 | it('Channel 1', function () { 948 | let expectation = '!'; 949 | let result = k.commandChannelOn(1); 950 | return expect(result).to.eventually.equal(expectation); 951 | }); 952 | it('Channel 2', function () { 953 | let expectation = '@'; 954 | let result = k.commandChannelOn(2); 955 | return expect(result).to.eventually.equal(expectation); 956 | }); 957 | it('Channel 3', function () { 958 | let expectation = '#'; 959 | let result = k.commandChannelOn(3); 960 | return expect(result).to.eventually.equal(expectation); 961 | }); 962 | it('Channel 4', function () { 963 | let expectation = '$'; 964 | let result = k.commandChannelOn(4); 965 | return expect(result).to.eventually.equal(expectation); 966 | }); 967 | it('Channel 5', function () { 968 | let expectation = '%'; 969 | let result = k.commandChannelOn(5); 970 | return expect(result).to.eventually.equal(expectation); 971 | }); 972 | it('Channel 6', function () { 973 | let expectation = '^'; 974 | let result = k.commandChannelOn(6); 975 | return expect(result).to.eventually.equal(expectation); 976 | }); 977 | it('Channel 7', function () { 978 | let expectation = '&'; 979 | let result = k.commandChannelOn(7); 980 | return expect(result).to.eventually.equal(expectation); 981 | }); 982 | it('Channel 8', function () { 983 | let expectation = '*'; 984 | let result = k.commandChannelOn(8); 985 | return expect(result).to.eventually.equal(expectation); 986 | }); 987 | it('Channel 9', function () { 988 | let expectation = 'Q'; 989 | let result = k.commandChannelOn(9); 990 | return expect(result).to.eventually.equal(expectation); 991 | }); 992 | it('Channel 10', function () { 993 | let expectation = 'W'; 994 | let result = k.commandChannelOn(10); 995 | return expect(result).to.eventually.equal(expectation); 996 | }); 997 | it('Channel 11', function () { 998 | let expectation = 'E'; 999 | let result = k.commandChannelOn(11); 1000 | return expect(result).to.eventually.equal(expectation); 1001 | }); 1002 | it('Channel 12', function () { 1003 | let expectation = 'R'; 1004 | let result = k.commandChannelOn(12); 1005 | return expect(result).to.eventually.equal(expectation); 1006 | }); 1007 | it('Channel 13', function () { 1008 | let expectation = 'T'; 1009 | let result = k.commandChannelOn(13); 1010 | return expect(result).to.eventually.equal(expectation); 1011 | }); 1012 | it('Channel 14', function () { 1013 | let expectation = 'Y'; 1014 | let result = k.commandChannelOn(14); 1015 | return expect(result).to.eventually.equal(expectation); 1016 | }); 1017 | it('Channel 15', function () { 1018 | let expectation = 'U'; 1019 | let result = k.commandChannelOn(15); 1020 | return expect(result).to.eventually.equal(expectation); 1021 | }); 1022 | it('Channel 16', function () { 1023 | let expectation = 'I'; 1024 | let result = k.commandChannelOn(16); 1025 | return expect(result).to.eventually.equal(expectation); 1026 | }); 1027 | it('Invalid channel request', function () { 1028 | let result = k.commandChannelOn(17); 1029 | return expect(result).to.be.rejected; 1030 | }); 1031 | }); 1032 | describe('Number of channels', function () { 1033 | it('Daisy', function () { 1034 | assert.equal(16, k.OBCINumberOfChannelsDaisy); 1035 | }); 1036 | it('Default', function () { 1037 | assert.equal(8, k.OBCINumberOfChannelsDefault); 1038 | }); 1039 | it('Cyton', function () { 1040 | assert.equal(8, k.OBCINumberOfChannelsCyton); 1041 | }); 1042 | it('Cyton', function () { 1043 | assert.equal(2, k.OBCINumberOfChannelsCytonBLE); 1044 | }); 1045 | it('Ganglion', function () { 1046 | assert.equal(4, k.OBCINumberOfChannelsGanglion); 1047 | }); 1048 | }); 1049 | describe('Possible Sample Rates', function () { 1050 | it('should be 125', function () { 1051 | assert.equal(125, k.OBCISampleRate125); 1052 | }); 1053 | it('should be 250', function () { 1054 | assert.equal(250, k.OBCISampleRate250); 1055 | }); 1056 | }); 1057 | describe('Max sample number', function () { 1058 | it('should be 255', function () { 1059 | assert.equal(255, k.OBCISampleNumberMax); 1060 | }); 1061 | }); 1062 | describe('Radio Channel Limits', function () { 1063 | it('should get the right channel number max', function () { 1064 | expect(k.OBCIRadioChannelMax).to.be.equal(25); 1065 | }); 1066 | it('should get the right channel number min', function () { 1067 | expect(k.OBCIRadioChannelMin).to.be.equal(1); 1068 | }); 1069 | it('should get the right poll time max', function () { 1070 | expect(k.OBCIRadioPollTimeMax).to.be.equal(255); 1071 | }); 1072 | it('should get the right poll time min', function () { 1073 | expect(k.OBCIRadioPollTimeMin).to.be.equal(0); 1074 | }); 1075 | }); 1076 | describe('Board Types', function () { 1077 | it('should get right name for chan daisy', function () { 1078 | expect(k.OBCIBoardDaisy).to.equal('daisy'); 1079 | }); 1080 | it('should get right name for chan cyton', function () { 1081 | expect(k.OBCIBoardCyton).to.equal('cyton'); 1082 | }); 1083 | it('should get right name for chan cyton BLE', function () { 1084 | expect(k.OBCIBoardCytonBLE).to.equal('cytonBLE'); 1085 | }); 1086 | it('should get right name for chan ganglion', function () { 1087 | expect(k.OBCIBoardGanglion).to.equal('ganglion'); 1088 | }); 1089 | it('should get right name for chan none', function () { 1090 | expect(k.OBCIBoardNone).to.equal('none'); 1091 | }); 1092 | }); 1093 | describe('numberOfChannelsForBoardTypes', function () { 1094 | it('should get right num chan for daisy board', function () { 1095 | expect(k.numberOfChannelsForBoardType(k.OBCIBoardDaisy)).to.equal(16); 1096 | }); 1097 | it('should get right num chan for cyton board', function () { 1098 | expect(k.numberOfChannelsForBoardType(k.OBCIBoardCyton)).to.equal(8); 1099 | }); 1100 | it('should get right num chan for cyton BLE board', function () { 1101 | expect(k.numberOfChannelsForBoardType(k.OBCIBoardCytonBLE)).to.equal(2); 1102 | }); 1103 | it('should get right num chan for ganglion', function () { 1104 | expect(k.numberOfChannelsForBoardType(k.OBCIBoardGanglion)).to.equal(4); 1105 | }); 1106 | it('should get right num chan for none', function () { 1107 | expect(k.numberOfChannelsForBoardType(k.OBCIBoardNone)).to.equal(0); 1108 | }); 1109 | }); 1110 | describe('boardTypeForNumberOfChannels', function () { 1111 | it('should get daisy board right for num chan', function () { 1112 | expect(k.boardTypeForNumberOfChannels(16)).to.equal(k.OBCIBoardDaisy); 1113 | }); 1114 | it('should get cyton board right for num chan', function () { 1115 | expect(k.boardTypeForNumberOfChannels(8)).to.equal(k.OBCIBoardCyton); 1116 | }); 1117 | it('should get cyton BLE board right for num chan', function () { 1118 | expect(k.boardTypeForNumberOfChannels(2)).to.equal(k.OBCIBoardCytonBLE); 1119 | }); 1120 | it('should get ganglion right for num chan', function () { 1121 | expect(k.boardTypeForNumberOfChannels(4)).to.equal(k.OBCIBoardGanglion); 1122 | }); 1123 | it('should get none right for num chan', function () { 1124 | expect(k.boardTypeForNumberOfChannels(0)).to.equal(k.OBCIBoardNone); 1125 | }); 1126 | }); 1127 | describe('#getChannelSetter', function () { 1128 | // 'channel 1, power on, gain 24, inputType normal, bias include, srb2 connect, srb1 dissconnect' 1129 | describe('channel input selection works', function () { 1130 | // this.timeout(5000) 1131 | it('channel 2', function (done) { 1132 | k.getChannelSetter(2, false, 24, 'normal', true, true, false).then(function (val) { 1133 | val.commandArray[1].should.equal('2'); 1134 | val.newChannelSettingsObject.channelNumber.should.equal(2); 1135 | val.newChannelSettingsObject.powerDown.should.equal(false); 1136 | val.newChannelSettingsObject.gain.should.equal(24); 1137 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1138 | val.newChannelSettingsObject.bias.should.equal(true); 1139 | val.newChannelSettingsObject.srb2.should.equal(true); 1140 | val.newChannelSettingsObject.srb1.should.equal(false); 1141 | done(); 1142 | }).catch(function (err) { 1143 | done(err); 1144 | }); 1145 | }); 1146 | it('channel 5', function (done) { 1147 | k.getChannelSetter(5, false, 24, 'normal', true, true, false).then(function (val) { 1148 | val.commandArray[1].should.equal('5'); 1149 | val.newChannelSettingsObject.channelNumber.should.equal(5); 1150 | val.newChannelSettingsObject.powerDown.should.equal(false); 1151 | val.newChannelSettingsObject.gain.should.equal(24); 1152 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1153 | val.newChannelSettingsObject.bias.should.equal(true); 1154 | val.newChannelSettingsObject.srb2.should.equal(true); 1155 | val.newChannelSettingsObject.srb1.should.equal(false); 1156 | done(); 1157 | }).catch(function (err) { 1158 | done(err); 1159 | }); 1160 | }); 1161 | it('channel 9', function (done) { 1162 | k.getChannelSetter(9, false, 24, 'normal', true, true, false).then(function (val) { 1163 | val.commandArray[1].should.equal('Q'); 1164 | val.newChannelSettingsObject.channelNumber.should.equal(9); 1165 | val.newChannelSettingsObject.powerDown.should.equal(false); 1166 | val.newChannelSettingsObject.gain.should.equal(24); 1167 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1168 | val.newChannelSettingsObject.bias.should.equal(true); 1169 | val.newChannelSettingsObject.srb2.should.equal(true); 1170 | val.newChannelSettingsObject.srb1.should.equal(false); 1171 | done(); 1172 | }).catch(function (err) { 1173 | done(err); 1174 | }); 1175 | }); 1176 | it('channel 15', function (done) { 1177 | k.getChannelSetter(15, false, 24, 'normal', true, true, false).then(function (val) { 1178 | val.commandArray[1].should.equal('U'); 1179 | val.newChannelSettingsObject.channelNumber.should.equal(15); 1180 | val.newChannelSettingsObject.powerDown.should.equal(false); 1181 | val.newChannelSettingsObject.gain.should.equal(24); 1182 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1183 | val.newChannelSettingsObject.bias.should.equal(true); 1184 | val.newChannelSettingsObject.srb2.should.equal(true); 1185 | val.newChannelSettingsObject.srb1.should.equal(false); 1186 | done(); 1187 | }).catch(function (err) { 1188 | done(err); 1189 | }); 1190 | }); 1191 | it('Invalid channel selection', function (done) { 1192 | k.getChannelSetter(0, false, 24, 'normal', true, true, false).should.be.rejected.and.notify(done); 1193 | }); 1194 | it('Invalid type', function (done) { 1195 | k.getChannelSetter('0', false, 24, 'normal', true, true, false).should.be.rejected.and.notify(done); 1196 | }); 1197 | }); 1198 | describe('power selection works', function () { 1199 | it('on', function (done) { 1200 | k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) { 1201 | val.commandArray[2].should.equal('0'); 1202 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1203 | val.newChannelSettingsObject.powerDown.should.equal(false); 1204 | val.newChannelSettingsObject.gain.should.equal(24); 1205 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1206 | val.newChannelSettingsObject.bias.should.equal(true); 1207 | val.newChannelSettingsObject.srb2.should.equal(true); 1208 | val.newChannelSettingsObject.srb1.should.equal(false); 1209 | done(); 1210 | }).catch(function (err) { 1211 | done(err); 1212 | }); 1213 | }); 1214 | it('off', function (done) { 1215 | k.getChannelSetter(1, true, 24, 'normal', true, true, false).then(function (val) { 1216 | val.commandArray[2].should.equal('1'); 1217 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1218 | val.newChannelSettingsObject.powerDown.should.equal(true); 1219 | val.newChannelSettingsObject.gain.should.equal(24); 1220 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1221 | val.newChannelSettingsObject.bias.should.equal(true); 1222 | val.newChannelSettingsObject.srb2.should.equal(true); 1223 | val.newChannelSettingsObject.srb1.should.equal(false); 1224 | done(); 1225 | }).catch(function (err) { 1226 | done(err); 1227 | }); 1228 | }); 1229 | it('Invalid type', function (done) { 1230 | k.getChannelSetter(1, 'taco', 24, 'normal', true, true, false).should.be.rejected.and.notify(done); 1231 | }); 1232 | }); 1233 | describe('gain selection works', function () { 1234 | it('1x', function (done) { 1235 | k.getChannelSetter(1, false, 1, 'normal', true, true, false).then(function (val) { 1236 | val.commandArray[3].should.equal('0'); 1237 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1238 | val.newChannelSettingsObject.powerDown.should.equal(false); 1239 | val.newChannelSettingsObject.gain.should.equal(1); 1240 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1241 | val.newChannelSettingsObject.bias.should.equal(true); 1242 | val.newChannelSettingsObject.srb2.should.equal(true); 1243 | val.newChannelSettingsObject.srb1.should.equal(false); 1244 | done(); 1245 | }).catch(function (err) { 1246 | done(err); 1247 | }); 1248 | }); 1249 | it('2x', function (done) { 1250 | k.getChannelSetter(1, false, 2, 'normal', true, true, false).then(function (val) { 1251 | val.commandArray[3].should.equal('1'); 1252 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1253 | val.newChannelSettingsObject.powerDown.should.equal(false); 1254 | val.newChannelSettingsObject.gain.should.equal(2); 1255 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1256 | val.newChannelSettingsObject.bias.should.equal(true); 1257 | val.newChannelSettingsObject.srb2.should.equal(true); 1258 | val.newChannelSettingsObject.srb1.should.equal(false); 1259 | done(); 1260 | }).catch(function (err) { 1261 | done(err); 1262 | }); 1263 | }); 1264 | it('4x', function (done) { 1265 | k.getChannelSetter(1, false, 4, 'normal', true, true, false).then(function (val) { 1266 | val.commandArray[3].should.equal('2'); 1267 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1268 | val.newChannelSettingsObject.powerDown.should.equal(false); 1269 | val.newChannelSettingsObject.gain.should.equal(4); 1270 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1271 | val.newChannelSettingsObject.bias.should.equal(true); 1272 | val.newChannelSettingsObject.srb2.should.equal(true); 1273 | val.newChannelSettingsObject.srb1.should.equal(false); 1274 | done(); 1275 | }).catch(function (err) { 1276 | done(err); 1277 | }); 1278 | }); 1279 | it('6x', function (done) { 1280 | k.getChannelSetter(1, false, 6, 'normal', true, true, false).then(function (val) { 1281 | val.commandArray[3].should.equal('3'); 1282 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1283 | val.newChannelSettingsObject.powerDown.should.equal(false); 1284 | val.newChannelSettingsObject.gain.should.equal(6); 1285 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1286 | val.newChannelSettingsObject.bias.should.equal(true); 1287 | val.newChannelSettingsObject.srb2.should.equal(true); 1288 | val.newChannelSettingsObject.srb1.should.equal(false); 1289 | done(); 1290 | }).catch(function (err) { 1291 | done(err); 1292 | }); 1293 | }); 1294 | it('8x', function (done) { 1295 | k.getChannelSetter(1, false, 8, 'normal', true, true, false).then(function (val) { 1296 | val.commandArray[3].should.equal('4'); 1297 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1298 | val.newChannelSettingsObject.powerDown.should.equal(false); 1299 | val.newChannelSettingsObject.gain.should.equal(8); 1300 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1301 | val.newChannelSettingsObject.bias.should.equal(true); 1302 | val.newChannelSettingsObject.srb2.should.equal(true); 1303 | val.newChannelSettingsObject.srb1.should.equal(false); 1304 | done(); 1305 | }).catch(function (err) { 1306 | done(err); 1307 | }); 1308 | }); 1309 | it('12x', function (done) { 1310 | k.getChannelSetter(1, false, 12, 'normal', true, true, false).then(function (val) { 1311 | val.commandArray[3].should.equal('5'); 1312 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1313 | val.newChannelSettingsObject.powerDown.should.equal(false); 1314 | val.newChannelSettingsObject.gain.should.equal(12); 1315 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1316 | val.newChannelSettingsObject.bias.should.equal(true); 1317 | val.newChannelSettingsObject.srb2.should.equal(true); 1318 | val.newChannelSettingsObject.srb1.should.equal(false); 1319 | done(); 1320 | }).catch(function (err) { 1321 | done(err); 1322 | }); 1323 | }); 1324 | it('24x', function (done) { 1325 | k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) { 1326 | val.commandArray[3].should.equal('6'); 1327 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1328 | val.newChannelSettingsObject.powerDown.should.equal(false); 1329 | val.newChannelSettingsObject.gain.should.equal(24); 1330 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1331 | val.newChannelSettingsObject.bias.should.equal(true); 1332 | val.newChannelSettingsObject.srb2.should.equal(true); 1333 | val.newChannelSettingsObject.srb1.should.equal(false); 1334 | done(); 1335 | }).catch(function (err) { 1336 | done(err); 1337 | }); 1338 | }); 1339 | it('Invalid type', function (done) { 1340 | k.getChannelSetter(1, false, '24', 'normal', true, true, false).should.be.rejected.and.notify(done); 1341 | }); 1342 | it('Invalid gain setting', function (done) { 1343 | k.getChannelSetter(1, false, 5, 'normal', true, true, false).should.be.rejected.and.notify(done); 1344 | }); 1345 | }); 1346 | describe('input type', function () { 1347 | it('normal', function (done) { 1348 | k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) { 1349 | val.commandArray[4].should.equal('0'); 1350 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1351 | val.newChannelSettingsObject.powerDown.should.equal(false); 1352 | val.newChannelSettingsObject.gain.should.equal(24); 1353 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1354 | val.newChannelSettingsObject.bias.should.equal(true); 1355 | val.newChannelSettingsObject.srb2.should.equal(true); 1356 | val.newChannelSettingsObject.srb1.should.equal(false); 1357 | done(); 1358 | }).catch(function (err) { 1359 | done(err); 1360 | }); 1361 | }); 1362 | it('shorted', function (done) { 1363 | k.getChannelSetter(1, false, 24, 'shorted', true, true, false).then(function (val) { 1364 | val.commandArray[4].should.equal('1'); 1365 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1366 | val.newChannelSettingsObject.powerDown.should.equal(false); 1367 | val.newChannelSettingsObject.gain.should.equal(24); 1368 | val.newChannelSettingsObject.inputType.should.equal('shorted'); 1369 | val.newChannelSettingsObject.bias.should.equal(true); 1370 | val.newChannelSettingsObject.srb2.should.equal(true); 1371 | val.newChannelSettingsObject.srb1.should.equal(false); 1372 | done(); 1373 | }).catch(function (err) { 1374 | done(err); 1375 | }); 1376 | }); 1377 | it('biasMethod', function (done) { 1378 | k.getChannelSetter(1, false, 24, 'biasMethod', true, true, false).then(function (val) { 1379 | val.commandArray[4].should.equal('2'); 1380 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1381 | val.newChannelSettingsObject.powerDown.should.equal(false); 1382 | val.newChannelSettingsObject.gain.should.equal(24); 1383 | val.newChannelSettingsObject.inputType.should.equal('biasMethod'); 1384 | val.newChannelSettingsObject.bias.should.equal(true); 1385 | val.newChannelSettingsObject.srb2.should.equal(true); 1386 | val.newChannelSettingsObject.srb1.should.equal(false); 1387 | done(); 1388 | }).catch(function (err) { 1389 | done(err); 1390 | }); 1391 | }); 1392 | it('mvdd', function (done) { 1393 | k.getChannelSetter(1, false, 24, 'mvdd', true, true, false).then(function (val) { 1394 | val.commandArray[4].should.equal('3'); 1395 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1396 | val.newChannelSettingsObject.powerDown.should.equal(false); 1397 | val.newChannelSettingsObject.gain.should.equal(24); 1398 | val.newChannelSettingsObject.inputType.should.equal('mvdd'); 1399 | val.newChannelSettingsObject.bias.should.equal(true); 1400 | val.newChannelSettingsObject.srb2.should.equal(true); 1401 | val.newChannelSettingsObject.srb1.should.equal(false); 1402 | done(); 1403 | }).catch(function (err) { 1404 | done(err); 1405 | }); 1406 | }); 1407 | it('temp', function (done) { 1408 | k.getChannelSetter(1, false, 24, 'temp', true, true, false).then(function (val) { 1409 | val.commandArray[4].should.equal('4'); 1410 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1411 | val.newChannelSettingsObject.powerDown.should.equal(false); 1412 | val.newChannelSettingsObject.gain.should.equal(24); 1413 | val.newChannelSettingsObject.inputType.should.equal('temp'); 1414 | val.newChannelSettingsObject.bias.should.equal(true); 1415 | val.newChannelSettingsObject.srb2.should.equal(true); 1416 | val.newChannelSettingsObject.srb1.should.equal(false); 1417 | done(); 1418 | }).catch(function (err) { 1419 | done(err); 1420 | }); 1421 | }); 1422 | it('testsig', function (done) { 1423 | k.getChannelSetter(1, false, 24, 'testSig', true, true, false).then(function (val) { 1424 | val.commandArray[4].should.equal('5'); 1425 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1426 | val.newChannelSettingsObject.powerDown.should.equal(false); 1427 | val.newChannelSettingsObject.gain.should.equal(24); 1428 | val.newChannelSettingsObject.inputType.should.equal('testSig'); 1429 | val.newChannelSettingsObject.bias.should.equal(true); 1430 | val.newChannelSettingsObject.srb2.should.equal(true); 1431 | val.newChannelSettingsObject.srb1.should.equal(false); 1432 | done(); 1433 | }).catch(function (err) { 1434 | done(err); 1435 | }); 1436 | }); 1437 | it('biasDrp', function (done) { 1438 | k.getChannelSetter(1, false, 24, 'biasDrp', true, true, false).then(function (val) { 1439 | val.commandArray[4].should.equal('6'); 1440 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1441 | val.newChannelSettingsObject.powerDown.should.equal(false); 1442 | val.newChannelSettingsObject.gain.should.equal(24); 1443 | val.newChannelSettingsObject.inputType.should.equal('biasDrp'); 1444 | val.newChannelSettingsObject.bias.should.equal(true); 1445 | val.newChannelSettingsObject.srb2.should.equal(true); 1446 | val.newChannelSettingsObject.srb1.should.equal(false); 1447 | done(); 1448 | }).catch(function (err) { 1449 | done(err); 1450 | }); 1451 | }); 1452 | it('biasDrn', function (done) { 1453 | k.getChannelSetter(1, false, 24, 'biasDrn', true, true, false).then(function (val) { 1454 | val.commandArray[4].should.equal('7'); 1455 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1456 | val.newChannelSettingsObject.powerDown.should.equal(false); 1457 | val.newChannelSettingsObject.gain.should.equal(24); 1458 | val.newChannelSettingsObject.inputType.should.equal('biasDrn'); 1459 | val.newChannelSettingsObject.bias.should.equal(true); 1460 | val.newChannelSettingsObject.srb2.should.equal(true); 1461 | val.newChannelSettingsObject.srb1.should.equal(false); 1462 | done(); 1463 | }).catch(function (err) { 1464 | done(err); 1465 | }); 1466 | }); 1467 | it('Invalid setting', function (done) { 1468 | k.getChannelSetter(1, false, 24, 'taco', true, true, false).should.be.rejected.and.notify(done); 1469 | }); 1470 | it('Invalid type', function (done) { 1471 | k.getChannelSetter(1, false, 24, 1, true, true, false).should.be.rejected.and.notify(done); 1472 | }); 1473 | }); 1474 | describe('bias selection works', function () { 1475 | it('Include', function (done) { 1476 | k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) { 1477 | val.commandArray[5].should.equal('1'); 1478 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1479 | val.newChannelSettingsObject.powerDown.should.equal(false); 1480 | val.newChannelSettingsObject.gain.should.equal(24); 1481 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1482 | val.newChannelSettingsObject.bias.should.equal(true); 1483 | val.newChannelSettingsObject.srb2.should.equal(true); 1484 | val.newChannelSettingsObject.srb1.should.equal(false); 1485 | done(); 1486 | }).catch(function (err) { 1487 | done(err); 1488 | }); 1489 | }); 1490 | it('Remove', function (done) { 1491 | k.getChannelSetter(1, false, 24, 'normal', false, true, false).then(function (val) { 1492 | val.commandArray[5].should.equal('0'); 1493 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1494 | val.newChannelSettingsObject.powerDown.should.equal(false); 1495 | val.newChannelSettingsObject.gain.should.equal(24); 1496 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1497 | val.newChannelSettingsObject.bias.should.equal(false); 1498 | val.newChannelSettingsObject.srb2.should.equal(true); 1499 | val.newChannelSettingsObject.srb1.should.equal(false); 1500 | done(); 1501 | }).catch(function (err) { 1502 | done(err); 1503 | }); 1504 | }); 1505 | it('Invalid type', function (done) { 1506 | k.getChannelSetter(1, false, 24, 'normal', 'taco', true, false).should.be.rejected.and.notify(done); 1507 | }); 1508 | }); 1509 | describe('SRB2 selection works', function () { 1510 | it('Connect', function (done) { 1511 | k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) { 1512 | val.commandArray[6].should.equal('1'); 1513 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1514 | val.newChannelSettingsObject.powerDown.should.equal(false); 1515 | val.newChannelSettingsObject.gain.should.equal(24); 1516 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1517 | val.newChannelSettingsObject.bias.should.equal(true); 1518 | val.newChannelSettingsObject.srb2.should.equal(true); 1519 | val.newChannelSettingsObject.srb1.should.equal(false); 1520 | done(); 1521 | }).catch(function (err) { 1522 | done(err); 1523 | }); 1524 | }); 1525 | it('Disconnect', function (done) { 1526 | k.getChannelSetter(1, false, 24, 'normal', true, false, false).then(function (val) { 1527 | val.commandArray[6].should.equal('0'); 1528 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1529 | val.newChannelSettingsObject.powerDown.should.equal(false); 1530 | val.newChannelSettingsObject.gain.should.equal(24); 1531 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1532 | val.newChannelSettingsObject.bias.should.equal(true); 1533 | val.newChannelSettingsObject.srb2.should.equal(false); 1534 | val.newChannelSettingsObject.srb1.should.equal(false); 1535 | done(); 1536 | }).catch(function (err) { 1537 | done(err); 1538 | }); 1539 | }); 1540 | it('Invalid type', function (done) { 1541 | k.getChannelSetter(1, false, 24, 'normal', true, 'taco', false).should.be.rejected.and.notify(done); 1542 | }); 1543 | }); 1544 | describe('SRB1 selection works', function () { 1545 | it('Connect', function (done) { 1546 | k.getChannelSetter(1, false, 24, 'normal', true, true, true).then(function (val) { 1547 | val.commandArray[7].should.equal('1'); 1548 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1549 | val.newChannelSettingsObject.powerDown.should.equal(false); 1550 | val.newChannelSettingsObject.gain.should.equal(24); 1551 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1552 | val.newChannelSettingsObject.bias.should.equal(true); 1553 | val.newChannelSettingsObject.srb2.should.equal(true); 1554 | val.newChannelSettingsObject.srb1.should.equal(true); 1555 | done(); 1556 | }).catch(function (err) { 1557 | done(err); 1558 | }); 1559 | }); 1560 | it('Disconnect', function (done) { 1561 | k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) { 1562 | val.commandArray[7].should.equal('0'); 1563 | val.newChannelSettingsObject.channelNumber.should.equal(1); 1564 | val.newChannelSettingsObject.powerDown.should.equal(false); 1565 | val.newChannelSettingsObject.gain.should.equal(24); 1566 | val.newChannelSettingsObject.inputType.should.equal('normal'); 1567 | val.newChannelSettingsObject.bias.should.equal(true); 1568 | val.newChannelSettingsObject.srb2.should.equal(true); 1569 | val.newChannelSettingsObject.srb1.should.equal(false); 1570 | done(); 1571 | }).catch(function (err) { 1572 | done(err); 1573 | }); 1574 | }); 1575 | it('Invalid type', function (done) { 1576 | k.getChannelSetter(1, false, 24, 'normal', true, true, 'taco').should.be.rejected.and.notify(done); 1577 | }); 1578 | }); 1579 | }); 1580 | describe('#getTestSignalCommand', function () { 1581 | it('ground', function () { 1582 | let expectation = '0'; 1583 | let result = k.getTestSignalCommand('ground'); 1584 | return expect(result).to.eventually.equal(expectation); 1585 | }); 1586 | it('dc', function () { 1587 | let expectation = 'p'; 1588 | let result = k.getTestSignalCommand('dc'); 1589 | return expect(result).to.eventually.equal(expectation); 1590 | }); 1591 | it('Pulse 1x Fast', function () { 1592 | let expectation = '='; 1593 | let result = k.getTestSignalCommand('pulse1xFast'); 1594 | return expect(result).to.eventually.equal(expectation); 1595 | }); 1596 | it('Pulse 1x Slow', function () { 1597 | let expectation = '-'; 1598 | let result = k.getTestSignalCommand('pulse1xSlow'); 1599 | return expect(result).to.eventually.equal(expectation); 1600 | }); 1601 | it('Pulse 2x Fast', function () { 1602 | let expectation = ']'; 1603 | let result = k.getTestSignalCommand('pulse2xFast'); 1604 | return expect(result).to.eventually.equal(expectation); 1605 | }); 1606 | it('Pulse 2x Slow', function () { 1607 | let expectation = '['; 1608 | let result = k.getTestSignalCommand('pulse2xSlow'); 1609 | return expect(result).to.eventually.equal(expectation); 1610 | }); 1611 | it('none', function () { 1612 | let expectation = 'd'; 1613 | let result = k.getTestSignalCommand('none'); 1614 | return expect(result).to.eventually.equal(expectation); 1615 | }); 1616 | }); 1617 | describe('#getVersionNumber', function () { 1618 | it('should get the major version number from a github standard version string', () => { 1619 | let expectedVersion = 6; 1620 | let inputStringVersion = 'v6.0.0'; 1621 | 1622 | expect(k.getVersionNumber(inputStringVersion)).to.equal(expectedVersion); 1623 | }); 1624 | }); 1625 | describe('#getImpedanceSetter', function () { 1626 | describe('channel input selection works', function () { 1627 | it('channel 2', function (done) { 1628 | k.getImpedanceSetter(2, false, false).then(function (arrayOfCommands) { 1629 | arrayOfCommands[1].should.equal('2'); 1630 | done(); 1631 | }).catch(function (err) { 1632 | done(err); 1633 | }); 1634 | }); 1635 | it('channel 5', function (done) { 1636 | k.getImpedanceSetter(5, false, false).then(function (arrayOfCommands) { 1637 | arrayOfCommands[1].should.equal('5'); 1638 | done(); 1639 | }).catch(function (err) { 1640 | done(err); 1641 | }); 1642 | }); 1643 | it('channel 9', function (done) { 1644 | k.getImpedanceSetter(9, false, false).then(function (arrayOfCommands) { 1645 | arrayOfCommands[1].should.equal('Q'); 1646 | done(); 1647 | }).catch(function (err) { 1648 | done(err); 1649 | }); 1650 | }); 1651 | it('channel 15', function (done) { 1652 | k.getImpedanceSetter(15, false, false).then(function (arrayOfCommands) { 1653 | arrayOfCommands[1].should.equal('U'); 1654 | done(); 1655 | }).catch(function (err) { 1656 | done(err); 1657 | }); 1658 | }); 1659 | it('Invalid channel selection', function (done) { 1660 | k.getImpedanceSetter(0, false, false).should.be.rejected.and.notify(done); 1661 | }); 1662 | it('Invalid type', function (done) { 1663 | k.getImpedanceSetter('1', false, false).should.be.rejected.and.notify(done); 1664 | }); 1665 | }); 1666 | describe('P Input selection works', function () { 1667 | it('Test Signal Applied', function (done) { 1668 | k.getImpedanceSetter(1, true, false).then(function (arrayOfCommands) { 1669 | arrayOfCommands[2].should.equal('1'); 1670 | done(); 1671 | }).catch(function (err) { 1672 | done(err); 1673 | }); 1674 | }); 1675 | it('Test Signal Not Applied', function (done) { 1676 | k.getImpedanceSetter(1, false, false).then(function (arrayOfCommands) { 1677 | console.log('\n\n\narray: ' + arrayOfCommands + '\n\n\n'); 1678 | arrayOfCommands[2].should.equal('0'); 1679 | done(); 1680 | }).catch(function (err) { 1681 | done(err); 1682 | }); 1683 | }); 1684 | it('Invalid type', function (done) { 1685 | k.getImpedanceSetter(1, 'taco', false).should.be.rejected.and.notify(done); 1686 | }); 1687 | }); 1688 | describe('N Input selection works', function () { 1689 | it('Test Signal Applied', function (done) { 1690 | k.getImpedanceSetter(1, false, true).then(function (arrayOfCommands) { 1691 | arrayOfCommands[3].should.equal('1'); 1692 | done(); 1693 | }).catch(function (err) { 1694 | done(err); 1695 | }); 1696 | }); 1697 | it('Test Signal Not Applied', function (done) { 1698 | k.getImpedanceSetter(1, false, false).then(function (arrayOfCommands) { 1699 | arrayOfCommands[3].should.equal('0'); 1700 | done(); 1701 | }).catch(function (err) { 1702 | done(err); 1703 | }); 1704 | }); 1705 | it('Invalid type', function (done) { 1706 | k.getImpedanceSetter(1, false, 'taco').should.be.rejected.and.notify(done); 1707 | }); 1708 | }); 1709 | describe('Prefix and postfix commands work', function () { 1710 | it('Set', function (done) { 1711 | k.getImpedanceSetter(1, true, true).then(function (arrayOfCommands) { 1712 | arrayOfCommands[0].should.equal('z'); 1713 | done(); 1714 | }).catch(function (err) { 1715 | done(err); 1716 | }); 1717 | }); 1718 | it('Latch', function (done) { 1719 | k.getImpedanceSetter(1, true, true).then(function (arrayOfCommands) { 1720 | arrayOfCommands[4].should.equal('Z'); 1721 | done(); 1722 | }).catch(function (err) { 1723 | done(err); 1724 | }); 1725 | }); 1726 | }); 1727 | }); 1728 | describe('sampleRateSetter', function () { 1729 | it('Works for ganglion', function (done) { 1730 | k.getSampleRateSetter('ganglion', 200).then(function (arrayOfCommands) { 1731 | arrayOfCommands[0].should.equal('~'); 1732 | arrayOfCommands[1].should.equal('7'); 1733 | done(); 1734 | }).catch(function (err) { 1735 | done(err); 1736 | }); 1737 | }); 1738 | it('Works for cyton', function (done) { 1739 | k.getSampleRateSetter('cyton', 250).then(function (arrayOfCommands) { 1740 | arrayOfCommands[0].should.equal('~'); 1741 | arrayOfCommands[1].should.equal('6'); 1742 | done(); 1743 | }).catch(function (err) { 1744 | done(err); 1745 | }); 1746 | }); 1747 | it('Works for daisy', function (done) { 1748 | k.getSampleRateSetter('daisy', 1000).then(function (arrayOfCommands) { 1749 | arrayOfCommands[0].should.equal('~'); 1750 | arrayOfCommands[1].should.equal('4'); 1751 | done(); 1752 | }).catch(function (err) { 1753 | done(err); 1754 | }); 1755 | }); 1756 | it('Invalid board type', function (done) { 1757 | k.getSampleRateSetter('taco', 1600).should.be.rejected.and.notify(done); 1758 | }); 1759 | it('Invalid board type type', function (done) { 1760 | k.getSampleRateSetter(10, 1600).should.be.rejected.and.notify(done); 1761 | }); 1762 | it('Invalid sample rate type', function (done) { 1763 | k.getSampleRateSetter('daisy', 'taco').should.be.rejected.and.notify(done); 1764 | }); 1765 | }); 1766 | describe('boardModeSetter', function () { 1767 | it('Works for good args', function (done) { 1768 | k.getBoardModeSetter('default').then(function (arrayOfCommands) { 1769 | arrayOfCommands[0].should.equal('/'); 1770 | arrayOfCommands[1].should.equal('0'); 1771 | done(); 1772 | }).catch(function (err) { 1773 | done(err); 1774 | }); 1775 | }); 1776 | it('bad board mode', function (done) { 1777 | k.getBoardModeSetter('daisy').should.be.rejected.and.notify(done); 1778 | }); 1779 | it('Invalid board mode type', function (done) { 1780 | k.getBoardModeSetter(10).should.be.rejected.and.notify(done); 1781 | }); 1782 | }); 1783 | describe('fun funcs', function () { 1784 | describe('#isNumber', function () { 1785 | it('should return true for object of named type', function () { 1786 | expect(k.isNumber(1)).to.equal(true); 1787 | }); 1788 | it('should return false for not of named type', function () { 1789 | expect(k.isNumber('taco')).to.equal(false); 1790 | }); 1791 | }); 1792 | describe('#isBoolean', function () { 1793 | it('should return true for object of named type', function () { 1794 | expect(k.isBoolean(true)).to.equal(true); 1795 | }); 1796 | it('should return false for not of named type', function () { 1797 | expect(k.isBoolean('taco')).to.equal(false); 1798 | }); 1799 | }); 1800 | describe('#isString', function () { 1801 | it('should return true for object of named type', function () { 1802 | expect(k.isString('taco')).to.equal(true); 1803 | }); 1804 | it('should return false for not of named type', function () { 1805 | expect(k.isString(1)).to.equal(false); 1806 | }); 1807 | }); 1808 | describe('#isUndefined', function () { 1809 | it('should return true for object of named type', function () { 1810 | expect(k.isUndefined()).to.equal(true); 1811 | }); 1812 | it('should return false for not of named type', function () { 1813 | expect(k.isUndefined('im here')).to.equal(false); 1814 | }); 1815 | }); 1816 | describe('#isNull', function () { 1817 | it('should return true for object of named type', function () { 1818 | expect(k.isNull(null)).to.equal(true); 1819 | }); 1820 | it('should return false for not of named type', function () { 1821 | expect(k.isNull()).to.equal(false); 1822 | }); 1823 | it('should return false for not of named type', function () { 1824 | expect(k.isNull('taco')).to.equal(false); 1825 | }); 1826 | }); 1827 | }); 1828 | describe('Emitters', function () { 1829 | it('Event Emitter Accelerometer', function () { 1830 | assert.equal('accelerometer', k.OBCIEmitterAccelerometer); 1831 | }); 1832 | it('Event Emitter BLE Powered On', function () { 1833 | assert.equal('blePoweredOn', k.OBCIEmitterBlePoweredUp); 1834 | }); 1835 | it('Event Emitter Close', function () { 1836 | assert.equal('close', k.OBCIEmitterClose); 1837 | }); 1838 | it('Event Emitter Dropped Packet', function () { 1839 | assert.equal('droppedPacket', k.OBCIEmitterDroppedPacket); 1840 | }); 1841 | it('Event Emitter EOT', function () { 1842 | assert.equal('eot', k.OBCIEmitterEot); 1843 | }); 1844 | it('Event Emitter Error', function () { 1845 | assert.equal('error', k.OBCIEmitterError); 1846 | }); 1847 | it('Event Emitter Ganglion Found', function () { 1848 | assert.equal('ganglionFound', k.OBCIEmitterGanglionFound); 1849 | }); 1850 | it('Event Emitter Hard Set', function () { 1851 | assert.equal('hardSet', k.OBCIEmitterHardSet); 1852 | }); 1853 | it('Event Emitter Impedance', function () { 1854 | assert.equal('impedance', k.OBCIEmitterImpedance); 1855 | }); 1856 | it('Event Emitter Impedance Array', function () { 1857 | assert.equal('impedanceArray', k.OBCIEmitterImpedanceArray); 1858 | }); 1859 | it('Event Emitter Message', function () { 1860 | assert.equal('message', k.OBCIEmitterMessage); 1861 | }); 1862 | it('Event Emitter Query', function () { 1863 | assert.equal('query', k.OBCIEmitterQuery); 1864 | }); 1865 | it('Event Emitter Raw Data Packet', function () { 1866 | assert.equal('rawDataPacket', k.OBCIEmitterRawDataPacket); 1867 | }); 1868 | it('Event Emitter Ready', function () { 1869 | assert.equal('ready', k.OBCIEmitterReady); 1870 | }); 1871 | it('Event Emitter RFduino', function () { 1872 | assert.equal('rfduino', k.OBCIEmitterRFduino); 1873 | }); 1874 | it('Event Emitter Sample', function () { 1875 | assert.equal('sample', k.OBCIEmitterSample); 1876 | }); 1877 | it('Event Emitter Scan Stopped', function () { 1878 | assert.equal('scanStopped', k.OBCIEmitterScanStopped); 1879 | }); 1880 | it('Event Emitter Synced', function () { 1881 | assert.equal('synced', k.OBCIEmitterSynced); 1882 | }); 1883 | }); 1884 | describe('Errors', function () { 1885 | it('errorInvalidByteLength', function () { 1886 | assert.equal(k.OBCIErrorInvalidByteLength, 'Invalid Packet Byte Length'); 1887 | }); 1888 | it('errorInvalidByteStart', function () { 1889 | assert.equal(k.OBCIErrorInvalidByteStart, 'Invalid Start Byte'); 1890 | }); 1891 | it('errorInvalidByteStop', function () { 1892 | assert.equal(k.OBCIErrorInvalidByteStop, 'Invalid Stop Byte'); 1893 | }); 1894 | it('OBCIErrorInvalidData', function () { 1895 | assert.equal(k.OBCIErrorInvalidData, 'Invalid data - try again'); 1896 | }); 1897 | it('errorInvalidType', function () { 1898 | assert.equal(k.OBCIErrorInvalidType, 'Invalid type - check comments for input type'); 1899 | }); 1900 | it('errorMissingRegisterSetting', function () { 1901 | assert.equal(k.OBCIErrorMissingRegisterSetting, 'Missing register setting'); 1902 | }); 1903 | it('errorMissingRequiredProperty', function () { 1904 | assert.equal(k.OBCIErrorMissingRequiredProperty, 'Missing property in JSON'); 1905 | }); 1906 | it('errorNobleAlreadyScanning', function () { 1907 | assert.equal(k.OBCIErrorNobleAlreadyScanning, 'Scan already under way'); 1908 | }); 1909 | it('errorNobleNotAlreadyScanning', function () { 1910 | assert.equal(k.OBCIErrorNobleNotAlreadyScanning, 'No scan started'); 1911 | }); 1912 | it('errorNobleNotInPoweredOnState', function () { 1913 | assert.equal(k.OBCIErrorNobleNotInPoweredOnState, 'Please turn blue tooth on.'); 1914 | }); 1915 | it('errorTimeSyncIsNull', function () { 1916 | assert.equal(k.OBCIErrorTimeSyncIsNull, "'this.sync.curSyncObj' must not be null"); 1917 | }); 1918 | it('errorTimeSyncNoComma', function () { 1919 | assert.equal(k.OBCIErrorTimeSyncNoComma, 'Missed the time sync sent confirmation. Try sync again'); 1920 | }); 1921 | it('errorUndefinedOrNullInput', function () { 1922 | assert.equal(k.OBCIErrorUndefinedOrNullInput, 'Undefined or Null Input'); 1923 | }); 1924 | }); 1925 | describe('Packet Size', function () { 1926 | it('Standard packet size', function () { 1927 | assert.equal(33, k.OBCIPacketSize); 1928 | }); 1929 | it('Cyton BLE packet size', function () { 1930 | assert.equal(20, k.OBCIPacketSizeBLECyton); 1931 | }); 1932 | it('Small packet size', function () { 1933 | assert.equal(12, k.OBCIPacketSizeBLERaw); 1934 | }); 1935 | }); 1936 | describe('Register Query on Cyton', function () { 1937 | assert.equal(k.OBCIRegisterQueryAccelerometerFirmwareV1, '\nLIS3DH Registers\n0x07.0\n0x08.0\n0x09.0\n0x0A.0\n0x0B.0\n0x0C.0\n0x0D.0\n0x0E.0\n0x0F.33\n\n0x1F.0\n0x20.8\n0x21.0\n0x22.0\n0x23.18\n0x24.0\n0x25.0\n0x26.0\n0x27.0\n0x28.0\n0x29.0\n0x2A.0\n0x2B.0\n0x2C.0\n0x2D.0\n0x2E.0\n0x2F.20\n0x30.0\n0x31.0\n0x32.0\n0x33.0\n\n0x38.0\n0x39.0\n0x3A.0\n0x3B.0\n0x3C.0\n0x3D.0\n'); 1938 | assert.equal(k.OBCIRegisterQueryAccelerometerFirmwareV3, '\nLIS3DH Registers\n0x07 00\n0x08 00\n0x09 00\n0x0A 00\n0x0B 00\n0x0C 00\n0x0D 00\n0x0E 00\n0x0F 33\n\n0x1F 00\n0x20 08\n0x21 00\n0x22 00\n0x23 18\n0x24 00\n0x25 00\n0x26 00\n0x27 00\n0x28 00\n0x29 00\n0x2A 00\n0x2B 00\n0x2C 00\n0x2D 00\n0x2E 00\n0x2F 20\n0x30 00\n0x31 00\n0x32 00\n0x33 00\n\n0x38 00\n0x39 00\n0x3A 00\n0x3B 00\n0x3C 00\n0x3D 00\n'); 1939 | assert.equal(k.OBCIRegisterQueryCyton, '\nBoard ADS Registers\nADS_ID, 00, 3E, 0, 0, 1, 1, 1, 1, 1, 0\nCONFIG1, 01, 96, 1, 0, 0, 1, 0, 1, 1, 0\nCONFIG2, 02, C0, 1, 1, 0, 0, 0, 0, 0, 0\nCONFIG3, 03, EC, 1, 1, 1, 0, 1, 1, 0, 0\nLOFF, 04, 02, 0, 0, 0, 0, 0, 0, 1, 0\nCH1SET, 05, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH2SET, 06, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH3SET, 07, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH4SET, 08, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH5SET, 09, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH6SET, 0A, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH7SET, 0B, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH8SET, 0C, 68, 0, 1, 1, 0, 1, 0, 0, 0\nBIAS_SENSP, 0D, FF, 1, 1, 1, 1, 1, 1, 1, 1\nBIAS_SENSN, 0E, FF, 1, 1, 1, 1, 1, 1, 1, 1\nLOFF_SENSP, 0F, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_SENSN, 10, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_FLIP, 11, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_STATP, 12, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_STATN, 13, 00, 0, 0, 0, 0, 0, 0, 0, 0\nGPIO, 14, 0F, 0, 0, 0, 0, 1, 1, 1, 1\nMISC1, 15, 00, 0, 0, 0, 0, 0, 0, 0, 0\nMISC2, 16, 00, 0, 0, 0, 0, 0, 0, 0, 0\nCONFIG4, 17, 00, 0, 0, 0, 0, 0, 0, 0, 0\n'); 1940 | assert.equal(k.OBCIRegisterQueryCytonDaisy, '\nDaisy ADS Registers\nADS_ID, 00, 3E, 0, 0, 1, 1, 1, 1, 1, 0\nCONFIG1, 01, 96, 1, 0, 0, 1, 0, 1, 1, 0\nCONFIG2, 02, C0, 1, 1, 0, 0, 0, 0, 0, 0\nCONFIG3, 03, EC, 1, 1, 1, 0, 1, 1, 0, 0\nLOFF, 04, 02, 0, 0, 0, 0, 0, 0, 1, 0\nCH1SET, 05, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH2SET, 06, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH3SET, 07, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH4SET, 08, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH5SET, 09, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH6SET, 0A, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH7SET, 0B, 68, 0, 1, 1, 0, 1, 0, 0, 0\nCH8SET, 0C, 68, 0, 1, 1, 0, 1, 0, 0, 0\nBIAS_SENSP, 0D, FF, 1, 1, 1, 1, 1, 1, 1, 1\nBIAS_SENSN, 0E, FF, 1, 1, 1, 1, 1, 1, 1, 1\nLOFF_SENSP, 0F, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_SENSN, 10, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_FLIP, 11, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_STATP, 12, 00, 0, 0, 0, 0, 0, 0, 0, 0\nLOFF_STATN, 13, 00, 0, 0, 0, 0, 0, 0, 0, 0\nGPIO, 14, 0F, 0, 0, 0, 0, 1, 1, 1, 1\nMISC1, 15, 00, 0, 0, 0, 0, 0, 0, 0, 0\nMISC2, 16, 00, 0, 0, 0, 0, 0, 0, 0, 0\nCONFIG4, 17, 00, 0, 0, 0, 0, 0, 0, 0, 0\n'); 1941 | assert.equal(k.OBCIRegisterQuerySizeCytonFirmwareV1, k.OBCIRegisterQueryCyton.length + k.OBCIRegisterQueryAccelerometerFirmwareV1.length); 1942 | assert.equal(k.OBCIRegisterQuerySizeCytonDaisyFirmwareV1, k.OBCIRegisterQueryCyton.length + k.OBCIRegisterQueryCytonDaisy.length + k.OBCIRegisterQueryAccelerometerFirmwareV1.length); 1943 | assert.equal(k.OBCIRegisterQuerySizeCytonFirmwareV3, k.OBCIRegisterQueryCyton.length + k.OBCIRegisterQueryAccelerometerFirmwareV3.length); 1944 | assert.equal(k.OBCIRegisterQuerySizeCytonDaisyFirmwareV3, k.OBCIRegisterQueryCyton.length + k.OBCIRegisterQueryCytonDaisy.length + k.OBCIRegisterQueryAccelerometerFirmwareV3.length); 1945 | assert.equal(k.OBCIRegisterQueryNameMISC1, 'MISC1'); 1946 | assert.equal(k.OBCIRegisterQueryNameBIASSENSP, 'BIAS_SENSP'); 1947 | assert.equal(k.OBCIRegisterQueryNameCHnSET[0], 'CH1SET'); 1948 | assert.equal(k.OBCIRegisterQueryNameCHnSET[1], 'CH2SET'); 1949 | assert.equal(k.OBCIRegisterQueryNameCHnSET[2], 'CH3SET'); 1950 | assert.equal(k.OBCIRegisterQueryNameCHnSET[3], 'CH4SET'); 1951 | assert.equal(k.OBCIRegisterQueryNameCHnSET[4], 'CH5SET'); 1952 | assert.equal(k.OBCIRegisterQueryNameCHnSET[5], 'CH6SET'); 1953 | assert.equal(k.OBCIRegisterQueryNameCHnSET[6], 'CH7SET'); 1954 | assert.equal(k.OBCIRegisterQueryNameCHnSET[7], 'CH8SET'); 1955 | }); 1956 | describe('General', function () { 1957 | it('Ganglion prefix', function () { 1958 | assert.equal('Ganglion', k.OBCIGanglionPrefix); 1959 | }); 1960 | it('Ganglion ble search time', function () { 1961 | assert.equal(0.016, k.OBCIGanglionAccelScaleFactor); 1962 | }); 1963 | it('Ganglion ble search time', function () { 1964 | assert.equal(20000, k.OBCIGanglionBleSearchTime); 1965 | }); 1966 | it('packet size', function () { 1967 | assert.equal(20, k.OBCIGanglionPacketSize); 1968 | }); 1969 | it('samples per packet', function () { 1970 | assert.equal(2, k.OBCIGanglionSamplesPerPacket); 1971 | }); 1972 | it('packet positions 18 bit', function () { 1973 | expect(k.OBCIGanglionPacket18Bit).to.deep.equal({ 1974 | auxByte: 20, 1975 | byteId: 0, 1976 | dataStart: 1, 1977 | dataStop: 19 1978 | }); 1979 | }); 1980 | it('packet positions 19 bit', function () { 1981 | expect(k.OBCIGanglionPacket19Bit).to.deep.equal({ 1982 | byteId: 0, 1983 | dataStart: 1, 1984 | dataStop: 20 1985 | }); 1986 | }); 1987 | }); 1988 | describe('Commands', function () { 1989 | it('Synthetic data mode enable', function () { 1990 | assert.equal('t', k.OBCIGanglionSyntheticDataEnable); 1991 | }); 1992 | it('Synthetic data mode disable', function () { 1993 | assert.equal('T', k.OBCIGanglionSyntheticDataDisable); 1994 | }); 1995 | it('Impedance start', function () { 1996 | assert.equal('z', k.OBCIGanglionImpedanceStart); 1997 | }); 1998 | it('Impedance stop', function () { 1999 | assert.equal('Z', k.OBCIGanglionImpedanceStop); 2000 | }); 2001 | }); 2002 | describe('Byte Id', function () { 2003 | it('Uncompressed', function () { 2004 | assert.equal(0, k.OBCIGanglionByteIdUncompressed); 2005 | }); 2006 | it('should have correct values for 18 bit', function () { 2007 | expect(k.OBCIGanglionByteId18Bit).to.deep.equal({ 2008 | max: 100, 2009 | min: 1 2010 | }); 2011 | }); 2012 | it('should have correct values for 18 bit', function () { 2013 | expect(k.OBCIGanglionByteId19Bit).to.deep.equal({ 2014 | max: 200, 2015 | min: 101 2016 | }); 2017 | }); 2018 | it('Impedance channel 1', function () { 2019 | assert.equal(201, k.OBCIGanglionByteIdImpedanceChannel1); 2020 | }); 2021 | it('Impedance channel 2', function () { 2022 | assert.equal(202, k.OBCIGanglionByteIdImpedanceChannel2); 2023 | }); 2024 | it('Impedance channel 3', function () { 2025 | assert.equal(203, k.OBCIGanglionByteIdImpedanceChannel3); 2026 | }); 2027 | it('Impedance channel 4', function () { 2028 | assert.equal(204, k.OBCIGanglionByteIdImpedanceChannel4); 2029 | }); 2030 | it('Impedance channel reference', function () { 2031 | assert.equal(205, k.OBCIGanglionByteIdImpedanceChannelReference); 2032 | }); 2033 | it('Multi packet', function () { 2034 | assert.equal(206, k.OBCIGanglionByteIdMultiPacket); 2035 | }); 2036 | it('Multi packet stop', function () { 2037 | assert.equal(207, k.OBCIGanglionByteIdMultiPacketStop); 2038 | }); 2039 | }); 2040 | describe('simblee', function () { 2041 | it('Service', function () { 2042 | assert.equal('fe84', k.SimbleeUuidService); 2043 | }); 2044 | it('Receive', function () { 2045 | assert.equal('2d30c082f39f4ce6923f3484ea480596', k.SimbleeUuidReceive); 2046 | }); 2047 | it('Write', function () { 2048 | assert.equal('2d30c083f39f4ce6923f3484ea480596', k.SimbleeUuidSend); 2049 | }); 2050 | it('Disconnect', function () { 2051 | assert.equal('2d30c084f39f4ce6923f3484ea480596', k.SimbleeUuidDisconnect); 2052 | }); 2053 | }); 2054 | describe('RFduino BLE UUID', function () { 2055 | it('Service', function () { 2056 | assert.equal(k.RFduinoUuidService, '2220'); 2057 | }); 2058 | it('Receive', function () { 2059 | assert.equal(k.RFduinoUuidReceive, '2221'); 2060 | }); 2061 | it('Write/Notify/Subscribe', function () { 2062 | assert.equal(k.RFduinoUuidSend, '2222'); 2063 | }); 2064 | it('supposed to be a send but can\'t get it working', function () { 2065 | assert.equal(k.RFduinoUuidSendTwo, '2223'); 2066 | }); 2067 | }); 2068 | describe('Cyton BLE', function () { 2069 | it('3 samples per packet', function () { 2070 | assert.equal(k.OBCICytonBLESamplesPerPacket, 3); 2071 | }); 2072 | }); 2073 | describe('noble', function () { 2074 | it('Peripheral Connect', function () { 2075 | assert.equal('connect', k.OBCINobleEmitterPeripheralConnect); 2076 | }); 2077 | it('Peripheral Disconnect', function () { 2078 | assert.equal('disconnect', k.OBCINobleEmitterPeripheralDisconnect); 2079 | }); 2080 | it('Peripheral Discover', function () { 2081 | assert.equal('discover', k.OBCINobleEmitterPeripheralDiscover); 2082 | }); 2083 | it('Peripheral Services Discover', function () { 2084 | assert.equal('servicesDiscover', k.OBCINobleEmitterPeripheralServicesDiscover); 2085 | }); 2086 | it('Service Characteristics Discover', function () { 2087 | assert.equal('characteristicsDiscover', k.OBCINobleEmitterServiceCharacteristicsDiscover); 2088 | }); 2089 | it('Service Read', function () { 2090 | assert.equal('read', k.OBCINobleEmitterServiceRead); 2091 | }); 2092 | it('Discover', function () { 2093 | assert.equal('discover', k.OBCINobleEmitterDiscover); 2094 | }); 2095 | it('Scan Start', function () { 2096 | assert.equal('scanStart', k.OBCINobleEmitterScanStart); 2097 | }); 2098 | it('Scan Stop', function () { 2099 | assert.equal('scanStop', k.OBCINobleEmitterScanStop); 2100 | }); 2101 | it('State Change', function () { 2102 | assert.equal('stateChange', k.OBCINobleEmitterStateChange); 2103 | }); 2104 | it('State Powered On', function () { 2105 | assert.equal('poweredOn', k.OBCINobleStatePoweredOn); 2106 | }); 2107 | }); 2108 | describe('#getPeripheralLocalNames', function () { 2109 | it('should resolve a list of localNames from an array of peripherals', function (done) { 2110 | let numPerifs = 3; 2111 | let perifs = getListOfPeripheralsOfSize(numPerifs); 2112 | k.getPeripheralLocalNames(perifs).then(list => { 2113 | expect(list.length).to.equal(numPerifs); 2114 | for (let i = 0; i < list.length; i++) { 2115 | expect(list[i]).to.equal(makeLocalName(i)); 2116 | } 2117 | done(); 2118 | }).catch(done); 2119 | }); 2120 | it('should reject if array is empty', function (done) { 2121 | k.getPeripheralLocalNames([]).should.be.rejected.and.notify(done); 2122 | }); 2123 | }); 2124 | describe('#getPeripheralWithLocalName', function () { 2125 | it('should resovle a peripheral with local name', function (done) { 2126 | let numOfPerifs = 4; 2127 | let perifs = getListOfPeripheralsOfSize(numOfPerifs); 2128 | // console.log('perifs', perifs) 2129 | let goodName = makeLocalName(numOfPerifs - 1); // Will be in the list 2130 | // console.log(`goodName: ${goodName}`) 2131 | k.getPeripheralWithLocalName(perifs, goodName).should.be.fulfilled.and.notify(done); 2132 | }); 2133 | it('should reject if local name is not in perif list', function (done) { 2134 | let numOfPerifs = 4; 2135 | let perifs = getListOfPeripheralsOfSize(numOfPerifs); 2136 | let badName = makeLocalName(numOfPerifs + 2); // Garuenteed to not be in the list 2137 | k.getPeripheralWithLocalName(perifs, badName).should.be.rejected.and.notify(done); 2138 | }); 2139 | it('should reject if pArray is not array local name is not in perif list', function (done) { 2140 | let badName = makeLocalName(1); // Garuenteed to not be in the list 2141 | k.getPeripheralWithLocalName(badName).should.be.rejected.and.notify(done); 2142 | }); 2143 | }); 2144 | describe('#isPeripheralGanglion', function () { 2145 | it('should return true when proper localName', function () { 2146 | let list = getListOfPeripheralsOfSize(1); 2147 | let perif = list[0]; 2148 | expect(k.isPeripheralGanglion(perif)).to.equal(true); 2149 | }); 2150 | it('should return false when incorrect localName', function () { 2151 | let list = getListOfPeripheralsOfSize(1); 2152 | let perif = list[0]; 2153 | perif.advertisement.localName = 'burrito'; 2154 | expect(k.isPeripheralGanglion(perif)).to.equal(false); 2155 | }); 2156 | it('should return false when bad object', function () { 2157 | expect(k.isPeripheralGanglion({})).to.equal(false); 2158 | }); 2159 | it('should return false if nothing input', function () { 2160 | expect(k.isPeripheralGanglion()).to.equal(false); 2161 | }); 2162 | it('should return false if undfined unput input', function () { 2163 | let list = getListOfPeripheralsOfSize(1); 2164 | let perif = list[0]; 2165 | perif.advertisement.localName = undefined; 2166 | expect(k.isPeripheralGanglion(perif)).to.equal(false); 2167 | }); 2168 | it('should return false when missing advertisement object', function () { 2169 | let list = getListOfPeripheralsOfSize(1); 2170 | let perif = list[0]; 2171 | perif.advertisement = null; 2172 | expect(k.isPeripheralGanglion(perif)).to.equal(false); 2173 | }); 2174 | }); 2175 | }); 2176 | -------------------------------------------------------------------------------- /test/timingEventsAsPromises.js: -------------------------------------------------------------------------------- 1 | // Converts timing events to use promises, to gain bluebird's checks 2 | 3 | function instrumentTimingEvents (module, type) { 4 | // replaces module[type] with a function that does the same thing but uses a promise 5 | // assumes the first argument will be to a callback function 6 | 7 | // if this a setSomething function with a clearSomething partner, the partner will also be instrumented 8 | var setName = type; 9 | var clearName = null; 10 | if (type.substring(0, 3) === 'set') { 11 | clearName = 'clear' + type.substring(3); 12 | } 13 | 14 | if (!module[setName]) return; 15 | 16 | // store original functions 17 | var originalSet = module[setName]; 18 | var originalClear = module[clearName]; 19 | exports[setName + 'Ignored'] = originalSet; 20 | 21 | // dictionary to store promise details for each call 22 | var events = {}; 23 | 24 | // setAsPromise() is the brunt of the function. It replaces the previous global function, 25 | // and sets up a promise to resolve when the callback is called 26 | var eventCount = 0; 27 | var setAsPromise = function (callback) { 28 | var args = [].slice.call(arguments); 29 | 30 | var eventNum = ++eventCount; 31 | var eventHandle; 32 | 33 | if (setAsPromise._ignoreCount > 0) { 34 | --setAsPromise._ignoreCount; 35 | 36 | return originalSet.apply(this, args); 37 | } 38 | 39 | // actual callback is replaced by promise resolve 40 | args[0] = function () { 41 | if (!events[eventNum]) throw new Error(setName + ' ' + eventNum + ' disappeared'); 42 | events[eventNum].resolve([].slice.call(arguments)); 43 | }; 44 | 45 | eventHandle = originalSet.apply(this, args) || eventNum; 46 | 47 | // this portion is a function so that setInterval may be handled via recursion 48 | function dispatch () { 49 | var handlerDetails = { handle: eventHandle }; 50 | 51 | var promise = new Promise((resolve, reject) => { 52 | handlerDetails.resolve = resolve; 53 | handlerDetails.reject = reject; 54 | }); 55 | 56 | handlerDetails.promise = promise; 57 | events[eventNum] = handlerDetails; 58 | 59 | promise.then(function (argumentArray) { 60 | if (type !== 'setInterval') { 61 | delete events[eventNum]; 62 | } else { 63 | dispatch(); 64 | } 65 | 66 | // call original handler 67 | callback.apply(this, argumentArray); 68 | }, () => { 69 | originalClear(eventHandle); 70 | delete events[eventNum]; 71 | }); 72 | 73 | return promise; 74 | } 75 | 76 | dispatch(); 77 | 78 | return eventNum; 79 | }; 80 | 81 | // actually replace functions with instrumented ones 82 | setAsPromise._ignoreCount = 0; 83 | module[setName] = setAsPromise; 84 | Object.defineProperty(setAsPromise, 'name', { value: setName + 'AsPromise' }); 85 | 86 | if (clearName) { 87 | module[clearName] = (eventNum) => { 88 | if (!events[eventNum]) { 89 | originalClear(eventNum); 90 | } else { 91 | events[eventNum].reject(new Error('cleared')); 92 | } 93 | }; 94 | Object.defineProperty(module[clearName], 'name', { value: clearName + 'AsPromise' }); 95 | } 96 | } 97 | 98 | instrumentTimingEvents(global, 'setTimeout'); 99 | instrumentTimingEvents(global, 'setInterval'); 100 | instrumentTimingEvents(global, 'setImmediate'); 101 | // // Possible TODO: nextTick needs some exceptions included to prevent infinite recursion 102 | // instrumentTimingEvents(process, 'nextTick'); 103 | 104 | // the next call to the passed function should not be promisified 105 | // may be queued multiple times 106 | exports.ignoreOnce = (ignored) => { 107 | ignored._ignoreCount ++; 108 | }; 109 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const library = 'OpenBCIUtilities'; 4 | const librarySnakeCase = 'openbci-utilities'; 5 | const libraryExport = 'default'; 6 | 7 | const config = { 8 | entry: { 9 | [librarySnakeCase]: './src/index.js', 10 | utilities: './src/utilities.js', 11 | constants: './src/constants.js', 12 | debug: './src/debug.js' 13 | }, 14 | module: { 15 | rules: [ 16 | { 17 | test: /\.js$/, 18 | exclude: /(node_modules)/, 19 | use: { 20 | loader: 'babel-loader' 21 | } 22 | } 23 | ] 24 | }, 25 | devtool: 'eval', 26 | devServer: { 27 | compress: true, 28 | port: 9000 29 | } 30 | }; 31 | 32 | const exportLibraryTarget = (libraryTarget, name) => 33 | Object.assign({}, config, { 34 | output: { 35 | path: path.resolve(__dirname, 'dist'), 36 | filename: `${name}.js`, 37 | library, 38 | libraryTarget, 39 | libraryExport 40 | } 41 | }); 42 | 43 | module.exports = [ 44 | exportLibraryTarget('umd', '[name]'), 45 | exportLibraryTarget('var', '[name].var') 46 | ]; 47 | --------------------------------------------------------------------------------