UNPKG

johnny-five

Version:

The JavaScript Arduino Programming Framework.

183 lines (142 loc) 4.05 kB
var Board = require("../lib/board.js"), events = require("events"), util = require("util"), within = require("./mixins/within"), __ = require("./fn"); var priv = new Map(); var Devices; /** * Sonar * @constructor * * @param {Object} opts Options: pin (analog) */ function Sonar(opts) { if (!(this instanceof Sonar)) { return new Sonar(opts); } // Initialize a Device instance on a Board Board.Device.call( this, opts = Board.Options(opts) ); var device, state; // Sonar instance properties this.freq = opts.freq || 100; this.value = null; state = { last: 0, median: 0, samples: [] }; priv.set(this, state); if (typeof opts.device === "string") { device = Devices[opts.device]; } else { device = opts.device; } if (typeof device === "undefined") { device = Devices.DEFAULT; } device.initialize.call(this); if (!device.descriptor.inches) { device.descriptor.inches = { get: function() { return +(this.cm * 0.39).toFixed(2); } }; } Object.defineProperties(this, device.descriptor); // Throttle setInterval(function() { var err = null; // Nothing read since previous interval if (state.samples.length === 0) { return; } state.median = state.samples.sort()[Math.floor(state.samples.length / 2)]; this.value = state.median; // @DEPRECATE this.emit("read", err, state.median); // The "read" event has been deprecated in // favor of a "data" event. this.emit("data", err, state.median); // If the state.median value for this interval is not the same as the // state.median value in the last interval, fire a "change" event. // if (state.last && state.median && (state.median.toFixed(1) !== state.last.toFixed(1))) { this.emit("change", err, state.median); } // Store this media value for comparison // in next interval state.last = state.median; // Reset state.samples; state.samples.length = 0; }.bind(this), this.freq); } util.inherits(Sonar, events.EventEmitter); __.mixin(Sonar.prototype, within); Devices = { SRF10: { initialize: function() { var samples = priv.get(this).samples; var address = 0x70; var delay = 65; // Set up I2C data connection this.io.sendI2CConfig(0); // Startup parameter this.io.sendI2CWriteRequest(address, [0x01, 16]); this.io.sendI2CWriteRequest(address, [0x02, 255]); this.io.setMaxListeners(100); function read() { this.io.sendI2CWriteRequest(address, [0x02]); this.io.sendI2CReadRequest(address, 2, function(data) { samples.push((data[0] << 8) | data[1]); }.bind(this)); prime.call(this); } function prime() { // 0x52 result in us (microseconds) this.io.sendI2CWriteRequest(address, [0x00, 0x52]); setTimeout(read.bind(this), delay); } prime.call(this); }, descriptor: { cm: { get: function() { var median = priv.get(this).median; return +((((median / 2) * 343.2) / 10) / 1000).toFixed(1); } } } }, DEFAULT: { initialize: function() { var samples = priv.get(this).samples; // Set the pin to ANALOG mode this.mode = this.io.MODES.ANALOG; this.io.pinMode(this.pin, this.mode); this.io.analogRead(this.pin, function(data) { samples.push(data); }.bind(this)); }, descriptor: { cm: { get: function() { var median = priv.get(this).median; return +((median / 2) * 2.54).toFixed(1); } } } } }; Devices.SRF02 = Devices.SRF08 = Devices.SRF10; module.exports = Sonar; // Reference // // http://www.maxbotix.com/tutorials.htm#Code_example_for_the_BasicX_BX24p // http://www.electrojoystick.com/tutorial/?page_id=285 // Tutorials // // http://www.sensorpedia.com/blog/how-to-interface-an-ultrasonic-rangefinder-with-sensorpedia-via-twitter-guide-2/