Skip to content

Instantly share code, notes, and snippets.

@soundanalogous
Last active August 29, 2015 13:57
Show Gist options
  • Save soundanalogous/9861279 to your computer and use it in GitHub Desktop.
Save soundanalogous/9861279 to your computer and use it in GitHub Desktop.
Experimental BMA250 module for Breakout.js
/**
* Copyright (c) 2011-2014 Jeff Hoefs <[email protected]>
* Released under the MIT license. See LICENSE file for details.
*/
JSUTILS.namespace('BO.io.AccelerometerBMA250');
/**
* @namespace BO.io
*/
BO.io.AccelerometerBMA250 = (function () {
"use strict";
var AccelerometerBMA250;
// private static constants
var RAD_TO_DEG = 180 / Math.PI,
DATA_RANGE = 0x0f,
DATA_BANDWIDTH = 0x10,
DATAX0 = 0x02,
//ALL_AXIS = DATAX0 | 0x80, // not sure if this will work with BMA250
NUM_BYTES = 6;
// dependencies
var I2CBase = BO.I2CBase,
AccelerometerEvent = BO.io.AccelerometerEvent;
/**
* Creates an interface to an BMA250 3-axis accelerometer. Use the
* accelerometer to read the acceleration along the x, y, and z axis of an
* object it is attached to. You can also obtain the pitch and roll. See the
* example in [Breakout/examples/sensors/adxl345.html](https://github.com/soundanalogous/Breakout/blob/master/examples/sensors/adxl345.html).
*
* @class AccelerometerBMA250
* @constructor
* @extends BO.I2CBase
* @param {IOBoard} board The IOBoard instance
* @param {Number} range The dynamic range selection in Gs (options `RANGE_2G`, `RANGE_4G`,
* `RANGE_8G`, `RANGE_16G`). Default is `RANGE_2G`.
* @param {Number} bandwidth The bandwidth selection in Hz (options `)
* @param {Number} address The i2c address of the accelerometer (default is 0x18)
*/
AccelerometerBMA250 = function (board, range, bandwidth, address) {
address = address || AccelerometerBMA250.DEVICE_ID;
I2CBase.call(this, board, address);
this.name = "AccelerometerBMA250";
this._dynamicRange = range || AccelerometerBMA250.RANGE_2G;
this._bandwidth = bandwidth || AccelerometerBMA250.BAND_7_81HZ;
this._isReading = false;
this._debugMode = BO.enableDebugging;
this._x = 0;
this._y = 0;
this._z = 0;
this._rawX = 0;
this._rawY = 0;
this._rawZ = 0;
this.setBandwidth(this._bandwidth);
// sets the dynamic range
this.setRange(this._dynamicRange);
};
AccelerometerBMA250.prototype = JSUTILS.inherit(I2CBase.prototype);
AccelerometerBMA250.prototype.constructor = AccelerometerBMA250;
// Implement Acceleromter interface:
Object.defineProperties(AccelerometerBMA250.prototype, {
// Properties that apply to any accelereomter
/**
* [read-only] the accelerometer dynamic range in Gs (either 2G, 4G, 8G, or 16G for this sensor)..
* @property dynamicRange
* @type Number
*/
dynamicRange: {
get: function () {
return this._dynamicRange;
}
},
/**
* [read-only] the accelerometer bandwidth in Hz
* @property bandwidth
* @type Number
*/
bandwidth: {
get: function () {
return this._bandwidth;
}
},
/**
* [read-only] The acceleration value in Gs (9.8m/sec^2) along the x-axis.
* @property x
* @type Number
*/
x: {
get: function () {
return this._x;
}
},
/**
* [read-only] The acceleration value in Gs (9.8m/sec^2) along the y-axis.
* @property y
* @type Number
*/
y: {
get: function () {
return this._y;
}
},
/**
* [read-only] The acceleration value in Gs (9.8m/sec^2) along the z-axis.
* @property z
* @type Number
*/
z: {
get: function () {
return this._z;
}
},
/**
* [read-only] The pitch value in degrees
* @property pitch
* @type Number
*/
pitch: {
get: function () {
// -180 to 180
//return Math.atan2(this._x, this._z) * RAD_TO_DEG;
// -90 to 90
return Math.atan2(this._x, Math.sqrt(this._y * this._y + this._z * this._z)) * RAD_TO_DEG;
}
},
/**
* [read-only] The roll value in degrees
* @property roll
* @type Number
*/
roll: {
get: function () {
// -180 to 180
//return Math.atan2(this._y, this._z) * RAD_TO_DEG;
// -90 to 90
return Math.atan2(this._y, Math.sqrt(this._x * this._x + this._z * this._z)) * RAD_TO_DEG;
}
},
// Properties specific to this I2C Accelerometers:
/**
* [read-only] The raw value of the x axis
* @property rawX
* @type Number
*/
rawX: {
get: function () {
return this._rawX;
}
},
/**
* [read-only] The raw value of the y axis
* @property rawY
* @type Number
*/
rawY: {
get: function () {
return this._rawY;
}
},
/**
* [read-only] The raw value of the z axis
* @property rawZ
* @type Number
*/
rawZ: {
get: function () {
return this._rawZ;
}
},
/**
* [read-only] The state of continuous read mode. True if continuous read mode
* is enabled, false if it is disabled.
* @property isRunning
* @type Boolean
*/
isRunning: {
get: function () {
return this._isReading;
}
}
});
/**
* @private
* @method setRange
*/
AccelerometerBMA250.prototype.setRange = function (range) {
this.sendI2CRequest([I2CBase.WRITE, this._address, DATA_RANGE, range]);
};
/**
* @private
* @method setBandwidth
*/
AccelerometerBMA250.prototype.setBandwidth = function (bandwidth) {
this._bandwidth = bandwidth;
this.sendI2CRequest([I2CBase.WRITE, this._address, DATA_BANDWIDTH, this._bandwidth]);
};
/**
* @private
* @method handleI2C
*/
AccelerometerBMA250.prototype.handleI2C = function (data) {
// data[0] contains the register address. make sure we have a match
if (data[0] == DATAX0) {
this.readAccel(data);
}
};
/**
* Start continuous reading of the sensor.
* @method startReading
*/
AccelerometerBMA250.prototype.startReading = function () {
if (!this._isReading) {
this._isReading = true;
this.sendI2CRequest([I2CBase.READ_CONTINUOUS, this.address, DATAX0, NUM_BYTES]);
}
};
/**
* Stop continuous reading of the sensor.
* @method stopReading
*/
AccelerometerBMA250.prototype.stopReading = function () {
this._isReading = false;
this.sendI2CRequest([I2CBase.STOP_READING, this.address]);
};
/**
* Sends read request to accelerometer and updates accelerometer values.
* @method update
*/
AccelerometerBMA250.prototype.update = function () {
if (this._isReading) {
this.stopReading();
}
// read data: contents of X, Y, and Z registers
this.sendI2CRequest([I2CBase.READ, this.address, DATAX0, NUM_BYTES]);
};
/**
* @private
* @method readAccel
*/
AccelerometerBMA250.prototype.readAccel = function (data) {
var x_val,
y_val,
z_val;
if (data.length != NUM_BYTES + 1) {
throw new Error("Incorrect number of bytes returned");
}
x_val = ((data[2] << 8) | data[1]) >> 6;
y_val = ((data[4] << 8) | data[3]) >> 6;
z_val = ((data[6] << 8) | data[5]) >> 6;
this._rawX = x_val;
this._rawY = y_val;
this._rawZ = z_val;
// TO DO: set this._x, this._y, this._z in Gs
this.dispatchEvent(new AccelerometerEvent(AccelerometerEvent.UPDATE));
};
/**
* for debugging
* @private
*/
AccelerometerBMA250.prototype.debug = function (str) {
if (this._debugMode) {
console.log(str);
}
};
// public static constants
/**
* @property AccelerometerBMA250.RANGE_2G
* @static
*/
AccelerometerBMA250.RANGE_2G = 0x03;
/**
* @property AccelerometerBMA250.RANGE_4G
* @static
*/
AccelerometerBMA250.RANGE_4G = 0x05;
/**
* @property AccelerometerBMA250.RANGE_8G
* @static
*/
AccelerometerBMA250.RANGE_8G = 0x08;
/**
* @property AccelerometerBMA250.RANGE_16G
* @static
*/
AccelerometerBMA250.RANGE_16G = 0x0C;
/**
* @property AccelerometerBMA250.BAND_7_81HZ
* @static
*/
AccelerometerBMA250.BAND_7_81HZ = 0x08;
/**
* @property AccelerometerBMA250.BAND_15_63HZ
* @static
*/
AccelerometerBMA250.BAND_15_63HZ = 0x09;
/**
* @property AccelerometerBMA250.BAND_31_25HZ
* @static
*/
AccelerometerBMA250.BAND_31_25HZ = 0x0A;
/**
* @property AccelerometerBMA250.DEVICE_ID
* @static
*/
AccelerometerBMA250.DEVICE_ID = 0x18;
// document events
/**
* The update event is dispatched when the accelerometer values are updated.
* @type BO.io.AccelerometerEvent.UPDATE
* @event update
* @param {BO.io.AccelerometerBMA250} target A reference to the AccelerometerBMA250 object.
*/
return AccelerometerBMA250;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment