Skip to content

Commit

Permalink
IMU/Multi: HTU21D maintenance and improvements
Browse files Browse the repository at this point in the history
Signed-off-by: Rick Waldron <waldron.rick@gmail.com>
  • Loading branch information
rwaldron committed May 5, 2016
1 parent 40d018a commit a69fa0e
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 75 deletions.
13 changes: 11 additions & 2 deletions lib/hygrometer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var Board = require("./board"),
// References
//
var Controllers = {
// https://cdn-shop.adafruit.com/product-files/2857/Sensirion_Humidity_SHT3x_Datasheet_digital-767294.pdf
SHT31D: {
initialize: {
value: function(opts, dataHandler) {
Expand All @@ -22,11 +23,17 @@ var Controllers = {
// Page 2
// Table 1
// 1.1 Humidity Sensor Performance
//
// Page 14
// 4.13 Conversion of Signal Output
// RH = 100 * (Srh / ((2 ** 26) - 1))
// Srh = Sensor raw humidity
return +((100 * raw / 65535)).toFixed(2);
}
}
},

// https://www.adafruit.com/datasheets/1899_HTU21D.pdf
HTU21D: {
initialize: {
value: function(opts, dataHandler) {
Expand All @@ -39,8 +46,10 @@ var Controllers = {
},
toRelativeHumidity: {
value: function(raw) {
// Based on the "Relative Humidity Conversion" formula
// https://www.adafruit.com/datasheets/1899_HTU21D.pdf
// Page 15
// CONVERSION OF SIGNAL OUTPUTS
// RH = -6 + 125 * (Srh / (2 ** 26))
// Srh = Sensor raw humidity
return (125 * raw / 65536) - 6;
}
}
Expand Down
43 changes: 28 additions & 15 deletions lib/imu.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,8 @@ var Drivers = {
}
}
},
// Based on the AdaFruit Arduino driver
// https://github.com/adafruit/Adafruit_HTU21DF_Library
// https://www.adafruit.com/products/1899

// https://www.adafruit.com/datasheets/1899_HTU21D.pdf
HTU21D: {
ADDRESSES: {
value: [0x40]
Expand All @@ -100,6 +99,7 @@ var Drivers = {
value: {
HUMIDITY: 0xE5,
TEMPERATURE: 0xE3,
SOFT_RESET: 0xFE,
}
},
initialize: {
Expand All @@ -116,25 +116,38 @@ var Drivers = {
opts.delay = 50000;

io.i2cConfig(opts);
io.i2cWrite(address, this.REGISTER.SOFT_RESET);

// http://cdn.sparkfun.com/datasheets/BreakoutBoards/HTU21D.pdf
var computed = {
temperature: null,
humidity: null,
};

// Despite the registers being back to back, the HTU21D
// does not like when 5 bytes are requested, so we put
// the two data sources on their own read channels.
io.i2cRead(address, this.REGISTER.TEMPERATURE, 2, function(data) {
computed.temperature = int16(data[0], data[1]);
this.emit("data", computed);
}.bind(this));
var cycle = 0;
var readCycle = function() {
// Despite the registers being back to back, the HTU21D
// does not like when 5 bytes are requested, so we put
// the two data sources on their own read channels.
var isTemperatureCycle = cycle === 0;
var register = isTemperatureCycle ? this.REGISTER.TEMPERATURE : this.REGISTER.HUMIDITY;

io.i2cRead(address, this.REGISTER.HUMIDITY, 3, function(data) {
computed.humidity = int16(data[0], data[1]);
this.emit("data", computed);
}.bind(this));
io.i2cReadOnce(address, register, 2, function(data) {
if (isTemperatureCycle) {
computed.temperature = int16(data[0], data[1]);
} else {
computed.humidity = int16(data[0], data[1]);
}

if (++cycle === 2) {
cycle = 0;
this.emit("data", computed);
}

readCycle();
}.bind(this));
}.bind(this);

readCycle();
}
},
identifier: {
Expand Down
14 changes: 12 additions & 2 deletions lib/thermometer.js
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ var Controllers = {
if (!address || dataAddress === address) {
dataHandler(data);
}
}.bind(this));
});
}
},
toCelsius: {
Expand Down Expand Up @@ -514,6 +514,11 @@ var Controllers = {
// Page 4
// Table 1.2 Temperature Sensor Performance
// Resolution: 0.015
//
// Page 14
// 4.13 Conversion of Signal Output
// T[C] = -45 + 175 * (St / ((2 ** 26) - 1))
// St = Sensor raw temperature
return +((175 * raw / 65535) - 45).toFixed(3);
}
}
Expand All @@ -535,6 +540,11 @@ var Controllers = {
// Page 5
// Digital Relative Humidity sensor with Temperature output
// Resolution shows 0.01-0.04
//
// Page 15
// CONVERSION OF SIGNAL OUTPUTS
// T = -46.85 + 175.72 * (Stemp / (2 ** 16))
// Stemp = Sensor raw temperature
return +((175.72 * raw / 65536) - 46.85).toFixed(2);
}
}
Expand Down Expand Up @@ -917,7 +927,7 @@ function Thermometer(opts) {
},
fahrenheit: {
get: function() {
return (this.celsius * 9 / 5) + 32;
return +((this.celsius * 9 / 5) + 32).toFixed(2);
}
},
kelvin: {
Expand Down
71 changes: 36 additions & 35 deletions test/hygrometer.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ exports["Hygrometer -- HTU21D"] = {

setUp: function(done) {
this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig");
this.i2cRead = this.sandbox.spy(MockFirmata.prototype, "i2cRead");
this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce");

this.hygrometer = new Hygrometer({
controller: "HTU21D",
Expand Down Expand Up @@ -125,65 +125,66 @@ exports["Hygrometer -- HTU21D"] = {
},

data: function(test) {
test.expect(4);

test.equal(this.i2cRead.callCount, 2);
test.deepEqual(this.i2cRead.lastCall.args.slice(0, 3), [
0x40, // address
0xE5, // register
3, // data length
]);


test.expect(8);
var readOnce;
var spy = this.sandbox.spy();
var read = this.i2cRead.lastCall.args[3];

this.hygrometer.on("data", spy);

read([0x6F, 0xFF, 0x00]); // humidity
test.equal(this.i2cReadOnce.callCount, 1);
test.equal(this.i2cReadOnce.lastCall.args[0], 0x40);
test.equal(this.i2cReadOnce.lastCall.args[1], 0xE3);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 100, 76 ]);
this.clock.tick(10);

test.ok(spy.calledOnce);
test.equal(Math.round(spy.args[0][0].relativeHumidity), 49);

test.equal(this.i2cReadOnce.callCount, 2);
test.equal(this.i2cReadOnce.lastCall.args[0], 0x40);
test.equal(this.i2cReadOnce.lastCall.args[1], 0xE5);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 94, 6 ]);
this.clock.tick(10);

test.equal(spy.callCount, 1);
test.equal(Math.round(this.hygrometer.relativeHumidity), 40);
test.done();
},

change: function(test) {
test.expect(4);

test.equal(this.i2cRead.callCount, 2);
test.deepEqual(this.i2cRead.lastCall.args.slice(0, 3), [
0x40, // address
0xE5, // register
3, // data length
]);

test.expect(5);

var readOnce;
var spy = this.sandbox.spy();
var read = this.i2cRead.lastCall.args[3];

this.hygrometer.on("change", spy);

read([0x6F, 0xFF, 0x6F, 0xFF]); // humidity
test.equal(this.i2cReadOnce.callCount, 1);
test.equal(this.i2cReadOnce.lastCall.args[0], 0x40);
test.equal(this.i2cReadOnce.lastCall.args[1], 0xE3);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 100, 136 ]);
this.clock.tick(10);

