├── .gitignore ├── LICENSE ├── README.md ├── examples ├── test-async.js └── test.js ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 emersion 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-i2c-mpu6050 2 | 3 | Read data from MPU6050 with i2c. 4 | 5 | ```js 6 | var i2c = require('i2c-bus'); 7 | var MPU6050 = require('i2c-mpu6050'); 8 | 9 | var address = 0x68; 10 | var i2c1 = i2c.openSync(1); 11 | 12 | var sensor = new MPU6050(i2c1, address); 13 | 14 | var data = sensor.readSync(); 15 | console.log(data); 16 | ``` 17 | 18 | Values are in degrees. 19 | 20 | ## Docs 21 | 22 | * MPU6050 datasheet: https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf 23 | * MPU6050 on I2Cdevlib: http://www.i2cdevlib.com/devices/mpu6050#registers 24 | * How to set up i2c:https://learn.adafruit.com/adafruits-raspberry-pi-lesson-4-gpio-setup/configuring-i2c 25 | * Allow i2c to be used without root privileges: `sudo usermod -G i2c pi` then logout and login 26 | -------------------------------------------------------------------------------- /examples/test-async.js: -------------------------------------------------------------------------------- 1 | var i2c = require('i2c-bus'); 2 | var MPU6050 = require('..'); 3 | 4 | var address = 0x68; 5 | var i2c1 = i2c.open(1, function (err) { 6 | if (err) throw err; 7 | 8 | var sensor = MPU6050(i2c1, address); 9 | 10 | (function read() { 11 | sensor.read(function (err, data) { 12 | if (err) throw err; 13 | console.log(data); 14 | read(); 15 | }); 16 | }()); 17 | }); -------------------------------------------------------------------------------- /examples/test.js: -------------------------------------------------------------------------------- 1 | var i2c = require('i2c-bus'); 2 | var MPU6050 = require('..'); 3 | 4 | var address = 0x68; 5 | var i2c1 = i2c.openSync(1); 6 | 7 | var sensor = new MPU6050(i2c1, address); 8 | 9 | var data = sensor.readSync(); 10 | console.log(data); 11 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var async = require('async'); 2 | 3 | // Registers 4 | var POWER_MGMT_1 = 0x6b, 5 | POWER_MGMT_2 = 0x6c; 6 | var ACCEL_XOUT = 0x3b, 7 | ACCEL_YOUT = 0x3d, 8 | ACCEL_ZOUT = 0x3f; 9 | var TEMP_OUT = 0x41; 10 | var GYRO_XOUT = 0x43, 11 | GYRO_YOUT = 0x45, 12 | GYRO_ZOUT = 0x47; 13 | 14 | var ACCEL_LSB_SENSITIVITY = 16384, 15 | GYRO_LSB_SENSITIVITY = 131; 16 | 17 | function toDegrees(angle) { 18 | return angle * (180 / Math.PI); 19 | } 20 | 21 | function dist(a, b) { 22 | return Math.sqrt(a*a + b*b); 23 | } 24 | 25 | function getRotation(a, b, c) { 26 | var radians = Math.atan2(a, dist(b, c)); 27 | return -toDegrees(radians); 28 | } 29 | function getXRotation(x, y, z) { 30 | return getRotation(y, x, z); 31 | } 32 | function getYRotation(x, y, z) { 33 | return getRotation(x, y, z); 34 | } 35 | 36 | function scaleData(data, factor) { 37 | var scaled = {}; 38 | for (var axis in data) { 39 | scaled[axis] = data[axis] / factor; 40 | } 41 | return scaled; 42 | } 43 | 44 | function applyCalibration(data, cal) { 45 | if (!cal) return data; 46 | 47 | for (var axis in data) { 48 | if (cal[axis] && typeof cal[axis] == 'number') { 49 | data[axis] += cal[axis]; 50 | } 51 | } 52 | return data; 53 | } 54 | 55 | 56 | function Sensor(bus, address) { 57 | if (!(this instanceof Sensor)) { 58 | return new Sensor(bus, address); 59 | } 60 | 61 | this.bus = bus; 62 | this.address = address; 63 | this.calibration = {}; 64 | 65 | // Now wake the MPU6050 up as it starts in sleep mode 66 | bus.writeByteSync(address, POWER_MGMT_1, 0); 67 | } 68 | 69 | Sensor.prototype.calibrateGyro = function (cal) { 70 | this.calibration.gyro = cal; 71 | }; 72 | Sensor.prototype.calibrateAccel = function (cal) { 73 | this.calibration.accel = cal; 74 | }; 75 | 76 | Sensor.prototype.readWord = function (cmd, done) { 77 | var high, low; 78 | var that = this; 79 | async.series([ 80 | function (cb) { 81 | that.bus.readByte(that.address, cmd, function (err, value) { 82 | high = value; 83 | cb(err); 84 | }); 85 | }, 86 | function (cb) { 87 | that.bus.readByte(that.address, cmd + 1, function (err, value) { 88 | low = value; 89 | cb(err); 90 | }); 91 | } 92 | ], function (err) { 93 | if (err) return done(err); 94 | 95 | var value = (high << 8) + low; 96 | done(null, value); 97 | }); 98 | }; 99 | 100 | Sensor.prototype.readWordSync = function (cmd) { 101 | var high = this.bus.readByteSync(this.address, cmd); 102 | var low = this.bus.readByteSync(this.address, cmd+1); 103 | var value = (high << 8) + low; 104 | return value; 105 | }; 106 | 107 | Sensor.prototype.readWord2c = function (cmd, done) { 108 | this.readWord(cmd, function (err, value) { 109 | if (err) return done(err); 110 | 111 | if (value >= 0x8000) { 112 | done(null, -((65535 - value) + 1)); 113 | } else { 114 | done(null, value); 115 | } 116 | }); 117 | }; 118 | 119 | Sensor.prototype.readWord2cSync = function (cmd) { 120 | var value = this.readWordSync(cmd); 121 | if (value >= 0x8000) { 122 | return -((65535 - value) + 1); 123 | } else { 124 | return value; 125 | } 126 | }; 127 | 128 | Sensor.prototype.readGyro = function (done) { 129 | var data = {}; 130 | 131 | var that = this; 132 | async.series([ 133 | function (cb) { 134 | that.readWord2c(GYRO_XOUT, function (err, value) { 135 | data.x = value; 136 | cb(err); 137 | }); 138 | }, 139 | function (cb) { 140 | that.readWord2c(GYRO_YOUT, function (err, value) { 141 | data.y = value; 142 | cb(err); 143 | }); 144 | }, 145 | function (cb) { 146 | that.readWord2c(GYRO_ZOUT, function (err, value) { 147 | data.z = value; 148 | cb(err); 149 | }); 150 | } 151 | ], function (err) { 152 | if (err) return done(err); 153 | 154 | data = scaleData(data, GYRO_LSB_SENSITIVITY); 155 | data = applyCalibration(data, that.calibration.gyro); 156 | done(null, data); 157 | }); 158 | }; 159 | 160 | Sensor.prototype.readGyroSync = function () { 161 | var data = { 162 | x: this.readWord2cSync(GYRO_XOUT), 163 | y: this.readWord2cSync(GYRO_YOUT), 164 | z: this.readWord2cSync(GYRO_ZOUT) 165 | }; 166 | data = scaleData(data, GYRO_LSB_SENSITIVITY); 167 | data = applyCalibration(data, this.calibration.gyro); 168 | return data; 169 | }; 170 | 171 | Sensor.prototype.readAccel = function (done) { 172 | var data = {}; 173 | 174 | var that = this; 175 | async.series([ 176 | function (cb) { 177 | that.readWord2c(ACCEL_XOUT, function (err, value) { 178 | data.x = value; 179 | cb(err); 180 | }); 181 | }, 182 | function (cb) { 183 | that.readWord2c(ACCEL_YOUT, function (err, value) { 184 | data.y = value; 185 | cb(err); 186 | }); 187 | }, 188 | function (cb) { 189 | that.readWord2c(ACCEL_ZOUT, function (err, value) { 190 | data.z = value; 191 | cb(err); 192 | }); 193 | } 194 | ], function (err) { 195 | if (err) return done(err); 196 | 197 | data = scaleData(data, ACCEL_LSB_SENSITIVITY); 198 | data = applyCalibration(data, that.calibration.accel); 199 | done(null, data); 200 | }); 201 | }; 202 | 203 | Sensor.prototype.readAccelSync = function () { 204 | var data = { 205 | x: this.readWord2cSync(ACCEL_XOUT), 206 | y: this.readWord2cSync(ACCEL_YOUT), 207 | z: this.readWord2cSync(ACCEL_ZOUT) 208 | }; 209 | data = scaleData(data, ACCEL_LSB_SENSITIVITY); 210 | data = applyCalibration(data, this.calibration.accel); 211 | return data; 212 | }; 213 | 214 | Sensor.prototype.readTemp = function (done) { 215 | this.readWord2c(TEMP_OUT, function (err, value) { 216 | if (err) return done(err); 217 | var temp = value / 340 + 36.53; // In degrees Celcius 218 | done(null, temp); 219 | }); 220 | }; 221 | 222 | Sensor.prototype.readTempSync = function () { 223 | return this.readWord2cSync(TEMP_OUT) / 340 + 36.53; 224 | }; 225 | 226 | Sensor.prototype.readRotation = function (done) { 227 | this.readAccel(function (err, accel) { 228 | if (err) return done(err); 229 | 230 | done(null, { 231 | x: getXRotation(accel.x, accel.y, accel.z), 232 | y: getYRotation(accel.x, accel.y, accel.z) 233 | }); 234 | }); 235 | }; 236 | 237 | Sensor.prototype.readRotationSync = function (accel) { 238 | if (!accel) { 239 | accel = this.readAccelSync(); 240 | } 241 | 242 | return { 243 | x: getXRotation(accel.x, accel.y, accel.z), 244 | y: getYRotation(accel.x, accel.y, accel.z) 245 | }; 246 | }; 247 | 248 | Sensor.prototype.readSync = function () { 249 | var gyro = this.readGyroSync(); 250 | var accel = this.readAccelSync(); 251 | var rotation = this.readRotationSync(accel); 252 | var temp = this.readTempSync(); 253 | 254 | return { 255 | gyro: gyro, 256 | accel: accel, 257 | rotation: rotation, 258 | temp: temp 259 | }; 260 | }; 261 | 262 | Sensor.prototype.read = function (done) { 263 | var gyro, accel, rotation, temp; 264 | var that = this; 265 | async.series([ 266 | function (cb) { 267 | that.readGyro(function (err, data) { 268 | gyro = data; 269 | cb(err); 270 | }); 271 | }, 272 | function (cb) { 273 | that.readAccel(function (err, data) { 274 | accel = data; 275 | cb(err); 276 | }); 277 | }, 278 | function (cb) { 279 | that.readTemp(function (err, data) { 280 | temp = data; 281 | cb(err); 282 | }); 283 | } 284 | ], function (err) { 285 | if (err) return done(err); 286 | 287 | rotation = that.readRotationSync(accel); 288 | 289 | done(null, { 290 | gyro: gyro, 291 | accel: accel, 292 | rotation: rotation, 293 | temp: temp 294 | }); 295 | }); 296 | }; 297 | 298 | module.exports = Sensor; 299 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "i2c-mpu6050", 3 | "version": "2.3.0", 4 | "description": "Read data from MPU6050 with i2c", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/emersion/node-i2c-mpu6050.git" 12 | }, 13 | "keywords": [ 14 | "mpu6050", 15 | "raspberry", 16 | "pi", 17 | "i2c" 18 | ], 19 | "author": "emersion", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/emersion/node-i2c-mpu6050/issues" 23 | }, 24 | "homepage": "https://github.com/emersion/node-i2c-mpu6050", 25 | "dependencies": { 26 | "async": "^0.9.0" 27 | } 28 | } 29 | --------------------------------------------------------------------------------