diff --git a/README.md b/README.md
index 8e51eac9f..d2a71b277 100644
--- a/README.md
+++ b/README.md
@@ -253,6 +253,12 @@ To interactively navigate the examples, visit the [Johnny-Five examples](http://
- [IR Reflectance](https://github.com/rwaldron/johnny-five/blob/master/docs/ir-reflect.md)
- [IR Reflectance Array](https://github.com/rwaldron/johnny-five/blob/master/docs/ir-reflect-array.md)
+### Proximity
+- [Proximity](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity.md)
+- [Proximity - SRF10](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-srf10.md)
+- [Proximity - MB1003](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-mb1003.md)
+- [Proximity - HC-SR04](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-hcsr04.md)
+
### Joystick
- [Joystick](https://github.com/rwaldron/johnny-five/blob/master/docs/joystick.md)
- [Joystick - Claw control](https://github.com/rwaldron/johnny-five/blob/master/docs/joystick-claw.md)
diff --git a/docs/breadboard/proximity-hcsr04.fzz b/docs/breadboard/proximity-hcsr04.fzz
new file mode 100644
index 000000000..f3959e5b1
Binary files /dev/null and b/docs/breadboard/proximity-hcsr04.fzz differ
diff --git a/docs/breadboard/proximity-hcsr04.png b/docs/breadboard/proximity-hcsr04.png
new file mode 100644
index 000000000..da5ca08d6
Binary files /dev/null and b/docs/breadboard/proximity-hcsr04.png differ
diff --git a/docs/breadboard/proximity-mb1003.fzz b/docs/breadboard/proximity-mb1003.fzz
new file mode 100644
index 000000000..6fe87f327
Binary files /dev/null and b/docs/breadboard/proximity-mb1003.fzz differ
diff --git a/docs/breadboard/proximity-mb1003.png b/docs/breadboard/proximity-mb1003.png
new file mode 100644
index 000000000..615924989
Binary files /dev/null and b/docs/breadboard/proximity-mb1003.png differ
diff --git a/docs/breadboard/proximity-srf10.fzz b/docs/breadboard/proximity-srf10.fzz
new file mode 100644
index 000000000..35bbadbec
Binary files /dev/null and b/docs/breadboard/proximity-srf10.fzz differ
diff --git a/docs/breadboard/proximity-srf10.png b/docs/breadboard/proximity-srf10.png
new file mode 100644
index 000000000..90e53ba43
Binary files /dev/null and b/docs/breadboard/proximity-srf10.png differ
diff --git a/docs/breadboard/proximity.fzz b/docs/breadboard/proximity.fzz
new file mode 100644
index 000000000..03f1bb335
Binary files /dev/null and b/docs/breadboard/proximity.fzz differ
diff --git a/docs/breadboard/proximity.png b/docs/breadboard/proximity.png
new file mode 100644
index 000000000..9aa7ec7fa
Binary files /dev/null and b/docs/breadboard/proximity.png differ
diff --git a/docs/proximity-hcsr04.md b/docs/proximity-hcsr04.md
new file mode 100644
index 000000000..89d06c0b5
--- /dev/null
+++ b/docs/proximity-hcsr04.md
@@ -0,0 +1,66 @@
+
+
+# Proximity - HC-SR04
+
+
+Basic ping Proximity example with HC-SR04 sensor.
+
+
+Run with:
+```bash
+node eg/proximity-hcsr04.js
+```
+
+
+
+```javascript
+var five = require("johnny-five");
+
+five.Board().on("ready", function() {
+
+ var proximity = new five.Proximity({
+ controller: "HCSR04",
+ pin: 7
+ });
+
+ proximity.on("data", function(data) {
+ console.log(data.cm + "cm", data.in + "in");
+ });
+
+ proximity.on("change", function(data) {
+ console.log("The obstruction has moved.");
+ });
+
+});
+
+```
+
+
+## Illustrations / Photos
+
+
+### Breadboard for "Proximity - HC-SR04"
+
+
+
+![docs/breadboard/proximity-hcsr04.png](breadboard/proximity-hcsr04.png)
+
+Fritzing diagram: [docs/breadboard/proximity-hcsr04.fzz](breadboard/proximity-hcsr04.fzz)
+
+
+
+
+
+
+
+
+
+
+
+## License
+Copyright (c) 2012, 2013, 2014 Rick Waldron
+Licensed under the MIT license.
+Copyright (c) 2014, 2015 The Johnny-Five Contributors
+Licensed under the MIT license.
+
+
diff --git a/docs/proximity-mb1003.md b/docs/proximity-mb1003.md
new file mode 100644
index 000000000..4b9313dbf
--- /dev/null
+++ b/docs/proximity-mb1003.md
@@ -0,0 +1,66 @@
+
+
+# Proximity - MB1003
+
+
+Basic sonar Proximity example with MB1003 sensor.
+
+
+Run with:
+```bash
+node eg/proximity-mb1003.js
+```
+
+
+
+```javascript
+var five = require("johnny-five");
+
+five.Board().on("ready", function() {
+
+ var proximity = new five.Proximity({
+ controller: "MB1003",
+ pin: "A0"
+ });
+
+ proximity.on("data", function(data) {
+ console.log(data.cm + "cm", data.in + "in");
+ });
+
+ proximity.on("change", function(data) {
+ console.log("The obstruction has moved.");
+ });
+
+});
+
+```
+
+
+## Illustrations / Photos
+
+
+### Breadboard for "Proximity - MB1003"
+
+
+
+![docs/breadboard/proximity-mb1003.png](breadboard/proximity-mb1003.png)
+
+Fritzing diagram: [docs/breadboard/proximity-mb1003.fzz](breadboard/proximity-mb1003.fzz)
+
+
+
+
+
+
+
+
+
+
+
+## License
+Copyright (c) 2012, 2013, 2014 Rick Waldron
+Licensed under the MIT license.
+Copyright (c) 2014, 2015 The Johnny-Five Contributors
+Licensed under the MIT license.
+
+
diff --git a/docs/proximity-srf10.md b/docs/proximity-srf10.md
new file mode 100644
index 000000000..17646571a
--- /dev/null
+++ b/docs/proximity-srf10.md
@@ -0,0 +1,65 @@
+
+
+# Proximity - SRF10
+
+
+Basic sonar Proximity example with SRF10 sensor.
+
+
+Run with:
+```bash
+node eg/proximity-srf10.js
+```
+
+
+
+```javascript
+var five = require("johnny-five");
+
+five.Board().on("ready", function() {
+
+ var proximity = new five.Proximity({
+ controller: "SRF10"
+ });
+
+ proximity.on("data", function(data) {
+ console.log(data.cm + "cm", data.in + "in");
+ });
+
+ proximity.on("change", function(data) {
+ console.log("The obstruction has moved.");
+ });
+
+});
+
+```
+
+
+## Illustrations / Photos
+
+
+### Breadboard for "Proximity - SRF10"
+
+
+
+![docs/breadboard/proximity-srf10.png](breadboard/proximity-srf10.png)
+
+Fritzing diagram: [docs/breadboard/proximity-srf10.fzz](breadboard/proximity-srf10.fzz)
+
+
+
+
+
+
+
+
+
+
+
+## License
+Copyright (c) 2012, 2013, 2014 Rick Waldron
+Licensed under the MIT license.
+Copyright (c) 2014, 2015 The Johnny-Five Contributors
+Licensed under the MIT license.
+
+
diff --git a/docs/proximity.md b/docs/proximity.md
new file mode 100644
index 000000000..d5ee7cfb9
--- /dev/null
+++ b/docs/proximity.md
@@ -0,0 +1,66 @@
+
+
+# Proximity
+
+
+Basic infrared Proximity example
+
+
+Run with:
+```bash
+node eg/proximity.js
+```
+
+
+
+```javascript
+var five = require("johnny-five");
+
+five.Board().on("ready", function() {
+
+ var proximity = new five.Proximity({
+ controller: "GP2Y0A21YK",
+ pin: "A0"
+ });
+
+ proximity.on("data", function(data) {
+ console.log(data.cm + "cm", data.in + "in");
+ });
+
+ proximity.on("change", function(data) {
+ console.log("The obstruction has moved.");
+ });
+
+});
+
+```
+
+
+## Illustrations / Photos
+
+
+### Breadboard for "Proximity"
+
+
+
+![docs/breadboard/proximity.png](breadboard/proximity.png)
+
+Fritzing diagram: [docs/breadboard/proximity.fzz](breadboard/proximity.fzz)
+
+
+
+
+
+
+
+
+
+
+
+## License
+Copyright (c) 2012, 2013, 2014 Rick Waldron
+Licensed under the MIT license.
+Copyright (c) 2014, 2015 The Johnny-Five Contributors
+Licensed under the MIT license.
+
+
diff --git a/eg/proximity-hcsr04.js b/eg/proximity-hcsr04.js
new file mode 100644
index 000000000..e8de84258
--- /dev/null
+++ b/eg/proximity-hcsr04.js
@@ -0,0 +1,18 @@
+var five = require("../lib/johnny-five.js");
+
+five.Board().on("ready", function() {
+
+ var proximity = new five.Proximity({
+ controller: "HCSR04",
+ pin: 7
+ });
+
+ proximity.on("data", function(data) {
+ console.log(data.cm + "cm", data.in + "in");
+ });
+
+ proximity.on("change", function(data) {
+ console.log("The obstruction has moved.");
+ });
+
+});
diff --git a/eg/proximity-mb1003.js b/eg/proximity-mb1003.js
new file mode 100644
index 000000000..03e2ba5c3
--- /dev/null
+++ b/eg/proximity-mb1003.js
@@ -0,0 +1,18 @@
+var five = require("../lib/johnny-five.js");
+
+five.Board().on("ready", function() {
+
+ var proximity = new five.Proximity({
+ controller: "MB1003",
+ pin: "A0"
+ });
+
+ proximity.on("data", function(data) {
+ console.log(data.cm + "cm", data.in + "in");
+ });
+
+ proximity.on("change", function(data) {
+ console.log("The obstruction has moved.");
+ });
+
+});
diff --git a/eg/proximity-srf10.js b/eg/proximity-srf10.js
new file mode 100644
index 000000000..91cc26a7f
--- /dev/null
+++ b/eg/proximity-srf10.js
@@ -0,0 +1,17 @@
+var five = require("../lib/johnny-five.js");
+
+five.Board().on("ready", function() {
+
+ var proximity = new five.Proximity({
+ controller: "SRF10"
+ });
+
+ proximity.on("data", function(data) {
+ console.log(data.cm + "cm", data.in + "in");
+ });
+
+ proximity.on("change", function(data) {
+ console.log("The obstruction has moved.");
+ });
+
+});
diff --git a/eg/proximity.js b/eg/proximity.js
index 8344601bd..1afb648c7 100644
--- a/eg/proximity.js
+++ b/eg/proximity.js
@@ -1,51 +1,18 @@
-var five = require("../lib/johnny-five.js"),
- prox, led;
+var five = require("../lib/johnny-five.js");
five.Board().on("ready", function() {
- // Create a new IR Proximity Sensor hardware instance.
- //
- // five.IR.Proximity();
- //
- // (Alias of:
- // new five.IR({
- // device: "GP2Y0D805Z0F",
- // freq: 50
- // });
- // )
- //
-
- prox = new five.IR.Proximity();
- led = new five.Led(13);
-
-
-
-
-
- // Properties
-
- // prox.state
- //
-
- // Proximity Event API
-
- // "motionstart"
- //
- // Fired motion is detected with 2"
- //
-
+ var proximity = new five.Proximity({
+ controller: "GP2Y0A21YK",
+ pin: "A0"
+ });
- // "motionend"
- //
- // Fired following a "motionstart" event
- // when no movement has occurred in X ms
- //
- prox.on("motionstart", function(err, timestamp) {
- led.on();
+ proximity.on("data", function(data) {
+ console.log(data.cm + "cm", data.in + "in");
});
- prox.on("motionend", function(err, timestamp) {
- led.off();
+ proximity.on("change", function(data) {
+ console.log("The obstruction has moved.");
});
});
diff --git a/lib/distance.js b/lib/distance.js
index f4ff8cfa7..ebd6ea98a 100644
--- a/lib/distance.js
+++ b/lib/distance.js
@@ -78,6 +78,8 @@ Controllers["0A02"] = Controllers.GP2Y0A02YK0F;
/**
* IR.Distance
+ *
+ * @deprecated
* @constructor
*
* five.IR.Distance("A0");
@@ -114,7 +116,9 @@ function Distance(opts) {
Object.defineProperties(this, controller);
if (!this.toCm) {
- this.toCm = opts.toCm || function(x) { return x; };
+ this.toCm = opts.toCm || function(x) {
+ return x;
+ };
}
Object.defineProperties(this, {
@@ -129,7 +133,7 @@ function Distance(opts) {
}
},
cm: {
- get: function () {
+ get: function() {
return this.centimeters;
}
},
@@ -143,8 +147,8 @@ function Distance(opts) {
return +(this.centimeters * 0.39).toFixed(2);
}
},
- in: {
- get: function () {
+ in : {
+ get: function() {
return this.inches;
}
},
diff --git a/lib/johnny-five.js b/lib/johnny-five.js
index 909c815b1..e5a7dcd4a 100644
--- a/lib/johnny-five.js
+++ b/lib/johnny-five.js
@@ -26,6 +26,7 @@ module.exports = {
Ping: require("./ping"),
Pir: require("./pir"),
Pin: require("./pin"),
+ Proximity: require("./proximity"),
Relay: require("./relay"),
Repl: require("./repl"),
Sensor: require("./sensor"),
@@ -66,8 +67,11 @@ module.exports.Digital = function(opts) {
module.exports.Sensor.Analog = module.exports.Analog;
module.exports.Sensor.Digital = module.exports.Digital;
+/**
+ * @deprecated Will be deleted in version 0.9.0. Use Proximity instead.
+ */
module.exports.IR.Distance = function(opts) {
- console.log("IR.Distance is deprecated. Use IR.Proximity instead");
+ console.log("IR.Distance is deprecated. Use Proximity instead");
return new module.exports.Distance(opts);
};
@@ -79,7 +83,11 @@ module.exports.IR.Motion = function(opt) {
);
};
+/**
+ * @deprecated Will be deleted in version 0.9.0. Use Proximity instead.
+ */
module.exports.IR.Proximity = function(opts) {
+ console.log("IR.Proximity is deprecated. Use Proximity instead");
// Fix a naming mistake.
if (module.exports.Distance.Controllers.includes(opts.controller)) {
return new module.exports.Distance(opts);
diff --git a/lib/proximity.js b/lib/proximity.js
new file mode 100644
index 000000000..f41c7e66c
--- /dev/null
+++ b/lib/proximity.js
@@ -0,0 +1,273 @@
+var Board = require("../lib/board.js"),
+ within = require("./mixins/within"),
+ __ = require("./fn"),
+ events = require("events"),
+ util = require("util");
+
+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);
+ }
+ }
+ },
+ SRF10: {
+ initialize: {
+ value: function(opts, dataHandler) {
+
+ var address = 0x70;
+ var delay = 65;
+
+ // Set up I2C data connection
+ this.io.i2cConfig(0);
+
+ // 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), delay);
+ }
+
+ prime.call(this);
+ }
+ },
+ toCm: {
+ value: function(raw) {
+ return raw;
+ }
+ }
+ },
+ MB1003: {
+ initialize: {
+ value: analogHandler
+ },
+ toCm: {
+ value: function(raw) {
+ // http://www.maxbotix.com/articles/032.htm
+ return raw / 2;
+ }
+ }
+ },
+ HCSR04: {
+ initialize: {
+ value: function (opts, dataHandler) {
+ // Private settings object
+ var settings = {
+ pin: opts.pin,
+ value: this.io.HIGH,
+ pulseOut: 5
+ };
+
+ setInterval(function() {
+ this.io.pulseIn(settings, function(microseconds) {
+ dataHandler(microseconds);
+ });
+ }.bind(this), opts.freq || 25);
+ }
+ },
+ toCm: {
+ value: function (raw) {
+ return +(raw / 29.1 / 2).toFixed(3);
+ }
+ }
+ }
+};
+
+// Sensor aliases
+// IR
+Controllers["2Y0A21"] = Controllers.GP2Y0A21YK;
+Controllers["2D120X"] = Controllers.GP2D120XJ00F;
+Controllers["2Y0A02"] = Controllers.GP2Y0A02YK0F;
+Controllers["OA41SK"] = Controllers.GP2Y0A41SK0F;
+Controllers["0A21"] = Controllers.GP2Y0A21YK;
+Controllers["0A02"] = Controllers.GP2Y0A02YK0F;
+
+// Sonar
+Controllers["HRLV-MaxSonar-EZ0"] = Controllers.MB1003;
+
+// Ping
+Controllers["HC-SR04"] = Controllers.HCSR04;
+
+/**
+ * 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;
+ 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;
+ };
+ }
+
+ 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, events.EventEmitter);
+
+__.mixin(Proximity.prototype, within);
+
+module.exports = Proximity;
diff --git a/test/proximity.js b/test/proximity.js
index bb03b3691..546a64edc 100644
--- a/test/proximity.js
+++ b/test/proximity.js
@@ -3,15 +3,14 @@ var MockFirmata = require("./util/mock-firmata"),
events = require("events"),
sinon = require("sinon"),
Board = five.Board,
- Sensor = five.Sensor,
- Proximity = five.IR.Proximity,
+ Proximity = five.Proximity,
board = new Board({
io: new MockFirmata(),
debug: false,
repl: false
});
-exports["IR.Proximity"] = {
+exports["Proximity"] = {
setUp: function(done) {
this.clock = sinon.useFakeTimers();
this.analogRead = sinon.spy(board.io, "analogRead");
@@ -46,12 +45,6 @@ exports["IR.Proximity"] = {
test.done();
},
- sensor: function(test) {
- test.expect(1);
- test.ok(this.distance instanceof Sensor);
- test.done();
- },
-
emitter: function(test) {
test.expect(1);
test.ok(this.distance instanceof events.EventEmitter);
@@ -59,7 +52,7 @@ exports["IR.Proximity"] = {
}
};
-exports["IR.Proximity: GP2Y0A21YK"] = {
+exports["Proximity: GP2Y0A21YK"] = {
setUp: function(done) {
this.clock = sinon.useFakeTimers();
this.analogRead = sinon.spy(board.io, "analogRead");
@@ -95,7 +88,7 @@ exports["IR.Proximity: GP2Y0A21YK"] = {
}
};
-exports["IR.Proximity: GP2D120XJ00F"] = {
+exports["Proximity: GP2D120XJ00F"] = {
setUp: function(done) {
this.clock = sinon.useFakeTimers();
this.analogRead = sinon.spy(board.io, "analogRead");
@@ -130,7 +123,7 @@ exports["IR.Proximity: GP2D120XJ00F"] = {
}
};
-exports["IR.Proximity: GP2Y0A02YK0F"] = {
+exports["Proximity: GP2Y0A02YK0F"] = {
setUp: function(done) {
this.clock = sinon.useFakeTimers();
this.analogRead = sinon.spy(board.io, "analogRead");
@@ -166,7 +159,7 @@ exports["IR.Proximity: GP2Y0A02YK0F"] = {
}
};
-exports["IR.Proximity: GP2Y0A41SK0F"] = {
+exports["Proximity: GP2Y0A41SK0F"] = {
setUp: function(done) {
this.clock = sinon.useFakeTimers();
this.analogRead = sinon.spy(board.io, "analogRead");
@@ -202,6 +195,280 @@ exports["IR.Proximity: GP2Y0A41SK0F"] = {
}
};
+exports["Proximity: MB1003"] = {
+ setUp: function(done) {
+ this.clock = sinon.useFakeTimers();
+ this.analogRead = sinon.spy(board.io, "analogRead");
+ this.distance = new Proximity({
+ controller: "MB1003",
+ pin: "A1",
+ board: board
+ });
+
+ done();
+ },
+
+ tearDown: function(done) {
+ this.clock.restore();
+ this.analogRead.restore();
+ done();
+ },
+
+ MB1003: function(test) {
+ var callback = this.analogRead.args[0][1];
+
+ test.expect(4);
+
+ // 500 is an actual reading at ~250cm
+ callback(500);
+
+ test.equals(Math.round(this.distance.centimeters), 250);
+ test.equals(Math.round(this.distance.cm), 250);
+ test.equals(Math.round(this.distance.inches), 98);
+ test.equals(Math.round(this.distance.in), 98);
+
+ test.done();
+ }
+};
+
+
+exports["Proximity: SRF10"] = {
+
+ setUp: function(done) {
+
+ this.clock = sinon.useFakeTimers();
+ this.i2cReadOnce = sinon.spy(board.io, "i2cReadOnce");
+ this.i2cWrite = sinon.spy(board.io, "i2cWrite");
+ this.i2cConfig = sinon.spy(board.io, "i2cConfig");
+
+ this.proximity = new Proximity({
+ controller: "SRF10",
+ board: board
+ });
+
+ this.proto = [{
+ name: "within"
+ }];
+
+ this.instance = [{
+ name: "centimeters"
+ }, {
+ name: "cm"
+ },{
+ name: "inches"
+ }, {
+ name: "in"
+ }];
+
+ done();
+ },
+
+ tearDown: function(done) {
+ this.clock.restore();
+ this.i2cReadOnce.restore();
+ this.i2cWrite.restore();
+ this.i2cConfig.restore();
+
+ done();
+ },
+
+ shape: function(test) {
+ test.expect(this.proto.length + this.instance.length);
+
+ this.proto.forEach(function(method) {
+ test.equal(typeof this.proximity[method.name], "function");
+ }, this);
+
+ this.instance.forEach(function(property) {
+ test.notEqual(typeof this.proximity[property.name], 0);
+ }, this);
+
+ test.done();
+ },
+
+ initialize: function(test) {
+ test.expect(5);
+
+ test.ok(this.i2cConfig.called);
+ test.ok(this.i2cWrite.calledThrice);
+
+ test.deepEqual(this.i2cConfig.args[0], [0]);
+ test.deepEqual(
+ this.i2cWrite.firstCall.args, [0x70, [0x01, 16]]
+ );
+ test.deepEqual(
+ this.i2cWrite.secondCall.args, [0x70, [0x02, 255]]
+ );
+
+ test.done();
+ },
+
+ data: function(test) {
+ test.expect(2);
+
+ this.clock.tick(100);
+
+ var callback = this.i2cReadOnce.args[0][2],
+ spy = sinon.spy();
+
+ test.equal(spy.callCount, 0);
+
+ this.proximity.on("data", spy);
+
+ callback([3, 225]);
+ callback([3, 255]);
+
+ this.clock.tick(100);
+
+ test.ok(spy.called);
+ test.done();
+ },
+
+ change: function(test) {
+ this.clock.tick(100);
+
+ var callback = this.i2cReadOnce.args[0][2],
+ spy = sinon.spy();
+
+ test.expect(1);
+ this.proximity.on("change", spy);
+
+ this.clock.tick(100);
+ callback([3, 225]);
+
+ this.clock.tick(100);
+ callback([3, 255]);
+
+ this.clock.tick(100);
+
+ test.ok(spy.called);
+ test.done();
+ },
+
+ within_unit: function(test) {
+ this.clock.tick(65);
+
+ var callback = this.i2cReadOnce.args[0][2];
+ var called = false;
+
+ test.expect(1);
+
+ this.proximity.within([3, 6], "inches", function() {
+ if (!called) {
+ called = true;
+ test.equal(this.inches, 3.9);
+ test.done();
+ }
+ });
+
+ callback([0, 10]);
+ this.clock.tick(100);
+ }
+};
+
+exports["Proximity: HCSR04"] = {
+ setUp: function(done) {
+ this.clock = sinon.useFakeTimers();
+ this.pulseVal = 1000;
+
+ sinon.stub(board.io, "pulseIn", function(settings, handler) {
+ handler(this.pulseVal);
+ }.bind(this));
+
+ this.ping = new Proximity({
+ controller: "HCSR04",
+ pin: 7,
+ freq: 100,
+ board: board
+ });
+
+ this.proto = [{
+ name: "within"
+ }];
+
+ this.instance = [{
+ name: "centimeters"
+ }, {
+ name: "cm"
+ },{
+ name: "inches"
+ }, {
+ name: "in"
+ }];
+
+ done();
+ },
+
+ tearDown: function(done) {
+ board.io.pulseIn.restore();
+ this.clock.restore();
+ done();
+ },
+
+ shape: function(test) {
+ test.expect(this.proto.length + this.instance.length);
+
+ this.proto.forEach(function(method) {
+ test.equal(typeof this.ping[method.name], "function");
+ }, this);
+
+ this.instance.forEach(function(property) {
+ test.notEqual(typeof this.ping[property.name], 0);
+ }, this);
+
+ test.done();
+ },
+
+ data: function(test) {
+ var spy = sinon.spy();
+ test.expect(1);
+
+ // tick the clock forward to trigger the pulseIn handler
+ this.clock.tick(250);
+
+ this.ping.on("data", spy);
+ this.clock.tick(100);
+ test.ok(spy.calledOnce);
+ test.done();
+ },
+
+ change: function(test) {
+ var spy = sinon.spy();
+ test.expect(1);
+
+ this.pulseVal = 0;
+
+ // tick the clock forward to trigger the pulseIn handler
+ this.clock.tick(250);
+
+ this.pulseVal = 1000;
+
+ this.ping.on("change", spy);
+ this.clock.tick(100);
+ test.ok(spy.calledOnce);
+ test.done();
+
+ },
+
+ within: function(test) {
+ var spy = sinon.spy();
+ test.expect(2);
+
+ // tick the clock forward to trigger the pulseIn handler
+ this.clock.tick(250);
+
+ this.ping.within([0, 120], "inches", function() {
+ // The fake microseconds value is 1000, which
+ // calculates to 6.76 inches.
+ test.equal(this.inches, 6.7);
+ spy();
+ });
+
+ this.clock.tick(100);
+ test.ok(spy.calledOnce);
+ test.done();
+ }
+};
// - GP2Y0A21YK
// https://www.sparkfun.com/products/242
diff --git a/tpl/programs.json b/tpl/programs.json
index d94fe2103..f024d8a09 100644
--- a/tpl/programs.json
+++ b/tpl/programs.json
@@ -421,6 +421,32 @@
}
]
},
+ {
+ "topic": "Proximity",
+ "classes": ["Proximity"],
+ "examples": [
+ {
+ "file": "proximity.js",
+ "title": "Proximity",
+ "description": "Basic infrared Proximity example"
+ },
+ {
+ "file": "proximity-srf10.js",
+ "title": "Proximity - SRF10",
+ "description": "Basic sonar Proximity example with SRF10 sensor."
+ },
+ {
+ "file": "proximity-mb1003.js",
+ "title": "Proximity - MB1003",
+ "description": "Basic sonar Proximity example with MB1003 sensor."
+ },
+ {
+ "file": "proximity-hcsr04.js",
+ "title": "Proximity - HC-SR04",
+ "description": "Basic ping Proximity example with HC-SR04 sensor."
+ }
+ ]
+ },
{
"topic": "Joystick",
"classes": ["Joystick"],