Socket
Socket
Sign inDemoInstall

accel-mma84

Package Overview
Dependencies
Maintainers
2
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

accel-mma84 - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

COPYRIGHT

32

examples/accelerometer.js

@@ -1,13 +0,23 @@

var accel = require('../').connect(myhardwareapi);
/*********************************************
This basic accelerometer example logs a stream
of x, y, and z data from the accelerometer
*********************************************/
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
var tessel = require('tessel');
var accel = require('../').use(tessel.port['A']); // Replace '../' with 'accel-mma84' in your own code
// Initialize the accelerometer.
accel.on('connected', function () {
// Loop forever.
setInterval(function () {
accel.getAcceleration(function (err, xyz) {
console.log("x:", xyz.x.toFixed(2),
"y:", xyz.y.toFixed(2),
"z:", xyz.z.toFixed(2));
});
}, 100);
});
accel.on('ready', function () {
// Stream accelerometer data
accel.on('data', function (xyz) {
console.log('x:', xyz[0].toFixed(2),
'y:', xyz[1].toFixed(2),
'z:', xyz[2].toFixed(2));
});
});
setInterval(function(){}, 20000);
var util = require('util');
var EventEmitter = require('events').EventEmitter;
var queue = require('sync-queue');
// Copyright 2014 Technical Machine, Inc. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/**
* Configuration
*/
// The SparkFun breakout board defaults to 1, set to 0 if SA0 jumper on the bottom of the board is set
var I2C_ADDRESS = 0x1D // 0x1D if SA0 is high, 0x1C if low
var I2C_ADDRESS = 0x1D; // 0x1D if SA0 is high, 0x1C if low
// Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values.
var GSCALE = 2
// See the many application notes for more info on setting all of these registers:
// http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA8452Q
// MMA8452 registers
var OUT_X_MSB = 0x01
var XYZ_DATA_CFG = 0x0E
var WHO_AM_I = 0x0D
var CTRL_REG1 = 0x2A
var OUT_X_MSB = 0x01;
var XYZ_DATA_CFG = 0x0E;
var WHO_AM_I = 0x0D;
var CTRL_REG1 = 0x2A;
var CTRL_REG4 = 0x2D;
function Accelerometer (hardware, callback) {
var self = this;
// Command Queue
self.queue = new queue();
// Port assignment
self.hardware = hardware;
// Rate at which data is collected and is ready to be read
self.outputRate = 12.5;
// Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values.
self.scaleRange = 2;
// Interrupt pin for the data ready event
self.dataInterrupt = self.hardware.gpio(2);
// Address for i2C
// TODO: Account for manual address changes?
self.i2c = hardware.I2C(I2C_ADDRESS);
/**
* MMA
*/
// Check that we can read the correct chip id
self._getChipID(function IDRead(err, c) {
if (err) {
// Fail the init
return self._failProcedure(err);
}
// should always return 0x2A
if (c !== 0x2A) {
// This is the wrong chip
err = new Error("Could not connect to MMA8452Q, received " + c.toString() + ". Expected 0x2A.");
// Fail the init
return self._failProcedure(err);
}
// Set the scale range to standard
self.setScaleRange(self.scaleRange, function(err) {
if (err) {
return self._failProcedure(err, callback);
}
else {
// Set the output rate to standard
self.setOutputRate(self.outputRate, function(err) {
if (err) {
return self._failProcedure(err, callback);
}
else {
// Emit the ready event
setImmediate(function emitReady() {
self.emit('ready');
});
// Call the callback with object
if (callback) callback(null, self);
function Accelerometer (hardware)
{
var self = this;
return;
}
});
}
});
this.hardware = hardware;
// Set up an interrupt handler for data ready
self.dataInterrupt.watch('low', self._dataReady.bind(self));
self.i2c = new hardware.I2C(I2C_ADDRESS);
self.i2c.initialize();
self.on('newListener', function(event) {
// If we have a new sample listener
if (event == 'data' || event == 'sample') {
// Enable interrupts at whatever rate was previously set.
self.enableDataInterrupts(true, queueNext);
}
});
self._readRegister(WHO_AM_I, function (err, c) {
if (c == 0x2A) { // WHO_AM_I should always return 0x2A
console.log("MMA8452Q is online...");
} else {
console.log("Could not connect to MMA8452Q, received", c);
while (1) { continue; } // Loop forever if communication doesn't happen
}
// Must be in standby to change registers
self.modeStandby(function () {
// Set up the full scale range to 2, 4, or 8g.
var fsr = GSCALE;
if (fsr > 8) fsr = 8; //Easy error check
fsr >>= 2; // Neat trick, see page 22. 00 = 2G, 01 = 4A, 10 = 8G
self._writeRegister(XYZ_DATA_CFG, fsr, function () {
// The default data rate is 800Hz and we don't modify it in this example code
self.modeActive(function () {
self.emit('connected');
}); // Set to active to start reading
});
self.on('removeListener', function(event) {
// If we have a new || event == 'sample' listener
if (event == 'data' || event == 'sample') {
// Disable interrupt.
self.enableDataInterrupts(false, queueNext);
}
});
})
});
}
util.inherits(Accelerometer, EventEmitter)
util.inherits(Accelerometer, EventEmitter);
Accelerometer.prototype._readRegisters = function (addressToRead, bytesToRead, next)
{
this.i2c.transfer([addressToRead], bytesToRead, next);
}
Accelerometer.prototype._changeRegister = function(change, callback) {
var self = this;
Accelerometer.prototype._readRegister = function (addressToRead, next)
{
this._readRegisters(addressToRead, 1, function (err, regs) {
next(err, regs && regs[0]);
// Put the accelerometer into standby
self._modeStandby(function inStandby(err) {
if (err) {
return self._failProcedure(err, callback);
}
else {
// Make whatever change was requested
change( function setActive(err) {
if (err) {
return self._failProcedure(err, callback);
}
else {
// Put the accelerometer back into active mode
self._modeActive(callback);
}
});
}
});
}
};
// Write a single byte to the register.
Accelerometer.prototype._writeRegister = function (addressToWrite, dataToWrite, next)
{
this.i2c.send([addressToWrite, dataToWrite], next);
}
Accelerometer.prototype._dataReady = function() {
var self = this;
// Data is ready so grab the data
self.getAcceleration(function(err, xyz) {
// If we had an error, emit it
if (err) {
// Emitting error
self.emit('error', err);
}
// If there was no error
else {
// Emit the data
self.emit('data', xyz); // old-style, deprecated
self.emit('sample', xyz);
}
// Sets the MMA8452 to standby mode. It must be in standby to change most register settings
Accelerometer.prototype.modeStandby = function (next)
{
self.dataInterrupt.watch('low', self._dataReady.bind(self));
});
};
Accelerometer.prototype._failProcedure = function(err, callback) {
var self = this;
// Clear the active bit to go into standby
self._readRegister(CTRL_REG1, function (err, c) {
self._writeRegister(CTRL_REG1, c & ~(0x01), next);
})
}
// Emit the error
setImmediate(function emitErr() {
self.emit('error', err);
});
// Call the callback
if (callback) callback(err);
return;
};
// Get the id of the chip
Accelerometer.prototype._getChipID = function(callback) {
this._readRegister(WHO_AM_I, function (err, c) {
if (callback) callback(err, c);
});
};
Accelerometer.prototype._getClosestOutputRate = function(requestedRate, callback) {
// If a negative number is requested, stop output (0 hz)
if (requestedRate < 0) requestedRate = 0;
// If 0 hz is requested, return just that so that output will be stopped
if (requestedRate === 0) {
if (callback) callback(null, 0);
return;
}
// Get the available rates
var available = this.availableOutputRates();
// Iterate through each
for (var i = 0; i < available.length; i++) {
// The first available rate less than or equal to requested is a match
if (available[i] <= requestedRate) {
// Send the match back
if (callback) callback(null, available[i]);
return;
}
}
// If there were no match, this number must be between 0 and 1.56. Use 1.56
if (callback) callback(null, available[available.length-1]);
};
// Sets the MMA8452 to active mode. Needs to be in this mode to output data
Accelerometer.prototype.modeActive = function (next)
{
Accelerometer.prototype._modeActive = function (callback) {
var self = this;
// Set the active bit to begin detection
self._readRegister(CTRL_REG1, function (err, c) {
self._writeRegister(CTRL_REG1, c | (0x01), next);
if (err) {
return _failProcedure(err);
}
else {
return self._writeRegister(CTRL_REG1, c | (0x01), callback);
}
});
}
};
Accelerometer.prototype.getAcceleration = function (next)
{
// Sets the MMA8452 to standby mode. It must be in standby to change most register settings
Accelerometer.prototype._modeStandby = function (callback) {
var self = this;
self._readRegisters(OUT_X_MSB, 6, function (err, rawData) {
// Loop to calculate 12-bit ADC and g value for each axis
var out = [], axes = ['x', 'y', 'z'];
for (var i = 0; i < 3 ; i++) {
var gCount = (rawData[i*2] << 8) | rawData[(i*2)+1]; //Combine the two 8 bit registers into one 12-bit number
// Clear the active bit to go into standby
self._readRegister(CTRL_REG1, function (err, c) {
if (err) {
return self._failProcedure(err, callback);
}
else {
return self._writeRegister(CTRL_REG1, c & ~(0x01), callback);
}
});
};
gCount = (gCount >> 4); //The registers are left align, here we right align the 12-bit integer
Accelerometer.prototype._readRegister = function (addressToRead, callback) {
this._readRegisters(addressToRead, 1, function (err, regs) {
callback(err, regs && regs[0]);
});
};
// If the number is negative, we have to make it so manually (no 12-bit data type)
if (rawData[i*2] > 0x7F) {
gCount = -(1 + 0xFFF - gCount); // Transform into negative 2's complement
Accelerometer.prototype._readRegisters = function (addressToRead, bytesToRead, callback) {
this.i2c.transfer(new Buffer([addressToRead]), bytesToRead, callback);
};
// Write a single byte to the register.
Accelerometer.prototype._writeRegister = function (addressToWrite, dataToWrite, callback) {
this.i2c.send(new Buffer([addressToWrite, dataToWrite]), callback);
};
// Logs the available interrupt rates in Hz
Accelerometer.prototype.availableOutputRates = function() {
return [800, 400, 200, 100, 50, 12.5, 6.25, 1.56];
};
// Logs the available accelerometer ranges (in units of Gs)
Accelerometer.prototype.availableScaleRanges = function() {
// The higher the range, the less accurate the readings are
return [2, 4, 8];
};
// Enables or disables data interrupts. Set the first param truthy to enable, false to disable.
Accelerometer.prototype.enableDataInterrupts = function(enable, callback) {
var self = this;
// Don't call unnecessarily.
if (this._dataInterrupts == !!enable) {
return callback && callback();
}
this._dataInterrupts = !!enable;
self.queue.place(function queueEnable() {
// We're going to change register 4
self._changeRegister(function change(complete) {
// Read the register first
self._readRegister(CTRL_REG4, function(err, reg4) {
if (err) {
return complete(err);
}
else {
// If we are enabling, set first bit to 1, else 0
var regVal = (enable ? (reg4 |= 1) : (reg4 &= ~1));
// Write to the register
self._writeRegister(CTRL_REG4, regVal, function(err) {
return complete(err);
});
}
});
}, function intSet(err) {
if (callback) {
callback(err);
}
setImmediate(self.queue.next);
});
});
};
out[axes[i]] = gCount / ((1<<12)/(2*GSCALE));
}
// Gets the acceleration from the device, outputs as array [x, y, z]
Accelerometer.prototype.getAcceleration = function (callback) {
var self = this;
next(null, out);
self.queue.place( function readAccel() {
self._readRegisters(OUT_X_MSB, 6, function (err, rawData) {
if (err) throw err;
// Loop to calculate 12-bit ADC and g value for each axis
var out = [];
for (var i = 0; i < 3 ; i++) {
var gCount = (rawData[i*2] << 8) | rawData[(i*2)+1]; // Combine the two 8 bit registers into one 12-bit number
gCount = (gCount >> 4); // The registers are left align, here we right align the 12-bit integer
// If the number is negative, we have to make it so manually (no 12-bit data type)
if (rawData[i*2] > 0x7F) {
gCount = -(1 + 0xFFF - gCount); // Transform into negative 2's complement
}
out[i] = gCount / ((1<<12)/(2*self.scaleRange));
}
callback(null, out);
setImmediate(self.queue.next);
});
});
};
// Sets the output rate of the data (1.56-800 Hz)
Accelerometer.prototype.setOutputRate = function (hz, callback) {
var self = this;
// Put accel into standby
self.queue.place(function addedQueue() {
self._changeRegister( function setRegisters(finishChange) {
// Find the closest available rate (rounded down)
self._getClosestOutputRate(hz, function gotRequested(err, closest) {
if (err) {
return finishChange(new Error("Rate must be >= 1.56Hz"));
}
else {
// Set our property
self.outputRate = closest;
// Get the binary representation of the rate (for the register)
var bin = self.availableOutputRates().indexOf(closest);
// If the binary rep could be found
if (bin !== -1) {
// Read the current register value
self._readRegister(CTRL_REG1, function readComplete(err, regVal) {
if (err) {
return finishChange(err);
}
else {
// Clear the three bits of output rate control (0b11000111 = 199)
regVal &= 199;
// Move the binary rep into place (bits 3:5)
if (bin !== 0) regVal |= (bin << 3);
// Write that value into the control register
self._writeRegister(CTRL_REG1, regVal, finishChange);
}
});
}
else {
return finishChange(new Error("Invalid output rate."));
}
}
});
},
function rateSet(err) {
if (callback) {
callback(err);
}
setImmediate(self.queue.next);
});
});
};
// Sets the accelerometer to read up to 2, 4, or 8 Gs of acceleration (smaller range = better precision)
Accelerometer.prototype.setScaleRange = function(scaleRange, callback) {
var self = this;
var fsr = scaleRange;
if (fsr > 8) fsr = 8; //Easy error check
fsr >>= 2; // Neat trick, see page 22. 00 = 2G, 01 = 4G, 10 = 8G
// Go into standby to edit registers
self.queue.place( function queueScale() {
self._changeRegister(function change(complete) {
if (err) {
return complete(err);
}
else {
// Write the new scale into the register
self._writeRegister(XYZ_DATA_CFG, fsr, function wroteReg(err) {
self.scaleRange = scaleRange;
return complete(err);
});
}
}, function scaleSet(err) {
if (callback) {
callback(err);
}
setImmediate(self.queue.next);
});
});
};
function use (hardware, callback) {
return new Accelerometer(hardware, callback);
}
exports.Accelerometer = Accelerometer;
exports.connect = function (hardware) {
return new Accelerometer(hardware);
};
exports.use = use;
{
"name": "accel-mma84",
"version": "0.1.0",
"version": "0.2.0",
"description": "Library to run the MMA8452Q accelerometer.",
"main": "index.js",
"dependencies" : {
"sync-queue" : "0.0.1"
},
"hardware": {
"./examples": false
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "./testsuite.js"
},
"repository": "",
"devDependencies": {
"tape": "~2.3.2",
"tap": "git+https://github.com/tcr/node-tap.git#3cb76e",
"shelljs": "~0.3.0"
},
"repository": "https://github.com/tessel/accel-mma84",
"author": "Tim Cameron Ryan <tim@timryan.org>",
"license": "MIT"
}

@@ -1,41 +0,68 @@

# MMA8452Q accelerometer driver
#Accelerometer
Driver for the accel-mma84 Tessel accelerometer module ([MMA8452Q](http://www.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf)).
Install:
##Installation
```sh
npm install accel-mma84
```
npm install accel-mmq84
```
Import:
##Example
```js
/*********************************************
This basic accelerometer example logs a stream
of x, y, and z data from the accelerometer
*********************************************/
var tessel = require('tessel');
var accel = require('accel-mma84').use(tessel.port['A']);
// Initialize the accelerometer.
accel.on('ready', function () {
// Stream accelerometer data
accel.on('data', function (xyz) {
console.log("x:", xyz[0].toFixed(2),
"y:", xyz[1].toFixed(2),
"z:", xyz[2].toFixed(2));
});
});
accel.on('error', function(err) {
console.log('error connecting', err);
});
setInterval(function(){}, 20000);
```
var accel = require('accel-mma84').connect(myhardwareapi);
```
Functions:
##Methods
* **`accel`.initialize()**
##### * `accel.availableOutputRates()` Logs the available interrupt rates in Hz.
* **`accel`.getAcceleration(callback(err, xyz))**
##### * `accel.availableScaleRanges()` Logs the available accelerometer ranges (in units of Gs).
## Example
##### * `accel.enableDataInterrupts(trueOrFalse, callback(err))` Enables or disables data interrupts. Set the first param truthy to enable, falsy to disable.
`
var accel = require('../').connect(myhardwareapi);
##### * `accel.getAcceleration(callback(err, xyz))` Gets the acceleration from the device, outputs as array [x, y, z].
// Initialize the accelerometer.
accel.on('connected', function () {
// Loop forever.
setInterval(function () {
accel.getAcceleration(function (err, xyz) {
console.log("x:", xyz.x.toFixed(2),
"y:", xyz.y.toFixed(2),
"z:", xyz.z.toFixed(2));
});
}, 100);
});
`
##### * `accel.setOutputRate(rateInHz, callback(err))` Sets the output rate of the data (1.56-800 Hz).
##### * `accel.setScaleRange(scaleRange, callback(err))` Sets the accelerometer to read up to 2, 4, or 8 Gs of acceleration (smaller range = better precision).
##Events
##### * `accel.on('data', callback(xyz))` Emitted when data is available. `xyz` is an array in the form of [x, y, z].
##### * `accel.on('error', callback(err))` Emitted upon error.
##### * `accel.on('ready', callback())` Emitted upon first successful communication between the Tessel and the module.
##Further Examples
See the examples folder for code.
* show-axes: Manipulate LEDs based on acceleration in the three axes.
* change-rates: Change the polling rate.
## License
MIT
MIT
APACHE

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc