UNPKG

johnny-five-electron

Version:

Temporary fork to support Electron (to be deprecated)

426 lines (380 loc) 9.99 kB
var Board = require("../lib/board"); var EVS = require("../lib/evshield"); var within = require("./mixins/within"); var __ = require("./fn"); var Emitter = require("events").EventEmitter; var util = require("util"); var priv = new Map(); function analogHandler(opts, dataHandler) { this.io.pinMode(this.pin, this.io.MODES.ANALOG); this.io.analogRead(this.pin, function(data) { dataHandler.call(this, data); }.bind(this)); } var Controllers = { GP2Y0A21YK: { // https://www.sparkfun.com/products/242 initialize: { value: analogHandler }, toCm: { value: function(raw) { return +(12343.85 * Math.pow(raw, -1.15)).toFixed(2); } } }, GP2D120XJ00F: { // https://www.sparkfun.com/products/8959 initialize: { value: analogHandler }, toCm: { value: function(raw) { return +((2914 / (raw + 5)) - 1).toFixed(2); } } }, GP2Y0A02YK0F: { // https://www.sparkfun.com/products/8958 // 15cm - 150cm initialize: { value: analogHandler }, toCm: { value: function(raw) { return +(10650.08 * Math.pow(raw, -0.935) - 10).toFixed(2); } } }, GP2Y0A41SK0F: { // https://www.sparkfun.com/products/12728 // 4cm - 30cm initialize: { value: analogHandler }, toCm: { value: function(raw) { return +(2076 / (raw - 11)).toFixed(2); } } }, GP2Y0A710K0F: { // https://www.adafruit.com/products/1568 // 100cm - 500cm initialize: { value: analogHandler }, toCm: { value: function(raw) { // http://www.basicx.com/Products/robotbook/ir%20curve%20fit.pdf return 3.8631e8 * Math.pow(raw, -2.463343); } } }, SRF10: { initialize: { value: function(opts, dataHandler) { var address = 0x70; var msUntilNextRead = 65; // Set up I2C data connection this.io.i2cConfig(opts); // Startup parameter this.io.i2cWrite(address, [0x01, 16]); this.io.i2cWrite(address, [0x02, 255]); function read() { this.io.i2cWrite(address, [0x02]); this.io.i2cReadOnce(address, 2, function(data) { dataHandler((data[0] << 8) | data[1]); }.bind(this)); prime.call(this); } function prime() { // 0x51 result in cm (centimeters) this.io.i2cWrite(address, [0x00, 0x51]); setTimeout(read.bind(this), msUntilNextRead); } prime.call(this); } }, toCm: { value: function(raw) { return raw; } } }, // LV-MaxSonar-EZ // LV-MaxSonar-EZ0 // LV-MaxSonar-EZ1 MB1000: { initialize: { value: analogHandler }, toCm: { value: function(raw) { // From http://www.maxbotix.com/articles/032.htm // ADC -> inches -> cm return (raw / 2) * 2.54; } } }, // HRLV-MaxSonar-EZ0 MB1003: { initialize: { value: analogHandler }, toCm: { value: function(raw) { // http://www.maxbotix.com/articles/032.htm return raw / 2; } } }, // XL-MaxSonar-EZ3 MB1230: { initialize: { value: analogHandler }, toCm: { value: function(raw) { // From http://www.maxbotix.com/articles/016.htm // Using a Standard Range XL-MaxSonar with an ADC (Analog Digital Converter) // When using a standard XL-MaxSonar with an ADC, verify that the sensor // and micro-controller are referencing the same power supply and ground. // This also assumes that the ADC being used is perfectly accurate. // When reading the sensor's output with the scaling in centimeters with a // 10-bit ADC, the range can be read directly off the ADC. // If the ADC output reads 700 the range in centimeters is 700 centimeters. // // ADC -> cm return raw; } } }, HCSR04: { initialize: { value: function(opts, dataHandler) { // Private settings object var settings = { pin: opts.pin, value: this.io.HIGH, pulseOut: 5 }; var read = function() { this.io.pingRead(settings, function(microseconds) { dataHandler(microseconds); setTimeout(function() { read(); }, 65); }); }.bind(this); read(); } }, toCm: { value: function(raw) { return +(raw / 29.1 / 2).toFixed(3); } } }, LIDARLITE: { initialize: { value: function(opts, dataHandler) { var ADDRESS = 0x62; var ENABLE = 0x00; var MEASUREMODE = 0x04; var READREGISTER = 0x8f; var BYTES_TO_READ = 0x02; this.io.i2cConfig(opts); var read = function() { this.io.i2cWrite(ADDRESS, ENABLE, MEASUREMODE); setTimeout(function() { this.io.i2cReadOnce(ADDRESS, READREGISTER, BYTES_TO_READ, function(bytes) { // http://www.robotshop.com/media/files/pdf/operating-manual-llm20c132i500s011.pdf // Step 5 of Quick Start Guide dataHandler((bytes[0] << 8) + bytes[1]); read(); }); }.bind(this), 20); }.bind(this); read(); } }, toCm: { value: function(raw) { return raw; } } }, EVS_EV3_IR: { initialize: { value: function(opts, dataHandler) { var state = priv.get(this); state.shield = EVS.shieldPort(opts.pin); state.ev3 = new EVS(Object.assign(opts, { io: this.io })); state.ev3.setup(state.shield, EVS.Type_EV3); state.ev3.read(state.shield, EVS.Proximity, EVS.Proximity_Bytes, function(data) { var value = data[0] | (data[1] << 8); dataHandler(value); }); } }, toCm: { value: function(raw) { return raw; } } }, EVS_EV3_US: { initialize: { value: function(opts, dataHandler) { var state = priv.get(this); state.shield = EVS.shieldPort(opts.pin); state.ev3 = new EVS(Object.assign(opts, { io: this.io })); state.ev3.setup(state.shield, EVS.Type_EV3); state.ev3.read(state.shield, EVS.Proximity, EVS.Proximity_Bytes, function(data) { var value = data[0] | (data[1] << 8); dataHandler(value); }); } }, toCm: { value: function(raw) { return raw / 10; } } }, }; // Sensor aliases // IR Controllers["2Y0A21"] = Controllers.GP2Y0A21YK; Controllers["2D120X"] = Controllers.GP2D120XJ00F; Controllers["2Y0A02"] = Controllers.GP2Y0A02YK0F; Controllers["0A41"] = Controllers.GP2Y0A41SK0F; Controllers["0A21"] = Controllers.GP2Y0A21YK; Controllers["0A02"] = Controllers.GP2Y0A02YK0F; Controllers["41SK0F"] = Controllers.GP2Y0A41SK0F; Controllers["21YK"] = Controllers.GP2Y0A21YK; Controllers["2YK0F"] = Controllers.GP2Y0A02YK0F; // Sonar Controllers.MB1010 = Controllers.MB1000; Controllers["LV-MaxSonar-EZ"] = Controllers.MB1000; Controllers["LV-MaxSonar-EZ0"] = Controllers.MB1000; Controllers["LV-MaxSonar-EZ1"] = Controllers.MB1010; Controllers["HRLV-MaxSonar-EZ0"] = Controllers.MB1003; Controllers["XL-MaxSonar-EZ3"] = Controllers.MB1230; // Ping Controllers["HC-SR04"] = Controllers.HCSR04; Controllers["SR04"] = Controllers.HCSR04; Controllers["SRF05"] = Controllers.HCSR04; Controllers["SRF06"] = Controllers.HCSR04; Controllers["PARALLAXPING"] = Controllers.HCSR04; Controllers["SEEEDPING"] = Controllers.HCSR04; Controllers["GROVEPING"] = Controllers.HCSR04; Controllers["PING_PULSE_IN"] = Controllers.HCSR04; // LIDAR Lite Controllers["LIDAR-Lite"] = Controllers.LIDARLITE; /** * Proximity * @constructor * * five.Proximity("A0"); * * five.Proximity({ * controller: "GP2Y0A41SK0F", * pin: "A0", * freq: 100 * }); * * * @param {Object} opts [description] * */ function Proximity(opts) { if (!(this instanceof Proximity)) { return new Proximity(opts); } var controller = null; var state = {}; var raw = 0; var freq = opts.freq || 25; var last = 0; Board.Device.call( this, opts = Board.Options(opts) ); if (typeof opts.controller === "string") { controller = Controllers[opts.controller]; } else { controller = opts.controller || Controllers["GP2Y0A21YK"]; } Object.defineProperties(this, controller); if (!this.toCm) { this.toCm = opts.toCm || function(x) { return x; }; } priv.set(this, state); Object.defineProperties(this, { /** * [read-only] Calculated centimeter value * @property centimeters * @type Number */ centimeters: { get: function() { return this.toCm(raw); } }, cm: { get: function() { return this.centimeters; } }, /** * [read-only] Calculated inch value * @property inches * @type Number */ inches: { get: function() { return +(this.centimeters * 0.39).toFixed(2); } }, in: { get: function() { return this.inches; } }, }); if (typeof this.initialize === "function") { this.initialize(opts, function(data) { raw = data; }); } setInterval(function() { if (raw === undefined) { return; } var data = { cm: this.cm, centimeters: this.centimeters, in: this.in, inches: this.inches }; this.emit("data", data); if (raw !== last) { last = raw; this.emit("change", data); } }.bind(this), freq); } Proximity.Controllers = [ "2Y0A21", "GP2Y0A21YK", "2D120X", "GP2D120XJ00F", "2Y0A02", "GP2Y0A02YK0F", "OA41SK", "GP2Y0A41SK0F", "0A21", "GP2Y0A21YK", "0A02", "GP2Y0A02YK0F", ]; util.inherits(Proximity, Emitter); __.mixin(Proximity.prototype, within); module.exports = Proximity;