├── .gitignore ├── .gitmodules ├── .jshintrc ├── Jenkinsfile ├── LICENSE.md ├── README.md ├── docs ├── .gitignore ├── Makefile └── source │ ├── _templates │ └── layout.html │ ├── accelerometer.rst │ ├── advanced_features.rst │ ├── ambientlightsensor.rst │ ├── barometer.rst │ ├── conf.py │ ├── core_modules.rst │ ├── cppbridge.rst │ ├── dataprocessor.rst │ ├── datasignal.rst │ ├── event.rst │ ├── gpio.rst │ ├── gyro.rst │ ├── haptic.rst │ ├── humidity.rst │ ├── i2c.rst │ ├── ibeacon.rst │ ├── index.rst │ ├── led.rst │ ├── logger.rst │ ├── logging.rst │ ├── macro.rst │ ├── magnetometer.rst │ ├── metadataprocessor.rst │ ├── metawearboard.rst │ ├── metawearscanner.rst │ ├── peripherals.rst │ ├── sensor_fusion.rst │ ├── sensors.rst │ ├── settings.rst │ ├── spi.rst │ ├── temperature.rst │ └── timer.rst ├── examples ├── acc_thresh_detect.js ├── anonymous_datasignals.js ├── clear_led_on_switch.js ├── data_fuser.js ├── full_reset.js ├── led.js ├── led_dongle.js ├── led_macro.js ├── log_acc_bmi160.js ├── log_acc_bmi270.js ├── log_temp.js ├── multi_device.js ├── record_on_push.js ├── scan_connect.js ├── serialize.js ├── setup_connect.js ├── status_battery.js ├── stream_acc.js ├── stream_acc_accounter.js ├── stream_acc_accumulator.js ├── stream_acc_averager.js ├── stream_acc_buffer.js ├── stream_acc_gyro.js ├── stream_acc_gyro_packed.js ├── stream_acc_packed.js ├── stream_acc_x.js ├── stream_baro_comp.js ├── stream_gyro_packed.js ├── stream_quat.js ├── stream_switch_count.js ├── stream_temp.js └── stream_temp_timer.js ├── index.js ├── lib └── metawear.js ├── package-lock.json ├── package.json └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.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 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # VS-Code 61 | .vscode/ 62 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "MetaWear-SDK-Cpp"] 2 | path = MetaWear-SDK-Cpp 3 | url = https://github.com/mbientlab/MetaWear-SDK-Cpp.git 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "browser": true, 3 | "node": true, 4 | "mocha": true, 5 | "unused": false, //enable after cleanup 6 | "undef": false, //enable after cleanup 7 | "globals": { 8 | "Promise": true 9 | } 10 | } -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env groovy 2 | 3 | node { 4 | try { 5 | stage('checkout') { 6 | checkout([ 7 | $class: 'GitSCM', 8 | branches: [[name: '**']], 9 | doGenerateSubmoduleConfigurations: false, 10 | extensions: [[ 11 | $class: 'SubmoduleOption', 12 | disableSubmodules: false, 13 | parentCredentials: false, 14 | recursiveSubmodules: true, 15 | reference: '', 16 | trackingSubmodules: false 17 | ]], 18 | submoduleCfg: [], 19 | userRemoteConfigs: [[ 20 | credentialsId: 'github', 21 | url: 'https://github.com/mbientlab/MetaWear-SDK-JavaScript' 22 | ]] 23 | ]) 24 | } 25 | stage('prepare') { 26 | sh 'node -v' 27 | sh 'npm prune' 28 | } 29 | stage('compile') { 30 | sh 'npm install' 31 | } 32 | stage('test') { 33 | sh 'npm test' 34 | } 35 | } finally { 36 | stage('cleanup') { 37 | echo 'doing some cleanup...' 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2020 MbientLab Inc. All rights reserved. 2 | 3 | IMPORTANT: Your use of this Software is limited to those specific rights granted under the terms of a software license agreement between the user who downloaded the software, his/her employer (which must be your employer) and MbientLab Inc, (the "License"). 4 | You may not use this Software unless you agree to abide by the terms of the License which can be found at www.mbientlab.com/terms. 5 | The License limits your use, and you acknowledge, that the Software may be modified, copied, and distributed when used in conjunction with an MbientLab Inc, product. 6 | Other than for the foregoing purpose, you may not use, reproduce, copy, prepare derivative works of, modify, distribute, perform, display or sell this Software and/or its documentation for any purpose. 7 | 8 | YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MBIENTLAB OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. 9 | 10 | Should you have any questions regarding your right to use this Software, contact MbientLab via email: hello@mbientlab.com. 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MetaWear SDK for Javascript by MBIENTLAB 2 | 3 | [![Platforms](https://img.shields.io/badge/platform-linux%20-lightgrey?style=flat)](https://github.com/mbientlab/MetaWear-SDK-JavaScript) 4 | [![License](https://img.shields.io/cocoapods/l/MetaWear.svg?style=flat)](https://github.com/mbientlab/MetaWear-SDK-JavaScript/blob/master/LICENSE.md) 5 | [![Version](https://img.shields.io/badge/node-%2012-brightgreen?style=flat)](https://github.com/mbientlab/MetaWear-SDK-JavaScript) 6 | 7 | ![alt tag](https://raw.githubusercontent.com/mbientlab/MetaWear-SDK-iOS-macOS-tvOS/master/Images/Metawear.png) 8 | 9 | SDK for creating MetaWear apps that run on node.js. Supported on Linux only. 10 | 11 | This is a thin wrapper around the [MetaWear C++ API](https://github.com/mbientlab/Metawear-CppAPI) so you will find the C++ [documentation](https://mbientlab.com/cppdocs/latest/) and [API reference](https://mbientlab.com/docs/metawear/cpp/latest/globals.html) useful. 12 | 13 | Also, check out the JavaScript [examples](https://github.com/mbientlab/MetaWear-SDK-JavaScript/tree/master/examples). 14 | 15 | Under the hood it uses [Noble-Device](https://github.com/mbientlab/noble-device) and [Noble](https://github.com/mbientlab/noble) for Bluetooth Low Energy communications. These third party libraries have been abandoned and we are currently using the @abandonware release. 16 | 17 | > Only Node 12 on Linux is supported for release 1.2.0 18 | 19 | ## Getting Started 20 | 21 | ### Pre-Installation 22 | 23 | #### Node and NPM 24 | You need to make sure you have node and npm installed on your machine. Here's a quick rundown but you should google-fu proper steps for your specific OS and Node version. 25 | 26 | We are currently supporting Node 12 only (`node-ffi` does not work on higher node versions -- this will be addressed in future releases). 27 | 28 | Here are steps to install Node on Linux (Ubuntu). You have 3 options: 29 | 30 | ##### 1. You can install Node from the repositories: 31 | ``` 32 | sudo apt install nodejs 33 | sudo apt install npm 34 | nodejs -v 35 | ``` 36 | This will install the latest Node. You may need to alias nodejs to node. 37 | 38 | ##### 2. You can install Node from a PPA: 39 | ``` 40 | cd ~ 41 | curl -sL https://deb.nodesource.com/setup_12.x -o nodesource_setup.sh 42 | sudo bash nodesource_setup.sh 43 | sudo apt install nodejs 44 | nodejs -v 45 | ``` 46 | This will install node v12. You may need to alias nodejs to node. 47 | 48 | ##### 3. Using NVM (preferred method): 49 | ``` 50 | curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.35.3/install.sh -o install_nvm.sh 51 | bash install_nvm.sh 52 | source ~/.profile 53 | nvm install 12 54 | nvm use 12 55 | node -v 56 | ``` 57 | Check the latest version of NVM before you install (it might be higher than v0.35.3). 58 | 59 | ##### Using sudo - a Warning 60 | It is important to note that because our scripts use OS level Bluetooth libraries, it may be required to use sudo (or you will get a warning and the scripts won't work). You need to decide if you are ok to use sudo or not. If you are not, follow this [guide](https://github.com/sandeepmistry/noble#running-on-linux) 61 | 62 | You also need to check that the version of node you are using is as expected for sudo: 63 | ``` 64 | $ node -v 65 | v12.22.10 66 | $ sudo node -v 67 | v12.22.10 68 | ``` 69 | As you can see here, the sudo node version is not the same as the current user version. Here's a [workaround](https://stackoverflow.com/questions/21215059/cant-use-nvm-from-root-or-sudo). You can google-fu more about this topic. 70 | ``` 71 | n=$(which node); \ 72 | n=${n%/bin/node}; \ 73 | chmod -R 755 $n/bin/*; \ 74 | sudo cp -r $n/{bin,lib,share} /usr/local 75 | ``` 76 | 77 | ##### Using bluez, BLE Dongles, and Node 78 | Bluez 5.50 works but 5.54 might not work. Here's a good [tutorial](https://learn.adafruit.com/install-bluez-on-the-raspberry-pi/installation) 79 | 80 | If you are not using a BLE dongle, you need to make sure your system is working and supports Bluetooth 4.0+. 81 | 82 | If you are using a BLE dongle, you need to make sure it's working. You can google-fu how to use tools such as `bluetoothctl`, `hciconfig`, `btmon` and more to confirm this. There is an example of how to specify a dongle in the example folder. 83 | 84 | ### Installation 85 | You have three options for installation: 86 | 87 | #### 1. Use NPM 88 | The Mbient JavaScript SDK relies on [Noble](https://github.com/mbientlab/noble) and [Noble-Device](https://github.com/mbientlab/noble-device) for Bluetooth Low Energy communications. 89 | 90 | You need to setup the relevant [prerequisites for Noble](https://github.com/mbientlab/noble#prerequisites) and then [install Noble](https://github.com/mbientlab/noble#install). Make sure you use our versions of these libraries as the original packages have been abandoned. 91 | 92 | Then you can simply install the MetaWear package lib with NPM using the command line: 93 | ``` 94 | npm install metawear 95 | ``` 96 | This step takes a long time as all the packages are installed and the MetaWear CPP library will be compiled on your machine. You may or may not need to update. 97 | ``` 98 | npm update metawear 99 | ``` 100 | 101 | #### 2. Use our Repository 102 | You can install the metawear package straight from our repository by using: 103 | ``` 104 | npm install https://github.com/mbientlab/MetaWear-SDK-JavaScript.git 105 | ``` 106 | This step takes a long time as all the packages are installed and the MetaWear CPP library will be compiled on your machine. 107 | 108 | #### 3. Clone our Repository 109 | We packaged everything for you already in this repository -- see `package.json`. 110 | 111 | Make sure that when you clone this repository, that you clone the `MetaWear-SDK-Cpp` submodule with it. 112 | ``` 113 | git clone --recurse-submodules https://github.com/mbientlab/MetaWear-SDK-JavaScript.git 114 | cd MetaWear-SDK-JavaScript 115 | npm install 116 | ``` 117 | 118 | The installation step takes some time to install the packages and compile the C++ code in the submodule. 119 | 120 | #### Errors and Issues 121 | If you have any issues with the npm installation, make sure you are using the correct version of node, npm, nvm (if used), bluez, and that your machine is Bluetooth Low Energy compliant. 122 | 123 | If you have any issues compiling the `MetaWear-CPP-SDK` (this is a post script that runs at the end of npm install), simply build it from source. 124 | 125 | If you cloned the repo: 126 | ``` 127 | cd MetaWear-SDK-Cpp/ 128 | make 129 | ``` 130 | If you ran an npm command: 131 | ``` 132 | cd node_modules/metawear 133 | cd MetaWear-SDK-Cpp/ 134 | make 135 | ``` 136 | 137 | #### Running your first Script 138 | Once the install is successful, you can run our example scripts in the example folder (see the example folder in our repository): 139 | ```javascript 140 | node led.js 141 | ``` 142 | 143 | Please note that depending on your node and npm installation, you may need to run sudo (or use `su -`): 144 | ```javascript 145 | sudo node led.js 146 | ``` 147 | 148 | Please note that the examples in our examples folder will use the local metawear libraries (as this repository is meant for development): 149 | ```javascript 150 | var MetaWear = require('../index') 151 | ``` 152 | This is pointing to the local metawear Node.JS code. 153 | 154 | Simply change it to this if using `metawear` as a package (dependency) in your own app: 155 | ```javascript 156 | var MetaWear = require('metawear'); 157 | ``` 158 | This means metawear would be installed as a dependency in the `node_modules` directory of your app. 159 | 160 | #### Notes 161 | You should familiarize yourself with our tutorials since there a few limitiations and other gotchas spelled out, such as the maximum number of simultaneous Bluetooth connections. 162 | 163 | ### Usage 164 | Require the metawear package: 165 | ```javascript 166 | var MetaWear = require('metawear'); 167 | ``` 168 | 169 | Discover the first MetaWear device seen: 170 | ```javascript 171 | MetaWear.discover(function (device) { ... } 172 | ``` 173 | 174 | Or connect to a device with a specific MAC address: 175 | ```javascript 176 | MetaWear.discoverByAddress('cb:7d:c5:b0:20:8f', function(device) { ... } 177 | ``` 178 | There are other options too, documented in [Noble Device](https://github.com/mbientlab/noble-device#discovery-api) 179 | 180 | After that, you must connect to the device and init: 181 | ```javascript 182 | device.connectAndSetUp(function (error) { ... } 183 | ``` 184 | 185 | At this point you can call any of the MetaWear API's, for example, you can blink the LED green 186 | ```javascript 187 | var pattern = new MetaWear.LedPattern(); 188 | MetaWear.mbl_mw_led_load_p_pattern(pattern.ref(), MetaWear.LedPreset.BLINK); 189 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), MetaWear.LedColor.GREEN); 190 | MetaWear.mbl_mw_led_play(device.board); 191 | ``` 192 | 193 | ### Example 194 | ```javascript 195 | var MetaWear = require('metawear'); 196 | 197 | MetaWear.discover(function (device) { 198 | device.connectAndSetUp(function (error) { 199 | var pattern = new MetaWear.LedPattern(); 200 | MetaWear.mbl_mw_led_load_preset_pattern(pattern.ref(), MetaWear.LedPreset.BLINK); 201 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), MetaWear.LedColor.GREEN); 202 | MetaWear.mbl_mw_led_play(device.board); 203 | // After 5 seconds we reset the board to clear the LED, when we receive 204 | // a disconnect notice we know the reset is complete, so exit the program 205 | setTimeout(function () { 206 | device.on('disconnect', function () { 207 | process.exit(0); 208 | }); 209 | MetaWear.mbl_mw_debug_reset(device.board); 210 | }, 5000); 211 | }); 212 | }); 213 | ``` 214 | 215 | ### Tutorials 216 | Tutorials can be found [here](https://mbientlab.com/tutorials/). 217 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /html/ 3 | upload.sh 4 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 21 | 22 | .PHONY: help 23 | help: 24 | @echo "Please use \`make ' where is one of" 25 | @echo " html to make standalone HTML files" 26 | @echo " dirhtml to make HTML files named index.html in directories" 27 | @echo " singlehtml to make a single large HTML file" 28 | @echo " pickle to make pickle files" 29 | @echo " json to make JSON files" 30 | @echo " htmlhelp to make HTML files and a HTML help project" 31 | @echo " qthelp to make HTML files and a qthelp project" 32 | @echo " applehelp to make an Apple Help Book" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " epub3 to make an epub3" 36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 37 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 39 | @echo " text to make text files" 40 | @echo " man to make manual pages" 41 | @echo " texinfo to make Texinfo files" 42 | @echo " info to make Texinfo files and run them through makeinfo" 43 | @echo " gettext to make PO message catalogs" 44 | @echo " changes to make an overview of all changed/added/deprecated items" 45 | @echo " xml to make Docutils-native XML files" 46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 47 | @echo " linkcheck to check all external links for integrity" 48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 49 | @echo " coverage to run coverage check of the documentation (if enabled)" 50 | 51 | .PHONY: clean 52 | clean: 53 | rm -rf $(BUILDDIR)/* 54 | 55 | .PHONY: html 56 | html: 57 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 58 | @echo 59 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 60 | 61 | .PHONY: dirhtml 62 | dirhtml: 63 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 64 | @echo 65 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 66 | 67 | .PHONY: singlehtml 68 | singlehtml: 69 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 70 | @echo 71 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 72 | 73 | .PHONY: pickle 74 | pickle: 75 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 76 | @echo 77 | @echo "Build finished; now you can process the pickle files." 78 | 79 | .PHONY: json 80 | json: 81 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 82 | @echo 83 | @echo "Build finished; now you can process the JSON files." 84 | 85 | .PHONY: htmlhelp 86 | htmlhelp: 87 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 88 | @echo 89 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 90 | ".hhp project file in $(BUILDDIR)/htmlhelp." 91 | 92 | .PHONY: qthelp 93 | qthelp: 94 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 95 | @echo 96 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 97 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 98 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MetaWeariOSAPI.qhcp" 99 | @echo "To view the help file:" 100 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MetaWeariOSAPI.qhc" 101 | 102 | .PHONY: applehelp 103 | applehelp: 104 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 105 | @echo 106 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 107 | @echo "N.B. You won't be able to view it unless you put it in" \ 108 | "~/Library/Documentation/Help or install it in your application" \ 109 | "bundle." 110 | 111 | .PHONY: devhelp 112 | devhelp: 113 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 114 | @echo 115 | @echo "Build finished." 116 | @echo "To view the help file:" 117 | @echo "# mkdir -p $$HOME/.local/share/devhelp/MetaWeariOSAPI" 118 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MetaWeariOSAPI" 119 | @echo "# devhelp" 120 | 121 | .PHONY: epub 122 | epub: 123 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 124 | @echo 125 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 126 | 127 | .PHONY: epub3 128 | epub3: 129 | $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 130 | @echo 131 | @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." 132 | 133 | .PHONY: latex 134 | latex: 135 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 136 | @echo 137 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 138 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 139 | "(use \`make latexpdf' here to do that automatically)." 140 | 141 | .PHONY: latexpdf 142 | latexpdf: 143 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 144 | @echo "Running LaTeX files through pdflatex..." 145 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 146 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 147 | 148 | .PHONY: latexpdfja 149 | latexpdfja: 150 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 151 | @echo "Running LaTeX files through platex and dvipdfmx..." 152 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 153 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 154 | 155 | .PHONY: text 156 | text: 157 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 158 | @echo 159 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 160 | 161 | .PHONY: man 162 | man: 163 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 164 | @echo 165 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 166 | 167 | .PHONY: texinfo 168 | texinfo: 169 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 170 | @echo 171 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 172 | @echo "Run \`make' in that directory to run these through makeinfo" \ 173 | "(use \`make info' here to do that automatically)." 174 | 175 | .PHONY: info 176 | info: 177 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 178 | @echo "Running Texinfo files through makeinfo..." 179 | make -C $(BUILDDIR)/texinfo info 180 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 181 | 182 | .PHONY: gettext 183 | gettext: 184 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 185 | @echo 186 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 187 | 188 | .PHONY: changes 189 | changes: 190 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 191 | @echo 192 | @echo "The overview file is in $(BUILDDIR)/changes." 193 | 194 | .PHONY: linkcheck 195 | linkcheck: 196 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 197 | @echo 198 | @echo "Link check complete; look for any errors in the above output " \ 199 | "or in $(BUILDDIR)/linkcheck/output.txt." 200 | 201 | .PHONY: doctest 202 | doctest: 203 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 204 | @echo "Testing of doctests in the sources finished, look at the " \ 205 | "results in $(BUILDDIR)/doctest/output.txt." 206 | 207 | .PHONY: coverage 208 | coverage: 209 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 210 | @echo "Testing of coverage in the sources finished, look at the " \ 211 | "results in $(BUILDDIR)/coverage/python.txt." 212 | 213 | .PHONY: xml 214 | xml: 215 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 216 | @echo 217 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 218 | 219 | .PHONY: pseudoxml 220 | pseudoxml: 221 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 222 | @echo 223 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 224 | -------------------------------------------------------------------------------- /docs/source/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "!layout.html" %} 2 | 3 | {%- block extrahead %} 4 | 5 | 13 | 14 | 15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /docs/source/advanced_features.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Advanced Features 4 | ================= 5 | There are a few advanced features available on the MetaWear board described in this section. 6 | 7 | High Frequency Streaming 8 | ------------------------ 9 | Some developers may want to stream data from multiple motion sensors simultaneously or individually at frequencies higher than 100Hz. 10 | 11 | To accommodate this use case, acceleration, angular velocity, and magnetic field data have a packed output mode that combines 3 data samples into 1 ble packet increasing the data throughput by 3x. 12 | 13 | :: 14 | 15 | console.log('Setup acc.'); 16 | MetaWear.mbl_mw_acc_set_odr(device.board, 200.0); 17 | MetaWear.mbl_mw_acc_set_range(device.board, 4.0); 18 | MetaWear.mbl_mw_acc_write_acceleration_config(device.board); 19 | 20 | console.log('Get acc signal.'); 21 | let acc = MetaWear.mbl_mw_acc_get_packed_acceleration_data_signal(device.board); 22 | 23 | console.log('Set up stream.'); 24 | MetaWear.mbl_mw_datasignal_subscribe(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 25 | var data = pointer.deref(); 26 | var value = data.parseValue(); 27 | console.log('epoch: ' + data.epoch + ' acc: ' + value.x + ' ' + value.y + ' ' + value.z) 28 | })) 29 | 30 | console.log('Start accelerometer.'); 31 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 32 | MetaWear.mbl_mw_acc_start(device.board); 33 | 34 | 35 | In addition to using packed output, developers will also need to reduce the max connection interval to 7.5ms. Reducing the max connection interval can 36 | also be used to speed up log downloads. :: 37 | 38 | MetaWear.mbl_mw_settings_set_connection_parameters(deviceboard, 7.5, 7.5, 0, 6000); 39 | 40 | Don't forget the connection parameters can be rejected. 41 | 42 | Serialization 43 | ------------- 44 | The internal state of the 45 | `MblMwMetaWearBoard `_ object can be 46 | converted into a byte array, which can then be saved to the disk. 47 | 48 | You will need to free the allocated memory after you are done using the byte array. :: 49 | 50 | uint32_t size; 51 | uint8_t* state = mbl_mw_metawearboard_serialize(board, &size); 52 | 53 | for (uint32_t i = 0; i < size; i++) { 54 | // write content to a stream 55 | } 56 | 57 | mbl_mw_memory_free(state); 58 | 59 | To restore the board state, pass the byte array into mbl_mw_metawearboard_deserialize. You must still call 60 | `mbl_mw_metawearboard_initialize `_ after 61 | deserializing the state. :: 62 | 63 | uint8_t* state; 64 | uint32_t state_size; 65 | 66 | // assign state and state_size 67 | mbl_mw_metawearboard_deserialize(board, state, sizeof(state)); 68 | mbl_mw_metawearboard_initialize(board, [](MblMwMetaWearBoard* board, int32_t status) -> void { 69 | 70 | }); 71 | 72 | Anonymous Signals 73 | ------------------ 74 | Anonymous data signals are a variant of the `Logger `_ type used to retrieve logged data from a board that was not programmed by the current host device. 75 | 76 | For example, a linux device was used to start a log of accelerometer data at 20Hz on a MetaWear board and an Android device is expected to download it from that board at a later time (the Android device therefore does not know about which loggers are running). 77 | 78 | Use `mbl_mw_metawearboard_create_anonymous_datasignals `_ to sync the host device with the board's current logger state. 79 | 80 | If the function fails, a null pointer will be returned and the uint32_t parameter instead corresponds to a status code from the SDK. 81 | 82 | Because of the anonymous nature of the object, users will need to rely on an identifier string to determine what kind of data is being passed to each 83 | route. Generate the identifier string by calling `mbl_mw_logger_generate_identifier `_ for each 84 | ``MblMwDataLogger`` type and match these values with `mbl_mw_anonymous_datasignal_get_identifier `_. :: 85 | 86 | #include "metawear/core/datasignal.h" 87 | #include "metawear/core/logging.h" 88 | #include "metawear/platform/memory.h" 89 | #include "metawear/sensor/gyro_bmi160.h" 90 | 91 | void identifier_demo(MblMwMetaWearBoard* board) { 92 | auto gyro = mbl_mw_gyro_bmi160_get_rotation_data_signal(board); 93 | auto gyro_y = mbl_mw_datasignal_get_component(gyro, MBL_MW_GYRO_ROTATION_Y_AXIS_INDEX); 94 | mbl_mw_datasignal_log(gyro_y, [](MblMwDataLogger* logger) -> void { 95 | char* identifier = mbl_mw_logger_generate_identifier(logger); 96 | cout << "gyro_y identifier = " << identifier << endl; 97 | mbl_mw_memory_free(identifier); 98 | }); 99 | } 100 | 101 | A quick example: 102 | 103 | :: 104 | 105 | function download(device, callback) { 106 | // Setup the handlers for events during the download 107 | var downloadHandler = new MetaWear.LogDownloadHandler(); 108 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 109 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 110 | if (entriesLeft === 0) { 111 | callback(null); 112 | } 113 | }); 114 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 115 | console.log('received_unknown_entry'); 116 | }); 117 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 118 | var data = dataPtr.deref(); 119 | var dataPoint = data.parseValue(); 120 | console.log('received_unhandled_entry: ' + dataPoint); 121 | }); 122 | // Actually start the log download, this will cause all the handlers we setup to be invoked 123 | MetaWear.mbl_mw_logging_download(device.board, 20, downloadHandler.ref()); 124 | } 125 | 126 | MetaWear.mbl_mw_metawearboard_create_anonymous_datasignals(device.board, ref.NULL, 127 | MetaWear.FnVoid_VoidP_MetaWearBoardP_AnonymousDataSignalP_UInt.toPointer(function (context, board, anonymousSignals, size) { 128 | if (!anonymousSignals) { 129 | console.log('nothing being logged'); 130 | process.exit(1); 131 | } 132 | // Set the size on the array so we can index 133 | anonymousSignals.length = size; 134 | var i; 135 | for (i = 0; i < size; i++) { 136 | var identifier = MetaWear.mbl_mw_anonymous_datasignal_get_identifier(anonymousSignals[i]); 137 | MetaWear.mbl_mw_anonymous_datasignal_subscribe(anonymousSignals[i], ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 138 | var data = dataPtr.deref(); 139 | var pt = data.parseValue(); 140 | console.log(identifier + ':' + data.epoch + ' ' + JSON.stringify(pt)); 141 | })); 142 | } 143 | download(device, function () { 144 | device.once('disconnect', function (reason) { 145 | process.exit(0); 146 | }); 147 | MetaWear.mbl_mw_macro_erase_all(device.board); 148 | MetaWear.mbl_mw_debug_reset_after_gc(device.board); 149 | MetaWear.mbl_mw_debug_disconnect(device.board); 150 | }); 151 | })); 152 | }); 153 | 154 | As the C++ SDK does not yet support all available data sources, you will not be able to use this SDK to sync data from the accelerometer's detection 155 | algorithms except the BMI160's step and BMI160/BMA255 orientation detectors. 156 | -------------------------------------------------------------------------------- /docs/source/ambientlightsensor.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Ambient Light Sensor 4 | ==================== 5 | Light sensors measure illuminance, which can be used to measure more than the brightness of a light source. 6 | 7 | MetaWear RPro and Cpro, and MetaDetector board come with a `Lite-On LTR-329ALS `_ ambient light sensor that can measure light from 0.01 lux to 64k lux. 8 | 9 | Functions interacting with 10 | the light sensor are defined in the `ambientlight_ltr329.h `_ header file. 11 | 12 | Configuration 13 | ------------- 14 | The LTR329 sensor has 3 configurable parameters: 15 | 16 | ================ ========================================= 17 | Parameter Description 18 | ================ ========================================= 19 | Gain Controls data range and resolution 20 | Integration Time Measurement time for each cycle 21 | Measurement Rate How frequently to update illuminance data 22 | ================ ========================================= 23 | 24 | Possible values for each of these parameters are defined in their respective enums. After configuring the API with the desired settings, call 25 | `mbl_mw_als_ltr329_write_config `_. to 26 | write the settings to the sensor. :: 27 | 28 | // Set sensor gain to 96x 29 | MetaWear.mbl_mw_als_ltr329_set_gain(device.board, MBL_MW_ALS_LTR329_GAIN_96X); 30 | 31 | // Set the integration time to 400ms 32 | MetaWear.mbl_mw_als_ltr329_set_integration_time(device.board, MBL_MW_ALS_LTR329_TIME_400MS); 33 | 34 | // Set the measurement rate to 1000ms 35 | MetaWear.mbl_mw_als_ltr329_set_measurement_rate(device.board, MBL_MW_ALS_LTR329_RATE_1000MS); 36 | 37 | // Write the configuration to the sensor 38 | MetaWear.mbl_mw_als_ltr329_write_config(device.board); 39 | 40 | Illuminance Measurement 41 | ----------------------- 42 | To start measuring illuminance, call 43 | `mbl_mw_als_ltr329_start `_. 44 | Illuminance data is represented as an unsigned integer and is in units of milli lux. :: 45 | 46 | let signal = MetaWear.mbl_mw_als_ltr329_get_illuminance_data_signal(device.board); 47 | 48 | MetaWear.mbl_mw_datasignal_subscribe(signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 49 | var data = pointer.deref(); 50 | var value = data.parseValue(); 51 | console.log('epoch: ' + data.epoch + ' illuminance: ' + value/1000.0); 52 | })) 53 | 54 | MetaWear.mbl_mw_als_ltr329_start(device.board); -------------------------------------------------------------------------------- /docs/source/barometer.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Barometer 4 | ========= 5 | A barometer is a scientific instrument that is used to measure air pressure in a certain environment. The absolute barometric pressure sensor can measure pressure from 300 Pascal to 1100 hPa. 6 | 7 | MetaWear RPro and Cpro, MMR, MMC, MTR, and MetaEnvironment boards come with a Bosch barometer. 8 | 9 | The specific barometer model varies between the boards although both barometers are nearly identical save for a few settings. Bosch barometer functions are defined in the 10 | `barometer_bosch.h `_ header file where functions containing ``baro_bosch`` 11 | are barometer agnostic where as functions with ``baro_bmp280`` and ``baro_bme280`` are for those specific barometers. 12 | 13 | Users can programatically determine which barometer is on their board with the 14 | `mbl_mw_metawearboard_lookup_module `_ function. :: 15 | 16 | let gyroType = MetaWear.mbl_mw_metawearboard_lookup_module(device.board, MBL_MW_MODULE_BAROMETER); 17 | switch (gyroType) { 18 | case MBL_MW_MODULE_BARO_TYPE_BMP280: 19 | console.log("BMP280 barometer") 20 | break; 21 | case MBL_MW_MODULE_BARO_TYPE_BME280: 22 | console.log("BME280 barometer") 23 | break; 24 | case UInt8(MBL_MW_MODULE_TYPE_NA): 25 | console.log("no barometer") 26 | break; 27 | default: 28 | console.log("unknown barometer") 29 | break; 30 | } 31 | 32 | Sensor Configuration 33 | -------------------- 34 | The Bosch barometers have 3 configurable parameters: 35 | 36 | * Oversampling 37 | * Infinite impulse filter (iir) coefficient 38 | * Standby time 39 | 40 | These operational parameters work in conjunction to control the noise, output resolution, and sampling rate. When you are done setting the configuration, 41 | call `mbl_mw_baro_bosch_write_config `_ to 42 | write the changes to the sensor. :: 43 | 44 | // Set oversampling to ultra high resolution 45 | MetaWear.mbl_mw_baro_bosch_set_oversampling(device.board, MBL_MW_BARO_BOSCH_OVERSAMPLE_ULTRA_HIGH); 46 | 47 | // Set standby time to 62.5ms or closest valid value 48 | MetaWear.mbl_mw_baro_bosch_set_standby_time(device.board, 62.5); 49 | 50 | // Set iir filter coefficient 51 | MetaWear.mbl_mw_baro_bosch_set_iir_filter(device.board, MBL_MW_BARO_BOSCH_IIR_FILTER_AVG_4); 52 | 53 | // Write configuration to the sensor 54 | MetaWear.mbl_mw_baro_bosch_write_config(device.board); 55 | 56 | Pressure Sampling 57 | ----------------- 58 | Pressure data is represented as a float and is in units of Pascals. To receive pressure data, simply subscribe or log the pressure data signal and 59 | then start the sensor. :: 60 | 61 | console.log('Get barometer.') 62 | let baro = MetaWear.mbl_mw_baro_bosch_get_pressure_data_signal(device.board); 63 | 64 | console.log('Set up stream.') 65 | MetaWear.mbl_mw_datasignal_subscribe(baro, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 66 | var data = pointer.deref(); 67 | var value = data.parseValue(); 68 | console.log('epoch: ' + data.epoch + ' pressure: ' + value); 69 | })) 70 | 71 | console.log('Start barometer.'); 72 | MetaWear.mbl_mw_baro_bosch_start(device.board); 73 | 74 | Altitude Sampling 75 | ----------------- 76 | Altitude data is represented as a float and is in units of meters. To receive altitude data, simply subscribe or log the altitude data signal and then 77 | start the sensor. :: 78 | 79 | console.log('Setup barometer.') 80 | MetaWear.mbl_mw_baro_bosch_set_oversampling(device.board, MBL_MW_BARO_BOSCH_OVERSAMPLING_ULTRA_LOW_POWER); 81 | MetaWear.mbl_mw_baro_bosch_set_iir_filter(device.board, MBL_MW_BARO_BOSCH_IIR_FILTER_OFF); 82 | MetaWear.mbl_mw_baro_bmp280_set_standby_time(device.board, MBL_MW_BARO_BMP280_STANDBY_TIME_0_5ms); 83 | MetaWear.mbl_mw_baro_bosch_write_config(device.board); 84 | 85 | console.log('Get barometer.') 86 | let baro = MetaWear.mbl_mw_baro_bosch_get_altitude_data_signal(device.board); 87 | 88 | console.log('Set up stream.') 89 | MetaWear.mbl_mw_datasignal_subscribe(baro, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 90 | var data = pointer.deref(); 91 | var value = data.parseValue(); 92 | console.log('epoch: ' + data.epoch + ' pressure: ' + value); 93 | })) 94 | 95 | console.log('Start barometer.'); 96 | MetaWear.mbl_mw_baro_bosch_start(device.board); 97 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # MetaWear iOS API documentation build configuration file, created by 5 | # sphinx-quickstart on Sat Apr 16 02:20:42 2016. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | import sys 17 | import os 18 | 19 | # If extensions (or modules to document with autodoc) are in another directory, 20 | # add these directories to sys.path here. If the directory is relative to the 21 | # documentation root, use os.path.abspath to make it absolute, like shown here. 22 | #sys.path.insert(0, os.path.abspath('.')) 23 | 24 | # -- General configuration ------------------------------------------------ 25 | 26 | # If your documentation needs a minimal Sphinx version, state it here. 27 | #needs_sphinx = '1.0' 28 | 29 | # Add any Sphinx extension module names here, as strings. They can be 30 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 31 | # ones. 32 | extensions = ['sphinx.ext.autosectionlabel'] 33 | 34 | # Add any paths that contain templates here, relative to this directory. 35 | templates_path = ['_templates'] 36 | 37 | # The suffix(es) of source filenames. 38 | # You can specify multiple suffix as a list of string: 39 | # source_suffix = ['.rst', '.md'] 40 | source_suffix = '.rst' 41 | 42 | # The encoding of source files. 43 | #source_encoding = 'utf-8-sig' 44 | 45 | # The master toctree document. 46 | master_doc = 'index' 47 | 48 | # General information about the project. 49 | project = 'MetaWear Javascript API' 50 | copyright = '2021, MbientLab' 51 | author = 'MbientLab' 52 | 53 | # The version info for the project you're documenting, acts as replacement for 54 | # |version| and |release|, also used in various other places throughout the 55 | # built documents. 56 | # 57 | # The short X.Y version. 58 | version = '1.0.0' 59 | # The full version, including alpha/beta/rc tags. 60 | release = '1.0.0' 61 | 62 | # The language for content autogenerated by Sphinx. Refer to documentation 63 | # for a list of supported languages. 64 | # 65 | # This is also used if you do content translation via gettext catalogs. 66 | # Usually you set "language" from the command line for these cases. 67 | language = None 68 | 69 | # There are two options for replacing |today|: either, you set today to some 70 | # non-false value, then it is used: 71 | #today = '' 72 | # Else, today_fmt is used as the format for a strftime call. 73 | #today_fmt = '%B %d, %Y' 74 | 75 | # List of patterns, relative to source directory, that match files and 76 | # directories to ignore when looking for source files. 77 | # This patterns also effect to html_static_path and html_extra_path 78 | exclude_patterns = [] 79 | 80 | # The reST default role (used for this markup: `text`) to use for all 81 | # documents. 82 | #default_role = None 83 | 84 | # If true, '()' will be appended to :func: etc. cross-reference text. 85 | #add_function_parentheses = True 86 | 87 | # If true, the current module name will be prepended to all description 88 | # unit titles (such as .. function::). 89 | #add_module_names = True 90 | 91 | # If true, sectionauthor and moduleauthor directives will be shown in the 92 | # output. They are ignored by default. 93 | #show_authors = False 94 | 95 | # The name of the Pygments (syntax highlighting) style to use. 96 | pygments_style = 'sphinx' 97 | 98 | # A list of ignored prefixes for module index sorting. 99 | #modindex_common_prefix = [] 100 | 101 | # If true, keep warnings as "system message" paragraphs in the built documents. 102 | #keep_warnings = False 103 | 104 | # If true, `todo` and `todoList` produce output, else they produce nothing. 105 | todo_include_todos = False 106 | 107 | 108 | # -- Options for HTML output ---------------------------------------------- 109 | 110 | # The theme to use for HTML and HTML Help pages. See the documentation for 111 | # a list of builtin themes. 112 | html_theme = 'sphinx_rtd_theme' 113 | 114 | # Theme options are theme-specific and customize the look and feel of a theme 115 | # further. For a list of options available for each theme, see the 116 | # documentation. 117 | #html_theme_options = {} 118 | 119 | # Add any paths that contain custom themes here, relative to this directory. 120 | #html_theme_path = [] 121 | 122 | # The name for this set of Sphinx documents. 123 | # " v documentation" by default. 124 | #html_title = 'MetaWear iOS API v2.3.2' 125 | 126 | # A shorter title for the navigation bar. Default is the same as html_title. 127 | #html_short_title = None 128 | 129 | # The name of an image file (relative to this directory) to place at the top 130 | # of the sidebar. 131 | #html_logo = None 132 | 133 | # The name of an image file (relative to this directory) to use as a favicon of 134 | # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 135 | # pixels large. 136 | #html_favicon = None 137 | 138 | # Add any paths that contain custom static files (such as style sheets) here, 139 | # relative to this directory. They are copied after the builtin static files, 140 | # so a file named "default.css" will overwrite the builtin "default.css". 141 | html_static_path = [] 142 | 143 | # Add any extra paths that contain custom files (such as robots.txt or 144 | # .htaccess) here, relative to this directory. These files are copied 145 | # directly to the root of the documentation. 146 | #html_extra_path = [] 147 | 148 | # If not None, a 'Last updated on:' timestamp is inserted at every page 149 | # bottom, using the given strftime format. 150 | # The empty string is equivalent to '%b %d, %Y'. 151 | #html_last_updated_fmt = None 152 | 153 | # If true, SmartyPants will be used to convert quotes and dashes to 154 | # typographically correct entities. 155 | #html_use_smartypants = True 156 | 157 | # Custom sidebar templates, maps document names to template names. 158 | #html_sidebars = {} 159 | 160 | # Additional templates that should be rendered to pages, maps page names to 161 | # template names. 162 | #html_additional_pages = {} 163 | 164 | # If false, no module index is generated. 165 | #html_domain_indices = True 166 | 167 | # If false, no index is generated. 168 | #html_use_index = True 169 | 170 | # If true, the index is split into individual pages for each letter. 171 | #html_split_index = False 172 | 173 | # If true, links to the reST sources are added to the pages. 174 | #html_show_sourcelink = True 175 | 176 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 177 | #html_show_sphinx = True 178 | 179 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 180 | #html_show_copyright = True 181 | 182 | # If true, an OpenSearch description file will be output, and all pages will 183 | # contain a tag referring to it. The value of this option must be the 184 | # base URL from which the finished HTML is served. 185 | #html_use_opensearch = '' 186 | 187 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 188 | #html_file_suffix = None 189 | 190 | # Language to be used for generating the HTML full-text search index. 191 | # Sphinx supports the following languages: 192 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' 193 | # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh' 194 | #html_search_language = 'en' 195 | 196 | # A dictionary with options for the search language support, empty by default. 197 | # 'ja' uses this config value. 198 | # 'zh' user can custom change `jieba` dictionary path. 199 | #html_search_options = {'type': 'default'} 200 | 201 | # The name of a javascript file (relative to the configuration directory) that 202 | # implements a search results scorer. If empty, the default will be used. 203 | #html_search_scorer = 'scorer.js' 204 | 205 | # Output file base name for HTML help builder. 206 | htmlhelp_basename = 'MetaWeariOSAPIdoc' 207 | 208 | # -- Options for LaTeX output --------------------------------------------- 209 | 210 | latex_elements = { 211 | # The paper size ('letterpaper' or 'a4paper'). 212 | #'papersize': 'letterpaper', 213 | 214 | # The font size ('10pt', '11pt' or '12pt'). 215 | #'pointsize': '10pt', 216 | 217 | # Additional stuff for the LaTeX preamble. 218 | #'preamble': '', 219 | 220 | # Latex figure (float) alignment 221 | #'figure_align': 'htbp', 222 | } 223 | 224 | # Grouping the document tree into LaTeX files. List of tuples 225 | # (source start file, target name, title, 226 | # author, documentclass [howto, manual, or own class]). 227 | latex_documents = [ 228 | (master_doc, 'MetaWeariOSAPI.tex', 'MetaWear iOS/macOS/tvOS/watchOS API Documentation', 229 | 'MbientLab', 'manual'), 230 | ] 231 | 232 | # The name of an image file (relative to this directory) to place at the top of 233 | # the title page. 234 | #latex_logo = None 235 | 236 | # For "manual" documents, if this is true, then toplevel headings are parts, 237 | # not chapters. 238 | #latex_use_parts = False 239 | 240 | # If true, show page references after internal links. 241 | #latex_show_pagerefs = False 242 | 243 | # If true, show URL addresses after external links. 244 | #latex_show_urls = False 245 | 246 | # Documents to append as an appendix to all manuals. 247 | #latex_appendices = [] 248 | 249 | # If false, no module index is generated. 250 | #latex_domain_indices = True 251 | 252 | 253 | # -- Options for manual page output --------------------------------------- 254 | 255 | # One entry per manual page. List of tuples 256 | # (source start file, name, description, authors, manual section). 257 | man_pages = [ 258 | (master_doc, 'metaweariosapi', 'MetaWear iOS/macOS/tvOS/watchOS API Documentation', 259 | [author], 1) 260 | ] 261 | 262 | # If true, show URL addresses after external links. 263 | #man_show_urls = False 264 | 265 | 266 | # -- Options for Texinfo output ------------------------------------------- 267 | 268 | # Grouping the document tree into Texinfo files. List of tuples 269 | # (source start file, target name, title, author, 270 | # dir menu entry, description, category) 271 | texinfo_documents = [ 272 | (master_doc, 'MetaWeariOSAPI', 'MetaWear iOS/macOS/tvOS/watchOS API Documentation', 273 | author, 'MetaWeariOSAPI', 'One line description of project.', 274 | 'Miscellaneous'), 275 | ] 276 | 277 | # Documents to append as an appendix to all manuals. 278 | #texinfo_appendices = [] 279 | 280 | # If false, no module index is generated. 281 | #texinfo_domain_indices = True 282 | 283 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 284 | #texinfo_show_urls = 'footnote' 285 | 286 | # If true, do not generate a @detailmenu in the "Top" node's menu. 287 | #texinfo_no_detailmenu = False 288 | -------------------------------------------------------------------------------- /docs/source/core_modules.rst: -------------------------------------------------------------------------------- 1 | Core Modules 2 | ============ 3 | The MetaWear firmware comes with several powerful features that enable developers to fine-tune their board configuration for specific use cases. 4 | 5 | The :doc:`sensor_fusion` module is available on the MMC, MMR, and MMS only. The other modules are available on all boards. 6 | 7 | .. toctree:: 8 | :hidden: 9 | :maxdepth: 1 10 | 11 | dataprocessor 12 | logging 13 | macro 14 | sensor_fusion 15 | settings 16 | timer 17 | -------------------------------------------------------------------------------- /docs/source/cppbridge.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Bridge to CPP SDK 4 | =================== 5 | As mentioned previously, the MetaWear Javascript APIs are a wrapper around the CPP APIs. 6 | 7 | MetaWear 8 | --------------- 9 | Each script must include the node javascript library ``Metawear``. 10 | :: 11 | 12 | var MetaWear = require('metawear'); 13 | 14 | The core libraries are written in C++ and many of the calls made are from the CPP library. You will find the `C++ documentation `_ and `API reference `_ useful. 15 | 16 | The main MetaWear class in Node.JS can be found `here `_. 17 | 18 | Node-FFI 19 | --------------- 20 | Node-ffi is a Node.js addon for loading and calling dynamic libraries using pure JavaScript. It can be used to create bindings to native libraries without writing any C++ code. The library has been partially abandoned so MbientLab is hosting a custom copy `here `_. 21 | 22 | Node ffi is use along with the bindings file so that Node API calls can call the CPP SDK. 23 | 24 | Bindings 25 | --------------- 26 | The `bindings file `_ is the glue between the Javascript APIs and the CPP library. 27 | 28 | In the bindings file: :: 29 | 30 | /** 31 | * Stop sensor fusion 32 | * @param board Calling object 33 | */ 34 | 'mbl_mw_sensor_fusion_stop': [ref.types.void, [ref.refType(MetaWearBoard)]], 35 | 36 | In the CPP library: :: 37 | 38 | /** 39 | * Stop sensor fusion 40 | * @param board Calling object 41 | */ 42 | METAWEAR_API void mbl_mw_sensor_fusion_stop(const MblMwMetaWearBoard* board); 43 | 44 | Can be called in Node.JS: :: 45 | 46 | var MetaWear = require('metawear'); 47 | MetaWear.mbl_mw_sensor_fusion_stop(device.board); -------------------------------------------------------------------------------- /docs/source/event.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Events 4 | ====== 5 | An event is an asynchronous notification from the MetaWear board represented in the C++ API by the 6 | `MblMwEvent `_ struct. 7 | 8 | Recording Commands 9 | ------------------ 10 | The board can be programmed to execute MetaWear commands in response to an event firing. 11 | 12 | An event can be many things such as a data filter (average the accelerometer signal), a disconnect (the board has disconnected from the Bluetooth link), or even a timer (10 seconds have passed). 13 | 14 | To start recording commands, call 15 | `mbl_mw_event_record_commands `_. While in a recording 16 | state, all MetaWear functions called will instead be recorded on the board and executed when the event is fired. 17 | 18 | To stop recording, call `mbl_mw_event_end_record `_. This function is asynchronous and will alert the caller when it is completed via a callback function. 19 | 20 | In this example, we use a timed event to read the temperature sensor: 21 | 22 | :: 23 | 24 | MetaWear.mbl_mw_event_record_commands(tempTimer); 25 | 26 | MetaWear.mbl_mw_datasignal_read(tempSignal); 27 | 28 | promise = new Promise((resolve, reject) => { 29 | var rec = MetaWear.mbl_mw_event_end_record(tempTimer, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, status) { 30 | resolve(status); 31 | })); 32 | }); 33 | let rec = await promise; 34 | 35 | Here is the full example: 36 | 37 | :: 38 | 39 | // Get temp signal 40 | var temp = MetaWear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(device.board,1); 41 | 42 | // Subscribe to it 43 | MetaWear.mbl_mw_datasignal_subscribe(temp, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 44 | console.log('got data'); 45 | var data = pointer.deref(); 46 | var value = data.parseValue(); 47 | console.log('epoch: ' + data.epoch + ' temp: ' + value); 48 | })); 49 | 50 | // Create a timer 51 | var promise = new Promise((resolve, reject) => { 52 | var timer = MetaWear.mbl_mw_timer_create_indefinite(device.board, 1000, 0, ref.NULL, MetaWear.FnVoid_VoidP_TimerP.toPointer(function onSignall(context, timer) { 53 | resolve(timer); 54 | })); 55 | }); 56 | let timer = await promise; 57 | 58 | // Create event based on timer and record as a command 59 | MetaWear.mbl_mw_event_record_commands(timer); 60 | MetaWear.mbl_mw_datasignal_read(temp); 61 | promise = new Promise((resolve, reject) => { 62 | var rec = MetaWear.mbl_mw_event_end_record(timer, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 63 | console.log('Command created'); 64 | resolve(lstatus); 65 | })); 66 | }); 67 | let rec = await promise; 68 | 69 | // Start timer 70 | MetaWear.mbl_mw_timer_start(timer); -------------------------------------------------------------------------------- /docs/source/gpio.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | GPIO 4 | ==== 5 | A general-purpose input/output (GPIO) is an uncommitted digital or analog signal pin on the MetaWear board. 6 | 7 | All boards come with general purpose I/O pins allowing users to attach their own sensors. You can attach an analog heart-rate sensor, a thermistor, a push sensor and more using the GPIOs on the MetaWear board. 8 | 9 | Functions for communicating with the gpio pins are in the 10 | `gpio.h `_ header file. 11 | 12 | Analog Data 13 | ----------- 14 | Analog input data comes in 2 forms, an ADC value or a absolute reference value. These two modes are distinguished with the 15 | `MblMwGpioAnalogReadMode `_ enum. 16 | 17 | To read analog data, call 18 | `mbl_mw_datasignal_read `_ with your analog input 19 | signal. ADC values are represented as an unsigned integer and are simply ratiometric values with no units. The absolute reference value is also 20 | represented as an unsigned integer but has units of milli volts. :: 21 | 22 | // Get gpio signal 23 | var signal = MetaWear.mbl_mw_gpio_get_analog_input_data_signal(device.board, 1,MBL_MW_GPIO_ANALOG_READ_MODE_ABS_REF); 24 | 25 | // Subscribe to it 26 | MetaWear.mbl_mw_datasignal_subscribe(signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 27 | var data = pointer.deref(); 28 | var value = data.parseValue(); 29 | console.log('epoch: ' + data.epoch + ' gpio: ' + value/1000.0); // Units in mili volts 30 | })); 31 | 32 | // Read it 33 | MetaWear.mbl_mw_datasignal_read(signal); 34 | 35 | 36 | Enhanced Analog Reads 37 | --------------------- 38 | Starting with firmware v1.2.3, additional features have been added to the analog read. To use these features, call 39 | `mbl_mw_datasignal_read_with_parameters `_ 40 | and use a `MblMwGpioAnalogReadParameters `_ struct as the 41 | parameter. Not all of the struct variables are required, for the read. To indicate that any of the pin variables are not used, set them to 42 | `MBL_MW_GPIO_UNUSED_PIN `_, and to indicate the delay 43 | variable is unused, set it to 0. :: 44 | 45 | // read with pullup pin 0, unused pull down pin, virtual pin 21, unused delay 46 | var parameters = MblMwGpioAnalogReadParameters(0, MBL_MW_GPIO_UNUSED_PIN, 0x15, 0); 47 | MetaWear.mbl_mw_datasignal_read_with_parameters(adc_signal, parameters); 48 | 49 | Pullup and Pulldown Pins 50 | ^^^^^^^^^^^^^^^^^^^^^^^^ 51 | Setting a pullup/pulldown pin will have the board automatically set the pull mode on that pin prior to reading the analog data. :: 52 | 53 | // pullup pin 0 before reading pin 0 54 | var parameters = MblMwGpioAnalogReadParameters(0, MBL_MW_GPIO_UNUSED_PIN, MBL_MW_GPIO_UNUSED_PIN, 0); 55 | MetaWear.mbl_mw_datasignal_read_with_parameters(signal, parameters) 56 | 57 | Delay 58 | ^^^^^ 59 | The delay parameter controls how long the firmware will wait after the pull mode is set before reading the data. The firmware will wait for up to 60 | 1 millisecond or if unused, immediately read the analog signal. :: 61 | 62 | // wait 10 milliseconds after pulling down pin 2 before reading pin 1 63 | var parameters = MblMwGpioAnalogReadParameters(MBL_MW_GPIO_UNUSED_PIN, 2, MBL_MW_GPIO_UNUSED_PIN, 10); 64 | MetaWear.mbl_mw_datasignal_read_with_parameters(signal, parameters) 65 | 66 | Virtual Pins 67 | ^^^^^^^^^^^^ 68 | Virtual pins are dummy GPIO pins that can be used to redirect the analog output to another pin. For example, you can assign a unique pin for each 69 | read configuration in your circuit which will send the data for the configurations to different message handlers. Keep in mind that when using virtual 70 | pins, you will need to subscribe to both the original and virtual pin for streaming. :: 71 | 72 | // Get gpio signal 73 | var signal = MetaWear.mbl_mw_gpio_get_analog_input_data_signal(board, 0x15, MBL_MW_GPIO_ANALOG_READ_MODE_ADC); 74 | 75 | // Subscribe to it 76 | MetaWear.mbl_mw_datasignal_subscribe(signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 77 | var data = pointer.deref(); 78 | var value = data.parseValue(); 79 | console.log('epoch: ' + data.epoch + ' gpio 21 adc: ' + value); 80 | })); 81 | 82 | // Read it 83 | var parameters = MblMwGpioAnalogReadParameters(MBL_MW_GPIO_UNUSED_PIN, MBL_MW_GPIO_UNUSED_PIN, 0x15, 0); 84 | MetaWear.mbl_mw_datasignal_read_with_parameters(signal, parameters) 85 | 86 | 87 | Digital Data 88 | ------------ 89 | Digital input data is an input signal that is interpreted as a 1 or 0. As per the 90 | `product specification `_ section 6.1, a logical 91 | high is between 2.1 and 3.0 volts and low is between 0 and 0.9 volts. To ensure that your input signal resides within one of the valid ranges, set 92 | the pull mode with `mbl_mw_gpio_set_pull_mode `_. 93 | 94 | To read the data input value, issue a call to 95 | `mbl_mw_datasignal_read `_ with your digial signal. 96 | Digital data is interpreted as an unsigned integer. :: 97 | 98 | // Get gpio signal 99 | var signal = MetaWear.mbl_mw_gpio_get_digital_input_data_signal(device.board, 0); 100 | 101 | // Subscribe to it 102 | MetaWear.mbl_mw_datasignal_subscribe(signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 103 | var data = pointer.deref(); 104 | var value = data.parseValue(); 105 | console.log('epoch: ' + data.epoch + ' gpio: ' + value != 0 ? "1" : "0"); // 1 or 0 106 | })); 107 | 108 | // Read it 109 | MetaWear.mbl_mw_datasignal_read(signal); 110 | 111 | Input Monitoring 112 | ---------------- 113 | The firmware can also monitor the digital state of the input signal and alert the user if the state changes. Set the change type by calling 114 | `mbl_mw_gpio_set_pin_change_type `_ and then call 115 | `mbl_mw_gpio_start_pin_monitoring `_ to start the 116 | monitoring. :: 117 | 118 | // Get gpio signal 119 | var signal = MetaWear.mbl_mw_gpio_set_pin_change_type(device.board, 3, MBL_MW_GPIO_PIN_CHANGE_TYPE_ANY); 120 | 121 | // Subscribe to it 122 | MetaWear.mbl_mw_datasignal_subscribe(signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 123 | var data = pointer.deref(); 124 | var value = data.parseValue(); 125 | console.log('Change: ' + value); 126 | })); 127 | 128 | // Monitor it 129 | MetaWear.mbl_mw_gpio_start_pin_monitoring(device.board,3); -------------------------------------------------------------------------------- /docs/source/gyro.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Gyroscope 4 | ========== 5 | Gyroscopes, or gyros, are devices that measure or maintain rotational motion. The units of angular velocity are measured in degrees per second (°/s) or revolutions per second (RPS). Angular velocity is simply a measurement of speed of rotation. 6 | 7 | MetaWear RG, RPro, C, MMR, MMC, MTR, and CPro come with a `Bosch BMI160 `_ 6-axis IMU. The gyro 8 | functionality of this sensor is accessed by the functions in the 9 | `gyro_bmi160.h `_ header file. 10 | 11 | Configuration 12 | ------------- 13 | The gyro's data sampling rate and the range/resolution of the angular velocity are controlled by theoutput data rate and sampling range respectively. 14 | After selecting the desired settings in the API, call 15 | `mbl_mw_gyro_bmi160_write_config `_. to write the 16 | chnges to the sensor. :: 17 | 18 | // Set ODR to 50Hz 19 | MetaWear.mbl_mw_gyro_bmi160_set_odr(board, MBL_MW_GYRO_BMI160_ODR_50HZ); 20 | 21 | // Set data range to +/125 degrees per second 22 | MetaWear.mbl_mw_gyro_bmi160_set_range(board, MBL_MW_GYRO_BMI160_FSR_125DPS); 23 | 24 | // Write the changes to the sensor 25 | MetaWear.mbl_mw_gyro_bmi160_write_config(board); 26 | 27 | Rotation Rate Sampling 28 | ---------------------- 29 | Rotate rate sampling measures the rate of change of the pitch, yaw, and roll angles, in other words, the angular velocity of the spin around the XYZ 30 | axes. To enable rotation rate sampling, call 31 | `mbl_mw_gyro_bmi160_enable_rotation_sampling `_ 32 | before starting the gyro. 33 | 34 | Angular velocity is represented by the 35 | `MblMwCartesianFloat `_ struct and is in units of degrees per second. 36 | The ``x``, ``y``, and ``z`` fields contain the angular velocity of the spin around that axis. :: 37 | 38 | let gyro = MetaWear.mbl_mw_gyro_bmi160_get_rotation_data_signal(device.board); 39 | 40 | MetaWear.mbl_mw_datasignal_subscribe(gyro, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 41 | var data = pointer.deref(); 42 | var value = data.parseValue(); 43 | console.log('epoch: ' + data.epoch + ' gyro: ' + value.x + ' ' + value.y + ' ' + value.z) 44 | })) 45 | 46 | MetaWear.mbl_mw_gyro_bmi160_enable_rotation_sampling(device.board); 47 | MetaWear.mbl_mw_gyro_bmi160_start(device.board); 48 | 49 | High Frequency Stream 50 | ^^^^^^^^^^^^^^^^^^^^^ 51 | Firmware v1.2.3+ contains a packed mode for the hyro which combines 3 rotation data samples into 1 ble packet allowing the board to stream data at a 52 | throughput higher than 100Hz. This special data signal is retrieved from the 53 | `mbl_mw_gyro_bmi160_get_rotation_data_signal `_ 54 | function and is only for streaming; do not use it with data processing or logging. :: 55 | 56 | let gyro = MetaWear.mbl_mw_gyro_bmi160_get_rotation_data_signal(device.board); 57 | 58 | MetaWear.mbl_mw_gyro_bmi160_set_odr(device.board, 200); 59 | 60 | MetaWear.mbl_mw_datasignal_subscribe(gyro, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 61 | var data = pointer.deref(); 62 | var value = data.parseValue(); 63 | console.log('epoch: ' + data.epoch + ' gyro: ' + value.x + ' ' + value.y + ' ' + value.z) 64 | })) 65 | 66 | MetaWear.mbl_mw_gyro_bmi160_enable_rotation_sampling(device.board); 67 | MetaWear.mbl_mw_gyro_bmi160_start(device.board); -------------------------------------------------------------------------------- /docs/source/haptic.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Haptic 4 | ====== 5 | The haptic module controls a high current driver to power a motor or buzzer (or similar devices). 6 | 7 | In the MMR+ model, the coin vibration motor provides haptic feedback by vibrating using the haptic module. 8 | 9 | Functions are defined in the 10 | `haptic.h `_ header filer. Circuit diagrams for the driver pin are in section 8 of the 11 | `product specification `_. :: 12 | 13 | // Run buzzer for 500ms 14 | MetaWear.mbl_mw_haptic_start_buzzer(device.board, 500); 15 | 16 | // Run motor at 50% strength for 1000ms 17 | MetaWear.mbl_mw_haptic_start_motor(device.board, 50.0, 1000); 18 | 19 | The haptic module does not provide PWM (pulse-width modulation) capability. 20 | -------------------------------------------------------------------------------- /docs/source/humidity.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Humidity 4 | ======== 5 | A humidity sensor senses relative humidity. This means that it measures both air temperature and moisture. Relative humidity, expressed as a percent, is the ratio of actual moisture in the air to the highest amount of moisture air at that temperature can hold. 6 | 7 | MetaEnvironment and MTR boards have a Bosch `BME280 `_ integrated environmental unit. 8 | 9 | Humidity functionality of that sensor are controlled by the functions in the 10 | `humidity.h `_ header file. 11 | 12 | Oversampling 13 | ------------ 14 | The humidity sensing portion of the BME280 chip only has 1 configurable parameter which is the oversampling mode. This is set by calling 15 | `mbl_mw_humidity_bme280_set_oversampling `_. 16 | Unlike other configuration functions, this function will immediately write the change to the sensor. :: 17 | 18 | MetaWear.mbl_mw_humidity_bme280_set_oversampling(board, MBL_MW_HUMIDITY_BME280_OVERSAMPLING_16X); 19 | 20 | Humidity Measurement 21 | -------------------- 22 | Measuring humidity is manually triggered by calling 23 | `mbl_mw_datasignal_read `_ with a humidity data 24 | signal. Humidity data is percetange from 0 to 100 represented as a float. :: 25 | 26 | // Setup barometer 27 | MetaWear.mbl_mw_humidity_bme280_set_oversampling(device.board, MBL_MW_HUMIDITY_BME280_OVERSAMPLING_1X); 28 | 29 | // Get humidity signal 30 | var hum = MetaWear.mbl_mw_humidity_bme280_get_percentage_data_signal(device.board); 31 | 32 | // Subscribe to it 33 | console.log('Subscribe'); 34 | MetaWear.mbl_mw_datasignal_subscribe(hum, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 35 | var data = pointer.deref(); 36 | var value = data.parseValue(); 37 | console.log('epoch: ' + data.epoch + ' humidity: ' + value); 38 | })); 39 | 40 | // Read 41 | MetaWear.mbl_mw_datasignal_read(hum); -------------------------------------------------------------------------------- /docs/source/i2c.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | I2C 4 | === 5 | The Inter-Integrated Circuit (I2C) Protocol is a protocol intended to allow multiple "peripheral" digital integrated circuits ("chips") to communicate with the MetaWear board. 6 | 7 | The I2C module allows you to directly communicate with a sensor via the I2C bus. If you want to add sensors to the MetaWear board that communicate with I2C, this is possible using the I2C module. 8 | 9 | I2C functions are defined in the 10 | `i2c.h `_ header file. 11 | 12 | Data Signal 13 | ----------- 14 | I2C data signals are retrieved by calling 15 | `mbl_mw_i2c_get_data_signal `_. You will need to pass 16 | two parameters: 17 | 18 | * Length variable that sets how many bytes the signal is expected to receive 19 | * An unique ID identifying the signal 20 | 21 | If the id value has already been used, the length parameter will be ignored and the previously created signal will be returned. :: 22 | 23 | var length = 1; 24 | let signal = MetaWear.mbl_mw_i2c_get_data_signal(device.board, length, 0); 25 | 26 | Read 27 | ---- 28 | To read I2C data, use the 29 | `mbl_mw_datasignal_read_with_parameters `_ 30 | function with the parameters set by the `MblMwI2cReadParameters `_ 31 | struct. :: 32 | 33 | let deviceAddress = 0x1c; 34 | let registerAddress = 0xd; 35 | var length = 1; 36 | let signal = MetaWear.mbl_mw_i2c_get_data_signal(device.board, length, 0); 37 | 38 | var parameters = MblMwI2cReadParameters(device_addr: deviceAddress, register_addr: registerAddress); 39 | MetaWear.mbl_mw_datasignal_read_with_parameters(signal, parameters); 40 | 41 | MetaWear.mbl_mw_datasignal_subscribe(signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 42 | var data = pointer.deref(); 43 | var value = data.parseValue(); 44 | console.log('bytes: ' + value); 45 | })); 46 | 47 | 48 | Write 49 | ----- 50 | Writing data through the I2C bus is handled with the 51 | `mbl_mw_i2c_write `_ function. :: 52 | 53 | let deviceAddress = 0x77; 54 | let registerAddress = 0xf4; 55 | var writeData = 0x37; 56 | var length = 1; 57 | 58 | let array = Array(Data(bytes: writeData, count: Int(length))); 59 | 60 | MetaWear.mbl_mw_i2c_write(device.board, deviceAddress, registerAddress, array, length); -------------------------------------------------------------------------------- /docs/source/ibeacon.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | iBeacon 4 | ======= 5 | iBeacon is a protocol developed by Apple. The main purpose of Beacons (which are simply Bluetooth advertisers - not connectable) is for location-data and proximity marketing. 6 | 7 | The MetaWear firmware supports the iBeacon format and can advertise itself as an iBeacon. 8 | 9 | To enable iBeacon mode, all you need to do is call 10 | `mbl_mw_ibeacon_enable `_ and disconnect from the 11 | board. 12 | 13 | The other functions in the `ibeacon.h `_ header file configure the 14 | advertisement parameters. :: 15 | 16 | MetaWear.mbl_mw_ibeacon_set_major(device.board, 78); 17 | MetaWear.mbl_mw_ibeacon_set_minor(device.board, 7453); 18 | MetaWear.mbl_mw_ibeacon_set_period(device.board, 15027); 19 | MetaWear.mbl_mw_ibeacon_set_rx_power(device.board, -55); 20 | MetaWear.mbl_mw_ibeacon_set_tx_power(device.board, -12); 21 | MetaWear.mbl_mw_ibeacon_set_uuid(device.board, up); 22 | MetaWear.mbl_mw_ibeacon_enable(device.board); 23 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. MetaWear Javascript API documentation master file, created by 2 | sphinx-quickstart on Sat Apr 16 02:20:42 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Introduction 7 | ================= 8 | The MetaWear Javascript API provides a simple way to communicate with your MetaWear boards using Apple devices. 9 | 10 | This is a thin wrapper around the `MetaWear C++ API `_ so you will find the `C++ documentation `_ and `API reference `_ useful. 11 | 12 | If you are interested in the finer details of the library, see `source code `_ and `API documentation `_. 13 | 14 | This guide assumes you have fundamental knowledge of Javascript programming especially `Node.JS `_. 15 | 16 | 17 | .. toctree:: 18 | :hidden: 19 | :maxdepth: 1 20 | 21 | metawearboard 22 | metawearscanner 23 | cppbridge 24 | event 25 | datasignal 26 | metadataprocessor 27 | logger 28 | core_modules 29 | sensors 30 | peripherals 31 | advanced_features 32 | -------------------------------------------------------------------------------- /docs/source/led.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Led 4 | === 5 | All boards come with an on-board RGB LED. The RGB LED is able to light up the board in various colors and patterns. 6 | 7 | Users can control the LED with the functions in the `led.h `_ header file. 8 | 9 | Setting Patterns 10 | ---------------- 11 | An led pattern is represented by the `MblMwLedPattern `_ struct. Users can 12 | configure every part of the pulse or load one of the preset patterns using the 13 | `mbl_mw_led_load_preset_pattern `_ function. Patterns 14 | are written to the board with the 15 | `mbl_mw_led_write_pattern `_ function. 16 | 17 | To remove patterns, call `mbl_mw_led_stop__and_clear `_; 18 | this will also stop pattern playback. :: 19 | 20 | var pattern = new MetaWear.LedPattern(); 21 | MetaWear.mbl_mw_led_load_preset_pattern(pattern.ref(), MetaWear.LedPreset.BLINK); 22 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), MetaWear.LedColor.GREEN); 23 | MetaWear.mbl_mw_led_play(device.board); 24 | 25 | Pattern Playback 26 | ---------------- 27 | After writing patterns to the board, you can playback the pattern, similar to playing a music track, using 28 | `mbl_mw_led_play `_, 29 | `mbl_mw_led_pause `_, and 30 | `mbl_mw_led_stop `_. :: 31 | 32 | // Start playing the programmed patterns 33 | MetaWear.mbl_mw_led_play(device.board); -------------------------------------------------------------------------------- /docs/source/logger.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Logger 4 | ====== 5 | The MetaWear board can log sensor data and store it in the internal memory of the device using ``loggers`` to be retrieved at a later time. 6 | 7 | Loggers record data from a data signal and are represented by the 8 | `MblMwDataLogger `_ struct. 9 | 10 | Create an 11 | ``MblMwDataLogger`` object by calling 12 | `mbl_mw_datasignal_log `_ with the data signal 13 | you want to log. 14 | 15 | If successful, the callback function will be executed with a 16 | `MblMwDataLogger `_ pointer and if creating the 17 | logger failed, a ``null`` pointer will be returned. :: 18 | 19 | var accSignal = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 20 | 21 | MetaWear.mbl_mw_datasignal_log(accSignal, ref.NULL, MetaWear.FnVoid_VoidP_DataLoggerP.toPointer(function (context, logger) { 22 | accelLogger = logger; 23 | callback(logger.address() ? null : new Error('failed to start logging accel')); 24 | })) 25 | 26 | MblMwDataLogger objects only interact with the specific data signal, they do not control the logging features. Logging control functions are detailed in the :doc:`logging` section. 27 | 28 | ID 29 | -- 30 | MblMwDataLogger objects are identified by a numerical id. 31 | 32 | This id can be used to keep track of loggers when there is considerable time between the start of a log and the download of a log. It is also useful to get the state of the device (i.e is my device still downloading?). 33 | 34 | You can retrieve the id by calling 35 | `mbl_mw_logger_get_id `_. 36 | 37 | The id is used to retrieve existing loggers from the API with the 38 | `mbl_mw_logger_lookup_id `_ function. 39 | 40 | Handling Data 41 | ------------- 42 | Like a data signal, you can subscribe to an MblMwDataLogger to process the downloaded data. 43 | 44 | Call `mbl_mw_logger_subscribe `_ to attach a callback 45 | function to the MblMwDataLogger which handles all received data. :: 46 | 47 | // Subscribe to the accelerometer data 48 | MetaWear.mbl_mw_logger_subscribe(accelLogger, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 49 | var data = dataPtr.deref(); 50 | var pt = data.parseValue(); 51 | console.log(data.epoch + ' ' + pt.x + ',' + pt.y + ',' + pt.z); 52 | })); 53 | 54 | Removal 55 | ------- 56 | When you no longer want to log the values from a data signal, call 57 | `mbl_mw_logger_remove `_ to remove the logger. :: 58 | 59 | MetaWear.mbl_mw_logger_remove(accelLogger); 60 | -------------------------------------------------------------------------------- /docs/source/logging.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Logging 4 | ======= 5 | Logging functions in the `logging.h `_ header file control the on-board logger. 6 | 7 | These functions go hand in hand with the data signal logger outlined in the :doc:`datasignal` section. 8 | 9 | Once a logger is created; logging functions can be used. After you have setup the signal loggers, start 10 | the logger by calling `mbl_mw_logging_start `_. :: 11 | 12 | MetaWear.mbl_mw_logging_start(device.board, 0); 13 | 14 | Once we are done logging, simply call: :: 15 | 16 | MetaWear.mbl_mw_logging_stop(device.board); 17 | 18 | Note for the MMS 19 | ---------------- 20 | The MMS (MetaMotionS) board uses NAND flash memory to store data on the device itself. The NAND memory stores data in pages that are 512 entries large. When data is retrieved, it is retrieved in page sized chunks. 21 | 22 | Before doing a full download of the log memory on the MMS, the final set of data needs to be written to the NAND flash before it can be downloaded as a page. To do this, you must call the function: :: 23 | 24 | MetaWear.mbl_mw_logging_flush_page(device.board); 25 | 26 | This should not be called if you are still logging data. 27 | 28 | Downloading Data 29 | ---------------- 30 | When you are ready to retrieve the data, execute 31 | `mbl_mw_logging_download `_. 32 | 33 | You will need to pass in a `MblMwLogDownloadHandler `_ struct to handle notifications 34 | from the logger. :: 35 | 36 | // Setup the handlers for events during the download 37 | var downloadHandler = new MetaWear.LogDownloadHandler(); 38 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 39 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 40 | if (entriesLeft === 0) { 41 | // Remove all log entries if told to stop logging 42 | MetaWear.mbl_mw_metawearboard_tear_down(device.board); 43 | callback(null); 44 | } 45 | }); 46 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 47 | console.log('received_unknown_entry'); 48 | }); 49 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 50 | var data = dataPtr.deref(); 51 | var dataPoint = data.parseValue(); 52 | console.log('received_unhandled_entry: ' + dataPoint); 53 | }); 54 | 55 | Typical setup 56 | ---------------- 57 | Here is the skeleton code for a typical scenario logging and downloading the accelerometer data: :: 58 | 59 | function startLogging(device, callback) { 60 | // Setup accelerometer 61 | MetaWear.mbl_mw_acc_set_odr(device.board, 50.0); 62 | MetaWear.mbl_mw_acc_set_range(device.board, 16.0); 63 | MetaWear.mbl_mw_acc_write_acceleration_config(device.board); 64 | 65 | // See if we already created a logger 66 | var accSignal = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 67 | MetaWear.mbl_mw_datasignal_log(accSignal, ref.NULL, MetaWear.FnVoid_VoidP_DataLoggerP.toPointer(function (context, logger) { 68 | accelLogger = logger; 69 | callback(logger.address() ? null : new Error('failed to start logging accel')); 70 | })); 71 | 72 | // Start logging 73 | MetaWear.mbl_mw_logging_start(device.board, 0); 74 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 75 | MetaWear.mbl_mw_acc_start(device.board); 76 | } 77 | 78 | function downloadLog(device, callback) { 79 | // Shutdown accel 80 | MetaWear.mbl_mw_acc_stop(device.board); 81 | MetaWear.mbl_mw_acc_disable_acceleration_sampling(device.board); 82 | 83 | // Shutdown log 84 | MetaWear.mbl_mw_logging_stop(device.board); 85 | 86 | // Subscribe to accel logger 87 | MetaWear.mbl_mw_logger_subscribe(accelLogger, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 88 | var data = dataPtr.deref(); 89 | var pt = data.parseValue(); 90 | console.log(data.epoch + ' ' + pt.x + ',' + pt.y + ',' + pt.z); 91 | })); 92 | 93 | // Setup the handlers for events during the download 94 | var downloadHandler = new MetaWear.LogDownloadHandler(); 95 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 96 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 97 | if (entriesLeft === 0) { 98 | // Remove all log entries if told to stop logging 99 | MetaWear.mbl_mw_metawearboard_tear_down(device.board); 100 | callback(null); 101 | } 102 | }); 103 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 104 | console.log('received_unknown_entry'); 105 | }); 106 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 107 | var data = dataPtr.deref(); 108 | var dataPoint = data.parseValue(); 109 | console.log('received_unhandled_entry: ' + dataPoint); 110 | }); 111 | 112 | // Actually start the log download, this will cause all the handlers we setup to be invoked 113 | MetaWear.mbl_mw_logging_download(device.board, 20, downloadHandler.ref()); 114 | } -------------------------------------------------------------------------------- /docs/source/macro.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Macro 4 | ===== 5 | The on-board flash memory can also be used to store MetaWear commands instead of sensor data. 6 | 7 | A good example of this feature is to change the name of a device permanently so that is does not advertise as MetaWear. 8 | 9 | Recorded commands can be executed any time after being 10 | programmed with the functions in `macro.h `_ header file. 11 | 12 | Recording Commands 13 | ------------------ 14 | To record commands: 15 | 16 | 1. Call `mbl_mw_macro_record `_ to put the API in macro mode 17 | 2. Use the MetaWear commands that you want programmed 18 | 3. Exit macro mode with `mbl_mw_macro_end_record `_ :: 19 | 20 | MetaWear.mbl_mw_macro_record(device.board, 1) 21 | // COMMANDS 22 | MetaWear.mbl_mw_macro_end_record(device.board, ref.NULL, callback); 23 | 24 | Macros can be set to run on boot by setting the ``exec_on_boot`` parameter with a non-zero value. 25 | 26 | :: 27 | 28 | MetaWear.mbl_mw_macro_record(board, 1); // ON BOOT 29 | MetaWear.mbl_mw_macro_record(board, 0); // NOT ON BOOT 30 | 31 | In this example, the LED will blink blue on boot: 32 | 33 | :: 34 | 35 | // Start recording macro 36 | MetaWear.mbl_mw_macro_record(device.board, 1) 37 | 38 | // COMMAND - Create LED pattern 39 | var pattern = new MetaWear.LedPattern(); 40 | MetaWear.mbl_mw_led_load_preset_pattern(pattern.ref(), MetaWear.LedPreset.BLINK); 41 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), MetaWear.LedColor.GREEN); 42 | MetaWear.mbl_mw_led_play(device.board); 43 | 44 | // End recording macro 45 | var promise = new Promise((resolve, reject) => { 46 | var macro = MetaWear.mbl_mw_macro_end_record(device.board, ref.NULL, MetaWear.FnVoid_VoidP_Int.toPointer(function onSignal(context, rec) { 47 | console.log('Macro created'); 48 | resolve(rec); 49 | })); 50 | }); 51 | var rec = await promise; 52 | 53 | Erasing Macros 54 | -------------- 55 | Erasing macros is done with the `mbl_mw_macro_erase_all `_ 56 | method. The erase operation will not occur until you disconnect from the board. 57 | 58 | :: 59 | 60 | MetaWear.mbl_mw_macro_erase_all(device.board); 61 | 62 | -------------------------------------------------------------------------------- /docs/source/magnetometer.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Magnetometer 4 | ============ 5 | A magnetometer is a device for detecting and measuring magnetic fields (in Teslas). The device can be used in conjunction with a 3-axis accelerometer to produce orientation independent accurate compass heading information. 6 | 7 | MetaWear CPro, MMC, and MMR boards have a `BMM150 `_ geomagnetic sensor for sensing magnetic fields. 8 | 9 | Functions communicating with the magnetometer are defined in the 10 | `magnetometer_bmm150.h `_. 11 | 12 | Power Modes 13 | ----------- 14 | The `BMM150 `_ magnetometer has 4 recommended power modes: 15 | 16 | ================ ==== =============== =============================== 17 | Setting ODR Average Current Noise 18 | ================ ==== =============== =============================== 19 | LOW_POWER 10Hz 170µA 1.0µT (xy axis), 1.4µT (z axis) 20 | REGULAR 10Hz 0.5mA 0.6µT 21 | ENHANCED_REGULAR 10Hz 0.8mA 0.5µT 22 | HIGH_ACCURACY 20Hz 4.9mA 0.3µT 23 | ================ ==== =============== =============================== 24 | 25 | Constants identifying these power modes are defined by the 26 | `MblMwMagBmm150Preset `_ enum. 27 | For most use cases, ``MWL_MW_MAG_BMM_150_PP_LOW_POWER`` is the recommended power mode. :: 28 | 29 | // Use low power mode 30 | MetaWear.mbl_mw_mag_bmm150_set_power_preset(device.board, MWL_MW_MAG_BMM_150_PP_LOW_POWER); 31 | 32 | B Field Sampling 33 | ---------------- 34 | B field sampling measures the magnetic field strength for the XYZ directions. To enable **B** field sampling, call 35 | `mbl_mw_mag_bmm150_enable_b_field_sampling `_ 36 | before starting the magnetometer. 37 | 38 | Field strength is represented by the 39 | `MblMwCartesianFloat `_ struct and is in units of micro Teslas (µT). The 40 | ``x``, ``y``, and ``z`` fields contain the **B** field strength in that direction. :: 41 | 42 | console.log('Get mag signal.') 43 | let mag = MetaWear.mbl_mw_mag_bmm150_get_b_field_data_signal(device.board); 44 | 45 | console.log('Set up stream.') 46 | MetaWear.mbl_mw_datasignal_subscribe(mag, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 47 | var data = pointer.deref(); 48 | var value = data.parseValue(); 49 | console.log('epoch: ' + data.epoch + ' mag: ' + value.x + ' ' + value.y + ' ' + value.z) 50 | })) 51 | 52 | console.log('Start accelerometer.') 53 | MetaWear.mbl_mw_mag_bmm150_enable_b_field_sampling(device.board); 54 | MetaWear.mbl_mw_mag_bmm150_start(device.board); 55 | -------------------------------------------------------------------------------- /docs/source/metadataprocessor.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Data Processor 4 | ============== 5 | Data processors are functions in the firmware that filter or transform sensor data and are represented by the 6 | `MblMwDataProcessor `_ struct. 7 | 8 | In the C++ API, data processors can be thought of as a data signal whose data is produced by the on-board data processor. As such, a 9 | `MblMwDataProcessor `_ can be safely 10 | typecasted to a `MblMwDataSignal `_. 11 | 12 | .. list-table:: 13 | :header-rows: 1 14 | 15 | * - Processor Id 16 | - Name 17 | - Functionality 18 | * - 0x01 19 | - Passthrough 20 | - Allow a specific # of data (samples) through 21 | * - 0x02 22 | - Accumulator 23 | - Running sum of data 24 | * - 0x02 25 | - Counter 26 | - Keeps a tally of how many times it is called 27 | * - 0x03 28 | - Averager / Low Pass Filter 29 | - Computes a running average of the data 30 | * - 0x03 31 | - High Pass Filter 32 | - Compute the difference of the current value from a running average of the previous N samples 33 | * - 0x06 34 | - Comparator 35 | - Removes data that do not satisfy the comparison operation 36 | * - 0x07 37 | - RMS 38 | - Computes the root mean square over multi component data 39 | * - 0x07 40 | - RSS 41 | - Computes the root sum square, or vector magnitude, over multi component data 42 | * - 0x08 43 | - Time 44 | - Only allows data to pass at fixed intervals 45 | * - 0x09 46 | - Math 47 | - Performs arithmetic or logical operations on the data 48 | * - 0x0a 49 | - Sample 50 | - Only allowing data through once it has collected a set number of samples 51 | * - 0x0b 52 | - Pulse 53 | - Detects and quantifies a pulse over a set of data 54 | * - 0x0c 55 | - Delta 56 | - Computes the dif between 2 successive data values and only allows data through that creates a diff > threshold 57 | * - 0x0d 58 | - Threshold 59 | - Only allows data through that crosses a boundary 60 | * - 0x0f 61 | - Buffer 62 | - Captures input data which can be read at a later time 63 | * - 0x10 64 | - Packer 65 | - Combines multiple data samples into 1 BLE packet 66 | * - 0x11 67 | - Accounter 68 | - Adds additional information to the BTLE packet 69 | * - 0x1b 70 | - Fuser 71 | - Combine data from multiple sources into 1 72 | 73 | 74 | This section will focus on the 75 | `MblMwDataProcessor `_ struct. Details on 76 | supported processors and how to create them are covered in the :doc:`dataprocessor` section. 77 | 78 | ID 79 | -- 80 | Data processors are identified by a unique numerical ID; as identified in the table above. 81 | 82 | You can retrieve this id by calling 83 | `mbl_mw_dataprocessor_get_id `_. 84 | 85 | The data processor ID is used to lookup a previously created MblMwDataProcessor object with the 86 | `mbl_mw_dataprocessor_lookup_id `_ function. 87 | 88 | The object is needed to remove/delete processors (see section below). 89 | 90 | The object is useful as it can be used as the input to another processor. As such, it is possible to combine processors together for all sorts of functionality. 91 | 92 | A high pass filter on the accelerometer data can remove noise which can then be set as the input to an RMM to combine the x,y,z axis data into a signal signal. This can further be set as the input to a comparator or threshold detector to determine if the accelerometer experienced a shock higher than 4Gs. 93 | 94 | :: 95 | 96 | var processor = MetaWear.libmetawear.mbl_mw_dataprocessor_lookup_id(device.board, 1); 97 | MetaWear.mbl_mw_dataprocessor_remove(processor); 98 | 99 | State 100 | ----- 101 | Some processors have an internal state that can be read and modified; the internal state is treated as a readable 102 | `MblMwDataSignal `_. 103 | 104 | In this example, a buffer process is used. The state of the buffer processor is the data in the buffer: 105 | 106 | :: 107 | 108 | var processor = MetaWear.mbl_mw_dataprocessor_lookup_id(device.board, id); 109 | var state_signal = MetaWear.mbl_mw_dataprocessor_get_state_data_signal(processor); 110 | MetaWear.mbl_mw_datasignal_read(state_signal); 111 | 112 | The state of the counter processor is the count itself. 113 | 114 | :: 115 | 116 | // Previously setup the counter in function 117 | var processor = MetaWear.mbl_mw_dataprocessor_lookup_id(device.board, 2); 118 | var processor_state = MetaWear.mbl_mw_dataprocessor_get_state_data_signal(processor); 119 | MetaWear.mbl_mw_datasignal_subscribe(processor_state, sensor_data_handler); 120 | 121 | Removal 122 | ------- 123 | Removing a processor is handled by calling 124 | `mbl_mw_dataprocessor_remove `_. 125 | 126 | When a processor is removed, all processors that consume its output will also be removed. :: 127 | 128 | var processor= MetaWear.mbl_mw_dataprocessor_lookup_id(device.board, 1); 129 | MetaWear.mbl_mw_dataprocessor_remove(processor); 130 | -------------------------------------------------------------------------------- /docs/source/metawearboard.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | MetaWear Board 4 | ============== 5 | 6 | The `MetaWear `_ interface is a software representation of the MetaWear boards and is the central class of the MetaWear API. It contains methods for connecting, disconnecting, saving and restoring state. 7 | 8 | You always get a `MetaWear `_ object through the `MetaWearScanner `_ , afterwards, keep a reference to it as long as the app is running. From here on assume that inside code blocks ``device`` is a `MetaWear `_ object reference 9 | 10 | Bluetooth LE Connection 11 | ----------------------- 12 | Before using any API features, you must first connect to the board with `connectAsync `_. The returned task will finish when a connection has been established and the ``MetaWear`` state has been initialized. :: 13 | 14 | device.connectAndSetUp(function (error) { 15 | console.log('were connected!'); 16 | }); 17 | 18 | Conversely, call `cancelConnection `_ to close the connection. If there is a pending ``connectAndSetup`` task when ``cancelConnection`` is called, the connect task will be cancelled. :: 19 | 20 | device.disconnect(function (error) { 21 | console.log('were disconnected!'); 22 | }); 23 | 24 | Watching for Disconnects 25 | ^^^^^^^^^^^^^^^^^^^^^^^^ 26 | It is often useful to handle BLE disconnection events. The task returned from ``connectAndSetup`` will completes once this device disconnects, either expectedly or unexpectedly. :: 27 | 28 | device.on('disconnect', function () { 29 | console.log('we got disconnected!'); 30 | }); 31 | 32 | Saving MetaWears 33 | ----------------- 34 | If you expect to re-connect to a specific MetaWear device, you can "remember" it for easy retrieval later on through the MetaWearScanner. :: 35 | 36 | var devices = []; 37 | devices.push(device); 38 | 39 | Identifier 40 | ---------- 41 | Apple generates a unique identifier for each BLE device. Note, two different Apple devices will generate two different identifiers for the same MetaWear. It might be useful to use ``device.mac`` instead. :: 42 | 43 | console.log('discovered ' + device.address); 44 | 45 | Reset 46 | ---------- 47 | To fully reset your MetaWear board: :: 48 | 49 | MetaWear.mbl_mw_debug_reset_after_gc(device.board); 50 | 51 | -------------------------------------------------------------------------------- /docs/source/metawearscanner.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | MetaWear Scanner 4 | ================ 5 | Scanning and discovery of MetaWear devices is done with Noble `Device `_ which is a wrapper around `Noble `_. 6 | 7 | Scanning for MetaWears 8 | ---------------------- 9 | It's simple to start scanning for advertising MetaWear devices using the ``discoverByAddress`` to discover a MetaWear with a specific MAC: 10 | 11 | :: 12 | 13 | MetaWear.discoverByAddress('c8:4b:aa:97:50:05', function(device) { 14 | console.log(device); 15 | }); 16 | 17 | Scanning for Nearby MetaWears 18 | ----------------------------- 19 | Start scanning for advertising MetaWear devices using the ``discover`` function to discover nearby MetaWears: 20 | :: 21 | 22 | MetaWear.discover(function (device) { 23 | console.log(device); 24 | }); 25 | -------------------------------------------------------------------------------- /docs/source/peripherals.rst: -------------------------------------------------------------------------------- 1 | Peripherals 2 | =========== 3 | MetaWear boards come with several auxiliary features that developers can use to provide feedback to their users such as starting a vibration motion 4 | when 10,000 steps are taken or turning on the LED if the temperature is outside of a desireable range. 5 | 6 | Developers can also enhance the functionality of the boards by using the GPIO pins to add additional sensors or devices. 7 | 8 | .. toctree:: 9 | :hidden: 10 | :maxdepth: 1 11 | 12 | gpio 13 | haptic 14 | i2c 15 | ibeacon 16 | led 17 | spi 18 | -------------------------------------------------------------------------------- /docs/source/sensor_fusion.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Sensor Fusion 4 | ============= 5 | Sensor fusion software is a complete 9-axis fusion solution, which combines the measurements from 3-axis gyroscope, 3-axis geomagnetic sensor and a 3-axis accelerometer to provide a robust absolute orientation vector. The algorithm fuses the sensor raw data from three sensors in an intelligent way to improve each sensor’s output. 6 | 7 | This includes algorithms for offset calibration of each sensor, monitoring of the calibration status and Kalman filter fusion to provide distortion-free and refined orientation vectors. 8 | 9 | There are 5 outputs of sensor fusion: 10 | 11 | - Quaternion 12 | - Linear Acceleration 13 | - Rotation 14 | - Gravity 15 | - Robust Heading 16 | 17 | The `sensor_fusion.h `_ header file interfaces with the sensor fusion algorithm 18 | running on MetaMotion boards. When using the sensor fusion algorithm, it is important that you do not simultaneously use the 19 | Accelerometer, Gyro, and Magnetometer modules; the algorithm configures those sensors internally based on the selected fusion mode. 20 | 21 | The Sensor fusion algorithm we use is from BOSCH and is hardcoded at 100Hz. 22 | 23 | To activate the sensor fusion algorithm, first set the fusion mode and data ranges, then subscribe to and enable the desired output data, and finally, 24 | call `mbl_mw_sensor_fusion_start `_. 25 | 26 | Mode 27 | ---- 28 | The sensor fusion algorithm has 4 29 | `fusion modes `_, listed in the below table: 30 | 31 | ======== ========================================================================== 32 | Mode Description 33 | ======== ========================================================================== 34 | NDoF Calculates absolute orientation from accelerometer, gyro, and magnetometer 35 | IMUPlus Calculates relative orientation in space from accelerometer and gyro data 36 | Compass Determines geographic direction from the Earth's magnetic field 37 | M4G Similar to IMUPlus except rotation is detected with the magnetometer 38 | ======== ========================================================================== 39 | 40 | The sensor fusion algorithm provides raw acceleration, rotation, and magnetic field values along with quaternion values and Euler angles. 41 | 42 | Furthermore, the source of acceleration can be separated into gravity and linear acceleration and both values are also provided. Keep in mind that each sensor fusion mode has different sets of available data and produces it at different rates. 43 | 44 | ======== ====== ====== ===== 45 | Mode Acc Gyro Mag 46 | ======== ====== ====== ===== 47 | NDoF 100Hz 100Hz 25Hz 48 | IMUPlus 100Hz 100Hz N/A 49 | Compass 25Hz N/A 25Hz 50 | M4G 50Hz N/A 50Hz 51 | ======== ====== ====== ===== 52 | 53 | The mode is set with 54 | `mbl_mw_sensor_fusion_set_mode `_ and written 55 | to the board by calling 56 | `mbl_mw_sensor_fusion_write_config `_. Before 57 | writing the configuration, you can also set the acceleration and rotation ranges of the accelerometer and gyroscope respectively. 58 | 59 | :: 60 | 61 | MetaWear.mbl_mw_sensor_fusion_set_acc_range(device.board, MBL_MW_SENSOR_FUSION_ACC_RANGE_16G); 62 | MetaWear.mbl_mw_sensor_fusion_set_gyro_range(device.board, MBL_MW_SENSOR_FUSION_GYRO_RANGE_2000DPS); 63 | MetaWear.mbl_mw_sensor_fusion_set_mode(device.board, MBL_MW_SENSOR_FUSION_MODE_NDOF); 64 | MetaWear.mbl_mw_sensor_fusion_write_config(device.board); 65 | 66 | NDOF 67 | """"" 68 | This is a fusion mode with 9 degrees of freedom where the fused absolute orientation data is calculated from accelerometer, gyroscope and the magnetometer. 69 | 70 | The advantages of combining all three sensors are a fast calculation, resulting in high output data rate, and high robustness from magnetic field distortions. 71 | 72 | IMUPlus 73 | """"""""" 74 | In the IMU mode the relative orientation of the device in space is calculated from the accelerometer and gyroscope data. The calculation is fast (i.e. high output data rate). 75 | 76 | Compass 77 | """""""" 78 | The COMPASS mode is intended to measure the magnetic earth field and calculate the geographic direction. 79 | 80 | The measurement accuracy depends on the stability of the surrounding magnetic field (magnets can interfere with the magnetometer and provide false readings since the earth magnetic field is usually much smaller than the magnetic fields that occur around and inside electronic devices). 81 | 82 | M4G 83 | """"" 84 | The M4G mode is similar to the IMU mode, but instead of using the gyroscope signal to detect rotation, the changing orientation of the magnetometer in the magnetic field is used. 85 | 86 | Since the magnetometer has much lower power consumption than the gyroscope, this mode is less power consuming in comparison to the IMU mode. There are no drift effects in this mode which are inherent to the gyroscope. 87 | 88 | However, as for compass mode, the measurement accuracy depends on the stability of the surrounding magnetic field. For this mode no magnetometer calibration is required and also not available. 89 | 90 | Data 91 | ---- 92 | The sensor fusion algorithm provides raw acceleration, rotation, and magnetic field values along with quaternion values and Euler angles. Furthermore, 93 | the source of acceleration can be separated into gravity and linear acceleration and both values are also provided. Keep in mind that each sensor 94 | fusion mode has different sets of available data and produces it at different rates. 95 | 96 | ======== ===== ===== ==== 97 | Mode Acc Gyro Mag 98 | ======== ===== ===== ==== 99 | NDoF 100Hz 100Hz 25Hz 100 | IMUPlus 100Hz 100Hz N/A 101 | Compass 25Hz N/A 25Hz 102 | M4G 50Hz N/A 50Hz 103 | ======== ===== ===== ==== 104 | 105 | Also note that the units and type casting of the sensor fusion data is different for each type of data.. 106 | 107 | ============== ======= ============================ 108 | Data Units Casted Data 109 | ============== ======= ============================ 110 | Acceleration g MblMwCorrectedCartesianFloat 111 | Rotation deg/s MblMwCorrectedCartesianFloat 112 | Magnetic Field uT MblMwCorrectedCartesianFloat 113 | Quaternion None MblMwQuaternion 114 | Euler Angles degrees MblMwEulerAngles 115 | Linear Acc g MblMwCartesianFloat 116 | Gravity g MblMwCartesianFloat 117 | ============== ======= ============================ 118 | 119 | :: 120 | 121 | // Setup gyro, acc, and sensor fusion settings 122 | MetaWear.mbl_mw_sensor_fusion_set_mode(device.board, 1); //SensorFusionMode.NDOF); 123 | MetaWear.mbl_mw_sensor_fusion_set_acc_range(device.board, 2 ); //SensorFusionAccRange._8G) 124 | MetaWear.mbl_mw_sensor_fusion_set_gyro_range(device.board, 0); //SensorFusionGyroRange._2000DPS) 125 | MetaWear.mbl_mw_sensor_fusion_write_config(device.board); 126 | 127 | // Get quat signal 128 | let signal = MetaWear.mbl_mw_sensor_fusion_get_data_signal(device.board, 3); //SensorFusionData.QUATERNION); 129 | 130 | // Set up quat stream 131 | MetaWear.mbl_mw_datasignal_subscribe(signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 132 | var data = pointer.deref(); 133 | var value = data.parseValue(); 134 | console.log('epoch: ' + data.epoch + ' quat: ' + value.x + ' ' + value.y + ' ' + value.z); 135 | })); 136 | 137 | // Start sensor fusion 138 | MetaWear.mbl_mw_sensor_fusion_enable_data(device.board, 3); //SensorFusionData.QUATERNION); 139 | MetaWear.mbl_mw_sensor_fusion_start(device.board); 140 | -------------------------------------------------------------------------------- /docs/source/sensors.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Sensors 4 | ======= 5 | MetaWear comes with plenty of sensors ready to be used with only a few API calls. 6 | 7 | All boards have a different combination of sensors or even different sensor models so it is important to check the result of the 8 | `mbl_mw_metawearboard_lookup_module `_ method 9 | if your app is to be used with different board models e.g. the `MetaBase `_ app. 10 | 11 | :: 12 | 13 | if MetaWear.mbl_mw_metawearboard_lookup_module(device.board, MBL_MW_MODULE_LED) != MBL_MW_MODULE_TYPE_NA { 14 | // Board has LED 15 | } 16 | 17 | In this section we will look at everything from accelerometers to magnetometers. 18 | 19 | .. toctree:: 20 | :hidden: 21 | :maxdepth: 1 22 | 23 | accelerometer 24 | ambientlightsensor 25 | barometer 26 | gyro 27 | humidity 28 | magnetometer 29 | temperature 30 | -------------------------------------------------------------------------------- /docs/source/settings.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Settings 4 | ======== 5 | The Settings module configures Bluetooth LE parameters and reports diagnostic information about the board. 6 | 7 | Functions communicating with this module are defined in the `settings.h `_ header file. 8 | 9 | Battery State 10 | ------------- 11 | The battery data provided by the Settings module reports both charge percentange and voltage, encapsulated by the 12 | `MblMwBatteryState `_ struct. Unlike the battery gatt servive, this 13 | battery data can be utilized with MetaWear features such as the logger. :: 14 | 15 | var battSignal = MetaWear.mbl_mw_settings_get_battery_state_data_signal(device.board, ); 16 | 17 | MetaWear.mbl_mw_datasignal_read(battSignal); 18 | 19 | Handling Disconnects 20 | -------------------- 21 | The disconnect event is a type of `MblMwEvent `_ 22 | that is fired when the Bluetooth connection is terminated. :: 23 | 24 | var disEvent = MetaWear.mbl_mw_settings_get_disconnect_event(device.board); 25 | 26 | Transmit Power 27 | -------------------- 28 | The default transmission power is 0db on the MetaWear. This is the Bluetooth radio signal strength when transmitting and can be changed with `mbl_mw_settings_set_tx_power `_. 29 | 30 | Valid values are: 4, 0, -4, -8, -12, -16, -20, -30: :: 31 | 32 | MetaWear.mbl_mw_settings_set_tx_power(device.board, -10); 33 | 34 | Advertising Parameters 35 | ---------------------- 36 | Advertising parameters control how the Bluetooth radio sends its advertising data. You can modify the device name, timeout, tx power, and scan 37 | response. If you have set an timeout, you can manually begin another advertisement cycle by calling 38 | `mbl_mw_settings_start_advertising `_. :: 39 | 40 | MetaWear.mbl_mw_settings_set_ad_interval(device.board, 417, 180); 41 | MetaWear.mbl_mw_settings_start_advertising(device.board); 42 | 43 | Device Name 44 | ----------------- 45 | The advertised name of the device (default = MetaWear) can be changed with `mbl_mw_settings_set_device_name `_. :: 46 | 47 | let name = "METACOOL" 48 | MetaWear.mbl_mw_settings_set_device_name(device.board, name, name.length); 49 | 50 | Connection Parameters 51 | --------------------- 52 | Connection parameters control how BTLE devices communicate with each other. Modifying the connection parameters are all handled at the same time by 53 | calling 54 | `mbl_mw_settings_set_connection_parameters `_. 55 | 56 | - Connection interval = how often devices talk - min is 7.5ms, it increases in steps of 1.25ms - recommend setting min and max to same @ 7.5ms for performance. 57 | - Slave latency = metawear can choose not to answer when central asks for an update (i.e metawear can sleep longer - doesn't affect transfer speeds). 58 | - Connection supervision timeout = determines timeout from last data exchange (tells central how long to wait to attempt to reconnect to a lost conn - if your metawear goes in and out of range often, it is better to have a short timeout) 59 | 60 | Changing connection parameters is not guaranteed to work; Apple only accepts 15ms for example and will often default to 30ms. 61 | 62 | A more detailed explanation of about BTLE connection parameters can be found on this 63 | `post `_ from the Nordic Developer Zone forums. :: 64 | 65 | MetaWear.mbl_mw_settings_set_connection_parameters(device.board, 10.0, 1024.0, 0, 6000); 66 | 67 | MMS 3V Regulator 68 | --------------------- 69 | The MMS (MetaMotion) board has a 3V regulator that can be turned on and off for IOs. 70 | 71 | It is automatically turned on to power the coin vibration motor (if there is one attached), the ambient light sensor, and the LED. 72 | 73 | However, if you have an external peripheral on the IOs that needs 3V power (such as a buzzer or UV sensor), you can use this function to turn on the power: :: 74 | 75 | MetaWear.mbl_mw_settings_enable_3V_regulator(device.board, 1); 76 | 77 | And to turn it off: :: 78 | 79 | MetaWear.mbl_mw_settings_enable_3V_regulator(device.board, 0); -------------------------------------------------------------------------------- /docs/source/spi.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | SPI 4 | === 5 | SPI is also known as Serial Peripheral Interface, it is a synchronous serial data protocol that acts as an interface bus which operates at full-duplex where data can be sent and received simultaneously. 6 | 7 | SPI is one of the most popular communication peripheral used by microcontrollers to send data to one or more peripheral devices like SD cards and sensors quickly over short distances. 8 | 9 | The SPI module allows users to utilize the SPI bus. If you want to add a sensor to the MetaWear board that communicates with SPI, this is possible using the SPI module. 10 | 11 | Functions are defined in the `spi.h `_ header file. 12 | 13 | Data Signal 14 | ----------- 15 | I2C data signals are retrieved by calling 16 | `mbl_mw_spi_get_data_signal `_. You will need to pass 17 | two parameters: 18 | 19 | * Length variable that sets how many bytes the signal is expected to receive 20 | * An unique ID identifying the signal 21 | 22 | If the id value has already been used, the length parameter will be ignored and the previously created signal will be returned. :: 23 | 24 | let spi_signal = MetaWear.mbl_mw_spi_get_data_signal(device.board, 5, 0xe); 25 | 26 | Read 27 | ---- 28 | To read SPI data, use the 29 | `mbl_mw_datasignal_read_with_parameters `_ 30 | function with the parameters set by the `MblMwSpiParameters `_ struct. 31 | When reading SPI data, the byte array pointed to by the ``data`` field will be written on the bus before reading. 32 | 33 | SPI data is always returned as a byte array. :: 34 | 35 | var parameters = MblMwSpiParameters(MBL_MW_SPI_MODE_3, MBL_MW_SPI_FREQUENCY_8_MHZ, {0xda}, 1, 0xa, 0, 0xb, 7, 0, 1); 36 | 37 | MetaWear.mbl_mw_datasignal_read_with_parameters(spi_signal, parameters); 38 | 39 | MetaWear.mbl_mw_datasignal_subscribe(temp_signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 40 | var data = pointer.deref(); 41 | var value = data.parseValue(); 42 | console.log('bytes: ' + value); 43 | })); 44 | 45 | Write 46 | ----- 47 | Writing data through the SPI bus is handled with the 48 | `mbl_mw_spi_write `_ function. The same 49 | `MblMwSpiParameters `_ struct is used to wrap the required 50 | parameters into one variable. 51 | -------------------------------------------------------------------------------- /docs/source/temperature.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Temperature 4 | =========== 5 | A temperature sensor measures the ambient temperature in C or F degrees. 6 | 7 | All boards come with various temperature sensors that measure ambient temperature. Some of the temperature sensors are on the main CPU chip, others come in analog form as a thermistor and some temperature sensors are included in the barometer chip. 8 | 9 | Functions communicating with the on-board temperature sensors are 10 | defined in the `multichanneltemperature.h `_ header file. 11 | 12 | Source Types 13 | ------------ 14 | There are four types temperature sources providing data: 15 | 16 | =================== =================================================================== 17 | Source Description 18 | =================== =================================================================== 19 | nRF SOC Temperature sensor on the nRF SOC 20 | External Thermistor Separate thermistor that can be connected to the gpio pins 21 | Bosch Barometer Temperature sensor from either the BMP280 or BME280 barometers 22 | On-board Thermistor Thermistor on the MetaWear board 23 | =================== =================================================================== 24 | 25 | The 26 | `MblMwMetaWearRChannel `_ and 27 | `MblMwMetaWearRProChannel `_ enums 28 | map the channel ids to temperature sources providing a quick way to interact with the specific temperature source if you know specifically what board 29 | you are using. The RProChannel enum can be used with all boards except the MetaWear R. 30 | 31 | Users can also programatically check which source corresponds to each channel using the 32 | `mbl_mw_multi_chnl_temp_get_source `_ 33 | function. :: 34 | 35 | let channedCount = MetaWear.mbl_mw_multi_chnl_temp_get_num_channels(device.board); 36 | for (i = 0; i < channedCount; i++) { 37 | console.log("Channel: " + i); 38 | let source = MetaWear.mbl_mw_multi_chnl_temp_get_source(device.board, i); 39 | switch source { 40 | case MBL_MW_TEMPERATURE_SOURCE_NRF_DIE: 41 | //"On-Die" 42 | break; 43 | case MBL_MW_TEMPERATURE_SOURCE_EXT_THERM: 44 | //"External" 45 | break; 46 | case MBL_MW_TEMPERATURE_SOURCE_BMP280: 47 | //"BMP280" 48 | break; 49 | case MBL_MW_TEMPERATURE_SOURCE_PRESET_THERM: 50 | //"On-Board" 51 | break; 52 | default: 53 | //"Custom" 54 | } 55 | } 56 | 57 | External Thermistor 58 | ################### 59 | External thermistors require additional configuration before they can produce reliable data. Call 60 | `mbl_mw_multi_chnl_temp_configure_ext_thermistor `_ 61 | to tell the MetaWear what GPIO pins the thermistor is connected to and whether it is active high or low. 62 | 63 | We have a blog post on our project's page explaining how to connect an external thermistor to the gpio pins, link 64 | `here `_. 65 | 66 | Bosch Barometer 67 | ############### 68 | Both the BMP280 and BME380 chips also measure ambient temperature. To read from these temperature sources, you will need to first start the Bosch 69 | barometer. 70 | 71 | Boards that do not have a Bosch barometer, e.g. RG, C, and Detector boards, will always report 0C from this temperature source. 72 | 73 | Reading Temperature 74 | ------------------- 75 | Temperature reads are manually triggered by calling 76 | `mbl_mw_datasignal_read `_. The data is 77 | represented as a float and is in units of Celsius. :: 78 | 79 | // Get source 80 | let source = MetaWear.mbl_mw_multi_chnl_temp_get_source(device.board, MBL_MW_TEMPERATURE_SOURCE_PRESET_THERM); 81 | 82 | // Get temp signal 83 | var temp_signal = MetaWear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(device.board, 1); 84 | 85 | // Subscribe to it 86 | MetaWear.mbl_mw_datasignal_subscribe(temp_signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 87 | var data = pointer.deref(); 88 | var value = data.parseValue(); 89 | console.log('epoch: ' + data.epoch + ' temp: ' + value); 90 | })); 91 | 92 | // Read it 93 | MetaWear.mbl_mw_datasignal_read(temp_signal); 94 | -------------------------------------------------------------------------------- /docs/source/timer.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: javascript 2 | 3 | Timer 4 | ===== 5 | A MetaWear timer can be thought of as an event that is fired at fixed intervals. 6 | 7 | These timers are represented by the 8 | `MblMwTimer `_ struct and can be safely typcased to a 9 | `MblMwEvent `_ struct. 10 | 11 | Timers can be used to schedule periodic tasks or setup a delayed task execution. For example, you can use the timer to record temperature samples are extremely low frequencies such as once per day or once per hour. 12 | 13 | ID 14 | -- 15 | MblMwTimer objects are identified by a numerical id; you can retrieve the id by calling 16 | `mbl_mw_timer_get_id `_. 17 | 18 | The id is used to retrieve existing timers from the API with the 19 | `mbl_mw_timer_lookup_id `_ function. 20 | 21 | As with previous sections, you may want to keep the id handy so that you can retrieve a timer at a later time. 22 | 23 | Task Scheduling 24 | --------------- 25 | Before you can schedule tasks, you first need to create a timer, by calling either 26 | `mbl_mw_timer_create `_ or 27 | `mbl_mw_timer_create_indefinite `_. These functions are asynchronous and 28 | will pass a pointer to the caller when the timer is created. 29 | 30 | When you have a valid `MblMwTimer `_, you can use the command recording system outlined in 31 | :doc:`event` section to program the board to respond to the periodic events. 32 | 33 | Upon recording timer task commands, call 34 | `mbl_mw_timer_start `_ to start the timer. 35 | 36 | When you are done using a timer, you can remove it with 37 | `mbl_mw_timer_remove `_. 38 | 39 | A good example is the one mentioned above. Because the temperature sensor is a slow sensor, it must be read using a timer to get periodic readings (unlike setting the ODR for the accelerometer): 40 | 41 | :: 42 | 43 | // Get temp signal 44 | var temp = MetaWear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(device.board,1); 45 | 46 | // Subscribe to it 47 | MetaWear.mbl_mw_datasignal_subscribe(temp, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 48 | console.log('got data'); 49 | var data = pointer.deref(); 50 | var value = data.parseValue(); 51 | console.log('epoch: ' + data.epoch + ' switch: ' + value); 52 | })); 53 | 54 | // Create a timer to read every 1 second 55 | var promise = new Promise((resolve, reject) => { 56 | var timer = MetaWear.mbl_mw_timer_create_indefinite(device.board, 1000, 0, ref.NULL, MetaWear.FnVoid_VoidP_TimerP.toPointer(function onSignall(context, timer) { 57 | console.log('Timer created'); 58 | resolve(timer); 59 | })); 60 | }); 61 | let timer = await promise; 62 | 63 | // Create event based on timer and record as a command - Start record command 64 | MetaWear.mbl_mw_event_record_commands(timer); 65 | // Command to read temp when timer fires 66 | MetaWear.mbl_mw_datasignal_read(temp); 67 | // End record command 68 | promise = new Promise((resolve, reject) => { 69 | var rec = MetaWear.mbl_mw_event_end_record(timer, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 70 | console.log('Command created'); 71 | resolve(lstatus); 72 | })); 73 | }); 74 | let rec = await promise; 75 | 76 | // Start timer 77 | MetaWear.mbl_mw_timer_start(timer); -------------------------------------------------------------------------------- /examples/acc_thresh_detect.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | 8 | var ref = require('ref-napi'); 9 | // Store the log event for later download. If your program needs to terminate 10 | // before performing the log download, you will need to use mbl_mw_metawearboard_serialize 11 | // to store the device state and that pass that state as the second argument to 12 | // connectAndSetUp when you are ready to download. Use mbl_mw_logger_lookup_id 13 | // to retrieve this accelLogger object 14 | var thsLogger = null; 15 | 16 | MetaWear.discoverByAddress('ea:78:c3:d3:f0:8a', function(device) { 17 | console.log('Discovered'); 18 | device.connectAndSetUp(async function (error) { 19 | 20 | // setup accelerometer (odr 50Hz and 2Gs) 21 | console.log('Set up acc'); 22 | // For MMRL, MMR, MMC 23 | //MetaWear.mbl_mw_acc_bmi160_set_odr(device.board, 6); 24 | // For MMS 25 | MetaWear.mbl_mw_acc_bmi270_set_odr(device.board, cbindings.AccBmi270Odr._50Hz); 26 | MetaWear.mbl_mw_acc_set_range(device.board, 1); 27 | MetaWear.mbl_mw_acc_write_acceleration_config(device.board); 28 | 29 | // start to setup rms->avg->thresh->log chain 30 | console.log('Get acc signal'); 31 | var acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 32 | 33 | // create RMS - root mean square of acc X,Y,Z 34 | console.log('Create RMS'); 35 | let promise = new Promise((resolve, reject) => { 36 | var rms = MetaWear.mbl_mw_dataprocessor_rms_create(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 37 | console.log('RMS Created'); 38 | resolve(dataPtr); 39 | })); 40 | }); 41 | let rms = await promise; 42 | console.log(rms); 43 | 44 | // setup averager - averages over 8 RMS samples @ 50Hz 45 | console.log('Create AVG'); 46 | promise = new Promise((resolve, reject) => { 47 | var avg = MetaWear.mbl_mw_dataprocessor_average_create(rms, 8, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 48 | console.log('AVG Created'); 49 | resolve(dataPtr); 50 | })); 51 | }); 52 | let avg = await promise; 53 | console.log(avg); 54 | 55 | // setup event on avg - reset averager 56 | console.log('Record COMMAND'); 57 | MetaWear.mbl_mw_event_record_commands(avg); 58 | console.log('First command: reset averager after it fires -> 8 data pts'); 59 | MetaWear.mbl_mw_dataprocessor_average_reset(avg); 60 | console.log('End Record COMMAND'); 61 | promise = new Promise((resolve, reject) => { 62 | var rec = MetaWear.mbl_mw_event_end_record(avg, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 63 | console.log('COMMAND Created'); 64 | resolve(lstatus); 65 | })); 66 | }); 67 | let rec = await promise; 68 | console.log(rec); 69 | 70 | // setup threshold detector - detect anything above 1 71 | console.log('Create THRESH'); 72 | promise = new Promise((resolve, reject) => { 73 | var ths = MetaWear.mbl_mw_dataprocessor_threshold_create(avg, 1, 1.0, 0.0, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 74 | console.log('THRESH Created:' + dataPtr); 75 | resolve(dataPtr); 76 | })); 77 | }); 78 | let ths = await promise; 79 | console.log(ths); 80 | 81 | // setup logger - log the final signal of the averaged data 82 | console.log('Create LOGGER'); 83 | promise = new Promise((resolve, reject) => { 84 | var thsl = MetaWear.mbl_mw_datasignal_log(ths, ref.NULL, MetaWear.FnVoid_VoidP_DataLoggerP.toPointer(function onSignal(context, logger) { 85 | console.log('LOGGER Created: ' + logger); 86 | resolve(logger); 87 | })); 88 | }); 89 | thsLogger = await promise; 90 | console.log(thsLogger); 91 | 92 | // Start logging 93 | startLogging(device, function (error) { 94 | if (error) { 95 | console.log(error); 96 | process.exit(1); 97 | } 98 | console.log('wait 10s'); 99 | // Stop logging after 10 seconds 100 | setTimeout(function () { 101 | console.log('done waiting'); 102 | downloadLog(device, function (error) { 103 | device.once('disconnect', function (reason) { 104 | console.log('disconnect'); 105 | process.exit(0); 106 | }); 107 | MetaWear.mbl_mw_debug_reset(device.board); 108 | }); 109 | }, 10000); 110 | }); 111 | }); 112 | }); 113 | 114 | function startLogging(device, callback) { 115 | console.log('Enable Acc and Start logging'); 116 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 117 | MetaWear.mbl_mw_acc_start(device.board); 118 | MetaWear.mbl_mw_logging_start(device.board, 0); 119 | callback(null); 120 | } 121 | 122 | function downloadLog(device, callback) { 123 | console.log('Disable Acc and Stop logging'); 124 | // Shutdown accel and logger 125 | MetaWear.mbl_mw_acc_stop(device.board); 126 | MetaWear.mbl_mw_acc_disable_acceleration_sampling(device.board); 127 | MetaWear.mbl_mw_logging_stop(device.board); 128 | console.log('Setup Download'); 129 | // Subscribe to the logger of the signal 130 | MetaWear.mbl_mw_logger_subscribe(thsLogger, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 131 | var data = dataPtr.deref(); 132 | var pt = data.parseValue(); 133 | console.log('received_entry: ' + data.epoch + ' ' + pt); 134 | })); 135 | // Setup the handlers for events during the download 136 | var downloadHandler = new MetaWear.LogDownloadHandler(); 137 | // Handle download progress updates 138 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 139 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 140 | if (entriesLeft === 0) { 141 | // Remove all log entries if told to stop logging 142 | MetaWear.mbl_mw_metawearboard_tear_down(device.board); 143 | callback(null); 144 | } 145 | }); 146 | // Handle unknown entries 147 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 148 | console.log('received_unknown_entry'); 149 | }); 150 | // Handle bad entries 151 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 152 | var data = dataPtr.deref(); 153 | var dataPoint = data.parseValue(); 154 | console.log('received_unhandled_entry: ' + dataPoint); 155 | }); 156 | // Actually start the log download, this will cause all the handlers we setup to be invoked 157 | console.log('Start Download'); 158 | MetaWear.mbl_mw_logging_download(device.board, 20, downloadHandler.ref()); 159 | } 160 | 161 | -------------------------------------------------------------------------------- /examples/anonymous_datasignals.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi') 8 | 9 | // MetaWear.discoverByAddress('f6:3d:13:48:ce:ab', function (device) { 10 | MetaWear.discover(function (device) { 11 | console.log('connecting...' + device.address); 12 | device.connectAndSetUp(function (error) { 13 | console.log('connected!'); 14 | // Find the Anonymous signals 15 | MetaWear.mbl_mw_metawearboard_create_anonymous_datasignals(device.board, ref.NULL, 16 | MetaWear.FnVoid_VoidP_MetaWearBoardP_AnonymousDataSignalP_UInt.toPointer(function (context, board, anonymousSignals, size) { 17 | if (!anonymousSignals) { 18 | console.log('nothing being logged'); 19 | process.exit(1); 20 | } 21 | // Set the size on the array so we can index 22 | anonymousSignals.length = size; 23 | var i; 24 | for (i = 0; i < size; i++) { 25 | // Get signals that have been logged using the identifier api 26 | var identifier = MetaWear.mbl_mw_anonymous_datasignal_get_identifier(anonymousSignals[i]); 27 | // Subscribe to the signals we found 28 | MetaWear.mbl_mw_anonymous_datasignal_subscribe(anonymousSignals[i], ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 29 | var data = dataPtr.deref(); 30 | var pt = data.parseValue(); 31 | console.log(identifier + ':' + data.epoch + ' ' + JSON.stringify(pt)); 32 | })); 33 | } 34 | // Download the log 35 | download(device, function () { 36 | device.once('disconnect', function (reason) { 37 | // Exit App 38 | process.exit(0); 39 | }); 40 | // Reset 41 | MetaWear.mbl_mw_macro_erase_all(device.board); 42 | MetaWear.mbl_mw_debug_reset_after_gc(device.board); 43 | MetaWear.mbl_mw_debug_disconnect(device.board); 44 | }); 45 | })); 46 | }); 47 | }); 48 | 49 | function download(device, callback) { 50 | // Setup the handlers for events during the download 51 | var downloadHandler = new MetaWear.LogDownloadHandler(); 52 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 53 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 54 | if (entriesLeft === 0) { 55 | callback(null); 56 | } 57 | }); 58 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 59 | console.log('received_unknown_entry'); 60 | }); 61 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 62 | var data = dataPtr.deref(); 63 | var dataPoint = data.parseValue(); 64 | console.log('received_unhandled_entry: ' + dataPoint); 65 | }); 66 | // Actually start the log download, this will cause all the handlers we setup to be invoked 67 | MetaWear.mbl_mw_logging_download(device.board, 20, downloadHandler.ref()); 68 | } 69 | -------------------------------------------------------------------------------- /examples/clear_led_on_switch.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | MetaWear.discoverByAddress('f7:c0:14:1b:e5:86', function(device) { 10 | console.log('Discovered'); 11 | device.connectAndSetUp(async function (error) { 12 | 13 | console.log('Get button signal'); 14 | var switcher = MetaWear.mbl_mw_switch_get_state_data_signal(device.board); 15 | 16 | 17 | console.log('Create switch counter'); 18 | var promise = new Promise((resolve, reject) => { 19 | MetaWear.mbl_mw_dataprocessor_counter_create(switcher, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 20 | console.log('Comparator Created'); 21 | resolve(dataPtr); 22 | })); 23 | }); 24 | let counter = await promise; 25 | 26 | console.log('Create modular 2 calc on counter'); 27 | promise = new Promise((resolve, reject) => { 28 | MetaWear.mbl_mw_dataprocessor_math_create(counter, cbindings.MathOperation.MODULUS, 2.0, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 29 | console.log('Modulator Created'); 30 | resolve(dataPtr); 31 | })); 32 | }); 33 | let moder = await promise; 34 | 35 | console.log('Create odd comparator'); 36 | promise = new Promise((resolve, reject) => { 37 | MetaWear.mbl_mw_dataprocessor_comparator_create(moder, cbindings.ComparatorOperation.EQ, 1.0, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 38 | console.log('Odder Created'); 39 | resolve(dataPtr); 40 | })); 41 | }); 42 | let odder = await promise; 43 | 44 | console.log('Create even comparator'); 45 | promise = new Promise((resolve, reject) => { 46 | MetaWear.mbl_mw_dataprocessor_comparator_create(moder, cbindings.ComparatorOperation.EQ, 0.0, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 47 | console.log('Evener Created'); 48 | resolve(dataPtr); 49 | })); 50 | }); 51 | let evener = await promise; 52 | 53 | // Create a LED patter type 54 | console.log('Set up LED'); 55 | var pattern = new MetaWear.LedPattern(); 56 | // Load a LED pattern already in firmware 57 | MetaWear.mbl_mw_led_load_preset_pattern(pattern.ref(), cbindings.LedPreset.SOLID); 58 | 59 | console.log('Record COMMAND for even switch'); 60 | MetaWear.mbl_mw_event_record_commands(evener); 61 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), cbindings.LedColor.BLUE); 62 | MetaWear.mbl_mw_led_play(device.board); 63 | console.log('End Record COMMAND for even switch'); 64 | promise = new Promise((resolve, reject) => { 65 | var startLog = MetaWear.mbl_mw_event_end_record(evener, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 66 | console.log('COMMAND Created'); 67 | resolve(lstatus); 68 | })); 69 | }); 70 | let startLog = await promise; 71 | 72 | console.log('Record COMMAND for odd switch'); 73 | MetaWear.mbl_mw_event_record_commands(odder); 74 | MetaWear.mbl_mw_led_stop_and_clear(device.board); 75 | console.log('End Record COMMAND for odd switch'); 76 | promise = new Promise((resolve, reject) => { 77 | var stopLog = MetaWear.mbl_mw_event_end_record(odder, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 78 | console.log('COMMAND Created'); 79 | resolve(lstatus); 80 | })); 81 | }); 82 | let stopLog = await promise; 83 | 84 | MetaWear.mbl_mw_debug_disconnect(device.board); 85 | device.on('disconnect', function () { 86 | process.exit(0); 87 | }); 88 | }); 89 | }); 90 | -------------------------------------------------------------------------------- /examples/data_fuser.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi') 8 | 9 | // Main function 10 | async function mainAsync(mac) { 11 | // Find device 12 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 13 | await new Promise((resolve, reject) => { 14 | // Connect and setup 15 | device.connectAndSetUp(error => { 16 | if(error == null) resolve(null) 17 | else reject(error) 18 | }) 19 | }) 20 | 21 | // Get signals 22 | let acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board) 23 | // For MMRL, MMC, MMR... 24 | //let gyro = MetaWear.mbl_mw_gyro_bmi160_get_rotation_data_signal(device.board) 25 | // For MMS 26 | let gyro = MetaWear.mbl_mw_gyro_bmi270_get_rotation_data_signal(device.board) 27 | 28 | let fuser = await new Promise((resolve, reject) => { 29 | //ArrayType(ref.refType(AnonymousDataSignal)); 30 | console.log("creating fuser? ") 31 | console.log(acc) 32 | console.log(gyro) 33 | MetaWear.mbl_mw_dataprocessor_fuser_create(acc, new MetaWear.ArrayDataSignalP([gyro]), 1, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer((ctx, pointer) => { 34 | if (!pointer) { 35 | reject("Failed to create fuser") 36 | } else { 37 | resolve(pointer); 38 | } 39 | })) 40 | console.log("fuser created?") 41 | }) 42 | 43 | MetaWear.mbl_mw_datasignal_subscribe(fuser, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 44 | var data = pointer.deref(); 45 | var values = data.parseValue({'nElem': 2}); 46 | 47 | let acc = values[0] 48 | let gyro = values[1] 49 | 50 | console.log(`acc: (${acc.x},${acc.y},${acc.z}), gyro; (${gyro.x},${gyro.y},${gyro.z})`) 51 | })) 52 | 53 | // For MMRL, MMC, MMR... 54 | //MetaWear.mbl_mw_gyro_bmi160_enable_rotation_sampling(device.board) 55 | // For MMS 56 | MetaWear.mbl_mw_gyro_bmi270_enable_rotation_sampling(device.board) 57 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board) 58 | 59 | // For MMRL, MMC, MMR... 60 | //MetaWear.mbl_mw_gyro_bmi160_start(device.board) 61 | // For MMS 62 | MetaWear.mbl_mw_gyro_bmi270_start(device.board) 63 | MetaWear.mbl_mw_acc_start(device.board) 64 | 65 | // Reset when user enters anything in the terminal 66 | process.openStdin().addListener("data", data => { 67 | MetaWear.mbl_mw_debug_reset(device.board) 68 | process.exit(1); 69 | }) 70 | } 71 | 72 | mainAsync(process.argv[2]) 73 | -------------------------------------------------------------------------------- /examples/full_reset.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var ref = require('ref-napi'); 7 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 8 | 9 | function part1(device) { 10 | return new Promise(function(resolve, reject) { 11 | console.log('Find loggers'); 12 | MetaWear.mbl_mw_metawearboard_create_anonymous_datasignals(device.board, ref.NULL, 13 | MetaWear.FnVoid_VoidP_MetaWearBoardP_AnonymousDataSignalP_UInt.toPointer(function (context, board, anonymousSignals, size) { 14 | if (!anonymousSignals || (size == 0)) { 15 | console.log('Nothing being logged'); 16 | console.log('Stop logger just in case'); 17 | MetaWear.mbl_mw_logging_stop(device.board); 18 | resolve(); 19 | } else { 20 | console.log('Something is being logged'); 21 | anonymousSignals.length = size; 22 | var i; 23 | console.log(size); 24 | for (i = 0; i < size; i++) { 25 | console.log(i); 26 | var identifier = MetaWear.mbl_mw_anonymous_datasignal_get_identifier(anonymousSignals[i]); 27 | console.log('Found signal: ' + i + ' for ' + identifier); 28 | console.log('Removing this logger!'); 29 | MetaWear.mbl_mw_logger_remove(anonymousSignals[i]); 30 | } 31 | resolve(); 32 | } 33 | } 34 | )); 35 | }); 36 | } 37 | 38 | function part2(device) { 39 | return new Promise(function(resolve, reject) { 40 | console.log('Checking memory'); 41 | MetaWear.mbl_mw_logging_get_length_data_signal(device.board); 42 | var logSignal = MetaWear.mbl_mw_logging_get_length_data_signal(device.board); 43 | MetaWear.mbl_mw_datasignal_subscribe(logSignal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 44 | var data = pointer.deref(); 45 | var value = data.parseValue(); 46 | console.log('Log size is: ' + value); 47 | console.log('Delete all log entries'); 48 | MetaWear.mbl_mw_logging_clear_entries(device.board); 49 | resolve(0); 50 | })); 51 | MetaWear.mbl_mw_datasignal_read(logSignal); 52 | }); 53 | } 54 | 55 | function part3(device) { 56 | return new Promise(function(resolve, reject) { 57 | console.log('Stop LED'); 58 | MetaWear.mbl_mw_led_stop_and_clear(device.board); 59 | 60 | console.log('Remove data processors and timers'); 61 | MetaWear.mbl_mw_metawearboard_tear_down(device.board); 62 | 63 | console.log('Delete all macros'); 64 | MetaWear.mbl_mw_macro_erase_all(device.board); 65 | 66 | resolve(); 67 | }); 68 | } 69 | 70 | // Enter the board mac adddress 71 | MetaWear.discoverByAddress('f7:c0:14:1b:e5:86', function(device) { 72 | console.log('Discovered'); 73 | device.connectAndSetUp(function (error) { 74 | console.log('Connected'); 75 | part1(device).then((results) => { 76 | part2(device).then((results) => { 77 | part3(device).then((results) => { 78 | console.log('Reset sensor and garbage collect'); 79 | MetaWear.mbl_mw_debug_reset_after_gc(device.board); 80 | console.log("Wait 2 sec") 81 | setTimeout(function () { 82 | device.on('disconnect', function () { 83 | process.exit(0); 84 | }); 85 | console.log('Disconnect'); 86 | MetaWear.mbl_mw_debug_disconnect(device.board); 87 | }, 2000); 88 | }); 89 | }); 90 | }); 91 | }); 92 | }); -------------------------------------------------------------------------------- /examples/led.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 6 | var ref = require('ref-napi'); 7 | 8 | // If you know the MAC address: 9 | MetaWear.discoverByAddress('d1:e7:65:2a:ad:6f', function(device) { 10 | //MetaWear.discover(function (device) { 11 | device.connectAndSetUp(function (error) { 12 | // Create a LED patter type 13 | var pattern = new MetaWear.LedPattern(); 14 | // Load a LED pattern already in firmware 15 | MetaWear.mbl_mw_led_load_preset_pattern(pattern.ref(), MetaWear.LedPreset.BLINK); 16 | // Send pattern to Board 17 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), MetaWear.LedColor.GREEN); 18 | // Tell board to play pattern 19 | MetaWear.mbl_mw_led_play(device.board); 20 | setTimeout(function () { 21 | device.on('disconnect', function () { 22 | process.exit(0); 23 | }); 24 | // Stop LED 25 | MetaWear.mbl_mw_led_stop_and_clear(device.board); 26 | // Debug reset board 27 | MetaWear.mbl_mw_debug_reset(device.board); 28 | }, 5000); // Wait 5 seconds 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /examples/led_dongle.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | 8 | //Multiple Adapters 9 | //hci0 is used by default to override set the NOBLE_HCI_DEVICE_ID environment variable to the interface number. 10 | //Example, specify hci1: 11 | //sudo NOBLE_HCI_DEVICE_ID=1 node .js 12 | 13 | //Reporting all HCI events 14 | //By default noble waits for both the advertisement data and scan response data for each Bluetooth address. If your device does not use scan response the following environment variable can be used to bypass it. 15 | //sudo NOBLE_REPORT_ALL_HCI_EVENTS=1 node .js 16 | 17 | // If you know the MAC address: 18 | MetaWear.discoverByAddress('ea:78:c3:d3:f0:8a', function(device) { 19 | //MetaWear.discover(function (device) { 20 | device.connectAndSetUp(function (error) { 21 | // Create a LED patter type 22 | var pattern = new MetaWear.LedPattern(); 23 | // Load a LED pattern already in firmware 24 | MetaWear.mbl_mw_led_load_preset_pattern(pattern.ref(), MetaWear.LedPreset.BLINK); 25 | // Send pattern to Board 26 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), MetaWear.LedColor.GREEN); 27 | // Tell board to play pattern 28 | MetaWear.mbl_mw_led_play(device.board); 29 | setTimeout(function () { 30 | device.on('disconnect', function () { 31 | process.exit(0); 32 | }); 33 | // Stop LED 34 | MetaWear.mbl_mw_led_stop_and_clear(device.board); 35 | // Debug reset board 36 | MetaWear.mbl_mw_debug_reset(device.board); 37 | }, 5000); // Wait 5 seconds 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /examples/led_macro.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // If you know the MAC address: 10 | MetaWear.discoverByAddress('ea:78:c3:d3:f0:8a', function(device) { 11 | // This connects to the closest Metawear 12 | //MetaWear.discover(function (device) { 13 | device.connectAndSetUp(async function (error) { 14 | // Record the macro 15 | console.log('Macro started'); 16 | MetaWear.mbl_mw_macro_record(device.board, 1) // 1 means to exect the macro on boot, else macro must be executed with mbl_mw_execute 17 | // Create and LED pattern and play it 18 | console.log('LED'); 19 | var pattern = new MetaWear.LedPattern(); 20 | MetaWear.mbl_mw_led_load_preset_pattern(pattern.ref(), MetaWear.LedPreset.BLINK); 21 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), MetaWear.LedColor.GREEN); 22 | MetaWear.mbl_mw_led_play(device.board); 23 | console.log('END'); 24 | // End the macro recording 25 | var promise = new Promise((resolve, reject) => { 26 | var macro = MetaWear.mbl_mw_macro_end_record(device.board, ref.NULL, MetaWear.FnVoid_VoidP_Int.toPointer(function onSignal(context, rec) { 27 | console.log('Macro created'); 28 | console.log(rec); 29 | resolve(rec); 30 | })); 31 | }); 32 | var rec = await promise; 33 | setTimeout(function () { 34 | console.log('WAIT 5 SECONDS'); 35 | device.on('disconnect', function () { 36 | // End terminal process 37 | process.exit(0); 38 | }); 39 | // Reset board 40 | MetaWear.mbl_mw_debug_reset(device.board); 41 | }, 5000); // Wait 5 seconds 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /examples/log_acc_bmi160.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // THIS IS FOR THE MMR, MMC, or MMRL ONLY 10 | 11 | // Store the log event for later download. If your program needs to terminate 12 | // before performing the log download, you will need to use mbl_mw_metawearboard_serialize 13 | // to store the device state and that pass that state as the second argument to 14 | // connectAndSetUp when you are ready to download. Use mbl_mw_logger_lookup_id 15 | // to retrieve this accelLogger object 16 | var accelLogger = null; 17 | 18 | // If you know the MAC address: 19 | MetaWear.discoverByAddress('d1:e7:65:2a:ad:6f', function (device) { 20 | //MetaWear.discover(function (device) { 21 | console.log('discovered ' + device.address); 22 | device.connectAndSetUp(function (error) { 23 | if (error) { 24 | console.log(error); 25 | process.exit(1); 26 | } 27 | console.log('connected ' + device.address); 28 | // Start logging 29 | startLogging(device, function (error) { 30 | if (error) { 31 | console.log(error); 32 | process.exit(1); 33 | } 34 | // Stop logging after 10 seconds 35 | setTimeout(function () { 36 | downloadLog(device, function (error) { 37 | device.once('disconnect', function (reason) { 38 | process.exit(0); 39 | }); 40 | MetaWear.mbl_mw_debug_reset(device.board); 41 | }); 42 | }, 10000); 43 | }); 44 | }); 45 | }); 46 | 47 | function downloadLog(device, callback) { 48 | // Shutdown accel 49 | MetaWear.mbl_mw_acc_stop(device.board); 50 | MetaWear.mbl_mw_acc_disable_acceleration_sampling(device.board); 51 | // Shutdown log 52 | MetaWear.mbl_mw_logging_stop(device.board); 53 | // Setup handerl for accel data points 54 | MetaWear.mbl_mw_logger_subscribe(accelLogger, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 55 | var data = dataPtr.deref(); 56 | var pt = data.parseValue(); 57 | console.log(data.epoch + ' ' + pt.x + ',' + pt.y + ',' + pt.z); 58 | })); 59 | // Setup the handlers for events during the download 60 | var downloadHandler = new MetaWear.LogDownloadHandler(); 61 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 62 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 63 | if (entriesLeft === 0) { 64 | // Remove all log entries if told to stop logging 65 | MetaWear.mbl_mw_metawearboard_tear_down(device.board); 66 | callback(null); 67 | } 68 | }); 69 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 70 | console.log('received_unknown_entry'); 71 | }); 72 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 73 | var data = dataPtr.deref(); 74 | var dataPoint = data.parseValue(); 75 | console.log('received_unhandled_entry: ' + dataPoint); 76 | }); 77 | // Actually start the log download, this will cause all the handlers we setup to be invoked 78 | MetaWear.mbl_mw_logging_download(device.board, 20, downloadHandler.ref()); 79 | } 80 | 81 | function startLogging(device, callback) { 82 | MetaWear.mbl_mw_acc_set_odr(device.board, 50.0); 83 | MetaWear.mbl_mw_acc_set_range(device.board, 16.0); 84 | MetaWear.mbl_mw_acc_write_acceleration_config(device.board); 85 | 86 | // See if we already created a logger 87 | var accSignal = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 88 | MetaWear.mbl_mw_datasignal_log(accSignal, ref.NULL, MetaWear.FnVoid_VoidP_DataLoggerP.toPointer(function (context, logger) { 89 | accelLogger = logger; 90 | callback(logger.address() ? null : new Error('failed to start logging accel')); 91 | })); 92 | 93 | MetaWear.mbl_mw_logging_start(device.board, 0); 94 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 95 | MetaWear.mbl_mw_acc_start(device.board); 96 | } 97 | -------------------------------------------------------------------------------- /examples/log_acc_bmi270.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // THIS IS FOR THE MMS ONLY 10 | 11 | // Store the log event for later download. If your program needs to terminate 12 | // before performing the log download, you will need to use mbl_mw_metawearboard_serialize 13 | // to store the device state and that pass that state as the second argument to 14 | // connectAndSetUp when you are ready to download. Use mbl_mw_logger_lookup_id 15 | // to retrieve this accelLogger object 16 | 17 | var accelLogger = null; 18 | 19 | // If you know the MAC address: 20 | MetaWear.discoverByAddress('ea:78:c3:d3:f0:8a', function (device) { 21 | // If you don't know the MAC address, this will connect to nearest 22 | //MetaWear.discover(function (device) { 23 | console.log('discovered ' + device.address); 24 | // Connect and setup 25 | device.connectAndSetUp(function (error) { 26 | if (error) { 27 | console.log(error); 28 | process.exit(1); 29 | } 30 | console.log('connected ' + device.address); 31 | // Start logging 32 | startLogging(device, function (error) { 33 | if (error) { 34 | console.log(error); 35 | process.exit(1); 36 | } 37 | // Stop logging after 10 seconds 38 | setTimeout(function () { 39 | downloadLog(device, function (error) { 40 | device.once('disconnect', function (reason) { 41 | process.exit(0); 42 | }); 43 | MetaWear.mbl_mw_debug_reset(device.board); 44 | }); 45 | }, 10000); 46 | }); 47 | }); 48 | }); 49 | 50 | function downloadLog(device, callback) { 51 | // Shutdown accel 52 | MetaWear.mbl_mw_acc_stop(device.board); 53 | MetaWear.mbl_mw_acc_disable_acceleration_sampling(device.board); 54 | // Shutdown log 55 | MetaWear.mbl_mw_logging_stop(device.board); 56 | // MMS only call 57 | MetaWear.mbl_mw_logging_flush_page(device.board); 58 | // Setup handler for accel data points entries 59 | MetaWear.mbl_mw_logger_subscribe(accelLogger, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 60 | var data = dataPtr.deref(); 61 | var pt = data.parseValue(); 62 | console.log(data.epoch + ' ' + pt.x + ',' + pt.y + ',' + pt.z); 63 | })); 64 | // Setup the handlers for events during the download 65 | var downloadHandler = new MetaWear.LogDownloadHandler(); 66 | // Setup handler progress updates 67 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 68 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 69 | if (entriesLeft === 0) { 70 | // Remove timers and data processors 71 | MetaWear.mbl_mw_metawearboard_tear_down(device.board); 72 | callback(null); 73 | } 74 | }); 75 | // Setup handle for unknown entry 76 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 77 | console.log('received_unknown_entry'); 78 | }); 79 | // Setup handler for unhandled entry 80 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 81 | var data = dataPtr.deref(); 82 | var dataPoint = data.parseValue(); 83 | console.log('received_unhandled_entry: ' + dataPoint); 84 | }); 85 | // Actually start the log download, this will cause all the handlers we setup to be invoked 86 | MetaWear.mbl_mw_logging_download(device.board, 20, downloadHandler.ref()); 87 | } 88 | 89 | function startLogging(device, callback) { 90 | // Setup accelerometer 91 | MetaWear.mbl_mw_acc_set_odr(device.board, 50.0); 92 | MetaWear.mbl_mw_acc_set_range(device.board, 16.0); 93 | MetaWear.mbl_mw_acc_write_acceleration_config(device.board); 94 | 95 | // See if we already created a logger 96 | var accSignal = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 97 | // Log the signal 98 | MetaWear.mbl_mw_datasignal_log(accSignal, ref.NULL, MetaWear.FnVoid_VoidP_DataLoggerP.toPointer(function (context, logger) { 99 | accelLogger = logger; 100 | callback(logger.address() ? null : new Error('failed to start logging accel')); 101 | })); 102 | // Start logging 103 | MetaWear.mbl_mw_logging_start(device.board, 0); 104 | // Start the accelerometer 105 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 106 | MetaWear.mbl_mw_acc_start(device.board); 107 | } 108 | -------------------------------------------------------------------------------- /examples/log_temp.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | var tempLogger = null; 9 | var tempTimer = null; 10 | 11 | // Discover by MAC address 12 | MetaWear.discoverByAddress('ea:78:c3:d3:f0:8a', function(device) { 13 | console.log('Discovered'); 14 | // Connect and setup 15 | device.connectAndSetUp(async function (error) { 16 | console.log('Connected'); 17 | // Start logging 18 | startLogging(device, function (error) { 19 | if (error) { 20 | console.log(error); 21 | process.exit(1); 22 | } 23 | // Stop logging after 10 seconds 24 | console.log('Wait 10 seconds'); 25 | setTimeout(function () { 26 | console.log('Done waiting'); 27 | // Download log 28 | downloadLog(device, function (error) { 29 | device.once('disconnect', function (reason) { 30 | console.log('Disconnected'); 31 | process.exit(0); 32 | }); 33 | console.log('Disconnect'); 34 | // Reset device 35 | MetaWear.mbl_mw_debug_reset(device.board); 36 | }); 37 | }, 10000); 38 | }); 39 | }); 40 | }); 41 | 42 | function downloadLog(device, callback) { 43 | // Stop timer 44 | MetaWear.mbl_mw_timer_remove(tempTimer); 45 | // Shutdown log 46 | MetaWear.mbl_mw_logging_stop(device.board); 47 | // MMS only call 48 | MetaWear.mbl_mw_logging_flush_page(device.board); 49 | // Setup handler for accel data points 50 | MetaWear.mbl_mw_logger_subscribe(tempLogger, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 51 | var data = dataPtr.deref(); 52 | var pt = data.parseValue(); 53 | console.log(data.epoch + ' ' + pt); 54 | })); 55 | // Setup the handlers for events during the download 56 | var downloadHandler = new MetaWear.LogDownloadHandler(); 57 | // Handler for progress of download 58 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 59 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 60 | if (entriesLeft === 0) { 61 | // Remove all log entries if told to stop logging 62 | MetaWear.mbl_mw_metawearboard_tear_down(device.board); 63 | callback(null); 64 | } 65 | }); 66 | // Handler for unknown entry 67 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 68 | console.log('received_unknown_entry'); 69 | }); 70 | // Handler for unhandled entry 71 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 72 | var data = dataPtr.deref(); 73 | var dataPoint = data.parseValue(); 74 | console.log('received_unhandled_entry: ' + dataPoint); 75 | }); 76 | // Actually start the log download, this will cause all the handlers we setup to be invoked 77 | MetaWear.mbl_mw_logging_download(device.board, 20, downloadHandler.ref()); 78 | } 79 | 80 | async function startLogging(device, callback) { 81 | // Get temp signal 82 | console.log('Get temp signal'); 83 | var tempSignal = MetaWear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(device.board, 1); 84 | // Create a timer 85 | console.log('Create timer'); 86 | var promise = new Promise((resolve, reject) => { 87 | var timer = MetaWear.mbl_mw_timer_create_indefinite(device.board, 1000, 0, ref.NULL, MetaWear.FnVoid_VoidP_TimerP.toPointer(function onSignal(context, timer) { 88 | console.log(context); 89 | console.log('Timer created'); 90 | console.log(timer); 91 | resolve(timer); 92 | })); 93 | }); 94 | tempTimer = await promise; 95 | console.log(tempTimer); 96 | // Create event based on timer and record as a command 97 | console.log('Record command'); 98 | MetaWear.mbl_mw_event_record_commands(tempTimer); 99 | console.log('Command to read temp signal'); 100 | MetaWear.mbl_mw_datasignal_read(tempSignal); 101 | console.log('End record command'); 102 | promise = new Promise((resolve, reject) => { 103 | var rec = MetaWear.mbl_mw_event_end_record(tempTimer, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 104 | console.log('Command created'); 105 | resolve(lstatus); 106 | })); 107 | }); 108 | let rec = await promise; 109 | // Start timer 110 | MetaWear.mbl_mw_timer_start(tempTimer); 111 | // Create a logger 112 | MetaWear.mbl_mw_datasignal_log(tempSignal, ref.NULL, MetaWear.FnVoid_VoidP_DataLoggerP.toPointer(function (context, logger) { 113 | tempLogger = logger; 114 | callback(logger.address() ? null : new Error('failed to start logging temp')); 115 | })); 116 | // Start logger 117 | MetaWear.mbl_mw_logging_start(device.board, 0); 118 | } 119 | -------------------------------------------------------------------------------- /examples/multi_device.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var fs = require('fs'); 8 | var ref = require('ref-napi'); 9 | 10 | var addresses = [ 11 | 'ea:78:c3:d3:f0:8a', 12 | 'e6:fe:b6:b4:db:e7' 13 | ]; 14 | var devices = []; 15 | 16 | // Discover device function 17 | function onDiscover(device) { 18 | addresses.forEach(function (address) { 19 | if (device.address.toUpperCase() === address.toUpperCase()) { 20 | console.log('discovered ' + address); 21 | devices.push(device); 22 | } 23 | }); 24 | // Some adapters don't allow connecting while scanning is going on, 25 | // so we we complete our discovery only when scanning is finished 26 | if (addresses.length == devices.length) { 27 | MetaWear.stopDiscoverAll(onDiscover); 28 | setTimeout(function () { 29 | console.log('discover complete'); 30 | devices.forEach(function (device) { 31 | startAccelStream(device); 32 | }); 33 | }, 1000); 34 | } 35 | }; 36 | MetaWear.discoverAll(onDiscover); 37 | 38 | // Start the accelerometer stream function 39 | function startAccelStream(device) { 40 | device.connectAndSetUp(function (error) { 41 | if (error) { 42 | console.error(error); 43 | process.exit(1); 44 | } 45 | console.log('connected ' + device.address); 46 | // Set the max range of the accelerometer 47 | MetaWear.mbl_mw_acc_set_range(device.board, cbindings.AccBoschRange._8G); 48 | MetaWear.mbl_mw_acc_set_odr(device.board, 5); 49 | MetaWear.mbl_mw_acc_write_acceleration_config(device.board); 50 | console.log('get acc signal'); 51 | var accSignal = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 52 | // Setup acc download by subscribing to the signal 53 | console.log('subscribe to logger'); 54 | MetaWear.mbl_mw_datasignal_subscribe(accSignal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function gotTimer(context, dataPtr) { 55 | var data = dataPtr.deref(); 56 | var pt = data.parseValue(); 57 | console.log(pt.x, pt.y, pt.z); 58 | })); 59 | // Start acc 60 | console.log('start acc'); 61 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 62 | MetaWear.mbl_mw_acc_start(device.board); 63 | 64 | // Stop after 5 seconds 65 | setTimeout(function () { 66 | // Stop the stream 67 | console.log('stop and reset'); 68 | MetaWear.mbl_mw_acc_stop(device.board); 69 | MetaWear.mbl_mw_acc_disable_acceleration_sampling(device.board); 70 | MetaWear.mbl_mw_datasignal_unsubscribe(accSignal); 71 | MetaWear.mbl_mw_debug_disconnect(device.board); 72 | setTimeout(function () { 73 | process.exit(1); 74 | }, 1000); 75 | }, 5000); 76 | }); 77 | } 78 | -------------------------------------------------------------------------------- /examples/record_on_push.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | var accLogger = null; 9 | 10 | MetaWear.discoverByAddress('f7:c0:14:1b:e5:86', function(device) { 11 | console.log('Discovered'); 12 | device.connectAndSetUp(async function (error) { 13 | 14 | console.log('Set up acc'); 15 | MetaWear.mbl_mw_acc_bmi160_set_odr(device.board, cbindings.AccBmi160Odr._25Hz); 16 | MetaWear.mbl_mw_acc_set_range(device.board, cbindings.AccBoschRange._2G); 17 | MetaWear.mbl_mw_acc_write_acceleration_config(device.board); 18 | 19 | console.log('Get acc signal'); 20 | var acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 21 | 22 | console.log('Create LOGGER for acc'); 23 | var promise = new Promise((resolve, reject) => { 24 | MetaWear.mbl_mw_datasignal_log(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataLoggerP.toPointer(function onSignal(context, logger) { 25 | console.log('LOGGER Created for acc: ' + logger); 26 | resolve(logger); 27 | })); 28 | }); 29 | accLogger = await promise; 30 | 31 | console.log('Enable and Start Acc'); 32 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 33 | MetaWear.mbl_mw_acc_start(device.board); 34 | 35 | console.log('Get button signal'); 36 | var switcher = MetaWear.mbl_mw_switch_get_state_data_signal(device.board); 37 | 38 | console.log('Create switch counter'); 39 | promise = new Promise((resolve, reject) => { 40 | MetaWear.mbl_mw_dataprocessor_counter_create(switcher, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 41 | console.log('Comparator Created'); 42 | resolve(dataPtr); 43 | })); 44 | }); 45 | let counter = await promise; 46 | 47 | console.log('Create modular 2 calc on counter'); 48 | promise = new Promise((resolve, reject) => { 49 | MetaWear.mbl_mw_dataprocessor_math_create(counter, cbindings.MathOperation.MODULUS, 2.0, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 50 | console.log('Modulator Created'); 51 | resolve(dataPtr); 52 | })); 53 | }); 54 | let moder = await promise; 55 | 56 | console.log('Create odd comparator'); 57 | promise = new Promise((resolve, reject) => { 58 | MetaWear.mbl_mw_dataprocessor_comparator_create(moder, cbindings.ComparatorOperation.EQ, 1.0, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 59 | console.log('Odder Created'); 60 | resolve(dataPtr); 61 | })); 62 | }); 63 | let odder = await promise; 64 | 65 | console.log('Create even comparator'); 66 | promise = new Promise((resolve, reject) => { 67 | MetaWear.mbl_mw_dataprocessor_comparator_create(moder, cbindings.ComparatorOperation.EQ, 0.0, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, dataPtr) { 68 | console.log('Evener Created'); 69 | resolve(dataPtr); 70 | })); 71 | }); 72 | let evener = await promise; 73 | 74 | // Create a LED patter type 75 | console.log('Set up LED'); 76 | var pattern = new MetaWear.LedPattern(); 77 | // Load a LED pattern already in firmware 78 | MetaWear.mbl_mw_led_load_preset_pattern(pattern.ref(), cbindings.LedPreset.SOLID); 79 | 80 | console.log('Record COMMAND for even switch - not pressed'); 81 | MetaWear.mbl_mw_event_record_commands(evener); 82 | MetaWear.mbl_mw_logging_stop(device.board); 83 | MetaWear.mbl_mw_led_stop_and_clear(device.board); 84 | console.log('End Record COMMAND for even switch'); 85 | promise = new Promise((resolve, reject) => { 86 | var startLog = MetaWear.mbl_mw_event_end_record(evener, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 87 | console.log('COMMAND Created'); 88 | resolve(lstatus); 89 | })); 90 | }); 91 | let startLog = await promise; 92 | 93 | console.log('Record COMMAND for odd switch - pressed'); 94 | MetaWear.mbl_mw_event_record_commands(odder); 95 | MetaWear.mbl_mw_logging_start(device.board, 0); 96 | MetaWear.mbl_mw_led_write_pattern(device.board, pattern.ref(), cbindings.LedColor.RED); 97 | MetaWear.mbl_mw_led_play(device.board); 98 | console.log('End Record COMMAND for odd switch'); 99 | promise = new Promise((resolve, reject) => { 100 | var stopLog = MetaWear.mbl_mw_event_end_record(odder, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 101 | console.log('COMMAND Created'); 102 | resolve(lstatus); 103 | })); 104 | }); 105 | let stopLog = await promise; 106 | 107 | console.log('wait 10s'); 108 | // Stop after 10 seconds and download log 109 | setTimeout(function () { 110 | console.log('done waiting, lets download log'); 111 | downloadLog(device, function (error) { 112 | device.once('disconnect', function (reason) { 113 | console.log('disconnect'); 114 | process.exit(0); 115 | }); 116 | MetaWear.mbl_mw_debug_reset(device.board); 117 | }); 118 | }, 10000); 119 | }); 120 | }); 121 | 122 | function downloadLog(device, callback) { 123 | console.log('Disable Acc and Stop logging'); 124 | // Shutdown accel and logger 125 | MetaWear.mbl_mw_acc_stop(device.board); 126 | MetaWear.mbl_mw_acc_disable_acceleration_sampling(device.board); 127 | MetaWear.mbl_mw_logging_stop(device.board); 128 | 129 | console.log('Setup Download'); 130 | // Subscribe to the logger of the signal 131 | MetaWear.mbl_mw_logger_subscribe(accLogger, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 132 | var data = dataPtr.deref(); 133 | var pt = data.parseValue(); 134 | str = JSON.stringify(pt); 135 | var d = new Date(0); 136 | d.setUTCSeconds(data.epoch); 137 | console.log('received_entry: ' + d + ' ' + str); 138 | })); 139 | 140 | // Setup the handlers for events during the download 141 | var downloadHandler = new MetaWear.LogDownloadHandler(); 142 | 143 | // Handle download progress updates 144 | downloadHandler.received_progress_update = MetaWear.FnVoid_VoidP_UInt_UInt.toPointer(function onSignal(context, entriesLeft, totalEntries) { 145 | console.log('received_progress_update entriesLeft:' + entriesLeft + ' totalEntries:' + totalEntries); 146 | if (entriesLeft === 0) { 147 | // Remove all log entries if told to stop logging 148 | MetaWear.mbl_mw_metawearboard_tear_down(device.board); 149 | callback(null); 150 | } 151 | }); 152 | 153 | // Handle unknown entries 154 | downloadHandler.received_unknown_entry = MetaWear.FnVoid_VoidP_UByte_Long_UByteP_UByte.toPointer(function onSignal(context, id, epoch, data, length) { 155 | console.log('received_unknown_entry'); 156 | }); 157 | 158 | // Handle bad entries 159 | downloadHandler.received_unhandled_entry = MetaWear.FnVoid_VoidP_DataP.toPointer(function onSignal(context, dataPtr) { 160 | var data = dataPtr.deref(); 161 | var dataPoint = data.parseValue(); 162 | console.log('received_unhandled_entry: ' + dataPoint); 163 | }); 164 | 165 | // Actually start the log download, this will cause all the handlers we setup to be invoked 166 | console.log('Start Download'); 167 | MetaWear.mbl_mw_logging_download(device.board, 20, downloadHandler.ref()); 168 | } -------------------------------------------------------------------------------- /examples/scan_connect.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | // If you don't know the MAC address, you can uncomment this line 7 | // and it will connect to nearest automatically 8 | //MetaWear.discover(function (device) { 9 | MetaWear.discoverByAddress('f7:c0:14:1b:e5:86', function(device) { 10 | console.log(device); 11 | // you can be notified of disconnects 12 | device.on('disconnect', function () { 13 | console.log('we got disconnected! :( '); 14 | }); 15 | // you'll need to call connect and set up 16 | device.connectAndSetUp(function (error) { 17 | console.log('were connected!'); 18 | setTimeout(function () { 19 | device.disconnect(function (error) { 20 | console.log('disconnect call finished'); 21 | }); 22 | }, 1000); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /examples/serialize.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var ref = require('ref-napi'); 7 | 8 | // If you don't know the MAC address, you can uncomment this line 9 | // and it will connect to nearest automatically 10 | //MetaWear.discover(function (device) { 11 | MetaWear.discoverByAddress('f7:c0:14:1b:e5:86', function(device) { 12 | console.log(device); 13 | // you can be notified of disconnects 14 | device.on('disconnect', function () { 15 | console.log('we got disconnected! :( '); 16 | }); 17 | // you'll need to call connect and set up 18 | device.connectAndSetUp(function (error) { 19 | console.log('were connected!'); 20 | var intBuf = ref.alloc(ref.types.uint32); 21 | var raw = MetaWear.mbl_mw_metawearboard_serialize(device.board, intBuf); 22 | var sizeRead = intBuf.readUInt32LE(); 23 | var data = ref.reinterpret(raw, sizeRead, 0); 24 | console.log(data.toString('hex').match(/../g).join(' ')); 25 | var initStr = data.toString('hex'); 26 | setTimeout(function () { 27 | device.disconnect(function (error) { 28 | console.log('disconnect call finished'); 29 | process.exit(); 30 | }); 31 | }, 1000); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /examples/setup_connect.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | MetaWear.discoverByAddress('f7:c0:14:1b:e5:86', function(device) { 10 | //MetaWear.discover(function (device) { 11 | console.log('got em'); 12 | // you can be notified of disconnects 13 | device.on('disconnect', function () { 14 | console.log('we got disconnected! :( '); 15 | }); 16 | // Call connect and set up - this calls mbl_mw_metawearboard_initialize() 17 | device.connectAndSetUp(function (error) { 18 | console.log('were connected!'); 19 | // Adjust link speed - set the min conn interval to 7.5ms and the max conn interval to 7.5ms 20 | // Adjust link speed - set the latency to 0ms and the timeout to 4000ms 21 | // Connection interval = how often devices talk - min is 7.5ms, it increases in steps of 1.25ms 22 | // Slave latency = metawear can choose not to answer when central asks for an update (i.e metawear can sleep longer - doesn't affect transfer speeds) 23 | // Connection supervision timeout = determines timeout from last data exchange (tells central how long to wait to attempt to reconnect to a lost conn - if your metawear goes in and out of range often, it is better to have a short timeout) 24 | // This is not guaranteed to work, central can reject peripheral and vice-versa. Apple only accepts 15ms for example. 25 | MetaWear.mbl_mw_settings_set_connection_parameters(device.board, 7.5, 7.5, 0, 4000); 26 | console.log('link speed updated'); 27 | // Get the RSSI now: 28 | var rssi = device._peripheral.rssi; 29 | for (let i = 1; i < 5000; i++) { 30 | //console.log(device._peripheral.rssi); 31 | rssi += device._peripheral.rssi; 32 | } 33 | console.log('Average rssi :' + rssi/5000); 34 | // Set the highest signals strength 35 | MetaWear.mbl_mw_settings_set_tx_power(device.board, 4); 36 | // Everything we know about the device: 37 | //console.log(device); 38 | // Find out more about the sensor: 39 | model = MetaWear.mbl_mw_metawearboard_get_model(device.board); 40 | console.log('Model: ' + model); 41 | device.modelDescription = MetaWear.mbl_mw_metawearboard_get_model_name(device.board); 42 | console.log('Model Name: ' + device.modelDescription); 43 | var present = MetaWear.mbl_mw_metawearboard_lookup_module(device.board, 'GYRO'); 44 | console.log('Gyroscope: ' + (present == -1 ? 'Not Present' : 'Present')); 45 | present = MetaWear.mbl_mw_metawearboard_lookup_module(device.board, 'ACCELEROMETER'); 46 | console.log('Accelerometer: ' + (present == -1 ? 'Not Present' : 'Present')); 47 | present = MetaWear.mbl_mw_metawearboard_lookup_module(device.board, 'MAGNETOMETER'); 48 | console.log('Magnetometer: ' + (present == -1 ? 'Not Present' : 'Present')); 49 | present = MetaWear.mbl_mw_metawearboard_lookup_module(device.board, 'SENSOR_FUSION'); 50 | console.log('Sensor Fusion: ' + (present == -1 ? 'Not Present' : 'Present')); 51 | setTimeout(function () { 52 | device.disconnect(function (error) { 53 | console.log('disconnect call finished'); 54 | process.exit(0); 55 | }); 56 | }, 1000); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /examples/status_battery.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require("../index"); 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var ref = require("ref-napi"); 7 | 8 | // Discover by MAC address 9 | MetaWear.discoverByAddress("ea:78:c3:d3:f0:8a", function (device) { 10 | console.log("Discovered"); 11 | // Connect and setup 12 | device.connectAndSetUp(async function (error) { 13 | console.log("Connected"); 14 | 15 | readBatteryStatus(device); 16 | }); 17 | }); 18 | 19 | function readBatteryStatus(device) { 20 | const signal = MetaWear.mbl_mw_settings_get_battery_state_data_signal( 21 | device.board 22 | ); 23 | 24 | // Subscribe to it 25 | MetaWear.mbl_mw_datasignal_subscribe( 26 | signal, 27 | ref.NULL, 28 | MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 29 | const data = pointer.deref(); 30 | 31 | // { voltage: number, charge: number} ex: {"voltage":3972 "charge":77} 32 | const value = data.parseValue(); 33 | 34 | console.log("Status Battery", JSON.stringify(value), device.address); 35 | }) 36 | ); 37 | MetaWear.mbl_mw_datasignal_read(signal); 38 | } 39 | -------------------------------------------------------------------------------- /examples/stream_acc.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | var ref = require('ref-napi') 6 | 7 | // Main function 8 | async function mainAsync(mac) { 9 | // Discover 10 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 11 | await new Promise((resolve, reject) => { 12 | console.log('Connecting...') 13 | // Connect and setup 14 | device.connectAndSetUp(error => { 15 | console.log('Connected.') 16 | if(error == null) resolve(null) 17 | else reject(error) 18 | }) 19 | }) 20 | 21 | // Get acc signal 22 | let acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board) 23 | console.log('Set up stream.') 24 | 25 | var lastDate = new Date(); 26 | 27 | // Stream acc signal 28 | MetaWear.mbl_mw_datasignal_subscribe(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 29 | var data = pointer.deref(); 30 | var value = data.parseValue(); 31 | var newDate = new Date().setUTCSeconds(data.epoch); 32 | var seconds = (newDate.getTime() - lastDate.getTime()) / 1000; 33 | console.log('elapsed: ' + seconds + 'epoch: ' + data.epoch + ' acc: ' + value.x + ' ' + value.y + ' ' + value.z); 34 | var lastDate = newDate; 35 | })) 36 | 37 | // Start acc 38 | console.log('Start accelerometer.') 39 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board) 40 | MetaWear.mbl_mw_acc_start(device.board) 41 | 42 | // Terminal on terminal input 43 | process.openStdin().addListener("data", data => { 44 | console.log('Reset.') 45 | MetaWear.mbl_mw_debug_reset(device.board); 46 | MetaWear.mbl_mw_debug_disconnect(device.board); 47 | console.log('Disconnect'); 48 | setTimeout(function () { 49 | // Exit terminal 50 | process.exit(1); 51 | }, 4000); 52 | }) 53 | } 54 | 55 | // Run this example by putting the MAC address on the command line 56 | // sudo node stream_acc.js ea:78:c3:d3:f0:8a 57 | mainAsync(process.argv[2]) 58 | -------------------------------------------------------------------------------- /examples/stream_acc_accounter.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var ref = require('ref-napi'); 7 | 8 | async function mainAsync(mac) { 9 | // Find device with MAC address 10 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 11 | 12 | // Connect to device with MAC address 13 | await new Promise((resolve, reject) => { 14 | console.log('Connecting...') 15 | device.connectAndSetUp(error => { 16 | console.log('Connected.') 17 | if(error == null) resolve(null) 18 | else reject(error) 19 | }) 20 | }) 21 | 22 | // Get the accelerometer signal 23 | let acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 24 | 25 | // Add a counter to the accelerometer signal 26 | let accounter = await new Promise((resolve, reject) => { 27 | MetaWear.mbl_mw_dataprocessor_accounter_create(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer((ctx, pointer) => { 28 | console.log('Accounter Created'); 29 | resolve(pointer); 30 | })) 31 | }); 32 | console.log(accounter); 33 | 34 | // Setup logger 35 | console.log('Set up stream.') 36 | MetaWear.mbl_mw_datasignal_subscribe(accounter, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 37 | var data = pointer.deref(); 38 | var value = data.parseValue(); 39 | console.log('epoch: ' + data.epoch + ' acc: ' + value.x + ' ' + value.y + ' ' + value.z) 40 | })) 41 | 42 | // Start acc 43 | console.log('Start accelerometer.') 44 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board) 45 | MetaWear.mbl_mw_acc_start(device.board) 46 | 47 | // End process by entering anything into the terminal 48 | process.openStdin().addListener("data", data => { 49 | console.log('Reset.') 50 | MetaWear.mbl_mw_debug_reset(device.board) 51 | setTimeout(function () { 52 | // Exit terminal 53 | process.exit(1); 54 | }, 2000); 55 | }) 56 | } 57 | 58 | // Run this example by putting the MAC address on the command line 59 | // sudo node stream_acc_accounter.js ea:78:c3:d3:f0:8a 60 | mainAsync(process.argv[2]) 61 | 62 | -------------------------------------------------------------------------------- /examples/stream_acc_accumulator.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // Main function 10 | async function mainAsync(mac) { 11 | // Find device with MAC address 12 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 13 | 14 | // Connect to device with MAC address 15 | await new Promise((resolve, reject) => { 16 | console.log('Connecting...') 17 | // Setup and connect 18 | device.connectAndSetUp(error => { 19 | console.log('Connected.') 20 | if(error == null) resolve(null) 21 | else reject(error) 22 | }) 23 | }) 24 | 25 | // Get the barometer signal 26 | let baro = MetaWear.mbl_mw_baro_bosch_get_pressure_data_signal(device.board); 27 | 28 | // Create an averager of the baro (pressure) 29 | let accumulator = await new Promise((resolve, reject) => { 30 | MetaWear.mbl_mw_dataprocessor_accumulator_create(baro, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer((ctx, pointer) => { 31 | console.log('Accumulator Created'); 32 | resolve(pointer); 33 | })) 34 | }); 35 | console.log(accumulator); 36 | 37 | // Create accumulator 38 | MetaWear.mbl_mw_dataprocessor_set_accumulator_state(accumulator, 0); 39 | 40 | // Subscribe to logger 41 | console.log('Set up stream.') 42 | MetaWear.mbl_mw_datasignal_subscribe(accumulator, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 43 | var data = pointer.deref(); 44 | var value = data.parseValue(); 45 | console.log('epoch: ' + data.epoch + ' pressure: ' + value) 46 | })) 47 | 48 | // Start baromater 49 | console.log('Start barometer.') 50 | MetaWear.mbl_mw_baro_bosch_start(device.board); 51 | 52 | // Reset process on any terminal entry 53 | process.openStdin().addListener("data", data => { 54 | console.log('Reset.') 55 | MetaWear.mbl_mw_debug_reset(device.board) 56 | setTimeout(function () { 57 | // Exit terminal 58 | process.exit(1); 59 | }, 2000); 60 | }) 61 | } 62 | 63 | // Run this example by putting the MAC address on the command line 64 | // sudo node stream_acc_accumulator.js ea:78:c3:d3:f0:8a 65 | mainAsync(process.argv[2]) 66 | 67 | -------------------------------------------------------------------------------- /examples/stream_acc_averager.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // Main function 10 | async function mainAsync(mac) { 11 | // Find device with MAC address 12 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 13 | 14 | // Connect to device with MAC address 15 | await new Promise((resolve, reject) => { 16 | console.log('Connecting...') 17 | // Connect and setup 18 | device.connectAndSetUp(error => { 19 | console.log('Connected.') 20 | if(error == null) resolve(null) 21 | else reject(error) 22 | }) 23 | }) 24 | 25 | // Get the accelerometer signal 26 | let acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 27 | let acc_x = MetaWear.mbl_mw_datasignal_get_component(acc, cbindings.Const.ACC_ACCEL_X_AXIS_INDEX); 28 | 29 | // Create an averager of the acc (i/e filter) 30 | let averager = await new Promise((resolve, reject) => { 31 | MetaWear.mbl_mw_dataprocessor_average_create(acc_x, 8, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer((ctx, pointer) => { 32 | console.log('Averager Created'); 33 | resolve(pointer); 34 | })) 35 | }); 36 | console.log(averager); 37 | 38 | // Log the averaged signal (filter) 39 | console.log('Set up stream.') 40 | MetaWear.mbl_mw_datasignal_subscribe(averager, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 41 | var data = pointer.deref(); 42 | var value = data.parseValue(); 43 | console.log('epoch: ' + data.epoch + ' acc_x averaged: ' + value) 44 | })) 45 | 46 | // Start acc 47 | console.log('Start accelerometer.') 48 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board) 49 | MetaWear.mbl_mw_acc_start(device.board) 50 | 51 | // Terminate app on any terminal inpur 52 | process.openStdin().addListener("data", data => { 53 | console.log('Reset.') 54 | MetaWear.mbl_mw_debug_reset(device.board) 55 | setTimeout(function () { 56 | // Exit terminal 57 | process.exit(1); 58 | }, 2000); 59 | }) 60 | } 61 | 62 | // Run this example by putting the MAC address on the command line 63 | // sudo node stream_acc_averager.js ea:78:c3:d3:f0:8a 64 | mainAsync(process.argv[2]) 65 | 66 | -------------------------------------------------------------------------------- /examples/stream_acc_buffer.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // Setup function 10 | async function setupStream(device) { 11 | // Get the accelerometer signal 12 | console.log('Get Accelerometer Signal'); 13 | let acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 14 | 15 | // Create a buffer of the acc 16 | let buffer = await new Promise((resolve, reject) => { 17 | MetaWear.mbl_mw_dataprocessor_buffer_create(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer((ctx, pointer) => { 18 | console.log('Buffer Created'); 19 | resolve(pointer); 20 | })) 21 | }); 22 | console.log(buffer); 23 | 24 | // Log the buffer signal 25 | console.log('Set up stream.') 26 | MetaWear.mbl_mw_datasignal_subscribe(buffer, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 27 | var data = pointer.deref(); 28 | var value = data.parseValue(); 29 | console.log(value); 30 | })) 31 | 32 | // Start the acc 33 | console.log('Start accelerometer.'); 34 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 35 | MetaWear.mbl_mw_acc_start(device.board); 36 | } 37 | 38 | // Main function 39 | async function mainAsync(mac) { 40 | // Find device with MAC address 41 | console.log('Find device'); 42 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 43 | console.log('Found device'); 44 | 45 | // Connect and setup 46 | console.log('Connecting...') 47 | await new Promise((resolve, reject) => { 48 | device.connectAndSetUp(error => { 49 | if(error == null) resolve(null) 50 | else reject(error) 51 | }) 52 | }); 53 | console.log('Connected.'); 54 | 55 | // Setup acc + buffer 56 | setupStream(device); 57 | 58 | // Terminate on terminal input 59 | process.openStdin().addListener("data", data => { 60 | console.log('Reset.') 61 | MetaWear.mbl_mw_debug_reset(device.board) 62 | setTimeout(function () { 63 | // Exit terminal 64 | process.exit(1); 65 | }, 2000); 66 | }) 67 | } 68 | 69 | // Run this example by putting the MAC address on the command line 70 | // sudo node stream_acc_buffer.js ea:78:c3:d3:f0:8a 71 | mainAsync(process.argv[2]) 72 | 73 | -------------------------------------------------------------------------------- /examples/stream_acc_gyro.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi') 8 | 9 | // Main function 10 | async function mainAsync(mac) { 11 | // Discover 12 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 13 | await new Promise((resolve, reject) => { 14 | console.log('Connecting...') 15 | // Connect and setup 16 | device.connectAndSetUp(error => { 17 | console.log('Connected.') 18 | if(error == null) resolve(null) 19 | else reject(error) 20 | }) 21 | }) 22 | 23 | // Get acc and gyro signal 24 | console.log('Get gyro and acc signal'); 25 | let acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board) 26 | // For MMS 27 | let gyro = MetaWear.mbl_mw_gyro_bmi270_get_rotation_data_signal(device.board) 28 | // For MMRL, MMC, MMR 29 | //let gyro = MetaWear.mbl_mw_gyro_bmi160_get_rotation_data_signal(device.board) 30 | 31 | // Subscribe to the signals 32 | console.log('Set up stream.') 33 | MetaWear.mbl_mw_datasignal_subscribe(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 34 | var data = pointer.deref(); 35 | var value = data.parseValue(); 36 | console.log('epoch: ' + data.epoch + ' acc: ' + value.x + ' ' + value.y + ' ' + value.z) 37 | })) 38 | MetaWear.mbl_mw_datasignal_subscribe(gyro, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 39 | var data = pointer.deref(); 40 | var value = data.parseValue(); 41 | console.log('epoch: ' + data.epoch + ' gyro: ' + value.x + ' ' + value.y + ' ' + value.z) 42 | })) 43 | 44 | // Start the accelerometer 45 | console.log('Start accelerometer.') 46 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board) 47 | MetaWear.mbl_mw_acc_start(device.board) 48 | 49 | // Start the gyroscope 50 | console.log('Start gyroscope.') 51 | // For MMS 52 | MetaWear.mbl_mw_gyro_bmi270_enable_rotation_sampling(device.board) 53 | MetaWear.mbl_mw_gyro_bmi270_start(device.board) 54 | // Uncomment for MMRL, MMR, MMC 55 | //MetaWear.mbl_mw_gyro_bmi160_enable_rotation_sampling(device.board) 56 | //MetaWear.mbl_mw_gyro_bmi160_start(device.board) 57 | 58 | // End of terminal input 59 | process.openStdin().addListener("data", data => { 60 | console.log('Reset.') 61 | MetaWear.mbl_mw_debug_reset(device.board) 62 | setTimeout(function () { 63 | // Exit terminal 64 | process.exit(1); 65 | }, 2000); 66 | }) 67 | } 68 | 69 | // Run this example by putting the MAC address on the command line 70 | // sudo node stream_acc_gyro.js ea:78:c3:d3:f0:8a 71 | mainAsync(process.argv[2]) 72 | -------------------------------------------------------------------------------- /examples/stream_acc_gyro_packed.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var ref = require('ref-napi') 7 | 8 | async function mainAsync(mac) { 9 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 10 | await new Promise((resolve, reject) => { 11 | console.log('Connecting...') 12 | device.connectAndSetUp(error => { 13 | console.log('Connected.') 14 | if(error == null) resolve(null) 15 | else reject(error) 16 | }) 17 | }) 18 | 19 | let acc = MetaWear.mbl_mw_acc_get_packed_acceleration_data_signal(device.board) 20 | console.log('Set up stream acc .') 21 | MetaWear.mbl_mw_datasignal_subscribe(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 22 | var data = pointer.deref(); 23 | let value = data.parseValue() 24 | let entry = [value.x, value.y, value.z] 25 | console.log('epoch: ' + data.epoch + ' acc: ' + 'x: ' + entry[0].toFixed(3) + ' y: ' + entry[1].toFixed(3) + ' z: ' + entry[2].toFixed(3)) 26 | })) 27 | 28 | let gyro = MetaWear.mbl_mw_gyro_bmi270_get_packed_rotation_data_signal(device.board) 29 | 30 | console.log('Set up stream gyro.') 31 | MetaWear.mbl_mw_datasignal_subscribe(gyro, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 32 | var data = pointer.deref(); 33 | let value = data.parseValue() 34 | let entry = [value.x, value.y, value.z] 35 | console.log('epoch: ' + data.epoch + ' gyro: ' + 'x: ' + entry[0].toFixed(3) + ' y: ' + entry[1].toFixed(3) + ' z: ' + entry[2].toFixed(3)) 36 | })) 37 | 38 | console.log('Start accelerometer.') 39 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board) 40 | MetaWear.mbl_mw_acc_start(device.board) 41 | 42 | console.log('Start gyroscope.') 43 | MetaWear.mbl_mw_gyro_bmi270_enable_rotation_sampling(device.board) 44 | MetaWear.mbl_mw_gyro_bmi270_start(device.board) 45 | 46 | // Terminal on terminal input 47 | process.openStdin().addListener("data", data => { 48 | console.log('Reset.') 49 | MetaWear.mbl_mw_debug_reset(device.board) 50 | setTimeout(function () { 51 | // Exit terminal 52 | process.exit(1); 53 | }, 2000); 54 | }) 55 | } 56 | 57 | // Run this example by putting the MAC address on the command line 58 | // sudo node stream_acc_gyro_packed.js ea:78:c3:d3:f0:8a 59 | mainAsync(process.argv[2]) 60 | 61 | -------------------------------------------------------------------------------- /examples/stream_acc_packed.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var ref = require('ref') 7 | 8 | async function mainAsync(mac) { 9 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 10 | await new Promise((resolve, reject) => { 11 | console.log('Connecting...') 12 | device.connectAndSetUp(error => { 13 | console.log('Connected.') 14 | if(error == null) resolve(null) 15 | else reject(error) 16 | }) 17 | }) 18 | 19 | let acc = MetaWear.mbl_mw_acc_get_packed_acceleration_data_signal(device.board) 20 | console.log('Set up stream.') 21 | MetaWear.mbl_mw_datasignal_subscribe(acc, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 22 | var data = pointer.deref(); 23 | let value = data.parseValue() 24 | let entry = [value.x, value.y, value.z] 25 | console.log('epoch: ' + data.epoch + ' acc: ' + 'x: ' + entry[0].toFixed(3) + ' y: ' + entry[1].toFixed(3) + ' z: ' + entry[2].toFixed(3)) 26 | })) 27 | 28 | console.log('Start accelerometer.') 29 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board) 30 | MetaWear.mbl_mw_acc_start(device.board) 31 | 32 | // Terminal on terminal input 33 | process.openStdin().addListener("data", data => { 34 | console.log('Reset.') 35 | MetaWear.mbl_mw_debug_reset(device.board) 36 | setTimeout(function () { 37 | // Exit terminal 38 | process.exit(1); 39 | }, 2000); 40 | }) 41 | } 42 | 43 | // Run this example by putting the MAC address on the command line 44 | // sudo node stream_acc_packed.js ea:78:c3:d3:f0:8a 45 | mainAsync(process.argv[2]) 46 | 47 | -------------------------------------------------------------------------------- /examples/stream_acc_x.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var ref = require('ref-napi') 7 | 8 | // Main 9 | async function mainAsync(mac) { 10 | // Discover 11 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 12 | await new Promise((resolve, reject) => { 13 | console.log('Connecting...') 14 | // Connect 15 | device.connectAndSetUp(error => { 16 | console.log('Connected.') 17 | if(error == null) resolve(null) 18 | else reject(error) 19 | }) 20 | }) 21 | 22 | // Get acc 23 | console.log('Set up acc signal.'); 24 | let acc = MetaWear.mbl_mw_acc_get_acceleration_data_signal(device.board); 25 | 26 | // Keep only X component 27 | console.log('Get x component of acc.'); 28 | let acc_x = MetaWear.mbl_mw_datasignal_get_component(acc, 0); //cbindings.Const.ACC_ACCEL_X_AXIS_INDEX); 29 | 30 | // Subscribe to stream 31 | console.log('Set up stream.'); 32 | MetaWear.mbl_mw_datasignal_subscribe(acc_x, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 33 | var data = pointer.deref(); 34 | var value = data.parseValue(); 35 | console.log('epoch: ' + data.epoch + ' acc x: ' + value); 36 | })) 37 | 38 | // Start acc 39 | console.log('Start accelerometer.'); 40 | MetaWear.mbl_mw_acc_enable_acceleration_sampling(device.board); 41 | MetaWear.mbl_mw_acc_start(device.board); 42 | 43 | // Terminal on terminal input 44 | process.openStdin().addListener("data", data => { 45 | console.log('Reset.') 46 | MetaWear.mbl_mw_debug_reset(device.board) 47 | setTimeout(function () { 48 | // Exit terminal 49 | process.exit(1); 50 | }, 2000); 51 | }) 52 | } 53 | 54 | // Run this example by putting the MAC address on the command line 55 | // sudo node stream_acc_x.js ea:78:c3:d3:f0:8a 56 | mainAsync(process.argv[2]) 57 | -------------------------------------------------------------------------------- /examples/stream_baro_comp.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // Discover by MAC 10 | MetaWear.discoverByAddress('ea:78:c3:d3:f0:8a', function(device) { 11 | console.log('Discovered'); 12 | // Setup 13 | device.connectAndSetUp(async function (error) { 14 | console.log('Connected'); 15 | 16 | // Get pressure signal 17 | console.log('Get pressure'); 18 | var baro = MetaWear.mbl_mw_baro_bosch_get_pressure_data_signal(device.board); 19 | 20 | // Create a comparator to only allow pressure >= 102190 pascals to passthrough (5 is the opp type - see ComparatorOperation in binding file) 21 | var promise = new Promise((resolve, reject) => { 22 | var comparator = MetaWear.mbl_mw_dataprocessor_comparator_create(baro, 5, 102190.0, ref.NULL, MetaWear.FnVoid_VoidP_DataProcessorP.toPointer(function onSignal(context, comparator) {1 23 | console.log('comparator created'); 24 | resolve(comparator); 25 | })); 26 | }); 27 | let comparator = await promise; 28 | 29 | // Subscribe to it 30 | console.log('Subscribe'); 31 | MetaWear.mbl_mw_datasignal_subscribe(comparator, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((context, pointer) => { 32 | console.log('got data'); 33 | var data = pointer.deref(); 34 | var value = data.parseValue(); 35 | console.log('epoch: ' + data.epoch + ' pressure: ' + value); 36 | })); 37 | 38 | // Start timer 39 | console.log('Start'); 40 | MetaWear.mbl_mw_baro_bosch_start(device.board); 41 | 42 | // End on terminal input 43 | console.log('Press any key to exit'); 44 | process.stdin.setRawMode(true); 45 | process.stdin.resume(); 46 | process.stdin.on('data', () => { 47 | console.log('Disconnect'); 48 | MetaWear.mbl_mw_debug_reset(device.board); 49 | setTimeout(function () { 50 | // Exit terminal 51 | process.exit(1); 52 | }, 2000); 53 | }); 54 | }); 55 | }); 56 | 57 | -------------------------------------------------------------------------------- /examples/stream_gyro_packed.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var ref = require('ref-napi') 7 | 8 | async function mainAsync(mac) { 9 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 10 | await new Promise((resolve, reject) => { 11 | console.log('Connecting...') 12 | device.connectAndSetUp(error => { 13 | console.log('Connected.') 14 | if(error == null) resolve(null) 15 | else reject(error) 16 | }) 17 | }) 18 | 19 | // For MMS 20 | let gyro = MetaWear.mbl_mw_gyro_bmi270_get_packed_rotation_data_signal(device.board) 21 | // Uncomment for MMRL, MMR, MMC 22 | //let acc = MetaWear.mbl_mw_gyro_bmi160_get_packed_rotation_data_signal(device.board) 23 | 24 | console.log('Set up stream.') 25 | MetaWear.mbl_mw_datasignal_subscribe(gyro, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 26 | var data = pointer.deref(); 27 | let value = data.parseValue() 28 | let entry = [value.x, value.y, value.z] 29 | console.log('epoch: ' + data.epoch + ' gyro: ' + 'x: ' + entry[0].toFixed(3) + ' y: ' + entry[1].toFixed(3) + ' z: ' + entry[2].toFixed(3)) 30 | })) 31 | 32 | console.log('Start gyroscope.') 33 | // For MMS 34 | MetaWear.mbl_mw_gyro_bmi270_enable_rotation_sampling(device.board) 35 | MetaWear.mbl_mw_gyro_bmi270_start(device.board) 36 | // Uncomment for MMRL, MMR, MMC 37 | //MetaWear.mbl_mw_gyro_bmi160_enable_rotation_sampling(device.board) 38 | //MetaWear.mbl_mw_gyro_bmi160_start(device.board) 39 | 40 | // Terminal on terminal input 41 | process.openStdin().addListener("data", data => { 42 | console.log('Reset.') 43 | MetaWear.mbl_mw_debug_reset(device.board) 44 | setTimeout(function () { 45 | // Exit terminal 46 | process.exit(1); 47 | }, 2000); 48 | }) 49 | } 50 | 51 | // Run this example by putting the MAC address on the command line 52 | // sudo node stream_gyro_packed.js ea:78:c3:d3:f0:8a 53 | mainAsync(process.argv[2]) 54 | 55 | -------------------------------------------------------------------------------- /examples/stream_quat.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi') 8 | 9 | // Main 10 | async function mainAsync(mac) { 11 | // Discover 12 | var device = await new Promise((resolve, reject) => MetaWear.discoverByAddress(mac.toLowerCase(), d => resolve(d))) 13 | await new Promise((resolve, reject) => { 14 | console.log('Connecting...') 15 | // Connect + setup 16 | device.connectAndSetUp(error => { 17 | console.log('Connected.') 18 | if(error == null) resolve(null) 19 | else reject(error) 20 | }) 21 | }) 22 | 23 | // Setup gyro, acc, and sensor fusion settings 24 | MetaWear.mbl_mw_sensor_fusion_set_mode(device.board, 1); //SensorFusionMode.NDOF); 25 | MetaWear.mbl_mw_sensor_fusion_set_acc_range(device.board, 2 ); //SensorFusionAccRange._8G) 26 | MetaWear.mbl_mw_sensor_fusion_set_gyro_range(device.board, 0); //SensorFusionGyroRange._2000DPS) 27 | MetaWear.mbl_mw_sensor_fusion_write_config(device.board); 28 | 29 | // Get quaternion 30 | console.log('Get quat signal.'); 31 | let signal = MetaWear.mbl_mw_sensor_fusion_get_data_signal(device.board, 3); //See bindings - SensorFusionData.QUATERNION); 32 | 33 | // Stream quat 34 | console.log('Set up stream.'); 35 | MetaWear.mbl_mw_datasignal_subscribe(signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 36 | var data = pointer.deref(); 37 | var value = data.parseValue(); 38 | console.log('epoch: ' + data.epoch + ' quat: ' + value.x + ' ' + value.y + ' ' + value.z); 39 | })); 40 | 41 | // Start quat - setups acc/gyro/mag for you 42 | console.log('Start sensor fusion.'); 43 | MetaWear.mbl_mw_sensor_fusion_enable_data(device.board, 3); //See bindings - SensorFusionData.QUATERNION); 44 | MetaWear.mbl_mw_sensor_fusion_start(device.board); 45 | 46 | // Terminal on terminal input 47 | process.openStdin().addListener("data", data => { 48 | console.log('Reset.'); 49 | MetaWear.mbl_mw_sensor_fusion_stop(device.board); 50 | MetaWear.mbl_mw_datasignal_unsubscribe(signal); 51 | MetaWear.mbl_mw_debug_reset(device.board); 52 | setTimeout(function () { 53 | // Exit terminal 54 | process.exit(1); 55 | }, 2000); 56 | }); 57 | } 58 | 59 | // Run this example by putting the MAC address on the command line 60 | // sudo node stream_quat.js ea:78:c3:d3:f0:8a 61 | mainAsync(process.argv[2]) 62 | -------------------------------------------------------------------------------- /examples/stream_switch_count.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // Discover MAC 10 | MetaWear.discoverByAddress('f7:c0:14:1b:e5:86', function(device) { 11 | console.log('Discovered'); 12 | // Connect and setup 13 | device.connectAndSetUp(async function (error) { 14 | console.log('Connected'); 15 | 16 | // Get switch signal 17 | console.log('Get switch'); 18 | var switcher = MetaWear.mbl_mw_switch_get_state_data_signal(device.board); 19 | 20 | // Subscribe to it 21 | console.log('Subscribe'); 22 | MetaWear.mbl_mw_datasignal_subscribe(switcher, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 23 | console.log('got data'); 24 | var data = pointer.deref(); 25 | var value = data.parseValue(); 26 | console.log('epoch: ' + data.epoch + ' counter: ' + value); 27 | })); 28 | 29 | // Setup terminal to end on input 30 | console.log('Press any key to exit'); 31 | process.stdin.setRawMode(true); 32 | process.stdin.resume(); 33 | process.stdin.on('data', () => { 34 | console.log('Disconnect'); 35 | MetaWear.mbl_mw_debug_reset(device.board); 36 | setTimeout(function () { 37 | // Exit terminal 38 | process.exit(1); 39 | }, 2000); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /examples/stream_temp.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // Discover by MAC 10 | MetaWear.discoverByAddress('ea:78:c3:d3:f0:8a', function(device) { 11 | console.log('Discovered'); 12 | // Connect and setup 13 | device.connectAndSetUp(async function (error) { 14 | // Get temp signal 15 | console.log('Get temp signal'); 16 | var temp_signal = MetaWear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(device.board, 1); 17 | 18 | // Subscribe to it 19 | MetaWear.mbl_mw_datasignal_subscribe(temp_signal, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 20 | var data = pointer.deref(); 21 | var value = data.parseValue(); 22 | console.log('epoch: ' + data.epoch + ' temp: ' + value); 23 | })); 24 | 25 | // Read it once (only ONE time) 26 | MetaWear.mbl_mw_datasignal_read(temp_signal); 27 | 28 | // Terminal on any input in the terminal 29 | console.log('press any key to exit'); 30 | process.stdin.setRawMode(true); 31 | process.stdin.resume(); 32 | process.stdin.on('data', () => { 33 | console.log('disconnect'); 34 | MetaWear.mbl_mw_debug_reset(device.board); 35 | setTimeout(function () { 36 | // Exit terminal 37 | process.exit(1); 38 | }, 2000); 39 | }); 40 | }); 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /examples/stream_temp_timer.js: -------------------------------------------------------------------------------- 1 | // LOCAL 2 | var MetaWear = require('../index') 3 | // METAWEAR 4 | //require('metawear'); 5 | 6 | var cbindings = require('../MetaWear-SDK-Cpp/bindings/javascript/cbindings.js'); 7 | var ref = require('ref-napi'); 8 | 9 | // Discover by mac 10 | MetaWear.discoverByAddress('d1:e7:65:2a:ad:6f', function(device) { 11 | console.log('Discovered'); 12 | // Connect and setup 13 | device.connectAndSetUp(async function (error) { 14 | console.log('Connected'); 15 | 16 | // Get temp signal 17 | console.log('Get temp'); 18 | var temp = MetaWear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(device.board,1); 19 | 20 | // Subscribe to it 21 | console.log('Subscribe'); 22 | MetaWear.mbl_mw_datasignal_subscribe(temp, ref.NULL, MetaWear.FnVoid_VoidP_DataP.toPointer((ctx, pointer) => { 23 | console.log('got data'); 24 | var data = pointer.deref(); 25 | var value = data.parseValue(); 26 | console.log('epoch: ' + data.epoch + ' temp: ' + value); 27 | })); 28 | 29 | // Create a timer 30 | console.log('Create timer'); 31 | var promise = new Promise((resolve, reject) => { 32 | var timer = MetaWear.mbl_mw_timer_create_indefinite(device.board, 1000, 0, ref.NULL, MetaWear.FnVoid_VoidP_TimerP.toPointer(function onSignall(context, timer) { 33 | console.log('Timer created'); 34 | resolve(timer); 35 | })); 36 | }); 37 | let timer = await promise; 38 | 39 | // Create event based on timer and record as a command 40 | // The timer will read the temp signal every 1 second and repeat 41 | console.log('Record command'); 42 | MetaWear.mbl_mw_event_record_commands(timer); 43 | console.log('Command to read temp signal'); 44 | MetaWear.mbl_mw_datasignal_read(temp); 45 | console.log('End record command'); 46 | promise = new Promise((resolve, reject) => { 47 | var rec = MetaWear.mbl_mw_event_end_record(timer, ref.NULL, MetaWear.FnVoid_VoidP_EventP_Int.toPointer(function onSignal(context, dataPtr, lstatus) { 48 | console.log('Command created'); 49 | resolve(lstatus); 50 | })); 51 | }); 52 | let rec = await promise; 53 | 54 | // Start timer 55 | console.log('Start'); 56 | MetaWear.mbl_mw_timer_start(timer); 57 | 58 | // Terminal on any input in the terminal 59 | console.log('Press any key to exit'); 60 | process.stdin.setRawMode(true); 61 | process.stdin.resume(); 62 | process.stdin.on('data', () => { 63 | console.log('Disconnect'); 64 | MetaWear.mbl_mw_debug_reset(device.board); 65 | setTimeout(function () { 66 | // Exit terminal 67 | process.exit(1); 68 | }, 2000); 69 | }); 70 | }); 71 | }); 72 | 73 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var MetaWear = require('./lib/metawear'); 2 | 3 | module.exports = MetaWear; 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metawear", 3 | "version": "1.2.0", 4 | "author": "Laura Kassovic ", 5 | "license": "SEE LICENSE IN LICENSE", 6 | "description": "Official JavaScript SDK for MetaWear", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/mbientlab/MetaWear-SDK-JavaScript.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/mbientlab/MetaWear-SDK-JavaScript/issues" 13 | }, 14 | "keywords": [ 15 | "metawear", 16 | "mbientlab", 17 | "bluetooth", 18 | "ble", 19 | "sensors", 20 | "wearable" 21 | ], 22 | "main": "./index.js", 23 | "engines": { 24 | "node": ">=12.0.0 <13.0.0" 25 | }, 26 | "homepage": "https://github.com/mbientlab/MetaWear-SDK-JavaScript#readme", 27 | "dependencies": { 28 | "debug": "^2.6.9", 29 | "enum": "^2.5.0", 30 | "ffi-napi": "^4.0.3", 31 | "noble-device": "git+https://github.com/mbientlab/noble-device.git", 32 | "ref-array-di": "^1.2.2", 33 | "ref-napi": "^3.0.3", 34 | "ref-struct-di": "^1.1.1", 35 | "url-exists": "^1.0.3" 36 | }, 37 | "devDependencies": { 38 | "jshint": "^2.9.5", 39 | "mocha": "^9.2.1" 40 | }, 41 | "scripts": { 42 | "preinstall": "git submodule update --init --recursive", 43 | "install": "make OPT_FLAGS=-Wno-strict-aliasing -C MetaWear-SDK-Cpp/ -j", 44 | "uninstall": "make -C MetaWear-SDK-Cpp/ clean", 45 | "pretest": "jshint *.js lib/. test/.", 46 | "test": "mocha" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var MetaWear = require('../lib/metawear'); 3 | 4 | function Peripheral() { 5 | this.address = 'fa:55:aa:55:aa:55'; 6 | this.id = this.address; 7 | this.uuid = this.address; 8 | } 9 | 10 | describe('MetaWear', function () { 11 | it('should be able to create MetaWear object', function () { 12 | var device = new MetaWear(new Peripheral()); 13 | assert.equal('fa:55:aa:55:aa:55', device.address); 14 | }); 15 | }); --------------------------------------------------------------------------------