read = this.i2cRead.lastCall.args[3];
read([0x6F, 0xFF, 0x00]); // temperature
read = this.i2cRead.lastCall.args[3];
read([0x6F, 0xFF, 0x00]); // humidity -- same
readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 93, 202 ]);
this.clock.tick(10);

read = this.i2cRead.lastCall.args[3];
read([0x6F, 0xFF, 0x00]); // temperature
read = this.i2cRead.lastCall.args[3];
read([0x40, 0x00, 0x00]); // humidity -- different --

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 100, 76 ]);
this.clock.tick(10);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 94, 6 ]);
this.clock.tick(10);


test.equal(spy.callCount, 2);
test.equal(Math.round(spy.lastCall.args[0].relativeHumidity), 25);
test.equal(Math.round(this.hygrometer.relativeHumidity), 40);

test.done();
}
Expand Down
76 changes: 55 additions & 21 deletions test/thermometer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ exports["Thermometer -- HTU21D"] = {

setUp: function(done) {
this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig");
this.i2cRead = this.sandbox.spy(MockFirmata.prototype, "i2cRead");
this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce");

this.temperature = new Thermometer({
controller: "HTU21D",
Expand Down Expand Up @@ -1049,7 +1049,7 @@ exports["Thermometer -- HTU21D"] = {
this.i2cConfig.reset();

new Thermometer({
controller: "SI7020",
controller: "HTU21D",
address: 0xff,
bus: "i2c-1",
board: this.board
Expand All @@ -1062,35 +1062,69 @@ exports["Thermometer -- HTU21D"] = {
},

data: function(test) {
test.expect(7);
test.expect(8);
var readOnce;
var spy = this.sandbox.spy();

test.equal(this.i2cRead.callCount, 2);
test.deepEqual(this.i2cRead.firstCall.args.slice(0, 3), [
0x40, // address
0xE3, // register
2, // data length
]);
this.temperature.on("data", spy);

test.equal(this.i2cReadOnce.callCount, 1);
test.equal(this.i2cReadOnce.lastCall.args[0], 0x40);
test.equal(this.i2cReadOnce.lastCall.args[1], 0xE3);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 100, 76 ]);
this.clock.tick(10);

test.equal(this.i2cReadOnce.callCount, 2);
test.equal(this.i2cReadOnce.lastCall.args[0], 0x40);
test.equal(this.i2cReadOnce.lastCall.args[1], 0xE5);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 100, 76 ]);
this.clock.tick(10);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 94, 6 ]);
this.clock.tick(10);

test.equal(spy.callCount, 2);
test.equal(Math.round(this.temperature.C), 22);
test.done();
},

change: function(test) {
test.expect(5);

var readOnce;
var spy = this.sandbox.spy();
var read = this.i2cRead.firstCall.args[3];

this.temperature.on("data", spy);
this.temperature.on("change", spy);

read([0x67, 0x00]); // humidity
read = this.i2cRead.firstCall.args[3];
read([0x67, 0x00]); // temperature
read = this.i2cRead.firstCall.args[3];
read([0x67, 0x00]); // humidity again
test.equal(this.i2cReadOnce.callCount, 1);
test.equal(this.i2cReadOnce.lastCall.args[0], 0x40);
test.equal(this.i2cReadOnce.lastCall.args[1], 0xE3);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 100, 136 ]);
this.clock.tick(10);

test.ok(spy.calledOnce);
test.equals(Math.round(spy.getCall(0).args[0].celsius), 24);
test.equals(Math.round(spy.getCall(0).args[0].fahrenheit), 75);
test.equals(Math.round(spy.getCall(0).args[0].kelvin), 297);
readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 93, 202 ]);
this.clock.tick(10);

test.equal(digits.fractional(this.temperature.C), 2);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 100, 76 ]);
this.clock.tick(10);

readOnce = this.i2cReadOnce.lastCall.args[3];
readOnce([ 94, 6 ]);
this.clock.tick(10);


test.equal(spy.callCount, 2);
test.equal(Math.round(this.temperature.C), 22);

test.done();
}
Expand Down

0 comments on commit a69fa0e

Please sign in to comment.