Skip to content

Commit

Permalink
Accelerometer: ADXL345 support user defined range. Fixes gh-1135
Browse files Browse the repository at this point in the history
Signed-off-by: Rick Waldron <[email protected]>
  • Loading branch information
rwaldron committed May 17, 2016
1 parent 29a9ba0 commit 6071b2b
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 39 deletions.
6 changes: 5 additions & 1 deletion docs/accelerometer-adxl345.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ var board = new five.Board();

board.on("ready", function() {
var accelerometer = new five.Accelerometer({
controller: "ADXL345"
controller: "ADXL345",
// Optionally set the range to one of
// 2, 4, 8, 16 (±g)
// Defaults to ±2g
// range: ...
});

accelerometer.on("change", function() {
Expand Down
6 changes: 5 additions & 1 deletion eg/accelerometer-adxl345.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ var board = new five.Board();

board.on("ready", function() {
var accelerometer = new five.Accelerometer({
controller: "ADXL345"
controller: "ADXL345",
// Optionally set the range to one of
// 2, 4, 8, 16 (±g)
// Defaults to ±2g
// range: ...
});

accelerometer.on("change", function() {
Expand Down
122 changes: 86 additions & 36 deletions lib/accelerometer.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,22 @@ var Controllers = {
value: analogToGravity
}
},
ADXL345: {
// http://www.analog.com/en/mems-sensors/mems-inertial-sensors/adxl345/products/product.html
// http://www.i2cdevlib.com/devices/adxl345#source

// http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
ADXL345: {
ADDRESSES: {
value: [0x53]
},
REGISTER: {
value: {
// Page 23
// REGISTER MAP
//
POWER: 0x2D,
RANGE: 0x31,
READREGISTER: 0x32
// 0x31 49 DATA_FORMAT R/W 00000000 Data format control
DATA_FORMAT: 0x31,
// 0x32 50 DATAX0 R 00000000 X-Axis Data 0
DATAX0: 0x32
}
},
initialize: {
Expand All @@ -138,29 +142,6 @@ var Controllers = {

opts.address = address;

// Sensitivity:
//
// (ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD) = (0.004 * 9.80665) = 0.0390625
//
// Reference:
// https://github.com/adafruit/Adafruit_Sensor/blob/master/Adafruit_Sensor.h#L34-L37
// https://github.com/adafruit/Adafruit_ADXL345/blob/master/Adafruit_ADXL345_U.h#L73
// https://github.com/adafruit/Adafruit_ADXL345/blob/master/Adafruit_ADXL345_U.cpp#L298-L309
//
// Invert for parity with other controllers
//
// (1 / 0.0390625) * (1 / 9.8)
//
// OR
//
// (1 / ADXL345_MG2G_MULTIPLIER) = (1 / 0.004)
//
// OR
//
// 250
//
state.sensitivity = opts.sensitivity || 250;

this.io.i2cConfig(opts);

// Standby mode
Expand All @@ -169,22 +150,91 @@ var Controllers = {
// Enable measurements
this.io.i2cWrite(address, this.REGISTER.POWER, 8);

// Set range (this is 2G range, should be user defined?)
this.io.i2cWrite(address, this.REGISTER.RANGE, 8);

this.io.i2cRead(address, this.REGISTER.READREGISTER, READLENGTH, function(data) {
dataHandler.call(this, {
/*
Page 26
Register 0x31—DATA_FORMAT (Read/Write)
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| - | - | - | - | - | - | - | - |
| T | S | I | - | F | J | R |
T: SELF_TEST
S: SPI
I: INT_INVERT
-:-
F: FULL_RES
J: JUSTIFY
R: RANGE
Range notes: https://github.com/rwaldron/johnny-five/issues/1135#issuecomment-219541346
+/- 16g 0b11
+/- 8g 0b10
+/- 4g 0b01
+/- 2g 0b00
Start with FULL_RES bit on
0b00001000 = 0x08 = 8
*/
var format = 0x08;

/*
Determine range
0b00000000 = 0 = ±2g
0b00000001 = 1 = ±4g
0b00000010 = 2 = ±8g
0b00000011 = 3 = ±16g
*/
var range = ({ 2: 0, 4: 1, 8: 2, 16: 3 })[opts.range || 2];

/*
Page 4
Sensitivity at XOUT YOUT ZOUT
±2 g, 10-bit resolution 230 256 282
±4 g, 10-bit resolution 115 128 141
±8 g, 10-bit resolution 57 64 71
±16 g, 10-bit resolution 29 32 35
*/
state.sensitivity = [{
x: 230,
y: 256,
z: 282
}, {
x: 115,
y: 128,
z: 141
}, {
x: 57,
y: 64,
z: 71
}, {
x: 29,
y: 32,
z: 35
}][range];


// Merge the format and range bits to set the DATA_FORMAT
this.io.i2cWrite(address, this.REGISTER.DATA_FORMAT, format | range);

this.io.i2cRead(address, this.REGISTER.DATAX0, READLENGTH, function(data) {
dataHandler({
x: int16(data[1], data[0]),
y: int16(data[3], data[2]),
z: int16(data[5], data[4])
});
}.bind(this));
});
},
},
toGravity: {
value: function(raw) {
value: function(raw, axis) {
var state = priv.get(this);
return raw / state.sensitivity;
return raw / state.sensitivity[axis];
}
}
},
Expand Down
53 changes: 52 additions & 1 deletion test/accelerometer.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,9 +492,60 @@ exports["Accelerometer -- ADXL345"] = {
test.deepEqual(changeSpy.args[0], [{
x: 0.01,
y: 0.02,
z: 1.02
z: 0.9
}]);

test.done();
},

dataAltRange: function(test) {

this.i2cConfig.reset();
this.i2cWrite.reset();
this.i2cRead.reset();

this.accel = new Accelerometer({
controller: "ADXL345",
range: 16,
board: this.board,
});


var read, dataSpy = this.sandbox.spy(),
changeSpy = this.sandbox.spy();

// test.expect(12);
this.accel.on("data", dataSpy);
this.accel.on("change", changeSpy);

read = this.i2cRead.args[0][3];
read([
// Derived from actual reading set.
0x03, 0x00, 0x05, 0x00, 0xFE, 0x00
]);

test.ok(this.i2cConfig.calledOnce);

test.ok(this.i2cWrite.calledThrice);
test.deepEqual(this.i2cWrite.getCall(0).args, [83, 45, 0]);
test.deepEqual(this.i2cWrite.getCall(1).args, [83, 45, 8]);
test.deepEqual(this.i2cWrite.getCall(2).args, [83, 49, 11]);

test.ok(this.i2cRead.calledOnce);
test.deepEqual(this.i2cRead.getCall(0).args.slice(0, 3), [83, 50, 6]);

this.clock.tick(100);

test.ok(dataSpy.calledOnce);
test.deepEqual(dataSpy.args[0], [{
x: 3,
y: 5,
z: 254
}]);

test.ok(changeSpy.calledOnce);
test.deepEqual(changeSpy.args[0], [{ x: 0.1, y: 0.16, z: 7.26 }]);

test.done();
}
};
Expand Down

0 comments on commit 6071b2b

Please sign in to comment.