diff --git a/eg/hygrometer-htu21d.js b/eg/hygrometer-htu21d.js new file mode 100644 index 000000000..5ddd14b82 --- /dev/null +++ b/eg/hygrometer-htu21d.js @@ -0,0 +1,16 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "HTU21D" + }); + + hygrometer.on("data", function() { + console.log(this.relativeHumidity + " %"); + }); +}); + +// @markdown +// - [HTU21D - Humidity Sensor](https://www.adafruit.com/products/1899) +// @markdown \ No newline at end of file diff --git a/eg/temperature-htu21d.js b/eg/temperature-htu21d.js new file mode 100644 index 000000000..cb0022a9a --- /dev/null +++ b/eg/temperature-htu21d.js @@ -0,0 +1,16 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var temperature = new five.Temperature({ + controller: "HTU21D" + }); + + temperature.on("data", function() { + console.log(this.celsius + "°C", this.fahrenheit + "°F"); + }); +}); + +// @markdown +// - [HTU21D - Humidity Sensor](https://www.adafruit.com/products/1899) +// @markdown \ No newline at end of file diff --git a/lib/hygrometer.js b/lib/hygrometer.js new file mode 100644 index 000000000..b14b1a957 --- /dev/null +++ b/lib/hygrometer.js @@ -0,0 +1,96 @@ +var Board = require("../lib/board.js"), + Emitter = require("events").EventEmitter, + util = require("util"); + +// References +// +var Controllers = { + HTU21D: { + initialize: { + value: function(opts, dataHandler) { + var Multi = require("../lib/imu"); + var driver = Multi.Drivers.get(this.board, "HTU21D", opts); + driver.on("data", function(data) { + dataHandler(data.humidity); + }); + } + }, + toRelativeHumidity: { + value: function(raw) { + return (125.0*(raw/65536)) - 6; + } + } + } +}; + +var priv = new Map(); + +function Hygrometer(opts) { + var controller, freq, last = 0, raw; + + if (!(this instanceof Hygrometer)) { + return new Hygrometer(opts); + } + + Board.Component.call( + this, opts = Board.Options(opts) + ); + + freq = opts.freq || 25; + + if (opts.controller && typeof opts.controller === "string") { + controller = Controllers[opts.controller.toUpperCase()]; + } else { + controller = opts.controller; + } + + if (controller == null) { + controller = Controllers["ANALOG"]; + } + + priv.set(this, {}); + + Object.defineProperties(this, controller); + + if (!this.toRelativeHumidity) { + this.toRelativeHumidity = opts.toRelativeHumidity || function(x) { return x; }; + } + + var propDescriptors = { + relativeHumidity: { + get: function() { + return this.toRelativeHumidity(raw); + } + } + }; + // Convenience aliases + propDescriptors.RH = propDescriptors.relativeHumidity; + + Object.defineProperties(this, propDescriptors); + + if (typeof this.initialize === "function") { + this.initialize(opts, function(data) { + raw = data; + }); + } + + setInterval(function() { + if (raw === undefined) { + return; + } + + var data = {}; + data.RH = data.relativeHumidity = this.relativeHumidity; + + this.emit("data", null, data); + + if (this.relativeHumidity !== last) { + last = this.relativeHumidity; + this.emit("change", null, data); + } + }.bind(this), freq); +} + +util.inherits(Hygrometer, Emitter); + +module.exports = Hygrometer; \ No newline at end of file diff --git a/lib/imu.js b/lib/imu.js index e8d96bb5e..acfde95e8 100644 --- a/lib/imu.js +++ b/lib/imu.js @@ -14,6 +14,64 @@ var priv = new Map(); var activeDrivers = new Map(); var Drivers = { + // Based on the AdaFruit Arduino driver + // https://github.com/adafruit/Adafruit_HTU21DF_Library + // https://www.adafruit.com/products/1899 + HTU21D: { + ADDRESSES: { + value: [0x40] + }, + REGISTER: { + value: { + TEMPERATURE: 0xE3, + HUMIDITY: 0xE5 + } + }, + initialize: { + value: function(board, opts) { + var READLENGTH = 3; + var io = board.io; + var address = opts.address || this.ADDRESSES[0]; + + var computed = { + temperature: {}, + humidity: {} + }; + + var readCycle = function(isTemp) { + var register = isTemp ? this.REGISTER.TEMPERATURE : this.REGISTER.HUMIDITY; + + io.i2cReadOnce(address, register, READLENGTH, function(data) { + var msb = data[0]; + var lsb = data[1]; + + var value = (msb << 8) | lsb; + + if (isTemp) { + computed.temperature = value; + } else { + computed.humidity = value; + this.emit("data", computed); + } + + readCycle(!isTemp); + }.bind(this)); + }.bind(this); + + io.i2cConfig(opts); + + // Kick off "read loop" + // + readCycle(false); + } + }, + identifier: { + value: function(opts) { + var address = opts.address || Drivers["HTU21D"].ADDRESSES.value[0]; + return "htu-s1d-" + address; + } + } + }, // Based on the example code from // http://playground.arduino.cc/Main/MPU-6050 // http://www.invensense.com/mems/gyro/mpu6050.html diff --git a/lib/johnny-five.js b/lib/johnny-five.js index 04009c3ce..f6bd1df3d 100644 --- a/lib/johnny-five.js +++ b/lib/johnny-five.js @@ -17,6 +17,7 @@ module.exports = { Fn: require("./fn"), Gripper: require("./gripper"), Gyro: require("./gyro"), + Hygrometer: require("./hygrometer"), IMU: require("./imu"), IR: require("./ir"), Keypad: require("./keypad"), @@ -66,6 +67,7 @@ module.exports.Board.Virtual = function(opts) { }; module.exports.Multi = module.exports.IMU; +module.exports.Humidity = module.exports.Hygrometer; module.exports.Analog = function(opts) { return new module.exports.Sensor(opts); diff --git a/lib/temperature.js b/lib/temperature.js index f1ea39110..990157f51 100644 --- a/lib/temperature.js +++ b/lib/temperature.js @@ -287,6 +287,22 @@ var Controllers = { } } }, + HTU21D: { + initialize: { + value: function(opts, dataHandler) { + var Multi = require("../lib/imu"); + var driver = Multi.Drivers.get(this.board, "HTU21D", opts); + driver.on("data", function(data) { + dataHandler(data.temperature); + }); + } + }, + toCelsius: { + value: function(raw) { + return (175.25*raw/65536)-46.85; + } + } + }, //http://playground.arduino.cc/Main/MPU-6050 MPU6050: { initialize: {