Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

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.0.5 to 0.0.6

COPYRIGHT

50

examples/accelerometer-change-rates.js

@@ -9,29 +9,31 @@ /*********************************************

var tessel = require('tessel');
var accel = require('../').connect(tessel.port("A"));
var accel = require('../').use(tessel.port("A"));
// Initialize the accelerometer.
accel.on('connected', function () {
// Stream accelerometer data
accel.on('data', function (xyz) {
console.log("x:", xyz[0].toFixed(2),
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));
});
//After two seconds, stop streaming
setTimeout(function () {
console.log('Stopping stream')
accel.removeAllListeners('data', function () {
console.log('listener removed')
//After two more seconds, change stream rate, then stream again
setTimeout(function () {
console.log('Changing poll frequency')
accel.setPollFrequency(1000); // every 1 second (default is 10x/second)
accel.on('data', function (xyz) {
console.log("x:", xyz[0].toFixed(2),
"y:", xyz[1].toFixed(2),
"z:", xyz[2].toFixed(2));
});
}, 2000);
});
}, 2000);
});
});
//After two seconds, change stream rate, then stream again
setTimeout(function () {
console.log('Changing the output rate...');
accel.removeAllListeners('data');
// Setting the output data rate in Hz
accel.setOutputRate(1.56, function rateSet() {
accel.on('data', function (xyz) {
console.log("slower rate x:", xyz[0].toFixed(2),
"slower rate y:", xyz[1].toFixed(2),
"slower rate z:", xyz[2].toFixed(2));
});
});
}, 2000);
});
accel.on('error', function(err) {
console.log('there was an error', err);
});
setInterval(function() {}, 20000);

@@ -7,12 +7,19 @@ /*********************************************

var tessel = require('tessel');
var accel = require('../').connect(tessel.port("A"));
var accel = require('../').use(tessel.port("A"));
// Initialize the accelerometer.
accel.on('connected', function () {
accel.on('ready', function () {
// Stream accelerometer data
accel.on('data', function (xyz) {
console.log("x:", xyz[0].toFixed(2),
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 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;
/**
* MMA
*/
function Accelerometer (hardware)
function Accelerometer (hardware, callback)
{
var self = this;
// Command Queue
self.queue = new queue();
// Port assignment
self.hardware = hardware;
self.numListeners = 0;
self.listening = false;
self.pollFrequency = 100;
// 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);
self.i2c = new hardware.I2C(I2C_ADDRESS);
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
// 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);
}
// 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
});
// 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);
return;
}
});
}
});
// If we get a new listener
// Set up an interrupt handler for data ready
self.dataInterrupt.watch('low', self.dataReady.bind(self));
self.on('newListener', function(event) {
if (event == "data") {
// Add to the number of things listening
self.numListeners += 1;
// If we're not already listening
if (!self.listening) {
// Start listening
self.setListening();
// If we have a new data listener
if (event === 'data') {
// And the count was previously zero
if (self.listeners('event').length === 0) {
// Enable interrupts at whatever rate was previously set
self.enableDataInterrupts(true, queueNext);
}

@@ -74,62 +96,50 @@ }

// If we remove a listener
self.on('removeListener', function(event) {
if (event == "data") {
// Remove from the number of things listening
console.log('prev listeners', self.numListeners);
self.numListeners -= 1;
console.log('now', self.numListeners);
// Because we listen in a while loop, if this.listening goes to 0, we'll stop listening automatically
if (self.numListeners < 1) {
self.listening = 0;
// If we have a new data listener
if (event === 'data') {
// And the count was previously zero
if (self.listeners(event).length === 0) {
// Set the default rate of output
self.enableDataInterrupts(false, queueNext);
}
}
});
// If all listeners removed
self.on('removeAllListeners', function(event) {
self.numListeners = 0;
self.listening = 0;
});
});
}
util.inherits(Accelerometer, EventEmitter)
util.inherits(Accelerometer, EventEmitter);
Accelerometer.prototype._readRegisters = function (addressToRead, bytesToRead, next)
Accelerometer.prototype.failProcedure = function(err, callback) {
var self = this;
// Emit the error
setImmediate(function emitErr() {
self.emit('error', err);
});
// Call the callback
if (callback) callback(err);
return;
};
Accelerometer.prototype._readRegisters = function (addressToRead, bytesToRead, callback)
{
this.i2c.transfer(new Buffer([addressToRead]), bytesToRead, next);
}
this.i2c.transfer(new Buffer([addressToRead]), bytesToRead, callback);
};
Accelerometer.prototype._readRegister = function (addressToRead, next)
Accelerometer.prototype._readRegister = function (addressToRead, callback)
{
this._readRegisters(addressToRead, 1, function (err, regs) {
next(err, regs && regs[0]);
callback(err, regs && regs[0]);
});
}
};
// Write a single byte to the register.
Accelerometer.prototype._writeRegister = function (addressToWrite, dataToWrite, next)
Accelerometer.prototype._writeRegister = function (addressToWrite, dataToWrite, callback)
{
this.i2c.send(new Buffer([addressToWrite, dataToWrite]), next);
}
this.i2c.send(new Buffer([addressToWrite, dataToWrite]), callback);
};
Accelerometer.prototype.setListening = function () {
var self = this;
self.listening = true;
// Loop until nothing is listening
self.listeningLoop = setInterval (function () {
if (self.numListeners) {
self.getAcceleration(function (err, xyz) {
if (err) throw err;
self.emit('data', xyz);
});
} else {
clearInterval(listeningLoop);
}
}, self.pollFrequency);
}
// Sets the MMA8452 to standby mode. It must be in standby to change most register settings
Accelerometer.prototype.modeStandby = function (next)
Accelerometer.prototype.modeStandby = function (callback)
{

@@ -139,8 +149,13 @@ var self = this;

self._readRegister(CTRL_REG1, function (err, c) {
self._writeRegister(CTRL_REG1, c & ~(0x01), next);
})
}
if (err) {
return self.failProcedure(err, callback);
}
else {
return self._writeRegister(CTRL_REG1, c & ~(0x01), callback);
}
});
};
// 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)
{

@@ -150,43 +165,241 @@ var self = this;

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)
Accelerometer.prototype.getAcceleration = function (callback)
{
var self = this;
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
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
// 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
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));
}
out[i] = gCount / ((1<<12)/(2*GSCALE));
callback(null, out);
setImmediate(self.queue.next);
});
});
};
// 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.availableOutputRates = function() {
// Available interrupt rates in Hz
return [800, 400, 200, 100, 50, 12.5, 6.25, 1.56];
};
Accelerometer.prototype.availableScaleRanges = function() {
// Available accelerometer ranges (in units of Gs)
// The higher the range, the less accurate the readings are
return [2, 4, 8];
};
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;
}
}
next(null, out);
// 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]);
};
Accelerometer.prototype._changeRegister = function(change, callback) {
var self = this;
// 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);
}
});
}
});
}
};
// Sets the polling frequency for streamed data (default 100ms)
Accelerometer.prototype.setPollFrequency = function (milliseconds) {
// Sets the output rate of the data (1.56-800 Hz)
Accelerometer.prototype.setOutputRate = function (hz, callback) {
var self = this;
self.pollFrequency = milliseconds;
if (self.listening) {
clearInterval(self.listeningLoop);
self.setListening();
}
}
// 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);
});
});
};
Accelerometer.prototype.enableDataInterrupts = function(enable, callback) {
var self = this;
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);
});
});
};
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);
});
});
};
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);
}
self.dataInterrupt.watch('low', self.dataReady.bind(self));
});
};
exports.Accelerometer = Accelerometer;
exports.connect = function (hardware) {
return new Accelerometer(hardware);
exports.use = function (hardware, callback) {
return new Accelerometer(hardware, callback);
};
{
"name": "accel-mma84",
"version": "0.0.5",
"version": "0.0.6",
"description": "Library to run the MMA8452Q accelerometer.",

@@ -9,2 +9,5 @@ "main": "index.js",

},
"dependencies" : {
"sync-queue" : "0.0.1"
},
"hardware": {

@@ -11,0 +14,0 @@ "./examples": false

@@ -14,15 +14,17 @@ #Accelerometer

console.log("Connecting to accelerometer on port bank A");
var accel = require('accel-mma84').connect(tessel.port("A"));
var accel = require('accel-mma84').use(tessel.port("A"));
// Initialize the accelerometer.
accel.on('connected', function () {
// Loop forever.
setInterval(function () {
accel.getAcceleration(function (err, xyz) {
console.log("x:", xyz[0].toFixed(2),
"y:", xyz[1].toFixed(2),
"z:", xyz[2].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));
});
});
accel.on('error', function(err) {
console.log("Unable to connect to module: ", err);
})
```

@@ -32,10 +34,18 @@

* **`accel`.initialize()**
* **`accel`.getAcceleration(callback(err, xyz))**
* **`accel`.setOutputRate(rateInHz, callback(err, xyz))**
* **`accel`.availableOutputRates()**
* **`accel`.setScaleRange(scaleRange, callback(err, xyz))**
* **`accel`.availableScaleRanges()**
##Events
* *connected*
* *ready*
* *error*
* *data*

@@ -42,0 +52,0 @@

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