diff --git a/.gitignore b/.gitignore index 608b36098..3d10c6e00 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store +.nyc_output node_modules npm-debug.log wip/ diff --git a/.istanbul.yml b/.istanbul.yml deleted file mode 100644 index 4afec1a8b..000000000 --- a/.istanbul.yml +++ /dev/null @@ -1,13 +0,0 @@ -instrumentation: - root: lib/ - excludes: [ - # To be removed. - "gripper.js", - # These are deprecated and no new tests will be written. - # See tests for proxitimty, motion - "distance.js", - "ir.js", - "ping.js", - "pir.js", - "sonar.js", - ] diff --git a/.npmignore b/.npmignore index 616b82821..bffba578a 100644 --- a/.npmignore +++ b/.npmignore @@ -1,32 +1,35 @@ -node_modules/ +*.c +*.cpp +*.h +*.ino +*.py +.gitignore +.istanbul.yml +.jscsrc +.jshintrc +.nyc_output +.nycrc +.travis.yml +appveyor.yml +articles.js +articles.yaml assets/ +awesome.md +CODE_OF_CONDUCT.md +colors.js +CONTRIBUTING.md coverage/ docs/ eg/ +egs-markdown.js +egs.js +Gruntfile.js +LICENSE-MIT +node_modules/ +parts.md +release +send.sh test/ tpl/ util/ wip/ -articles.yaml -articles.js -*.c -*.ino -*.py -*.cpp -*.h -release -egs.js -send.sh -awesome.md -parts.md -Gruntfile.js -CODE_OF_CONDUCT.md -CONTRIBUTING.md -colors.js -.travis.yml -.jshintrc -.jscsrc -.gitignore -.istanbul.yml -appveyor.yml -LICENSE-MIT diff --git a/.nycrc b/.nycrc new file mode 100644 index 000000000..46c0077b2 --- /dev/null +++ b/.nycrc @@ -0,0 +1,18 @@ +{ + "reporter": [ + "lcov" + ], + "include": [ + "lib/**/*.js" + ], + "exclude": [ + "Gruntfile.js", + "lib/gripper.js", + "lib/distance.js", + "lib/ir.js", + "lib/ping.js", + "lib/pir.js", + "lib/sonar.js" + ] +} + diff --git a/.tesselignore b/.tesselignore index cf25548ac..f303410b7 100644 --- a/.tesselignore +++ b/.tesselignore @@ -2,6 +2,7 @@ assets/ docs/ eg/ +node_modules/browser-serialport node_modules/es6-shim node_modules/firmata node_modules/optimist diff --git a/Gruntfile.js b/Gruntfile.js index c4bbb28ba..4622a04a9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,11 +1,11 @@ if (!Array.from || !Object.assign || !Map) { require("es6-shim"); } -require("copy-paste"); var cp = require("child_process"); var fs = require("fs"); var path = require("path"); +var ncp = require("copy-paste"); var shell = require("shelljs"); process.env.IS_TEST_MODE = true; @@ -217,12 +217,19 @@ module.exports = function(grunt) { // Support running a complete set of tests with // extended (possibly-slow) tests included. grunt.registerTask("nodeunit:complete", function() { - var testConfig = grunt.config("nodeunit.tests"); - testConfig.push("test/extended/*.js"); - grunt.config("nodeunit.tests", testConfig); - grunt.task.run("nodeunit"); + console.log("\nDid you mean? 'grunt nodeunit:extended' ?"); }); + grunt.registerTask("nodeunit:extended", function() { + grunt.config("nodeunit.tests", [ + "test/extended/animation.js", + "test/extended/led.js", + "test/extended/piezo.js", + "test/extended/servo.js", + ]); + + grunt.task.run("nodeunit"); + }); grunt.registerMultiTask("examples", "Generate examples", function() { // Concat specified files. @@ -365,7 +372,8 @@ module.exports = function(grunt) { file.write("README.md", templates.readme({ noedit: noedit, - eglinks: readme.join("") + egcount: readme.length, + eglinks: readme.join(""), }) ); @@ -442,7 +450,7 @@ module.exports = function(grunt) { replacement = data.join(".").trim(); } - copy(replacement); + ncp.copy(replacement); return " \"version\": \"" + replacement + "\","; } diff --git a/README.md b/README.md index 475e650f6..5186d4120 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,8 @@ To get you up and running quickly, we provide a variety of examples for using ea To interactively navigate the examples, visit the [Johnny-Five examples](http://johnny-five.io/examples/) page on the official website. If you want to link directly to the examples in this repo, you can use one of the following links. +**There are presently 354 example programs with code and diagrams!** + ### Board @@ -231,6 +233,7 @@ To interactively navigate the examples, visit the [Johnny-Five examples](http:// ### GPS - [GPS - Adafruit Ultimate GPS Breakout](https://github.com/rwaldron/johnny-five/blob/master/docs/gps-adafruit.md) - [GPS - Default GPS](https://github.com/rwaldron/johnny-five/blob/master/docs/gps.md) +- [GPS - Sparkfun GP-20U7](https://github.com/rwaldron/johnny-five/blob/master/docs/gps-GP-20U7.md) ### Servo Animation - [Servo - Animation](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-animation.md) @@ -256,6 +259,8 @@ To interactively navigate the examples, visit the [Johnny-Five examples](http:// - [Motor - LUDUS](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-LUDUS.md) - [Motor - PCA9685](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-PCA9685.md) - [Motor - Sparkfun Dual H-bridge Edison Block](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-sparkfun-edison-hbridge.md) +- [Motor - Sparkfun TB6612FNG](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-TB6612FNG.md) +- [Motors - Dual H-Bridge](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-hbridge-dual.md) ### Stepper Motor - [Stepper - Driver](https://github.com/rwaldron/johnny-five/blob/master/docs/stepper-driver.md) @@ -368,15 +373,20 @@ To interactively navigate the examples, visit the [Johnny-Five examples](http:// - [IMU - BNO055](https://github.com/rwaldron/johnny-five/blob/master/docs/imu-bno055.md) - [IMU - BNO055 (Orientation)](https://github.com/rwaldron/johnny-five/blob/master/docs/imu-bno055-orientation.md) - [IMU - MPU6050](https://github.com/rwaldron/johnny-five/blob/master/docs/imu-mpu6050.md) +- [Multi - BME280](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-BME280.md) - [Multi - BMP085](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-bmp085.md) - [Multi - BMP180](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-bmp180.md) - [Multi - DHT11_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-DHT11_I2C_NANO_BACKPACK.md) +- [Multi - DHT21_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-DHT21_I2C_NANO_BACKPACK.md) +- [Multi - DHT22_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-DHT22_I2C_NANO_BACKPACK.md) +- [Multi - HIH6130](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-HIH6130.md) - [Multi - HTU21D](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-htu21d.md) - [Multi - MPL115A2](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-mpl115a2.md) - [Multi - MPL3115A2](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-mpl3115a2.md) - [Multi - MS5611](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-MS5611.md) - [Multi - SHT31D](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-sht31d.md) - [Multi - SI7020](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-SI7020.md) +- [Multi - SI7021](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-SI7021.md) - [Multi - TH02](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-TH02.md) ### Sensors @@ -401,10 +411,15 @@ To interactively navigate the examples, visit the [Johnny-Five examples](http:// - [Gyro - Analog LPR5150AL](https://github.com/rwaldron/johnny-five/blob/master/docs/gyro-lpr5150l.md) - [Gyro - I2C MPU6050](https://github.com/rwaldron/johnny-five/blob/master/docs/gyro-mpu6050.md) - [Hygrometer - DHT11_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/hygrometer-DHT11_I2C_NANO_BACKPACK.md) +- [Hygrometer - DHT21_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/hygrometer-DHT21_I2C_NANO_BACKPACK.md) +- [Hygrometer - DHT22_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/hygrometer-DHT22_I2C_NANO_BACKPACK.md) +- [Hygrometer - HIH6130](https://github.com/rwaldron/johnny-five/blob/master/docs/hygrometer-HIH6130.md) - [Hygrometer - HTU21D](https://github.com/rwaldron/johnny-five/blob/master/docs/hygrometer-htu21d.md) - [Hygrometer - SHT31D](https://github.com/rwaldron/johnny-five/blob/master/docs/hygrometer-sht31d.md) +- [Hygrometer - SI7021](https://github.com/rwaldron/johnny-five/blob/master/docs/hygrometer-SI7021.md) - [Hygrometer - TH02](https://github.com/rwaldron/johnny-five/blob/master/docs/hygrometer-TH02.md) - [Sensor](https://github.com/rwaldron/johnny-five/blob/master/docs/sensor.md) +- [Sensor - Digital Microwave](https://github.com/rwaldron/johnny-five/blob/master/docs/sensor-digital-microwave.md) - [Sensor - Force sensitive resistor](https://github.com/rwaldron/johnny-five/blob/master/docs/sensor-fsr.md) - [Sensor - Microphone](https://github.com/rwaldron/johnny-five/blob/master/docs/microphone.md) - [Sensor - Photoresistor](https://github.com/rwaldron/johnny-five/blob/master/docs/photoresistor.md) @@ -413,7 +428,10 @@ To interactively navigate the examples, visit the [Johnny-Five examples](http:// - [Thermometer - BMP085](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-bmp085.md) - [Thermometer - BMP180](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-BMP180.md) - [Thermometer - DHT11_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-DHT11_I2C_NANO_BACKPACK.md) +- [Thermometer - DHT21_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-DHT21_I2C_NANO_BACKPACK.md) +- [Thermometer - DHT22_I2C_NANO_BACKPACK](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-DHT22_I2C_NANO_BACKPACK.md) - [Thermometer - DS18B20](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-ds18b20.md) +- [Thermometer - HIH6130](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-HIH6130.md) - [Thermometer - HTU21D](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-htu21d.md) - [Thermometer - LM335](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-lm335.md) - [Thermometer - LM35](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-lm35.md) @@ -425,6 +443,7 @@ To interactively navigate the examples, visit the [Johnny-Five examples](http:// - [Thermometer - MS5611](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-MS5611.md) - [Thermometer - SHT31D](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-sht31d.md) - [Thermometer - SI7020](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-SI7020.md) +- [Thermometer - SI7021](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-SI7021.md) - [Thermometer - TH02](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-TH02.md) - [Thermometer - TMP102](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-tmp102.md) - [Thermometer - TMP36](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-tmp36.md) diff --git a/docs/accelerometer.md b/docs/accelerometer.md index d47e35573..d710d878c 100644 --- a/docs/accelerometer.md +++ b/docs/accelerometer.md @@ -120,13 +120,10 @@ board.on("ready", function() { ## Additional Notes - - [Triple Axis Accelerometer, MMA7361](https://www.sparkfun.com/products/9652) - [Triple-Axis Accelerometer, ADXL326](http://www.adafruit.com/products/1018) - - [Two or Three Axis Accelerometer, LIS344AL](http://www.st.ewi.tudelft.nl/~gemund/Courses/In4073/Resources/LIS344AL.pdf) -   diff --git a/docs/altimeter-BMP085.md b/docs/altimeter-BMP085.md index 6cb2df92d..af1d62158 100644 --- a/docs/altimeter-BMP085.md +++ b/docs/altimeter-BMP085.md @@ -35,7 +35,7 @@ var board = new five.Board(); board.on("ready", function() { // By including a base `elevation` property, the values // received will be absolute elevation (from sealevel) - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP085", // Change `elevation` with whatever is reported // on http://www.whatismyelevation.com/. @@ -43,8 +43,8 @@ board.on("ready", function() { elevation: 12, }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); @@ -67,12 +67,12 @@ var board = new five.Board(); board.on("ready", function() { // By omitting the base `elevation` property, the values // received will be relative to your present elevation - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP085", }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/docs/altimeter-BMP180.md b/docs/altimeter-BMP180.md index bb2601fa9..c9a18efea 100644 --- a/docs/altimeter-BMP180.md +++ b/docs/altimeter-BMP180.md @@ -35,7 +35,7 @@ var board = new five.Board(); board.on("ready", function() { // By including a base `elevation` property, the values // received will be absolute elevation (from sealevel) - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP180", // Change `elevation` with whatever is reported // on http://www.whatismyelevation.com/. @@ -43,8 +43,8 @@ board.on("ready", function() { elevation: 12, }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); @@ -67,12 +67,12 @@ var board = new five.Board(); board.on("ready", function() { // By omitting the base `elevation` property, the values // received will be relative to your present elevation - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP180", }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/docs/altimeter-MS5611.md b/docs/altimeter-MS5611.md index 783e100fa..1c328690f 100644 --- a/docs/altimeter-MS5611.md +++ b/docs/altimeter-MS5611.md @@ -35,7 +35,7 @@ var board = new five.Board(); board.on("ready", function() { // By including a base `elevation` property, the values // received will be absolute elevation (from sealevel) - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "MS5611", // Change `elevation` with whatever is reported // on http://www.whatismyelevation.com/. @@ -43,8 +43,8 @@ board.on("ready", function() { elevation: 12, }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); @@ -67,12 +67,12 @@ var board = new five.Board(); board.on("ready", function() { // By omitting the base `elevation` property, the values // received will be relative to your present elevation - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "MS5611", }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/docs/barometer-BMP085.md b/docs/barometer-BMP085.md index e73f62583..e455ea8ac 100644 --- a/docs/barometer-BMP085.md +++ b/docs/barometer-BMP085.md @@ -33,12 +33,12 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var bar = new five.Barometer({ + var barometer = new five.Barometer({ controller: "BMP085" }); - bar.on("change", function() { - console.log("barometer"); + barometer.on("change", function() { + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); }); diff --git a/docs/barometer-BMP180.md b/docs/barometer-BMP180.md index fa4b5c8ed..0bdfb5bc8 100644 --- a/docs/barometer-BMP180.md +++ b/docs/barometer-BMP180.md @@ -38,7 +38,7 @@ board.on("ready", function() { }); barometer.on("change", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); diff --git a/docs/barometer-MS5611.md b/docs/barometer-MS5611.md index 0bbdf9587..852ade61f 100644 --- a/docs/barometer-MS5611.md +++ b/docs/barometer-MS5611.md @@ -38,7 +38,7 @@ board.on("ready", function() { }); pressure.on("change", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); diff --git a/docs/barometer-mpl115a2.md b/docs/barometer-mpl115a2.md index 8b4c1fd0e..57f8d5aca 100644 --- a/docs/barometer-mpl115a2.md +++ b/docs/barometer-mpl115a2.md @@ -38,7 +38,7 @@ board.on("ready", function() { }); barometer.on("data", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); diff --git a/docs/barometer-mpl3115a2.md b/docs/barometer-mpl3115a2.md index 0ec6f2d8a..f019062d0 100644 --- a/docs/barometer-mpl3115a2.md +++ b/docs/barometer-mpl3115a2.md @@ -38,7 +38,7 @@ board.on("ready", function() { }); barometer.on("data", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); diff --git a/docs/breadboard/gps-GP-20U7.fzz b/docs/breadboard/gps-GP-20U7.fzz new file mode 100644 index 000000000..c24171368 Binary files /dev/null and b/docs/breadboard/gps-GP-20U7.fzz differ diff --git a/docs/breadboard/gps-GP-20U7.png b/docs/breadboard/gps-GP-20U7.png new file mode 100644 index 000000000..a61dd9e53 Binary files /dev/null and b/docs/breadboard/gps-GP-20U7.png differ diff --git a/docs/breadboard/motor-TB6612FNG.fzz b/docs/breadboard/motor-TB6612FNG.fzz new file mode 100644 index 000000000..e03c0d340 Binary files /dev/null and b/docs/breadboard/motor-TB6612FNG.fzz differ diff --git a/docs/breadboard/motor-TB6612FNG.png b/docs/breadboard/motor-TB6612FNG.png new file mode 100644 index 000000000..88b97e219 Binary files /dev/null and b/docs/breadboard/motor-TB6612FNG.png differ diff --git a/docs/breadboard/motor-enable.fzz b/docs/breadboard/motor-enable.fzz index 63bd8529b..f3eb1560a 100644 Binary files a/docs/breadboard/motor-enable.fzz and b/docs/breadboard/motor-enable.fzz differ diff --git a/docs/breadboard/motor-enable.png b/docs/breadboard/motor-enable.png index c6b3c8535..8e518d58f 100644 Binary files a/docs/breadboard/motor-enable.png and b/docs/breadboard/motor-enable.png differ diff --git a/docs/breadboard/motor-hbridge-dual.fzz b/docs/breadboard/motor-hbridge-dual.fzz new file mode 100644 index 000000000..e210c5632 Binary files /dev/null and b/docs/breadboard/motor-hbridge-dual.fzz differ diff --git a/docs/breadboard/motor-hbridge-dual.png b/docs/breadboard/motor-hbridge-dual.png new file mode 100644 index 000000000..8c31d8656 Binary files /dev/null and b/docs/breadboard/motor-hbridge-dual.png differ diff --git a/docs/breadboard/motor-hbridge.fzz b/docs/breadboard/motor-hbridge.fzz index 192f0d688..3e0f8dfba 100644 Binary files a/docs/breadboard/motor-hbridge.fzz and b/docs/breadboard/motor-hbridge.fzz differ diff --git a/docs/breadboard/motor-hbridge.png b/docs/breadboard/motor-hbridge.png index a4be201eb..922e64b86 100644 Binary files a/docs/breadboard/motor-hbridge.png and b/docs/breadboard/motor-hbridge.png differ diff --git a/docs/breadboard/multi-BME280-arduino.fzz b/docs/breadboard/multi-BME280-arduino.fzz new file mode 100644 index 000000000..cd94fa011 Binary files /dev/null and b/docs/breadboard/multi-BME280-arduino.fzz differ diff --git a/docs/breadboard/multi-BME280-arduino.png b/docs/breadboard/multi-BME280-arduino.png new file mode 100644 index 000000000..26eec2401 Binary files /dev/null and b/docs/breadboard/multi-BME280-arduino.png differ diff --git a/docs/breadboard/multi-BME280-tessel.fzz b/docs/breadboard/multi-BME280-tessel.fzz new file mode 100644 index 000000000..3196a2669 Binary files /dev/null and b/docs/breadboard/multi-BME280-tessel.fzz differ diff --git a/docs/breadboard/multi-BME280-tessel.png b/docs/breadboard/multi-BME280-tessel.png new file mode 100644 index 000000000..b01a4c256 Binary files /dev/null and b/docs/breadboard/multi-BME280-tessel.png differ diff --git a/docs/breadboard/multi-DHT11_I2C_NANO_BACKPACK.fzz b/docs/breadboard/multi-DHT11_I2C_NANO_BACKPACK.fzz index 52c0b5e2e..ba9dd4513 100644 Binary files a/docs/breadboard/multi-DHT11_I2C_NANO_BACKPACK.fzz and b/docs/breadboard/multi-DHT11_I2C_NANO_BACKPACK.fzz differ diff --git a/docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz b/docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz new file mode 100644 index 000000000..915c4a547 Binary files /dev/null and b/docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz differ diff --git a/docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.png b/docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.png new file mode 100644 index 000000000..9eb402bfd Binary files /dev/null and b/docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.png differ diff --git a/docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz b/docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz new file mode 100644 index 000000000..e9732d661 Binary files /dev/null and b/docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz differ diff --git a/docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.png b/docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.png new file mode 100644 index 000000000..d04a1ecc9 Binary files /dev/null and b/docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.png differ diff --git a/docs/breadboard/multi-HIH6130.fzz b/docs/breadboard/multi-HIH6130.fzz new file mode 100644 index 000000000..5847541d5 Binary files /dev/null and b/docs/breadboard/multi-HIH6130.fzz differ diff --git a/docs/breadboard/multi-HIH6130.png b/docs/breadboard/multi-HIH6130.png new file mode 100644 index 000000000..94d11baaa Binary files /dev/null and b/docs/breadboard/multi-HIH6130.png differ diff --git a/docs/breadboard/multi-SI7021-uno.fzz b/docs/breadboard/multi-SI7021-uno.fzz new file mode 100644 index 000000000..a7c83c41f Binary files /dev/null and b/docs/breadboard/multi-SI7021-uno.fzz differ diff --git a/docs/breadboard/multi-SI7021-uno.png b/docs/breadboard/multi-SI7021-uno.png new file mode 100644 index 000000000..e7d5c448e Binary files /dev/null and b/docs/breadboard/multi-SI7021-uno.png differ diff --git a/docs/breadboard/multi-SI7021.fzz b/docs/breadboard/multi-SI7021.fzz new file mode 100644 index 000000000..0f6be9efc Binary files /dev/null and b/docs/breadboard/multi-SI7021.fzz differ diff --git a/docs/breadboard/multi-SI7021.png b/docs/breadboard/multi-SI7021.png new file mode 100644 index 000000000..d3e526925 Binary files /dev/null and b/docs/breadboard/multi-SI7021.png differ diff --git a/docs/breadboard/multi-bmp180-sfe.fzz b/docs/breadboard/multi-bmp180-sfe.fzz index a1c4fc282..3980e5f60 100644 Binary files a/docs/breadboard/multi-bmp180-sfe.fzz and b/docs/breadboard/multi-bmp180-sfe.fzz differ diff --git a/docs/breadboard/multi-bmp180-sfe.png b/docs/breadboard/multi-bmp180-sfe.png index 9e5819ee1..da09e7d75 100644 Binary files a/docs/breadboard/multi-bmp180-sfe.png and b/docs/breadboard/multi-bmp180-sfe.png differ diff --git a/docs/breadboard/proximity-hcsr04-i2c.fzz b/docs/breadboard/proximity-hcsr04-i2c.fzz index 9dbc8f89f..d688d23e5 100644 Binary files a/docs/breadboard/proximity-hcsr04-i2c.fzz and b/docs/breadboard/proximity-hcsr04-i2c.fzz differ diff --git a/docs/breadboard/proximity-hcsr04-i2c.png b/docs/breadboard/proximity-hcsr04-i2c.png index fff36e08f..36fa493fe 100644 Binary files a/docs/breadboard/proximity-hcsr04-i2c.png and b/docs/breadboard/proximity-hcsr04-i2c.png differ diff --git a/docs/breadboard/sensor-digital-microwave.fzz b/docs/breadboard/sensor-digital-microwave.fzz new file mode 100644 index 000000000..01bfd06e3 Binary files /dev/null and b/docs/breadboard/sensor-digital-microwave.fzz differ diff --git a/docs/breadboard/sensor-digital-microwave.png b/docs/breadboard/sensor-digital-microwave.png new file mode 100644 index 000000000..db9840b82 Binary files /dev/null and b/docs/breadboard/sensor-digital-microwave.png differ diff --git a/docs/claw.md b/docs/claw.md index b654a9ca1..47b738dee 100644 --- a/docs/claw.md +++ b/docs/claw.md @@ -62,15 +62,12 @@ board.on("ready", function() { ## Additional Notes - - [Robotic Claw](https://www.sparkfun.com/products/11524) - [Robotic Claw Pan/Tilt](https://www.sparkfun.com/products/11674) - [Robotic Claw Assembly](https://www.sparkfun.com/tutorials/258) - ![Robotic Claw](https://cdn.sparkfun.com//assets/parts/7/4/4/4/11524-01a.jpg) ![Robotic Claw Pan/Tilt](https://cdn.sparkfun.com//assets/parts/7/7/6/7/11674-02.jpg) -   diff --git a/docs/edison-io-arduino.md b/docs/edison-io-arduino.md index 71de79f4d..2b01f7288 100644 --- a/docs/edison-io-arduino.md +++ b/docs/edison-io-arduino.md @@ -61,17 +61,13 @@ board.on("ready", function() { ## Additional Notes - In order to use the Edison-IO library, you will need to flash the Intel IoTDevKit Image on your Edison. Once the environment is created, install Johnny-Five and Edison-IO. - ```sh npm install johnny-five edison-io ``` - - ## Learn More - [edison-io on GitHub](https://github.com/rwaldron/edison-io/) diff --git a/docs/edison-io-miniboard.md b/docs/edison-io-miniboard.md index 6e67302fe..3962233e1 100644 --- a/docs/edison-io-miniboard.md +++ b/docs/edison-io-miniboard.md @@ -61,17 +61,13 @@ board.on("ready", function() { ## Additional Notes - In order to use the Edison-IO library, you will need to flash the Intel IoTDevKit Image on your Edison. Once the environment is created, install Johnny-Five and Edison-IO. - ```sh npm install johnny-five edison-io ``` - - ## Learn More - [edison-io on GitHub](https://github.com/rwaldron/edison-io/) diff --git a/docs/galileo-io.md b/docs/galileo-io.md index 7d0aba5f9..66a15d5ff 100644 --- a/docs/galileo-io.md +++ b/docs/galileo-io.md @@ -61,17 +61,13 @@ board.on("ready", function() { ## Additional Notes - In order to use the Galileo-IO library, you will need to flash the Intel IoTDevKit Image on your Galileo Gen 2. Once the environment is created, install Johnny-Five and Galileo-IO. - ```sh npm install johnny-five galileo-io ``` - - ## Learn More - [galileo-io on GitHub](https://github.com/rwaldron/galileo-io/) diff --git a/docs/gps-GP-20U7.md b/docs/gps-GP-20U7.md new file mode 100644 index 000000000..8046c0e16 --- /dev/null +++ b/docs/gps-GP-20U7.md @@ -0,0 +1,81 @@ + + +# GPS - Sparkfun GP-20U7 + + + + +When using GPS class with an Arduino (or similar microcontroller), be sure to upload the StandardFirmataPlus firmware to your board. + + + + + +##### Breadboard for "GPS - Sparkfun GP-20U7" + + + +![docs/breadboard/gps-GP-20U7.png](breadboard/gps-GP-20U7.png)
+ +Fritzing diagram: [docs/breadboard/gps-GP-20U7.fzz](breadboard/gps-GP-20U7.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/gps-GP-20U7.js +``` + + +```javascript +var five = require("johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + var gps = new five.GPS({ + pins: { + rx: 11, + tx: 10, + } + }); + + // If latitude, longitude data log it. + // This will output zero until a valid + // GPS position is detected. + gps.on("data", function() { + console.log("position"); + console.log(" latitude : ", this.latitude); + console.log(" longitude : ", this.longitude); + console.log(" altitude : ", this.altitude); + console.log("--------------------------------------"); + }); +}); + +``` + + + + + + + + + +## Learn More + +- [GPS Receiver - GP-20U7 (56 Channel)](https://www.sparkfun.com/products/13740) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/grove-accelerometer-adxl345-edison.md b/docs/grove-accelerometer-adxl345-edison.md index bae5044d6..e50317880 100644 --- a/docs/grove-accelerometer-adxl345-edison.md +++ b/docs/grove-accelerometer-adxl345-edison.md @@ -59,15 +59,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - 3-Axis Digital Accelerometer(±16g)](http://www.seeedstudio.com/depot/images/101020054%201.jpg) - -   diff --git a/docs/grove-accelerometer-mma7660-edison.md b/docs/grove-accelerometer-mma7660-edison.md index b9ce4b695..709530edc 100644 --- a/docs/grove-accelerometer-mma7660-edison.md +++ b/docs/grove-accelerometer-mma7660-edison.md @@ -59,15 +59,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - 3-Axis Digital Accelerometer(±1.5g)](http://www.seeedstudio.com/depot/images/101020039%201.jpg) - -   diff --git a/docs/grove-barometer-edison.md b/docs/grove-barometer-edison.md index 5e05dac34..77f2e1ae2 100644 --- a/docs/grove-barometer-edison.md +++ b/docs/grove-barometer-edison.md @@ -35,7 +35,7 @@ board.on("ready", function() { }); barometer.on("change", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); @@ -52,16 +52,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Barometer Sensor (BMP180)](http://www.seeedstudio.com/depot/images/product/Grove%20Barometer%20Sensor%20BMP180.jpg) - - [Grove - Barometer Sensor (BMP180)](http://www.seeedstudio.com/depot/Grove-Barometer-Sensor-BMP180-p-1840.html) -   diff --git a/docs/grove-button-edison.md b/docs/grove-button-edison.md index fbe88a1a3..387ca1d48 100644 --- a/docs/grove-button-edison.md +++ b/docs/grove-button-edison.md @@ -60,16 +60,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) - ![Grove - Button Module](http://www.seeedstudio.com/depot/images/product/bgpushb1.jpg) -   diff --git a/docs/grove-button.md b/docs/grove-button.md index 78334faf4..1dbc99385 100644 --- a/docs/grove-button.md +++ b/docs/grove-button.md @@ -55,14 +55,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) - ![Grove - Button Module](http://www.seeedstudio.com/depot/images/product/bgpushb1.jpg) -   diff --git a/docs/grove-compass-edison.md b/docs/grove-compass-edison.md index d1fe2ae05..375b38d30 100644 --- a/docs/grove-compass-edison.md +++ b/docs/grove-compass-edison.md @@ -59,17 +59,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - 3-Axis Digital Compass](http://www.seeedstudio.com/depot/images/101020034%201.jpg) - - [Grove - 3-Axis Digital Compass](http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Compass-p-759.html) - -   diff --git a/docs/grove-flame-sensor-edison.md b/docs/grove-flame-sensor-edison.md index 77de781b7..7aecbb9e9 100644 --- a/docs/grove-flame-sensor-edison.md +++ b/docs/grove-flame-sensor-edison.md @@ -55,16 +55,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Flame Detector Sensor](http://www.seeedstudio.com/depot/images/product/Flame%20Sensor.jpg) - - [Grove - Flame Detector Sensor](http://www.seeedstudio.com/depot/Grove-Flame-Sensor-p-1450.html) -   diff --git a/docs/grove-gas-mq2-edison.md b/docs/grove-gas-mq2-edison.md index 19789d511..881bcc8d5 100644 --- a/docs/grove-gas-mq2-edison.md +++ b/docs/grove-gas-mq2-edison.md @@ -56,16 +56,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Buzzer Module](http://www.seeedstudio.com/depot/images/107020000%201.jpg) - ![Grove - Gas Module](http://www.seeedstudio.com/depot/images/product/Gas%20Sensor%20MQ.jpg) -   diff --git a/docs/grove-gas-tp401-edison.md b/docs/grove-gas-tp401-edison.md index 060410708..4336c4083 100644 --- a/docs/grove-gas-tp401-edison.md +++ b/docs/grove-gas-tp401-edison.md @@ -94,18 +94,12 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Buzzer Module](http://www.seeedstudio.com/depot/images/107020000%201.jpg) - ![Grove - Air quality sensor](http://www.seeedstudio.com/depot/images/101020021%201.jpg) - - [Grove - Air quality sensor](http://www.seeedstudio.com/depot/Grove-Air-quality-sensor-p-1065.html -   diff --git a/docs/grove-humidity-temperature-edison.md b/docs/grove-humidity-temperature-edison.md index c8972500d..c58b1c4d0 100644 --- a/docs/grove-humidity-temperature-edison.md +++ b/docs/grove-humidity-temperature-edison.md @@ -44,10 +44,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); @@ -67,16 +67,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Temperature&Humidity Sensor (High-Accuracy & Mini)](https://github.com/rwaldron/johnny-five/raw/master/docs/breadboard/multi-TH02.png) - - [Grove - Temperature&Humidity Sensor (High-Accuracy & Mini)](http://www.seeedstudio.com/depot/Grove-TemperatureHumidity-Sensor-HighAccuracy-Mini-p-1921.html) -   diff --git a/docs/grove-i2c-motor-driver-edison.md b/docs/grove-i2c-motor-driver-edison.md index 41271da03..8b316a03e 100644 --- a/docs/grove-i2c-motor-driver-edison.md +++ b/docs/grove-i2c-motor-driver-edison.md @@ -73,17 +73,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - (Or similiar Grove shield and platform) - ![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) -   diff --git a/docs/grove-i2c-motor-driver.md b/docs/grove-i2c-motor-driver.md index 0c629cb9f..78b2e635b 100644 --- a/docs/grove-i2c-motor-driver.md +++ b/docs/grove-i2c-motor-driver.md @@ -68,14 +68,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - (Or similiar Grove shield and platform) - ![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) -   diff --git a/docs/grove-joystick-edison.md b/docs/grove-joystick-edison.md index 36c6962a4..95e579557 100644 --- a/docs/grove-joystick-edison.md +++ b/docs/grove-joystick-edison.md @@ -54,16 +54,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Joystick Module](http://www.seeedstudio.com/depot/images/product/bgjoy1.jpg) - ![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) -   diff --git a/docs/grove-joystick.md b/docs/grove-joystick.md index 8e0f08452..bb1a6aa92 100644 --- a/docs/grove-joystick.md +++ b/docs/grove-joystick.md @@ -49,12 +49,9 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Joystick Module](http://www.seeedstudio.com/depot/images/product/bgjoy1.jpg) -   diff --git a/docs/grove-lcd-rgb-edison.md b/docs/grove-lcd-rgb-edison.md index 67cdeaf10..4525138e4 100644 --- a/docs/grove-lcd-rgb-edison.md +++ b/docs/grove-lcd-rgb-edison.md @@ -71,16 +71,11 @@ function linear(start, end, step, steps) { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) - ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -   diff --git a/docs/grove-lcd-rgb-temperature-display-edison.md b/docs/grove-lcd-rgb-temperature-display-edison.md index a7581af00..776474bfe 100644 --- a/docs/grove-lcd-rgb-temperature-display-edison.md +++ b/docs/grove-lcd-rgb-temperature-display-edison.md @@ -30,7 +30,7 @@ board.on("ready", function() { // Plug the Temperature sensor module // into the Grove Shield's A0 jack - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "GROVE", pin: "A0" }); @@ -43,7 +43,7 @@ board.on("ready", function() { var f = 0; - temperature.on("data", function() { + thermometer.on("data", function() { // The LCD's background will change // color according to the temperature. @@ -90,15 +90,10 @@ function linear(start, end, step, steps) { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) - ![Grove - Temperature Sensor](http://www.seeedstudio.com/wiki/images/thumb/b/b0/Temperature1.jpg/400px-Temperature1.jpg) - -   diff --git a/docs/grove-lcd-rgb-temperature-display.md b/docs/grove-lcd-rgb-temperature-display.md index f80fd3254..650fb062e 100644 --- a/docs/grove-lcd-rgb-temperature-display.md +++ b/docs/grove-lcd-rgb-temperature-display.md @@ -36,7 +36,7 @@ board.on("ready", function() { // Plug the Temperature sensor module // into the Grove Shield's A0 jack - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "GROVE", pin: "A0" }); @@ -49,7 +49,7 @@ board.on("ready", function() { var f = 0; - temperature.on("data", function() { + thermometer.on("data", function() { // The LCD's background will change // color according to the temperature. @@ -96,17 +96,11 @@ function linear(start, end, step, steps) { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) - ![Grove - Temperature Sensor](http://www.seeedstudio.com/wiki/images/thumb/b/b0/Temperature1.jpg/400px-Temperature1.jpg) - -   diff --git a/docs/grove-lcd-rgb.md b/docs/grove-lcd-rgb.md index 9ff23d21a..e9f900d0b 100644 --- a/docs/grove-lcd-rgb.md +++ b/docs/grove-lcd-rgb.md @@ -77,14 +77,10 @@ function linear(start, end, step, steps) { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) - ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -   diff --git a/docs/grove-led-edison.md b/docs/grove-led-edison.md index f3af1e506..d31515f03 100644 --- a/docs/grove-led-edison.md +++ b/docs/grove-led-edison.md @@ -63,14 +63,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED.jpg) -   diff --git a/docs/grove-led.md b/docs/grove-led.md index c50d0c2d1..ef98ddf8f 100644 --- a/docs/grove-led.md +++ b/docs/grove-led.md @@ -58,12 +58,9 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED.jpg) -   diff --git a/docs/grove-light-sensor-edison.md b/docs/grove-light-sensor-edison.md index c0a159383..a013f38d7 100644 --- a/docs/grove-light-sensor-edison.md +++ b/docs/grove-light-sensor-edison.md @@ -50,16 +50,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Digital Light Sensor](http://www.seeedstudio.com/depot/images/101020030%201.jpg) - - [Grove - Digital Light Sensor](http://www.seeedstudio.com/depot/Grove-Digital-Light-Sensor-p-1281.html) -   diff --git a/docs/grove-moisture-edison.md b/docs/grove-moisture-edison.md index 2d127bc9b..7d5017eae 100644 --- a/docs/grove-moisture-edison.md +++ b/docs/grove-moisture-edison.md @@ -61,16 +61,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Moisture Module](http://www.seeedstudio.com/depot/images/101020008%201.jpg) - ![Grove - Relay Module](http://www.seeedstudio.com/depot/images/1030200051.jpg) -   diff --git a/docs/grove-q-touch.md b/docs/grove-q-touch.md index 1afc3f7dd..8b50ef7c8 100644 --- a/docs/grove-q-touch.md +++ b/docs/grove-q-touch.md @@ -76,15 +76,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - [![Grove - Q Touch Sensor](http://www.seeedstudio.com/depot/images/product/Grove-Q%20Touch%20Sensor_02.jpg)](http://www.seeedstudio.com/depot/GroveQ-Touch-Sensor-p-1854.html) - -   diff --git a/docs/grove-relay-edison.md b/docs/grove-relay-edison.md index 394ecaee2..2140345af 100644 --- a/docs/grove-relay-edison.md +++ b/docs/grove-relay-edison.md @@ -51,16 +51,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) ![Grove - Relay Module](http://www.seeedstudio.com/depot/images/1030200051.jpg) - - Learn More At: - - [JavaScript: Relay Control with Johnny-Five on Node](http://bocoup.com/weblog/javascript-relay-with-johnny-five/) -   diff --git a/docs/grove-rotary-potentiometer-edison.md b/docs/grove-rotary-potentiometer-edison.md index 30fce0ef6..22c52cf00 100644 --- a/docs/grove-rotary-potentiometer-edison.md +++ b/docs/grove-rotary-potentiometer-edison.md @@ -78,16 +78,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) - ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -   diff --git a/docs/grove-rotary-potentiometer.md b/docs/grove-rotary-potentiometer.md index 20ab6c974..d12270036 100644 --- a/docs/grove-rotary-potentiometer.md +++ b/docs/grove-rotary-potentiometer.md @@ -73,14 +73,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) - ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -   diff --git a/docs/grove-servo-edison.md b/docs/grove-servo-edison.md index f8092ee63..8c7c65309 100644 --- a/docs/grove-servo-edison.md +++ b/docs/grove-servo-edison.md @@ -58,16 +58,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Servo Module](http://www.seeedstudio.com/depot/images/product/GroveServo_01.jpg) - ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -   diff --git a/docs/grove-servo.md b/docs/grove-servo.md index 719fb72ce..c2d6aa682 100644 --- a/docs/grove-servo.md +++ b/docs/grove-servo.md @@ -53,14 +53,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - Servo Module](http://www.seeedstudio.com/depot/images/product/GroveServo_01.jpg) - ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -   diff --git a/docs/grove-touch-edison.md b/docs/grove-touch-edison.md index 8e3e56a33..bc7afe28a 100644 --- a/docs/grove-touch-edison.md +++ b/docs/grove-touch-edison.md @@ -62,16 +62,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) - ![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) -   diff --git a/docs/grove-touch.md b/docs/grove-touch.md index a86ce1230..4c24af069 100644 --- a/docs/grove-touch.md +++ b/docs/grove-touch.md @@ -57,14 +57,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) - ![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) -   diff --git a/docs/hygrometer-DHT11_I2C_NANO_BACKPACK.md b/docs/hygrometer-DHT11_I2C_NANO_BACKPACK.md index a82b52e72..d5381ee37 100644 --- a/docs/hygrometer-DHT11_I2C_NANO_BACKPACK.md +++ b/docs/hygrometer-DHT11_I2C_NANO_BACKPACK.md @@ -56,7 +56,7 @@ board.on("ready", function() { ## Learn More -- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht11_i2c_nano_backpack.ino) +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino)   diff --git a/docs/hygrometer-DHT21_I2C_NANO_BACKPACK.md b/docs/hygrometer-DHT21_I2C_NANO_BACKPACK.md new file mode 100644 index 000000000..90670e39d --- /dev/null +++ b/docs/hygrometer-DHT21_I2C_NANO_BACKPACK.md @@ -0,0 +1,71 @@ + + +# Hygrometer - DHT21_I2C_NANO_BACKPACK + + + + + + + + +##### Hygrometer DHT21 + + + +![docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.png](breadboard/multi-DHT21_I2C_NANO_BACKPACK.png)
+ +Fritzing diagram: [docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz](breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/hygrometer-DHT21_I2C_NANO_BACKPACK.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "DHT21_I2C_NANO_BACKPACK" + }); + + hygrometer.on("change", function() { + console.log("Hygrometer"); + console.log(" relative humidity : ", this.relativeHumidity); + console.log("--------------------------------------"); + }); +}); + +``` + + + + + + + + + +## Learn More + +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/hygrometer-DHT22_I2C_NANO_BACKPACK.md b/docs/hygrometer-DHT22_I2C_NANO_BACKPACK.md new file mode 100644 index 000000000..8c9e954e6 --- /dev/null +++ b/docs/hygrometer-DHT22_I2C_NANO_BACKPACK.md @@ -0,0 +1,72 @@ + + +# Hygrometer - DHT22_I2C_NANO_BACKPACK + + + + + + + + +##### Hygrometer DHT22 + + + +![docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.png](breadboard/multi-DHT22_I2C_NANO_BACKPACK.png)
+ +Fritzing diagram: [docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz](breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/hygrometer-DHT22_I2C_NANO_BACKPACK.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "DHT22_I2C_NANO_BACKPACK" + }); + + hygrometer.on("change", function() { + console.log("Hygrometer"); + console.log(" relative humidity : ", this.relativeHumidity); + console.log("--------------------------------------"); + }); +}); + + +``` + + + + + + + + + +## Learn More + +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/hygrometer-HIH6130.md b/docs/hygrometer-HIH6130.md new file mode 100644 index 000000000..b43598783 --- /dev/null +++ b/docs/hygrometer-HIH6130.md @@ -0,0 +1,71 @@ + + +# Hygrometer - HIH6130 + + + + + + + + +##### HIH6130 + + + +![docs/breadboard/multi-HIH6130.png](breadboard/multi-HIH6130.png)
+ +Fritzing diagram: [docs/breadboard/multi-HIH6130.fzz](breadboard/multi-HIH6130.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/hygrometer-HIH6130.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "HIH6130" + }); + + hygrometer.on("change", function() { + console.log("Hygrometer"); + console.log(" relative humidity : ", this.relativeHumidity); + console.log("--------------------------------------"); + }); +}); + +``` + + + + + + + + + +## Learn More + +- [HIH6130 Humidity/Temperature Sensor](https://www.sparkfun.com/products/11295) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/hygrometer-SI7021.md b/docs/hygrometer-SI7021.md new file mode 100644 index 000000000..37d50f4d4 --- /dev/null +++ b/docs/hygrometer-SI7021.md @@ -0,0 +1,69 @@ + + +# Hygrometer - SI7021 + + + + + + + + +##### SI7021 + + + +![docs/breadboard/multi-SI7021.png](breadboard/multi-SI7021.png)
+ +Fritzing diagram: [docs/breadboard/multi-SI7021.fzz](breadboard/multi-SI7021.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/hygrometer-SI7021.js +``` + + +```javascript +var five = require("johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "SI7021" + }); + + hygrometer.on("data", function() { + console.log(this.relativeHumidity + " %"); + }); +}); + +``` + + + + + + + + + +## Learn More + +- [Si7021 Humidity and Temperature Sensor Hookup Guide](https://learn.sparkfun.com/tutorials/si7021-humidity-and-temperature-sensor-hookup-guide) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/hygrometer-TH02.md b/docs/hygrometer-TH02.md index ea4dc3d08..6614de915 100644 --- a/docs/hygrometer-TH02.md +++ b/docs/hygrometer-TH02.md @@ -22,13 +22,13 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var humidity = new five.Hygrometer({ + var hygrometer = new five.Hygrometer({ controller: "TH02" }); - humidity.on("change", function() { + hygrometer.on("change", function() { console.log("Hygrometer"); - console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log(" relative humidity : ", this.relativeHumidity); console.log("--------------------------------------"); }); }); diff --git a/docs/imp-io.md b/docs/imp-io.md index 9e1f4a6b2..76ee54421 100644 --- a/docs/imp-io.md +++ b/docs/imp-io.md @@ -64,7 +64,6 @@ board.on("ready", function() { ## Additional Notes - To communicate with an Electric Imp using Johnny-Five w/ Imp-IO, you will need to upload the special [Tyrion](https://github.com/rwaldron/tyrion) @@ -74,22 +73,17 @@ firmware through Electric Imp's [IDE](https://ide.electricimp.com/login). We recommend you review [Electric Imp's Getting Started](http://www.electricimp.com/docs/gettingstarted/) before continuing. - Store your agent ID in a dot file so it can be accessed as a property of `process.env`. Create a file in your home directory called `.imprc` that contains: - ```sh export IMP_AGENT_ID="your agent id" ``` - Then add the following to your dot-rc file of choice: - ```sh source ~/.imprc ``` - ## Learn More - [imp-io on GitHub](https://github.com/rwaldron/imp-io) diff --git a/docs/imu-bno055.md b/docs/imu-bno055.md index 436c02d30..3ce3cb8af 100644 --- a/docs/imu-bno055.md +++ b/docs/imu-bno055.md @@ -59,13 +59,13 @@ board.on("ready", function() { imu.on("change", function() { - console.log("temperature"); + console.log("Thermometer"); console.log(" celsius : ", this.thermometer.celsius); console.log(" fahrenheit : ", this.thermometer.fahrenheit); console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("accelerometer"); + console.log("Accelerometer"); console.log(" x : ", this.accelerometer.x); console.log(" y : ", this.accelerometer.y); console.log(" z : ", this.accelerometer.z); @@ -76,7 +76,7 @@ board.on("ready", function() { console.log(" orientation : ", this.accelerometer.orientation); console.log("--------------------------------------"); - console.log("gyro"); + console.log("Gyroscope"); console.log(" x : ", this.gyro.x); console.log(" y : ", this.gyro.y); console.log(" z : ", this.gyro.z); diff --git a/docs/imu-mpu6050.md b/docs/imu-mpu6050.md index c8342fd13..8b34a6e96 100644 --- a/docs/imu-mpu6050.md +++ b/docs/imu-mpu6050.md @@ -38,13 +38,13 @@ board.on("ready", function() { }); imu.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("accelerometer"); + console.log("Accelerometer"); console.log(" x : ", this.accelerometer.x); console.log(" y : ", this.accelerometer.y); console.log(" z : ", this.accelerometer.z); @@ -55,7 +55,7 @@ board.on("ready", function() { console.log(" orientation : ", this.accelerometer.orientation); console.log("--------------------------------------"); - console.log("gyro"); + console.log("Gyroscope"); console.log(" x : ", this.gyro.x); console.log(" y : ", this.gyro.y); console.log(" z : ", this.gyro.z); diff --git a/docs/keypad-QTOUCH.md b/docs/keypad-QTOUCH.md index 8f8886e64..b15749a39 100644 --- a/docs/keypad-QTOUCH.md +++ b/docs/keypad-QTOUCH.md @@ -73,13 +73,9 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - [![Grove - Q Touch Sensor](http://www.seeedstudio.com/depot/images/product/Grove-Q%20Touch%20Sensor_02.jpg)](http://www.seeedstudio.com/depot/GroveQ-Touch-Sensor-p-1854.html) - -   diff --git a/docs/lcd-enumeratechars.md b/docs/lcd-enumeratechars.md index 4f335cbc2..04341f906 100644 --- a/docs/lcd-enumeratechars.md +++ b/docs/lcd-enumeratechars.md @@ -44,7 +44,7 @@ board.on("ready", function() { var k = 0; var i = 0; - var keys = Object.keys(five.LCD.Characters); + var keys = Object.keys(five.LCD.Characters.DEFAULT); var length = keys.length; var eights = []; diff --git a/docs/led-array.md b/docs/led-array.md index 95ca280fb..2f9406100 100644 --- a/docs/led-array.md +++ b/docs/led-array.md @@ -51,12 +51,10 @@ board.on("ready", function() { ## Additional Notes - Control multiple LEDs at once by creating an LED collection (`Leds`). All must be on PWM pins if you want to use methods such as `pulse()` or `fade()` -   diff --git a/docs/led-digits-clock-HT16K33.md b/docs/led-digits-clock-HT16K33.md index 3616b0ce5..76afb5b4a 100644 --- a/docs/led-digits-clock-HT16K33.md +++ b/docs/led-digits-clock-HT16K33.md @@ -62,12 +62,9 @@ function time(showColon) { ## Additional Notes - Learn More: - - [JavaScript: A Digital Clock with Johnny-Five](http://bocoup.com/weblog/javascript-arduino-digital-clock-johnny-five/) -   diff --git a/docs/led-digits-clock-dual.md b/docs/led-digits-clock-dual.md index 2d63da3c6..13d9a07a8 100644 --- a/docs/led-digits-clock-dual.md +++ b/docs/led-digits-clock-dual.md @@ -75,12 +75,9 @@ board.on("ready", function() { ## Additional Notes - Learn More: - - [JavaScript: A Digital Clock with Johnny-Five](http://bocoup.com/weblog/javascript-arduino-digital-clock-johnny-five/) -   diff --git a/docs/led-rainbow.md b/docs/led-rainbow.md index c4ccc762e..bc1caf5be 100644 --- a/docs/led-rainbow.md +++ b/docs/led-rainbow.md @@ -42,10 +42,10 @@ board.on("ready", function() { var rainbow = ["FF0000", "FF7F00", "FFFF00", "00FF00", "0000FF", "4B0082", "8F00FF"]; this.loop(1000, function() { - if (index + 1 === rainbow.length) { + rgb.color(rainbow[index++]); + if (index === rainbow.length) { index = 0; } - rgb.color(rainbow[index++]); }); }); diff --git a/docs/led.md b/docs/led.md index b9191bbb6..ac69f2799 100644 --- a/docs/led.md +++ b/docs/led.md @@ -94,16 +94,14 @@ Fritzing diagram: [docs/breadboard/led-13-mega.fzz](breadboard/led-13-mega.fzz) ## Additional Notes This script will make `led` available in the REPL, by default on pin 13. Now you can try, e.g.: - ```js >> led.stop() // to stop blinking -// then +then >> led.off() // to shut it off (stop doesn't mean "off") -// then +then >> led.on() // to turn on, but not blink ``` -   diff --git a/docs/motobot.md b/docs/motobot.md index 01930e85b..322c5b5d8 100644 --- a/docs/motobot.md +++ b/docs/motobot.md @@ -106,12 +106,9 @@ Motobot chassis before addings ## Additional Notes - ![Chassis](https://cdn.sparkfun.com//assets/parts/9/7/3/8/12866-01.jpg) - ![ArduMoto](https://cdn.sparkfun.com//assets/parts/3/8/4/9/09815-01.jpg) -   diff --git a/docs/motor-GROVE_I2C.md b/docs/motor-GROVE_I2C.md index d74ccdad3..bab65f7ea 100644 --- a/docs/motor-GROVE_I2C.md +++ b/docs/motor-GROVE_I2C.md @@ -68,17 +68,11 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) - - ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) - (Or similiar Grove shield and platform) - ![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) -   diff --git a/docs/motor-TB6612FNG.md b/docs/motor-TB6612FNG.md new file mode 100644 index 000000000..4ef176172 --- /dev/null +++ b/docs/motor-TB6612FNG.md @@ -0,0 +1,86 @@ + + +# Motor - Sparkfun TB6612FNG + + + + + + + + +##### Breadboard for "Motor - Sparkfun TB6612FNG" + + + +![docs/breadboard/motor-TB6612FNG.png](breadboard/motor-TB6612FNG.png)
+ +Fritzing diagram: [docs/breadboard/motor-TB6612FNG.fzz](breadboard/motor-TB6612FNG.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/motor-TB6612FNG.js +``` + + +```javascript +var five = require("johnny-five"); +var Tessel = require("tessel-io"); +var board = new five.Board({ + io: new Tessel() +}); + +board.on("ready", function() { + var spdt = new five.Switch("a0"); + var throttle = new five.Sensor("b0"); + + // See the comments below for more information about + // the pins shown in this pin array argument. + var motor = new five.Motor([ "a5", "a4", "a3" ]); + + spdt.on("open", () => { + motor.stop().forward(motor.speed()); + }); + + spdt.on("close", () => { + motor.stop().reverse(motor.speed()); + }); + + throttle.on("change", () => { + motor.speed(throttle.value >> 2); + }); +}); + +``` + + + + + + + + +## Additional Notes +Here's a breakdown of the pins used by these motor drivers, their corresponding Johnny-Five Motor class pin name, and capabilities: +| Control Type/Role | Johnny-Five Motor Pin Name | Breakout Printed Pin | +| ----------------- | -------------------------- | -------------------- | +| PWM | `pwm` | `PWMA` or `PWMB` | +| Counter Direction | `cdir` | `AIN2` or `BIN2` | +| Direction | `dir` | `AIN1` or `BIN1` | + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/motor-hbridge-dual.md b/docs/motor-hbridge-dual.md new file mode 100644 index 000000000..698ed34c1 --- /dev/null +++ b/docs/motor-hbridge-dual.md @@ -0,0 +1,110 @@ + + +# Motors - Dual H-Bridge + + + + + + + + +##### Breadboard for "Motors - Dual H-Bridge" + + + +![docs/breadboard/motor-hbridge-dual.png](breadboard/motor-hbridge-dual.png)
+ +Fritzing diagram: [docs/breadboard/motor-hbridge-dual.fzz](breadboard/motor-hbridge-dual.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/motor-hbridge-dual.js +``` + + +```javascript +/** + * This example is intended for dual H-bridge (quad half H-bridge) motor + * driver ICs, like the Texas Instruments SN754410. It isn't intended for + * motor driver breakout boards or more sophisticated drivers, which handle + * the PWM inversion for you. + */ + +var five = require("johnny-five"), + board = new five.Board(); + +board.on("ready", function() { + /** + * Motor A: PWM 11, dir 12 + * Motor B: PWM 5, dir 4 + */ + var motors = new five.Motors([ + { pins: { dir: 12, pwm: 11 }, invertPWM: true }, + { pins: { dir: 4, pwm: 5}, invertPWM: true } + ]); + + board.repl.inject({ + motors: motors + }); + + // Go forward at full speed for 5 seconds + console.log("Full speed ahead!"); + motors.forward(255); + board.wait(5000, function () { + motors.stop(); + }); + + // Go backwards at full speed for 5 seconds + console.log("Now backwards!"); + motors.reverse(255); + board.wait(5000, function () { + motors.stop(); + }); + + // Go left... + console.log("To the left!"); + motors[0].reverse(200); + motors[1].forward(200); + board.wait(5000, function () { + motors.stop(); + }); + + // Go right... + console.log("To the right!"); + motors[0].forward(200); + motors[1].reverse(200); + board.wait(5000, function () { + motors.stop(); + }); + + // Use REPL if you want to go further + console.log("Done auto-driving! Use `motors` to control motors in REPL"); + +}); + +``` + + + + + + + + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/multi-BME280.md b/docs/multi-BME280.md new file mode 100644 index 000000000..d5207df9a --- /dev/null +++ b/docs/multi-BME280.md @@ -0,0 +1,99 @@ + + +# Multi - BME280 + + + + + + + + +##### BME280 (Sparkfun) + + + +![docs/breadboard/multi-BME280-tessel.png](breadboard/multi-BME280-tessel.png)
+ +Fritzing diagram: [docs/breadboard/multi-BME280-tessel.fzz](breadboard/multi-BME280-tessel.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/multi-BME280.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "BME280" + }); + + multi.on("data", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Barometer"); + console.log(" pressure : ", this.barometer.pressure); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + + console.log("Altimeter"); + console.log(" feet : ", this.altimeter.feet); + console.log(" meters : ", this.altimeter.meters); + console.log("--------------------------------------"); + }); +}); + +``` + + +## Illustrations / Photos + + +##### BME280 (Adafruit) + + + +![docs/breadboard/multi-BME280-arduino.png](breadboard/multi-BME280-arduino.png)
+ +Fritzing diagram: [docs/breadboard/multi-BME280-arduino.fzz](breadboard/multi-BME280-arduino.fzz) + +  + + + + + + +## Learn More + +- [SparkFun Atmospheric Sensor Breakout - BME280](https://www.sparkfun.com/products/13676) + +- [Adafruit BME280 I2C or SPI Temperature Humidity Pressure Sensor](https://www.adafruit.com/products/2652) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/multi-DHT11_I2C_NANO_BACKPACK.md b/docs/multi-DHT11_I2C_NANO_BACKPACK.md index e39b12164..f452f7551 100644 --- a/docs/multi-DHT11_I2C_NANO_BACKPACK.md +++ b/docs/multi-DHT11_I2C_NANO_BACKPACK.md @@ -38,10 +38,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); @@ -62,7 +62,7 @@ board.on("ready", function() { ## Learn More -- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht11_i2c_nano_backpack.ino) +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino)   diff --git a/docs/multi-DHT21_I2C_NANO_BACKPACK.md b/docs/multi-DHT21_I2C_NANO_BACKPACK.md new file mode 100644 index 000000000..b6a7ff075 --- /dev/null +++ b/docs/multi-DHT21_I2C_NANO_BACKPACK.md @@ -0,0 +1,78 @@ + + +# Multi - DHT21_I2C_NANO_BACKPACK + + + + + + + + +##### DHT21 + + + +![docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.png](breadboard/multi-DHT21_I2C_NANO_BACKPACK.png)
+ +Fritzing diagram: [docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz](breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/multi-DHT21_I2C_NANO_BACKPACK.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "DHT21_I2C_NANO_BACKPACK", + pin: 2, + }); + + multi.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + }); +}); + +``` + + + + + + + + + +## Learn More + +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/multi-DHT22_I2C_NANO_BACKPACK.md b/docs/multi-DHT22_I2C_NANO_BACKPACK.md new file mode 100644 index 000000000..005922733 --- /dev/null +++ b/docs/multi-DHT22_I2C_NANO_BACKPACK.md @@ -0,0 +1,78 @@ + + +# Multi - DHT22_I2C_NANO_BACKPACK + + + + + + + + +##### DHT22 + + + +![docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.png](breadboard/multi-DHT22_I2C_NANO_BACKPACK.png)
+ +Fritzing diagram: [docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz](breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/multi-DHT22_I2C_NANO_BACKPACK.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "DHT22_I2C_NANO_BACKPACK", + pin: 2, + }); + + multi.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + }); +}); + +``` + + + + + + + + + +## Learn More + +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/multi-HIH6130.md b/docs/multi-HIH6130.md new file mode 100644 index 000000000..39c405e29 --- /dev/null +++ b/docs/multi-HIH6130.md @@ -0,0 +1,77 @@ + + +# Multi - HIH6130 + + + + + + + + +##### HIH6130 + + + +![docs/breadboard/multi-HIH6130.png](breadboard/multi-HIH6130.png)
+ +Fritzing diagram: [docs/breadboard/multi-HIH6130.fzz](breadboard/multi-HIH6130.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/multi-HIH6130.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "HIH6130" + }); + + multi.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + }); +}); + +``` + + + + + + + + + +## Learn More + +- [HIH6130 Humidity/Temperature Sensor](https://www.sparkfun.com/products/11295) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/multi-MS5611.md b/docs/multi-MS5611.md index f00fc174a..d7f75c886 100644 --- a/docs/multi-MS5611.md +++ b/docs/multi-MS5611.md @@ -42,17 +42,17 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); diff --git a/docs/multi-SI7020.md b/docs/multi-SI7020.md index cf2de9412..17ab5a308 100644 --- a/docs/multi-SI7020.md +++ b/docs/multi-SI7020.md @@ -38,10 +38,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); diff --git a/docs/multi-SI7021.md b/docs/multi-SI7021.md new file mode 100644 index 000000000..88c04ab1a --- /dev/null +++ b/docs/multi-SI7021.md @@ -0,0 +1,88 @@ + + +# Multi - SI7021 + + + + + + + + +##### Tessel with SI7021 + + + +![docs/breadboard/multi-SI7021.png](breadboard/multi-SI7021.png)
+ +Fritzing diagram: [docs/breadboard/multi-SI7021.fzz](breadboard/multi-SI7021.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/multi-SI7021.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "SI7021" + }); + + multi.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + }); +}); + +``` + + +## Illustrations / Photos + + +##### Arduino with SI7021 + + + +![docs/breadboard/multi-SI7021-uno.png](breadboard/multi-SI7021-uno.png)
+ +Fritzing diagram: [docs/breadboard/multi-SI7021-uno.fzz](breadboard/multi-SI7021-uno.fzz) + +  + + + + + + +## Learn More + +- [Si7021 Humidity and Temperature Sensor Hookup Guide](https://learn.sparkfun.com/tutorials/si7021-humidity-and-temperature-sensor-hookup-guide) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/multi-TH02.md b/docs/multi-TH02.md index a2dbd8127..dbf7f9e26 100644 --- a/docs/multi-TH02.md +++ b/docs/multi-TH02.md @@ -38,10 +38,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("Temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); diff --git a/docs/multi-bmp085.md b/docs/multi-bmp085.md index 3835c1929..7191fe7ec 100644 --- a/docs/multi-bmp085.md +++ b/docs/multi-bmp085.md @@ -38,17 +38,17 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("thermometer"); + console.log("Thermometer"); console.log(" celsius : ", this.thermometer.celsius); console.log(" fahrenheit : ", this.thermometer.fahrenheit); console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); diff --git a/docs/multi-bmp180.md b/docs/multi-bmp180.md index 921788205..e57e14922 100644 --- a/docs/multi-bmp180.md +++ b/docs/multi-bmp180.md @@ -38,17 +38,17 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("thermometer"); + console.log("Thermometer"); console.log(" celsius : ", this.thermometer.celsius); console.log(" fahrenheit : ", this.thermometer.fahrenheit); console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); diff --git a/docs/multi-htu21d.md b/docs/multi-htu21d.md index 007d5a0ed..2d9338565 100644 --- a/docs/multi-htu21d.md +++ b/docs/multi-htu21d.md @@ -38,10 +38,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); diff --git a/docs/multi-mpl115a2.md b/docs/multi-mpl115a2.md index d15966303..a25acf4c3 100644 --- a/docs/multi-mpl115a2.md +++ b/docs/multi-mpl115a2.md @@ -38,13 +38,13 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); }); diff --git a/docs/multi-mpl3115a2.md b/docs/multi-mpl3115a2.md index 2111a078b..bf0f191d0 100644 --- a/docs/multi-mpl3115a2.md +++ b/docs/multi-mpl3115a2.md @@ -42,17 +42,17 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); diff --git a/docs/multi-sht31d.md b/docs/multi-sht31d.md index b108325bf..ddf6db5d6 100644 --- a/docs/multi-sht31d.md +++ b/docs/multi-sht31d.md @@ -38,10 +38,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); diff --git a/docs/pcduino-io.md b/docs/pcduino-io.md index 036fcf96f..9b116c5c2 100644 --- a/docs/pcduino-io.md +++ b/docs/pcduino-io.md @@ -50,19 +50,14 @@ board.on("ready", function() { ## Additional Notes - In order to use the pcduino-io library, you will need to install node (0.10.x or better) and npm on your pcduino. Once the environment is created, install Johnny-Five and pcDuino-IO. - [Setup environment](https://github.com/rwaldron/pcduino-io#install-a-compatible-version-of-nodenpm) - ```sh npm install johnny-five pcduino-io ``` - - ## Learn More - [pcduino-io on GitHub](https://github.com/rwaldron/pcduino-io/) diff --git a/docs/raspi-io.md b/docs/raspi-io.md index 34ac51d13..c5cd50dc2 100644 --- a/docs/raspi-io.md +++ b/docs/raspi-io.md @@ -53,17 +53,13 @@ board.on("ready", function() { ## Additional Notes - In order to use the Raspi-IO library, it is recommended that you use the Raspbian OS. Others may work, but are untested. - ```sh npm install johnny-five raspi-io ``` - - ## Learn More - [raspi-io on GitHub](https://github.com/nebrius/raspi-io/) diff --git a/docs/relay.md b/docs/relay.md index d35852645..efdf7b259 100644 --- a/docs/relay.md +++ b/docs/relay.md @@ -72,10 +72,8 @@ Fritzing diagram: [docs/breadboard/relay-closed.fzz](breadboard/relay-closed.fzz ## Additional Notes - - [JavaScript: Relay Control with Johnny-Five on Node](http://bocoup.com/weblog/javascript-relay-with-johnny-five/) -   diff --git a/docs/repl.md b/docs/repl.md index 6622f66a1..1e6f38d09 100644 --- a/docs/repl.md +++ b/docs/repl.md @@ -65,14 +65,12 @@ board.on("ready", function() { ## Additional Notes This script will make `on()` and `off()` functions available in the REPL: - ```js >> on() // will turn on the LED -// or +or >> off() // will turn off the LED ``` -   diff --git a/docs/sensor-digital-microwave.md b/docs/sensor-digital-microwave.md new file mode 100644 index 000000000..ac14ab688 --- /dev/null +++ b/docs/sensor-digital-microwave.md @@ -0,0 +1,62 @@ + + +# Sensor - Digital Microwave + + + + + + + + +##### Breadboard for "Sensor - Digital Microwave" + + + +![docs/breadboard/sensor-digital-microwave.png](breadboard/sensor-digital-microwave.png)
+ +Fritzing diagram: [docs/breadboard/sensor-digital-microwave.fzz](breadboard/sensor-digital-microwave.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/sensor-digital-microwave.js +``` + + +```javascript +var five = require("johnny-five"); +var board = new five.Board(); + +board.on("ready", () => { + var microwave = new five.Sensor.Digital(7); + + microwave.on("change", () => { + console.log(microwave.value); + }); +}); + +``` + + + + + + + + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/sensor-photon-weather-shield-moisture.md b/docs/sensor-photon-weather-shield-moisture.md index a9d27f87a..b31dc471f 100644 --- a/docs/sensor-photon-weather-shield-moisture.md +++ b/docs/sensor-photon-weather-shield-moisture.md @@ -66,14 +66,10 @@ board.on("ready", function() { ## Additional Notes For this program, you'll need: - ![Particle Photon](https://docs.particle.io/assets/images/photon_vector2_600.png) - ![SparkFun Photon Weather Shield](https://cdn.sparkfun.com//assets/parts/1/1/0/1/7/13630-01a.jpg) - ![SparkFun Soil Moisture Sensor](https://cdn.sparkfun.com//assets/parts/1/0/6/1/0/13322-01.jpg) -   diff --git a/docs/servo.md b/docs/servo.md index af6c0aecd..ef6c113c0 100644 --- a/docs/servo.md +++ b/docs/servo.md @@ -46,9 +46,6 @@ board.on("ready", function() { invert: false, // Invert all specified positions startAt: 90, // Immediately move to a degree center: true, // overrides startAt if true and moves the servo to the center of the range - specs: { // Is it running at 5V or 3.3V? - speed: five.Servo.Continuous.speeds["@5.0V"] - } }); */ diff --git a/docs/spark-io.md b/docs/spark-io.md index 4950fc877..229992bb5 100644 --- a/docs/spark-io.md +++ b/docs/spark-io.md @@ -73,28 +73,21 @@ board.on("ready", function() { ## Additional Notes - In order to use the spark-io library, you will need to load the special [voodoospark](https://github.com/voodootikigod/voodoospark) firmware onto your device. We recommend you review [VoodooSpark's Getting Started](https://github.com/voodootikigod/voodoospark#getting-started) before continuing. - We also recommend storing your Spark token and device ID in a dot file so they can be accessed as properties of `process.env`. Create a file in your home directory called `.sparkrc` that contains: - ```sh export SPARK_TOKEN="your spark token" export SPARK_DEVICE_ID="your device id" ``` - Then add the following to your dot-rc file of choice: - ```sh source ~/.sparkrc ``` - Ensure your host computer (where you're running your Node application) and the Spark are on the same local network. - ## Learn More - [spark-io on GitHub](https://github.com/rwaldron/spark-io) diff --git a/docs/stepper-driver.md b/docs/stepper-driver.md index f12bd0af5..4e8311412 100644 --- a/docs/stepper-driver.md +++ b/docs/stepper-driver.md @@ -82,10 +82,8 @@ board.on("ready", function() { - [A4988 Stepper Motor Driver Carrier](http://www.pololu.com/catalog/product/1182) - [100uf 35v electrolytic cap](http://www.amazon.com/100uF-Radial-Mini-Electrolytic-Capacitor/dp/B0002ZP530) - [Stepper Motor (4 wire, bipolar)](https://www.sparkfun.com/products/9238) - ![docs/breadboard/stepper-driver-A4988.png](breadboard/stepper-driver-A4988.png) -   diff --git a/docs/temperature-BMP180.md b/docs/temperature-BMP180.md index 806bdebb4..193f17040 100644 --- a/docs/temperature-BMP180.md +++ b/docs/temperature-BMP180.md @@ -33,13 +33,13 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "BMP180", freq: 250 }); - temperature.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/docs/temperature-DHT11_I2C_NANO_BACKPACK.md b/docs/temperature-DHT11_I2C_NANO_BACKPACK.md index fa4529f8d..d88538c51 100644 --- a/docs/temperature-DHT11_I2C_NANO_BACKPACK.md +++ b/docs/temperature-DHT11_I2C_NANO_BACKPACK.md @@ -33,12 +33,12 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temp = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "DHT11_I2C_NANO_BACKPACK" }); - temp.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); @@ -59,7 +59,7 @@ board.on("ready", function() { ## Learn More -- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht11_i2c_nano_backpack.ino) +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino)   diff --git a/docs/temperature-DHT21_I2C_NANO_BACKPACK.md b/docs/temperature-DHT21_I2C_NANO_BACKPACK.md new file mode 100644 index 000000000..09a565cbe --- /dev/null +++ b/docs/temperature-DHT21_I2C_NANO_BACKPACK.md @@ -0,0 +1,74 @@ + + +# Thermometer - DHT21_I2C_NANO_BACKPACK + + + + + + + + +##### Thermometer DHT21 + + + +![docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.png](breadboard/multi-DHT21_I2C_NANO_BACKPACK.png)
+ +Fritzing diagram: [docs/breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz](breadboard/multi-DHT21_I2C_NANO_BACKPACK.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/temperature-DHT21_I2C_NANO_BACKPACK.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var thermometer = new five.Thermometer({ + controller: "DHT21_I2C_NANO_BACKPACK" + }); + + thermometer.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); + console.log("--------------------------------------"); + }); +}); + + +``` + + + + + + + + + +## Learn More + +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/temperature-DHT22_I2C_NANO_BACKPACK.md b/docs/temperature-DHT22_I2C_NANO_BACKPACK.md new file mode 100644 index 000000000..854c144f3 --- /dev/null +++ b/docs/temperature-DHT22_I2C_NANO_BACKPACK.md @@ -0,0 +1,74 @@ + + +# Thermometer - DHT22_I2C_NANO_BACKPACK + + + + + + + + +##### Thermometer DHT22 + + + +![docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.png](breadboard/multi-DHT22_I2C_NANO_BACKPACK.png)
+ +Fritzing diagram: [docs/breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz](breadboard/multi-DHT22_I2C_NANO_BACKPACK.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/temperature-DHT22_I2C_NANO_BACKPACK.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var thermometer = new five.Thermometer({ + controller: "DHT22_I2C_NANO_BACKPACK" + }); + + thermometer.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); + console.log("--------------------------------------"); + }); +}); + + +``` + + + + + + + + + +## Learn More + +- [I2C Backback Firmare](https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/temperature-HIH6130.md b/docs/temperature-HIH6130.md new file mode 100644 index 000000000..c5ca5edbb --- /dev/null +++ b/docs/temperature-HIH6130.md @@ -0,0 +1,74 @@ + + +# Thermometer - HIH6130 + + + + + + + + +##### HIH6130 + + + +![docs/breadboard/multi-HIH6130.png](breadboard/multi-HIH6130.png)
+ +Fritzing diagram: [docs/breadboard/multi-HIH6130.fzz](breadboard/multi-HIH6130.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/temperature-HIH6130.js +``` + + +```javascript +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var thermometer = new five.Thermometer({ + controller: "HIH6130" + }); + + thermometer.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); + console.log("--------------------------------------"); + }); +}); + + +``` + + + + + + + + + +## Learn More + +- [HIH6130 Humidity/Temperature Sensor](https://www.sparkfun.com/products/11295) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/temperature-MCP9808.md b/docs/temperature-MCP9808.md index 182a699d5..122753be6 100644 --- a/docs/temperature-MCP9808.md +++ b/docs/temperature-MCP9808.md @@ -33,12 +33,12 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temp = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MCP9808" }); - temp.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/docs/temperature-MS5611.md b/docs/temperature-MS5611.md index 1eabc939d..991ef0937 100644 --- a/docs/temperature-MS5611.md +++ b/docs/temperature-MS5611.md @@ -33,12 +33,12 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temp = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MS5611" }); - temp.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/docs/temperature-SI7021.md b/docs/temperature-SI7021.md new file mode 100644 index 000000000..f11ef465e --- /dev/null +++ b/docs/temperature-SI7021.md @@ -0,0 +1,84 @@ + + +# Thermometer - SI7021 + + + + + + + + +##### Tessel with SI7021 + + + +![docs/breadboard/multi-SI7021.png](breadboard/multi-SI7021.png)
+ +Fritzing diagram: [docs/breadboard/multi-SI7021.fzz](breadboard/multi-SI7021.fzz) + +  + + + + +Run this example from the command line with: +```bash +node eg/temperature-SI7021.js +``` + + +```javascript +var five = require("../"); +var Tessel = require("tessel-io"); +var board = new five.Board({ + io: new Tessel() +}); + +board.on("ready", function() { + var temp = new five.Thermometer({ + controller: "SI7021", + port: "A" + }); + + temp.on("change", function() { + console.log(this.celsius + "°C", this.fahrenheit + "°F"); + }); +}); + +``` + + +## Illustrations / Photos + + +##### Arduino with SI7021 + + + +![docs/breadboard/multi-SI7021-uno.png](breadboard/multi-SI7021-uno.png)
+ +Fritzing diagram: [docs/breadboard/multi-SI7021-uno.fzz](breadboard/multi-SI7021-uno.fzz) + +  + + + + + + +## Learn More + +- [Si7021 Humidity and Temperature Sensor Hookup Guide](https://learn.sparkfun.com/tutorials/si7021-humidity-and-temperature-sensor-hookup-guide) + +  + + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2017 The Johnny-Five Contributors +Licensed under the MIT license. + + diff --git a/docs/temperature-TH02.md b/docs/temperature-TH02.md index 71bc2a2d9..dd31e6eb7 100644 --- a/docs/temperature-TH02.md +++ b/docs/temperature-TH02.md @@ -22,15 +22,15 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temp = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "TH02" }); - temp.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + thermometer.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); console.log("--------------------------------------"); }); }); diff --git a/docs/temperature-bmp085.md b/docs/temperature-bmp085.md index ebd708f87..7510ca038 100644 --- a/docs/temperature-bmp085.md +++ b/docs/temperature-bmp085.md @@ -38,10 +38,10 @@ board.on("ready", function() { }); temp.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); console.log("--------------------------------------"); }); }); diff --git a/docs/temperature-ds18b20.md b/docs/temperature-ds18b20.md index 473191b0d..2b2c7e8f9 100644 --- a/docs/temperature-ds18b20.md +++ b/docs/temperature-ds18b20.md @@ -30,15 +30,16 @@ node eg/temperature-ds18b20.js ```javascript var five = require("johnny-five"); +var board = new five.Board(); -five.Board().on("ready", function() { +board.on("ready", function() { // This requires OneWire support using the ConfigurableFirmata - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "DS18B20", pin: 2 }); - temperature.on("change", function() { + thermometer.on("change", function() { console.log(this.celsius + "°C"); // console.log("0x" + this.address.toString(16)); }); diff --git a/docs/temperature-htu21d.md b/docs/temperature-htu21d.md index f8874a83a..f321be42f 100644 --- a/docs/temperature-htu21d.md +++ b/docs/temperature-htu21d.md @@ -33,11 +33,11 @@ var five = require("johnny-five"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "HTU21D" }); - temperature.on("change", function() { + thermometer.on("change", function() { console.log(this.celsius + "°C", this.fahrenheit + "°F"); }); }); diff --git a/docs/temperature-lm335.md b/docs/temperature-lm335.md index 791cf3992..81fadac0d 100644 --- a/docs/temperature-lm335.md +++ b/docs/temperature-lm335.md @@ -30,14 +30,15 @@ node eg/temperature-lm335.js ```javascript var five = require("johnny-five"); +var board = new five.Board(); -five.Board().on("ready", function() { - var temperature = new five.Thermometer({ +board.on("ready", function() { + var thermometer = new five.Thermometer({ controller: "LM335", pin: "A0" }); - temperature.on("change", function() { + thermometer.on("change", function() { console.log(this.celsius + "°C", this.fahrenheit + "°F"); }); }); diff --git a/docs/temperature-mpl115a2.md b/docs/temperature-mpl115a2.md index 4fa6edf20..34be216bf 100644 --- a/docs/temperature-mpl115a2.md +++ b/docs/temperature-mpl115a2.md @@ -33,12 +33,12 @@ var five = require("johnny-five"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MPL115A2" }); - temperature.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/docs/temperature-mpl3115a2.md b/docs/temperature-mpl3115a2.md index a77e553e2..d37764f40 100644 --- a/docs/temperature-mpl3115a2.md +++ b/docs/temperature-mpl3115a2.md @@ -33,12 +33,12 @@ var five = require("johnny-five"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MPL3115A2" }); - temperature.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/docs/temperature-mpu6050.md b/docs/temperature-mpu6050.md index 78a5f020d..2a7eb5d81 100644 --- a/docs/temperature-mpu6050.md +++ b/docs/temperature-mpu6050.md @@ -33,12 +33,12 @@ var five = require("johnny-five"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MPU6050" }); - temperature.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); @@ -57,7 +57,7 @@ board.on("ready", function() { ## Additional Notes -- [MPU-6050 - IMU with Temperature Sensor](http://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/) +- [MPU6050 - IMU with Temperature Sensor](http://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/)   diff --git a/eg/accelerometer.js b/eg/accelerometer.js index f1cc3c050..ad7a619f3 100644 --- a/eg/accelerometer.js +++ b/eg/accelerometer.js @@ -78,11 +78,11 @@ board.on("ready", function() { }); }); -// @markdown -// -// - [Triple Axis Accelerometer, MMA7361](https://www.sparkfun.com/products/9652) -// - [Triple-Axis Accelerometer, ADXL326](http://www.adafruit.com/products/1018) -// -// - [Two or Three Axis Accelerometer, LIS344AL](http://www.st.ewi.tudelft.nl/~gemund/Courses/In4073/Resources/LIS344AL.pdf) -// -// @markdown +/* @markdown + +- [Triple Axis Accelerometer, MMA7361](https://www.sparkfun.com/products/9652) +- [Triple-Axis Accelerometer, ADXL326](http://www.adafruit.com/products/1018) + +- [Two or Three Axis Accelerometer, LIS344AL](http://www.st.ewi.tudelft.nl/~gemund/Courses/In4073/Resources/LIS344AL.pdf) + +@markdown */ diff --git a/eg/altimeter-BMP085-relative-elevation.js b/eg/altimeter-BMP085-relative-elevation.js index 7792830de..625567508 100644 --- a/eg/altimeter-BMP085-relative-elevation.js +++ b/eg/altimeter-BMP085-relative-elevation.js @@ -4,12 +4,12 @@ var board = new five.Board(); board.on("ready", function() { // By omitting the base `elevation` property, the values // received will be relative to your present elevation - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP085", }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/eg/altimeter-BMP085.js b/eg/altimeter-BMP085.js index 819eb202e..6ec96b2d5 100644 --- a/eg/altimeter-BMP085.js +++ b/eg/altimeter-BMP085.js @@ -4,7 +4,7 @@ var board = new five.Board(); board.on("ready", function() { // By including a base `elevation` property, the values // received will be absolute elevation (from sealevel) - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP085", // Change `elevation` with whatever is reported // on http://www.whatismyelevation.com/. @@ -12,8 +12,8 @@ board.on("ready", function() { elevation: 12, }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/eg/altimeter-BMP180-relative-elevation.js b/eg/altimeter-BMP180-relative-elevation.js index 9e2d8c3c8..4656ed658 100644 --- a/eg/altimeter-BMP180-relative-elevation.js +++ b/eg/altimeter-BMP180-relative-elevation.js @@ -4,12 +4,12 @@ var board = new five.Board(); board.on("ready", function() { // By omitting the base `elevation` property, the values // received will be relative to your present elevation - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP180", }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/eg/altimeter-BMP180.js b/eg/altimeter-BMP180.js index 8884b83c4..5ddc8e7e2 100644 --- a/eg/altimeter-BMP180.js +++ b/eg/altimeter-BMP180.js @@ -4,7 +4,7 @@ var board = new five.Board(); board.on("ready", function() { // By including a base `elevation` property, the values // received will be absolute elevation (from sealevel) - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP180", // Change `elevation` with whatever is reported // on http://www.whatismyelevation.com/. @@ -12,8 +12,8 @@ board.on("ready", function() { elevation: 12, }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/eg/altimeter-BMP280.js b/eg/altimeter-BMP280.js index 19966f9cf..30f40bfb0 100644 --- a/eg/altimeter-BMP280.js +++ b/eg/altimeter-BMP280.js @@ -4,7 +4,7 @@ var board = new five.Board(); board.on("ready", function() { // By including a base `elevation` property, the values // received will be absolute elevation (from sealevel) - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "BMP280", // Change `elevation` with whatever is reported // on http://www.whatismyelevation.com/. @@ -12,8 +12,8 @@ board.on("ready", function() { elevation: 12, }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/eg/altimeter-MS5611-relative-elevation.js b/eg/altimeter-MS5611-relative-elevation.js index 154b609ce..f9853a5ec 100644 --- a/eg/altimeter-MS5611-relative-elevation.js +++ b/eg/altimeter-MS5611-relative-elevation.js @@ -4,12 +4,12 @@ var board = new five.Board(); board.on("ready", function() { // By omitting the base `elevation` property, the values // received will be relative to your present elevation - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "MS5611", }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/eg/altimeter-MS5611.js b/eg/altimeter-MS5611.js index 5094b3993..e0bfeeb30 100644 --- a/eg/altimeter-MS5611.js +++ b/eg/altimeter-MS5611.js @@ -4,7 +4,7 @@ var board = new five.Board(); board.on("ready", function() { // By including a base `elevation` property, the values // received will be absolute elevation (from sealevel) - var alt = new five.Altimeter({ + var altimeter = new five.Altimeter({ controller: "MS5611", // Change `elevation` with whatever is reported // on http://www.whatismyelevation.com/. @@ -12,8 +12,8 @@ board.on("ready", function() { elevation: 12, }); - alt.on("change", function() { - console.log("altimeter"); + altimeter.on("change", function() { + console.log("Altimeter"); console.log(" feet : ", this.feet); console.log(" meters : ", this.meters); console.log("--------------------------------------"); diff --git a/eg/altimeter-mpl3115a2.js b/eg/altimeter-mpl3115a2.js index eac0b3a0a..e9cfaeb84 100644 --- a/eg/altimeter-mpl3115a2.js +++ b/eg/altimeter-mpl3115a2.js @@ -18,9 +18,9 @@ board.on("ready", function() { }); }); -// @markdown -// - [MPL3115A2 - I2C Barometric Pressure/Altimiter/Temperature Sensor](https://www.adafruit.com/products/1893) -// - [SparkFun Altitude/Pressure Sensor Breakout - MPL3115A2](https://www.sparkfun.com/products/11084) -// - [SparkFun Weather Shield](https://www.sparkfun.com/products/12081) -// - [SparkFun Photon Weather Shield](https://www.sparkfun.com/products/13630) -// @markdown +/* @markdown +- [MPL3115A2 - I2C Barometric Pressure/Altimiter/Temperature Sensor](https://www.adafruit.com/products/1893) +- [SparkFun Altitude/Pressure Sensor Breakout - MPL3115A2](https://www.sparkfun.com/products/11084) +- [SparkFun Weather Shield](https://www.sparkfun.com/products/12081) +- [SparkFun Photon Weather Shield](https://www.sparkfun.com/products/13630) +@markdown */ diff --git a/eg/arduino-starter-kit/arduino-logo.html b/eg/arduino-starter-kit/arduino-logo.html new file mode 100644 index 000000000..58ebe24e7 --- /dev/null +++ b/eg/arduino-starter-kit/arduino-logo.html @@ -0,0 +1,19 @@ + + + + Tweak The Arduino Logo + + + + + + \ No newline at end of file diff --git a/eg/arduino-starter-kit/arduino-logo.js b/eg/arduino-starter-kit/arduino-logo.js new file mode 100644 index 000000000..eead74556 --- /dev/null +++ b/eg/arduino-starter-kit/arduino-logo.js @@ -0,0 +1,28 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var app = require("express")(); +var server = require("http").Server(app); +var io = require("socket.io")(server); + +server.listen(3000); + +app.get("/", function(req, res) { + res.sendFile(__dirname + "/arduino-logo.html"); +}); + +var board = new five.Board({ + io: new Edison() +}); +board.on("ready", function() { + io.on("connection", function(socket) { + socket.emit("news", { + hello: "world" + }); + var sensor = five.Sensor("A0"); + sensor.on("change", function() { + socket.emit("color", { + value: five.Fn.scale(this.value, 0, 1024, 0, 360) + }); + }); + }); +}); diff --git a/eg/arduino-starter-kit/color-mixing-lamp.js b/eg/arduino-starter-kit/color-mixing-lamp.js new file mode 100644 index 000000000..e45fbc804 --- /dev/null +++ b/eg/arduino-starter-kit/color-mixing-lamp.js @@ -0,0 +1,18 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var led = new five.Led.RGB([6, 5, 3]); + var sensors = new five.Sensors(["A0", "A1", "A2"]); + + sensors.on("change", function() { + var color = sensors.reduce(function(s, sensor) { + return s + sensor.analog.toString(16); + }, "#"); + console.log(color); + led.color(color); + }); +}); diff --git a/eg/arduino-starter-kit/crystal-ball.js b/eg/arduino-starter-kit/crystal-ball.js new file mode 100644 index 000000000..84a3f70c7 --- /dev/null +++ b/eg/arduino-starter-kit/crystal-ball.js @@ -0,0 +1,38 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +function CrystalBall(lcd) { + this.lcd = lcd; + this.next = 0; + this.replies = ["Yes", "Most likely", "Certainly", "Outlook good", "Unsure", "Ask again", "Doubtful", "No"]; +} + +CrystalBall.prototype.reply = function() { + this.lcd.clear(); + this.lcd.print("The ball says:"); + this.lcd.cursor(1, 0); + this.next = (this.next + 1) % 8; + this.lcd.print(this.replies[this.next]); +}; + +CrystalBall.prototype.ask = function() { + this.lcd.clear(); + this.lcd.print("Ask the"); + this.lcd.cursor(1, 0); + this.lcd.print("Crystal Ball"); +}; + +board.on("ready", function() { + var button = new five.Button(6); + var lcd = new five.LCD({ + pins: [12, 11, 5, 4, 3, 2], + }); + var crystalBall = new CrystalBall(lcd); + crystalBall.ask(); + button.on("press", function() { + crystalBall.reply(); + }); +}); diff --git a/eg/arduino-starter-kit/digital-hourglass.js b/eg/arduino-starter-kit/digital-hourglass.js new file mode 100644 index 000000000..1877c393b --- /dev/null +++ b/eg/arduino-starter-kit/digital-hourglass.js @@ -0,0 +1,19 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var leds = new five.Leds([2, 3, 4, 5, 6, 7]); + var tilt = new five.Sensor.Digital(8); + var i = 0; + this.loop(1000 * 60 * 10, function() { + leds[i].on(); + i = (i + 1) % 6; + }); + tilt.on("change", function() { + i = 0; + leds.off(); + }); +}); diff --git a/eg/arduino-starter-kit/keyboard.js b/eg/arduino-starter-kit/keyboard.js new file mode 100644 index 000000000..08cce0547 --- /dev/null +++ b/eg/arduino-starter-kit/keyboard.js @@ -0,0 +1,28 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var sensor = new five.Sensor({ + pin: "A0", + freq: 100, + threshold: 8 + }); + var piezo = new five.Piezo(8); + sensor.on("change", function() { + console.log(this.value); + if (five.Fn.inRange(this.value, 1020, 1023)) { + piezo.frequency(five.Piezo.Notes["c4"], 50); + } else if (five.Fn.inRange(this.value, 990, 1010)) { + piezo.frequency(five.Piezo.Notes["d4"], 50); + } else if (five.Fn.inRange(this.value, 500, 520)) { + piezo.frequency(five.Piezo.Notes["e4"], 50); + } else if (five.Fn.inRange(this.value, 20, 40)) { + piezo.frequency(five.Piezo.Notes["f4"], 50); + } else { + piezo.noTone(); + } + }); +}); diff --git a/eg/arduino-starter-kit/knock-lock.js b/eg/arduino-starter-kit/knock-lock.js new file mode 100644 index 000000000..accd7f854 --- /dev/null +++ b/eg/arduino-starter-kit/knock-lock.js @@ -0,0 +1,80 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +function Box(servo, red, green, yellow) { + this.quietKnock = 10; + this.loudKnock = 100; + this.numberOfKnocks = 0; + this.locked = false; + this.servo = servo; + this.red = red; + this.red.off(); + this.green = green; + green.on(); + this.yellow = yellow; + this.yellow.off(); + this.servo.to(0); + console.log("The box is unlocked!"); +} + +Box.prototype.lock = function() { + this.numberOfKnocks = 0; + this.locked = true; + this.green.off(); + this.red.on(); + this.servo.to(90); + console.log("The box is locked!"); +}; + +Box.prototype.knock = function(value) { + var self = this; + + function checkForKnock(value) { + if (value > self.quietKnock && value < self.loudKnock) { + self.yellow.on(); + setTimeout(function() { + self.yellow.off(); + console.log("Valid knock of value " + value); + }, 50); + return true; + } else { + console.log("Bad knock value " + value); + return false; + } + } + if (this.numberOfKnocks >= 3) { + this.locked = false; + this.servo.to(0); + this.green.on(); + this.red.off(); + console.log("The box is unlocked!"); + } else { + if (checkForKnock(value)) { + this.numberOfKnocks++; + } + console.log(3 - this.numberOfKnocks + " more knocks to go"); + } +}; + +board.on("ready", function() { + var piezo = new five.Sensor({ + pin: "A0", + threshold: 10 + }); + piezo.on("change", function() { + box.knock(this.value); + }); + var button = new five.Button(2); + button.on("press", function() { + box.lock(); + }); + + var yellow = new five.Led(3); + var green = new five.Led(4); + var red = new five.Led(5); + var servo = new five.Servo(9); + var box = new Box(servo, red, green, yellow); +}); diff --git a/eg/arduino-starter-kit/light-theremin.js b/eg/arduino-starter-kit/light-theremin.js new file mode 100644 index 000000000..af5d76aa6 --- /dev/null +++ b/eg/arduino-starter-kit/light-theremin.js @@ -0,0 +1,23 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var sensor = new five.Sensor({ + pin: "A0", + freq: 30 + }); + var piezo = new five.Piezo(8); + var min = 1024; + var max = 0; + + sensor.on("data", function() { + min = Math.min(min, this.value); + max = Math.max(max, this.value); + var pitch = five.Fn.scale(this.value, min, max, 50, 4000); + piezo.frequency(pitch, 20); + console.log(min, max, pitch); + }); +}); diff --git a/eg/arduino-starter-kit/love-o-meter.js b/eg/arduino-starter-kit/love-o-meter.js new file mode 100644 index 000000000..df31ae94d --- /dev/null +++ b/eg/arduino-starter-kit/love-o-meter.js @@ -0,0 +1,34 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + + var leds = five.Leds([2, 3, 4]); + + var tmp = new five.Thermometer({ + controller: "TMP36", + pin: "A0" + }); + + tmp.on("change", function() { + if (this.celsius >= 22) { + leds[0].on(); + } else { + leds[0].off(); + } + if (this.celsius >= 24) { + leds[1].on(); + } else { + leds[1].off(); + } + if (this.celsius >= 26) { + leds[2].on(); + } else { + leds[2].off(); + } + console.log(this.celsius + "°C"); + }); +}); diff --git a/eg/arduino-starter-kit/motorized-pinwheel.js b/eg/arduino-starter-kit/motorized-pinwheel.js new file mode 100644 index 000000000..b17dc6eeb --- /dev/null +++ b/eg/arduino-starter-kit/motorized-pinwheel.js @@ -0,0 +1,16 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var gate = new five.Pin(9); + var button = new five.Button(2); + button.on("press", function() { + gate.write(1); + }); + button.on("release", function() { + gate.write(0); + }); +}); diff --git a/eg/arduino-starter-kit/servo-mood-indicator.js b/eg/arduino-starter-kit/servo-mood-indicator.js new file mode 100644 index 000000000..afa2e8177 --- /dev/null +++ b/eg/arduino-starter-kit/servo-mood-indicator.js @@ -0,0 +1,14 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var potentiometer = new five.Sensor("A0"); + var servo = new five.Servo(9); + potentiometer.on("data", function() { + console.log(this.value, this.scaleTo(0, 179)); + servo.to(this.scaleTo(0, 179)); + }); +}); diff --git a/eg/arduino-starter-kit/spaceship-interface.js b/eg/arduino-starter-kit/spaceship-interface.js new file mode 100644 index 000000000..daad081cd --- /dev/null +++ b/eg/arduino-starter-kit/spaceship-interface.js @@ -0,0 +1,22 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({io: new Edison()}); + +board.on("ready", function() { + + var leds = five.Leds([3,4,5]); + var btn = five.Button(2); + + btn.on("press", function() { + leds[0].off(); + leds[1].on().blink(500); + leds[2].off().blink(500); + }); + + btn.on("release", function() { + leds[0].on(); + leds[1].off().stop(); + leds[2].off().stop(); + }); + +}); diff --git a/eg/arduino-starter-kit/zoetrope.js b/eg/arduino-starter-kit/zoetrope.js new file mode 100644 index 000000000..e6207edd9 --- /dev/null +++ b/eg/arduino-starter-kit/zoetrope.js @@ -0,0 +1,45 @@ +var five = require("johnny-five"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var sensor = new five.Sensor("A0"); + var motor = new five.Motor({ + pins: { + pwm: 9, + dir: 2, + cdir: 3 + } + }); + var btnA = new five.Button(4); + var btnB = new five.Button(5); + + var enabled = false; + var direction = "forward"; + var speed = 255; + + btnA.on("down", function() { + enabled = !enabled; + update(); + }); + + btnB.on("down", function() { + direction = direction === "forward" ? "reverse" : "forward"; + update(); + }); + + sensor.on("change", function() { + direction = this.value >> 2; + update(); + }); + + function update() { + if (enabled) { + motor[direction](speed); + } else { + motor.stop(); + } + } +}); diff --git a/eg/barometer-BMP085.js b/eg/barometer-BMP085.js index 97042cf2f..38a22363b 100644 --- a/eg/barometer-BMP085.js +++ b/eg/barometer-BMP085.js @@ -2,12 +2,12 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var bar = new five.Barometer({ + var barometer = new five.Barometer({ controller: "BMP085" }); - bar.on("change", function() { - console.log("barometer"); + barometer.on("change", function() { + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); }); diff --git a/eg/barometer-BMP180.js b/eg/barometer-BMP180.js index b80562324..8b2d68859 100644 --- a/eg/barometer-BMP180.js +++ b/eg/barometer-BMP180.js @@ -7,7 +7,7 @@ board.on("ready", function() { }); barometer.on("change", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); diff --git a/eg/barometer-MS5611.js b/eg/barometer-MS5611.js index 296292ccd..1d18615ff 100644 --- a/eg/barometer-MS5611.js +++ b/eg/barometer-MS5611.js @@ -7,7 +7,7 @@ board.on("ready", function() { }); pressure.on("change", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); diff --git a/eg/barometer-mpl115a2.js b/eg/barometer-mpl115a2.js index cbf7120f5..d0c4be160 100644 --- a/eg/barometer-mpl115a2.js +++ b/eg/barometer-mpl115a2.js @@ -7,7 +7,7 @@ board.on("ready", function() { }); barometer.on("data", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); diff --git a/eg/barometer-mpl3115a2.js b/eg/barometer-mpl3115a2.js index 914ff8b3c..3024c9fb0 100644 --- a/eg/barometer-mpl3115a2.js +++ b/eg/barometer-mpl3115a2.js @@ -7,15 +7,15 @@ board.on("ready", function() { }); barometer.on("data", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); }); -// @markdown -// - [MPL3115A2 - I2C Barometric Pressure/Altimiter/Temperature Sensor](https://www.adafruit.com/products/1893) -// - [SparkFun Altitude/Pressure Sensor Breakout - MPL3115A2](https://www.sparkfun.com/products/11084) -// - [SparkFun Weather Shield](https://www.sparkfun.com/products/12081) -// - [SparkFun Photon Weather Shield](https://www.sparkfun.com/products/13630) -// @markdown +/* @markdown +- [MPL3115A2 - I2C Barometric Pressure/Altimiter/Temperature Sensor](https://www.adafruit.com/products/1893) +- [SparkFun Altitude/Pressure Sensor Breakout - MPL3115A2](https://www.sparkfun.com/products/11084) +- [SparkFun Weather Shield](https://www.sparkfun.com/products/12081) +- [SparkFun Photon Weather Shield](https://www.sparkfun.com/products/13630) +@markdown */ diff --git a/eg/claw.js b/eg/claw.js index 0bb87e7b0..c63a7e1b7 100644 --- a/eg/claw.js +++ b/eg/claw.js @@ -31,13 +31,13 @@ board.on("ready", function() { }); -// @markdown -// -// - [Robotic Claw](https://www.sparkfun.com/products/11524) -// - [Robotic Claw Pan/Tilt](https://www.sparkfun.com/products/11674) -// - [Robotic Claw Assembly](https://www.sparkfun.com/tutorials/258) -// -// ![Robotic Claw](https://cdn.sparkfun.com//assets/parts/7/4/4/4/11524-01a.jpg) -// ![Robotic Claw Pan/Tilt](https://cdn.sparkfun.com//assets/parts/7/7/6/7/11674-02.jpg) -// -// @markdown +/* @markdown + +- [Robotic Claw](https://www.sparkfun.com/products/11524) +- [Robotic Claw Pan/Tilt](https://www.sparkfun.com/products/11674) +- [Robotic Claw Assembly](https://www.sparkfun.com/tutorials/258) + +![Robotic Claw](https://cdn.sparkfun.com//assets/parts/7/4/4/4/11524-01a.jpg) +![Robotic Claw Pan/Tilt](https://cdn.sparkfun.com//assets/parts/7/7/6/7/11674-02.jpg) + +@markdown */ diff --git a/eg/edison-io-arduino.js b/eg/edison-io-arduino.js index d01211472..867c184bc 100644 --- a/eg/edison-io-arduino.js +++ b/eg/edison-io-arduino.js @@ -9,14 +9,14 @@ board.on("ready", function() { led.blink(); }); -// @markdown -// -// In order to use the Edison-IO library, you will need to flash the Intel IoTDevKit Image -// on your Edison. Once the environment is created, install Johnny-Five and Edison-IO. -// -// ```sh -// npm install johnny-five edison-io -// ``` -// -// -// @markdown +/* @markdown + +In order to use the Edison-IO library, you will need to flash the Intel IoTDevKit Image +on your Edison. Once the environment is created, install Johnny-Five and Edison-IO. + +```sh +npm install johnny-five edison-io +``` + + +@markdown */ diff --git a/eg/edison-io-miniboard.js b/eg/edison-io-miniboard.js index 16b38cce1..997ab56c6 100644 --- a/eg/edison-io-miniboard.js +++ b/eg/edison-io-miniboard.js @@ -9,14 +9,14 @@ board.on("ready", function() { led.blink(); }); -// @markdown -// -// In order to use the Edison-IO library, you will need to flash the Intel IoTDevKit Image -// on your Edison. Once the environment is created, install Johnny-Five and Edison-IO. -// -// ```sh -// npm install johnny-five edison-io -// ``` -// -// -// @markdown +/* @markdown + +In order to use the Edison-IO library, you will need to flash the Intel IoTDevKit Image +on your Edison. Once the environment is created, install Johnny-Five and Edison-IO. + +```sh +npm install johnny-five edison-io +``` + + +@markdown */ diff --git a/eg/galileo-io.js b/eg/galileo-io.js index d0756b481..cefec0071 100644 --- a/eg/galileo-io.js +++ b/eg/galileo-io.js @@ -9,14 +9,14 @@ board.on("ready", function() { led.blink(); }); -// @markdown -// -// In order to use the Galileo-IO library, you will need to flash the Intel IoTDevKit Image -// on your Galileo Gen 2. Once the environment is created, install Johnny-Five and Galileo-IO. -// -// ```sh -// npm install johnny-five galileo-io -// ``` -// -// -// @markdown +/* @markdown + +In order to use the Galileo-IO library, you will need to flash the Intel IoTDevKit Image +on your Galileo Gen 2. Once the environment is created, install Johnny-Five and Galileo-IO. + +```sh +npm install johnny-five galileo-io +``` + + +@markdown */ diff --git a/eg/gps-GP-20U7.js b/eg/gps-GP-20U7.js new file mode 100644 index 000000000..68196404d --- /dev/null +++ b/eg/gps-GP-20U7.js @@ -0,0 +1,22 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var gps = new five.GPS({ + pins: { + rx: 11, + tx: 10, + } + }); + + // If latitude, longitude data log it. + // This will output zero until a valid + // GPS position is detected. + gps.on("data", function() { + console.log("position"); + console.log(" latitude : ", this.latitude); + console.log(" longitude : ", this.longitude); + console.log(" altitude : ", this.altitude); + console.log("--------------------------------------"); + }); +}); diff --git a/eg/gripper.js b/eg/gripper.js index 04988ff20..b75c13020 100644 --- a/eg/gripper.js +++ b/eg/gripper.js @@ -69,7 +69,7 @@ var five = require("../lib/johnny-five.js"), }); -// @markdown +/* @markdown // - [Parallax Boe-Bot Gripper](http://www.parallax.com/Portals/0/Downloads/docs/prod/acc/GripperManual-v3.0.pdf) // - [DFRobot LG-NS Gripper](http://www.dfrobot.com/index.php?route=product/product&filter_name=gripper&product_id=628#.UCvGymNST_k) -// @markdown +@markdown */ diff --git a/eg/grove-accelerometer-adxl345-edison.js b/eg/grove-accelerometer-adxl345-edison.js index 635512f7b..d69dec29d 100644 --- a/eg/grove-accelerometer-adxl345-edison.js +++ b/eg/grove-accelerometer-adxl345-edison.js @@ -25,14 +25,14 @@ board.on("ready", function() { console.log("--------------------------------------"); }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - 3-Axis Digital Accelerometer(±16g)](http://www.seeedstudio.com/depot/images/101020054%201.jpg) -// -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - 3-Axis Digital Accelerometer(±16g)](http://www.seeedstudio.com/depot/images/101020054%201.jpg) + + +@markdown */ diff --git a/eg/grove-accelerometer-mma7660-edison.js b/eg/grove-accelerometer-mma7660-edison.js index 4c3eb76a6..827bcd08d 100644 --- a/eg/grove-accelerometer-mma7660-edison.js +++ b/eg/grove-accelerometer-mma7660-edison.js @@ -25,14 +25,16 @@ board.on("ready", function() { console.log("--------------------------------------"); }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - 3-Axis Digital Accelerometer(±1.5g)](http://www.seeedstudio.com/depot/images/101020039%201.jpg) -// -// -// @markdown +/* @markdown +For this program, you'll need: + + + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - 3-Axis Digital Accelerometer(±1.5g)](http://www.seeedstudio.com/depot/images/101020039%201.jpg) + + +@markdown */ diff --git a/eg/grove-barometer-edison.js b/eg/grove-barometer-edison.js index 87ad07807..6d1da6d12 100644 --- a/eg/grove-barometer-edison.js +++ b/eg/grove-barometer-edison.js @@ -13,20 +13,20 @@ board.on("ready", function() { }); barometer.on("change", function() { - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.pressure); console.log("--------------------------------------"); }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Barometer Sensor (BMP180)](http://www.seeedstudio.com/depot/images/product/Grove%20Barometer%20Sensor%20BMP180.jpg) -// -// - [Grove - Barometer Sensor (BMP180)](http://www.seeedstudio.com/depot/Grove-Barometer-Sensor-BMP180-p-1840.html) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Barometer Sensor (BMP180)](http://www.seeedstudio.com/depot/images/product/Grove%20Barometer%20Sensor%20BMP180.jpg) + +- [Grove - Barometer Sensor (BMP180)](http://www.seeedstudio.com/depot/Grove-Barometer-Sensor-BMP180-p-1840.html) + +@markdown */ diff --git a/eg/grove-button-edison.js b/eg/grove-button-edison.js index d60eeb4fc..64ed532da 100644 --- a/eg/grove-button-edison.js +++ b/eg/grove-button-edison.js @@ -26,15 +26,15 @@ board.on("ready", function() { led.off(); }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) -// -// ![Grove - Button Module](http://www.seeedstudio.com/depot/images/product/bgpushb1.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) + +![Grove - Button Module](http://www.seeedstudio.com/depot/images/product/bgpushb1.jpg) + +@markdown */ diff --git a/eg/grove-button.js b/eg/grove-button.js index 15a946b51..f83ae3875 100644 --- a/eg/grove-button.js +++ b/eg/grove-button.js @@ -23,13 +23,13 @@ board.on("ready", function() { led.off(); }); }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) -// -// ![Grove - Button Module](http://www.seeedstudio.com/depot/images/product/bgpushb1.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) + +![Grove - Button Module](http://www.seeedstudio.com/depot/images/product/bgpushb1.jpg) + +@markdown */ diff --git a/eg/grove-compass-edison.js b/eg/grove-compass-edison.js index 789675748..1158b3777 100644 --- a/eg/grove-compass-edison.js +++ b/eg/grove-compass-edison.js @@ -25,16 +25,16 @@ board.on("ready", function() { console.log("--------------------------------------"); }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - 3-Axis Digital Compass](http://www.seeedstudio.com/depot/images/101020034%201.jpg) -// -// - [Grove - 3-Axis Digital Compass](http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Compass-p-759.html) -// -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - 3-Axis Digital Compass](http://www.seeedstudio.com/depot/images/101020034%201.jpg) + +- [Grove - 3-Axis Digital Compass](http://www.seeedstudio.com/depot/Grove-3Axis-Digital-Compass-p-759.html) + + +@markdown */ diff --git a/eg/grove-flame-sensor-edison.js b/eg/grove-flame-sensor-edison.js index 91a4c9329..f80f67c47 100644 --- a/eg/grove-flame-sensor-edison.js +++ b/eg/grove-flame-sensor-edison.js @@ -21,15 +21,15 @@ board.on("ready", function() { } }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Flame Detector Sensor](http://www.seeedstudio.com/depot/images/product/Flame%20Sensor.jpg) -// -// - [Grove - Flame Detector Sensor](http://www.seeedstudio.com/depot/Grove-Flame-Sensor-p-1450.html) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Flame Detector Sensor](http://www.seeedstudio.com/depot/images/product/Flame%20Sensor.jpg) + +- [Grove - Flame Detector Sensor](http://www.seeedstudio.com/depot/Grove-Flame-Sensor-p-1450.html) + +@markdown */ diff --git a/eg/grove-gas-mq2-edison.js b/eg/grove-gas-mq2-edison.js index 2b24632af..566f78e55 100644 --- a/eg/grove-gas-mq2-edison.js +++ b/eg/grove-gas-mq2-edison.js @@ -22,15 +22,15 @@ board.on("ready", function() { } }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Buzzer Module](http://www.seeedstudio.com/depot/images/107020000%201.jpg) -// -// ![Grove - Gas Module](http://www.seeedstudio.com/depot/images/product/Gas%20Sensor%20MQ.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Buzzer Module](http://www.seeedstudio.com/depot/images/107020000%201.jpg) + +![Grove - Gas Module](http://www.seeedstudio.com/depot/images/product/Gas%20Sensor%20MQ.jpg) + +@markdown */ diff --git a/eg/grove-gas-tp401-edison.js b/eg/grove-gas-tp401-edison.js index 41b2d48e0..1415bf654 100644 --- a/eg/grove-gas-tp401-edison.js +++ b/eg/grove-gas-tp401-edison.js @@ -60,17 +60,17 @@ board.on("ready", function() { return "Very High Pollution - Take Action Immediately"; } }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Buzzer Module](http://www.seeedstudio.com/depot/images/107020000%201.jpg) -// -// ![Grove - Air quality sensor](http://www.seeedstudio.com/depot/images/101020021%201.jpg) -// -// - [Grove - Air quality sensor](http://www.seeedstudio.com/depot/Grove-Air-quality-sensor-p-1065.html -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Buzzer Module](http://www.seeedstudio.com/depot/images/107020000%201.jpg) + +![Grove - Air quality sensor](http://www.seeedstudio.com/depot/images/101020021%201.jpg) + +- [Grove - Air quality sensor](http://www.seeedstudio.com/depot/Grove-Air-quality-sensor-p-1065.html + +@markdown */ diff --git a/eg/grove-humidity-temperature-edison.js b/eg/grove-humidity-temperature-edison.js index 1713d771c..4deb76a82 100644 --- a/eg/grove-humidity-temperature-edison.js +++ b/eg/grove-humidity-temperature-edison.js @@ -13,10 +13,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); @@ -24,15 +24,15 @@ board.on("ready", function() { console.log("--------------------------------------"); }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Temperature&Humidity Sensor (High-Accuracy & Mini)](https://github.com/rwaldron/johnny-five/raw/master/docs/breadboard/multi-TH02.png) -// -// - [Grove - Temperature&Humidity Sensor (High-Accuracy & Mini)](http://www.seeedstudio.com/depot/Grove-TemperatureHumidity-Sensor-HighAccuracy-Mini-p-1921.html) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Temperature&Humidity Sensor (High-Accuracy & Mini)](https://github.com/rwaldron/johnny-five/raw/master/docs/breadboard/multi-TH02.png) + +- [Grove - Temperature&Humidity Sensor (High-Accuracy & Mini)](http://www.seeedstudio.com/depot/Grove-TemperatureHumidity-Sensor-HighAccuracy-Mini-p-1921.html) + +@markdown */ diff --git a/eg/grove-i2c-motor-driver-edison.js b/eg/grove-i2c-motor-driver-edison.js index 50b2ab8e9..44d578d1b 100644 --- a/eg/grove-i2c-motor-driver-edison.js +++ b/eg/grove-i2c-motor-driver-edison.js @@ -39,16 +39,16 @@ board.on("ready", function() { b.fwd(127); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// (Or similiar Grove shield and platform) -// -// ![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +(Or similiar Grove shield and platform) + +![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) + +@markdown */ diff --git a/eg/grove-i2c-motor-driver.js b/eg/grove-i2c-motor-driver.js index 5a90e7e5e..98469cd71 100644 --- a/eg/grove-i2c-motor-driver.js +++ b/eg/grove-i2c-motor-driver.js @@ -36,13 +36,13 @@ board.on("ready", function() { b.fwd(127); }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// (Or similiar Grove shield and platform) -// -// ![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +(Or similiar Grove shield and platform) + +![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) + +@markdown */ diff --git a/eg/grove-joystick-edison.js b/eg/grove-joystick-edison.js index d3b822e34..075c18dc1 100644 --- a/eg/grove-joystick-edison.js +++ b/eg/grove-joystick-edison.js @@ -20,15 +20,15 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Joystick Module](http://www.seeedstudio.com/depot/images/product/bgjoy1.jpg) -// -// ![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Joystick Module](http://www.seeedstudio.com/depot/images/product/bgjoy1.jpg) + +![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) + +@markdown */ diff --git a/eg/grove-joystick.js b/eg/grove-joystick.js index 6a43a737d..5aa6ac8bf 100644 --- a/eg/grove-joystick.js +++ b/eg/grove-joystick.js @@ -17,11 +17,11 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Joystick Module](http://www.seeedstudio.com/depot/images/product/bgjoy1.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Joystick Module](http://www.seeedstudio.com/depot/images/product/bgjoy1.jpg) + +@markdown */ diff --git a/eg/grove-lcd-i2c-edison.js b/eg/grove-lcd-i2c-edison.js index f57a39521..45a5bdddc 100644 --- a/eg/grove-lcd-i2c-edison.js +++ b/eg/grove-lcd-i2c-edison.js @@ -18,7 +18,7 @@ board.on("ready", function() { lcd.blink().cursor(1, 0).print("Blinking? "); }); -// @markdown +/* @markdown // For this program, you'll need: // // ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) @@ -27,4 +27,4 @@ board.on("ready", function() { // // ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) // -// @markdown +@markdown */ diff --git a/eg/grove-lcd-i2c.js b/eg/grove-lcd-i2c.js index afdaf5c99..52666ee69 100644 --- a/eg/grove-lcd-i2c.js +++ b/eg/grove-lcd-i2c.js @@ -15,11 +15,11 @@ board.on("ready", function() { lcd.blink().cursor(1, 0).print("Blinking? "); }); -// @markdown +/* @markdown // For this program, you'll need: // // ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) // // ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) // -// @markdown +@markdown */ diff --git a/eg/grove-lcd-rgb-edison.js b/eg/grove-lcd-rgb-edison.js index 533d03ce3..e5b11ef57 100644 --- a/eg/grove-lcd-rgb-edison.js +++ b/eg/grove-lcd-rgb-edison.js @@ -37,15 +37,15 @@ function linear(start, end, step, steps) { } -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) -// -// ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) + +![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) + +@markdown */ diff --git a/eg/grove-lcd-rgb-temperature-display-edison.js b/eg/grove-lcd-rgb-temperature-display-edison.js index 62ecf5543..64798786a 100644 --- a/eg/grove-lcd-rgb-temperature-display-edison.js +++ b/eg/grove-lcd-rgb-temperature-display-edison.js @@ -8,7 +8,7 @@ board.on("ready", function() { // Plug the Temperature sensor module // into the Grove Shield's A0 jack - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "GROVE", pin: "A0" }); @@ -21,7 +21,7 @@ board.on("ready", function() { var f = 0; - temperature.on("data", function() { + thermometer.on("data", function() { // The LCD's background will change // color according to the temperature. @@ -56,14 +56,14 @@ function linear(start, end, step, steps) { return (end - start) * step / steps + start; } -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) -// -// ![Grove - Temperature Sensor](http://www.seeedstudio.com/wiki/images/thumb/b/b0/Temperature1.jpg/400px-Temperature1.jpg) -// -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) + +![Grove - Temperature Sensor](http://www.seeedstudio.com/wiki/images/thumb/b/b0/Temperature1.jpg/400px-Temperature1.jpg) + + +@markdown */ diff --git a/eg/grove-lcd-rgb-temperature-display.js b/eg/grove-lcd-rgb-temperature-display.js index 40a9cc1f0..be63e9693 100644 --- a/eg/grove-lcd-rgb-temperature-display.js +++ b/eg/grove-lcd-rgb-temperature-display.js @@ -5,7 +5,7 @@ board.on("ready", function() { // Plug the Temperature sensor module // into the Grove Shield's A0 jack - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "GROVE", pin: "A0" }); @@ -18,7 +18,7 @@ board.on("ready", function() { var f = 0; - temperature.on("data", function() { + thermometer.on("data", function() { // The LCD's background will change // color according to the temperature. @@ -53,16 +53,16 @@ function linear(start, end, step, steps) { return (end - start) * step / steps + start; } -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) -// -// ![Grove - Temperature Sensor](http://www.seeedstudio.com/wiki/images/thumb/b/b0/Temperature1.jpg/400px-Temperature1.jpg) -// -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) + +![Grove - Temperature Sensor](http://www.seeedstudio.com/wiki/images/thumb/b/b0/Temperature1.jpg/400px-Temperature1.jpg) + + +@markdown */ diff --git a/eg/grove-lcd-rgb.js b/eg/grove-lcd-rgb.js index e6b714f6e..678506fff 100644 --- a/eg/grove-lcd-rgb.js +++ b/eg/grove-lcd-rgb.js @@ -34,13 +34,13 @@ function linear(start, end, step, steps) { } -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) -// -// ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) + +![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) + +@markdown */ diff --git a/eg/grove-led-edison.js b/eg/grove-led-edison.js index d170338ac..9d0863c76 100644 --- a/eg/grove-led-edison.js +++ b/eg/grove-led-edison.js @@ -21,13 +21,13 @@ board.on("ready", function() { led.blink(500); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED.jpg) + +@markdown */ diff --git a/eg/grove-led.js b/eg/grove-led.js index 1815b3d70..4d0f53762 100644 --- a/eg/grove-led.js +++ b/eg/grove-led.js @@ -18,11 +18,11 @@ board.on("ready", function() { led.blink(500); }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED.jpg) + +@markdown */ diff --git a/eg/grove-light-sensor-edison.js b/eg/grove-light-sensor-edison.js index ed80dba5c..c0848b596 100644 --- a/eg/grove-light-sensor-edison.js +++ b/eg/grove-light-sensor-edison.js @@ -16,15 +16,15 @@ board.on("ready", function() { console.log("Ambient Light Level: ", this.level); }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Digital Light Sensor](http://www.seeedstudio.com/depot/images/101020030%201.jpg) -// -// - [Grove - Digital Light Sensor](http://www.seeedstudio.com/depot/Grove-Digital-Light-Sensor-p-1281.html) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Digital Light Sensor](http://www.seeedstudio.com/depot/images/101020030%201.jpg) + +- [Grove - Digital Light Sensor](http://www.seeedstudio.com/depot/Grove-Digital-Light-Sensor-p-1281.html) + +@markdown */ diff --git a/eg/grove-moisture-edison.js b/eg/grove-moisture-edison.js index 142895d52..b4e072764 100644 --- a/eg/grove-moisture-edison.js +++ b/eg/grove-moisture-edison.js @@ -27,15 +27,15 @@ board.on("ready", function() { } }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Moisture Module](http://www.seeedstudio.com/depot/images/101020008%201.jpg) -// -// ![Grove - Relay Module](http://www.seeedstudio.com/depot/images/1030200051.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Moisture Module](http://www.seeedstudio.com/depot/images/101020008%201.jpg) + +![Grove - Relay Module](http://www.seeedstudio.com/depot/images/1030200051.jpg) + +@markdown */ diff --git a/eg/grove-oled-ssd1308-edison.js b/eg/grove-oled-ssd1308-edison.js index a26d709ef..04b2b0cdb 100644 --- a/eg/grove-oled-ssd1308-edison.js +++ b/eg/grove-oled-ssd1308-edison.js @@ -20,8 +20,8 @@ board.on("ready", function() { // Check out the Oled.js API! // https://github.com/noopkat/oled-js#available-methods }); -// @markdown -// For this program, you'll need: +/* @markdown +For this program, you'll need: // // ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) // @@ -32,4 +32,4 @@ board.on("ready", function() { // - [Grove - OLED Display 1.12"](http://www.seeedstudio.com/depot/Grove-OLED-Display-112-p-781.html) // // -// @markdown +@markdown */ diff --git a/eg/grove-piezo-vibration-edison.js b/eg/grove-piezo-vibration-edison.js index 9e0be270d..9a26ef215 100644 --- a/eg/grove-piezo-vibration-edison.js +++ b/eg/grove-piezo-vibration-edison.js @@ -25,8 +25,8 @@ board.on("ready", function() { } }); }); -// @markdown -// For this program, you'll need: +/* @markdown +For this program, you'll need: // // ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) // @@ -37,4 +37,4 @@ board.on("ready", function() { // ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED.jpg) // // -// @markdown +@markdown */ diff --git a/eg/grove-pir-motion-detector-edison.js b/eg/grove-pir-motion-detector-edison.js index 2b65d5032..332096aed 100644 --- a/eg/grove-pir-motion-detector-edison.js +++ b/eg/grove-pir-motion-detector-edison.js @@ -26,7 +26,7 @@ board.on("ready", function() { console.log("motionend"); }); }); -// @markdown +/* @markdown // For this program, you'll need: // // ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) @@ -37,4 +37,4 @@ board.on("ready", function() { // // - [Grove - PIR Motion Sensor](http://www.seeedstudio.com/depot/Grove-PIR-Motion-Sensor-p-802.html) // -// @markdown +@markdown */ diff --git a/eg/grove-q-touch.js b/eg/grove-q-touch.js index 27fec43bb..41681908e 100644 --- a/eg/grove-q-touch.js +++ b/eg/grove-q-touch.js @@ -42,14 +42,14 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// [![Grove - Q Touch Sensor](http://www.seeedstudio.com/depot/images/product/Grove-Q%20Touch%20Sensor_02.jpg)](http://www.seeedstudio.com/depot/GroveQ-Touch-Sensor-p-1854.html) -// -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +[![Grove - Q Touch Sensor](http://www.seeedstudio.com/depot/images/product/Grove-Q%20Touch%20Sensor_02.jpg)](http://www.seeedstudio.com/depot/GroveQ-Touch-Sensor-p-1854.html) + + +@markdown */ diff --git a/eg/grove-relay-edison.js b/eg/grove-relay-edison.js index 734b9f55b..49ed013bb 100644 --- a/eg/grove-relay-edison.js +++ b/eg/grove-relay-edison.js @@ -17,15 +17,15 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// ![Grove - Relay Module](http://www.seeedstudio.com/depot/images/1030200051.jpg) -// -// -// Learn More At: -// -// - [JavaScript: Relay Control with Johnny-Five on Node.js](http://bocoup.com/weblog/javascript-relay-with-johnny-five/) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) +![Grove - Relay Module](http://www.seeedstudio.com/depot/images/1030200051.jpg) + + +Learn More At: + +- [JavaScript: Relay Control with Johnny-Five on Node.js](http://bocoup.com/weblog/javascript-relay-with-johnny-five/) + +@markdown */ diff --git a/eg/grove-rotary-potentiometer-edison.js b/eg/grove-rotary-potentiometer-edison.js index bae3a8bb5..69fb5a70e 100644 --- a/eg/grove-rotary-potentiometer-edison.js +++ b/eg/grove-rotary-potentiometer-edison.js @@ -24,15 +24,15 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) -// -// ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) + +![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) + +@markdown */ diff --git a/eg/grove-rotary-potentiometer.js b/eg/grove-rotary-potentiometer.js index 7f2d5e59e..a9f8cfa61 100644 --- a/eg/grove-rotary-potentiometer.js +++ b/eg/grove-rotary-potentiometer.js @@ -21,13 +21,13 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) -// -// ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) + +![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) + +@markdown */ diff --git a/eg/grove-servo-edison.js b/eg/grove-servo-edison.js index d787a98d0..0ea4958f9 100644 --- a/eg/grove-servo-edison.js +++ b/eg/grove-servo-edison.js @@ -24,15 +24,15 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Servo Module](http://www.seeedstudio.com/depot/images/product/GroveServo_01.jpg) -// -// ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Servo Module](http://www.seeedstudio.com/depot/images/product/GroveServo_01.jpg) + +![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) + +@markdown */ diff --git a/eg/grove-servo.js b/eg/grove-servo.js index 952dacd89..3fc650f7b 100644 --- a/eg/grove-servo.js +++ b/eg/grove-servo.js @@ -21,13 +21,13 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - Servo Module](http://www.seeedstudio.com/depot/images/product/GroveServo_01.jpg) -// -// ![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - Servo Module](http://www.seeedstudio.com/depot/images/product/GroveServo_01.jpg) + +![Grove - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) + +@markdown */ diff --git a/eg/grove-touch-edison.js b/eg/grove-touch-edison.js index 3b67e97dd..f9b42b1ab 100644 --- a/eg/grove-touch-edison.js +++ b/eg/grove-touch-edison.js @@ -28,15 +28,15 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) -// -// ![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) + +![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) + +@markdown */ diff --git a/eg/grove-touch.js b/eg/grove-touch.js index d0a86a060..9374f2a35 100644 --- a/eg/grove-touch.js +++ b/eg/grove-touch.js @@ -25,13 +25,13 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// ![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) -// -// ![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +![Grove - LED Module](http://www.seeedstudio.com/depot/images/product/Red%20LED_02.jpg) + +![Grove - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) + +@markdown */ diff --git a/eg/hygrometer-DHT21_I2C_NANO_BACKPACK.js b/eg/hygrometer-DHT21_I2C_NANO_BACKPACK.js new file mode 100644 index 000000000..3495e47bf --- /dev/null +++ b/eg/hygrometer-DHT21_I2C_NANO_BACKPACK.js @@ -0,0 +1,14 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "DHT21_I2C_NANO_BACKPACK" + }); + + hygrometer.on("change", function() { + console.log("Hygrometer"); + console.log(" relative humidity : ", this.relativeHumidity); + console.log("--------------------------------------"); + }); +}); diff --git a/eg/hygrometer-DHT22_I2C_NANO_BACKPACK.js b/eg/hygrometer-DHT22_I2C_NANO_BACKPACK.js new file mode 100644 index 000000000..2b3d251ae --- /dev/null +++ b/eg/hygrometer-DHT22_I2C_NANO_BACKPACK.js @@ -0,0 +1,15 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "DHT22_I2C_NANO_BACKPACK" + }); + + hygrometer.on("change", function() { + console.log("Hygrometer"); + console.log(" relative humidity : ", this.relativeHumidity); + console.log("--------------------------------------"); + }); +}); + diff --git a/eg/hygrometer-HIH6130.js b/eg/hygrometer-HIH6130.js new file mode 100644 index 000000000..b1d743291 --- /dev/null +++ b/eg/hygrometer-HIH6130.js @@ -0,0 +1,14 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "HIH6130" + }); + + hygrometer.on("change", function() { + console.log("Hygrometer"); + console.log(" relative humidity : ", this.relativeHumidity); + console.log("--------------------------------------"); + }); +}); diff --git a/eg/hygrometer-SI7021.js b/eg/hygrometer-SI7021.js new file mode 100644 index 000000000..71c3cd88b --- /dev/null +++ b/eg/hygrometer-SI7021.js @@ -0,0 +1,12 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var hygrometer = new five.Hygrometer({ + controller: "SI7021" + }); + + hygrometer.on("data", function() { + console.log(this.relativeHumidity + " %"); + }); +}); diff --git a/eg/hygrometer-TH02.js b/eg/hygrometer-TH02.js index fc6ca527e..4ef790f6c 100644 --- a/eg/hygrometer-TH02.js +++ b/eg/hygrometer-TH02.js @@ -2,13 +2,13 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var humidity = new five.Hygrometer({ + var hygrometer = new five.Hygrometer({ controller: "TH02" }); - humidity.on("change", function() { + hygrometer.on("change", function() { console.log("Hygrometer"); - console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log(" relative humidity : ", this.relativeHumidity); console.log("--------------------------------------"); }); }); diff --git a/eg/hygrometer-htu21d.js b/eg/hygrometer-htu21d.js index fa756a3e7..94da840c7 100644 --- a/eg/hygrometer-htu21d.js +++ b/eg/hygrometer-htu21d.js @@ -11,6 +11,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [HTU21D - Humidity Sensor](https://www.adafruit.com/products/1899) -// @markdown +/* @markdown +- [HTU21D - Humidity Sensor](https://www.adafruit.com/products/1899) +@markdown */ diff --git a/eg/hygrometer-sht31d.js b/eg/hygrometer-sht31d.js index 1c62b671a..1b1c92ac6 100644 --- a/eg/hygrometer-sht31d.js +++ b/eg/hygrometer-sht31d.js @@ -11,6 +11,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [SHT31D - Humidity Sensor](https://www.adafruit.com/products/2857) -// @markdown +/* @markdown +- [SHT31D - Humidity Sensor](https://www.adafruit.com/products/2857) +@markdown */ diff --git a/eg/imp-io.js b/eg/imp-io.js index 4f733ee1d..a7ecf7a68 100644 --- a/eg/imp-io.js +++ b/eg/imp-io.js @@ -12,29 +12,29 @@ board.on("ready", function() { led.blink(); }); -// @markdown -// -// To communicate with an Electric Imp using Johnny-Five w/ Imp-IO, -// you will need to upload the special -// [Tyrion](https://github.com/rwaldron/tyrion) -// **[agent](https://github.com/rwaldron/tyrion/blob/master/agent.nut)** and -// **[device](https://github.com/rwaldron/tyrion/blob/master/device.nut)** -// firmware through Electric Imp's [IDE](https://ide.electricimp.com/login). -// We recommend you review -// [Electric Imp's Getting Started](http://www.electricimp.com/docs/gettingstarted/) -// before continuing. -// -// Store your agent ID in a dot file so it can be accessed as a property of `process.env`. -// Create a file in your home directory called `.imprc` that contains: -// -// ```sh -// export IMP_AGENT_ID="your agent id" -// ``` -// -// Then add the following to your dot-rc file of choice: -// -// ```sh -// source ~/.imprc -// ``` -// -// @markdown +/* @markdown + +To communicate with an Electric Imp using Johnny-Five w/ Imp-IO, +you will need to upload the special +[Tyrion](https://github.com/rwaldron/tyrion) +**[agent](https://github.com/rwaldron/tyrion/blob/master/agent.nut)** and +**[device](https://github.com/rwaldron/tyrion/blob/master/device.nut)** +firmware through Electric Imp's [IDE](https://ide.electricimp.com/login). +We recommend you review +[Electric Imp's Getting Started](http://www.electricimp.com/docs/gettingstarted/) +before continuing. + +Store your agent ID in a dot file so it can be accessed as a property of `process.env`. +Create a file in your home directory called `.imprc` that contains: + +```sh +export IMP_AGENT_ID="your agent id" +``` + +Then add the following to your dot-rc file of choice: + +```sh +source ~/.imprc +``` + +@markdown */ diff --git a/eg/imu-bno055.js b/eg/imu-bno055.js index 9a158c019..b867c9af5 100644 --- a/eg/imu-bno055.js +++ b/eg/imu-bno055.js @@ -28,13 +28,13 @@ board.on("ready", function() { imu.on("change", function() { - console.log("temperature"); + console.log("Thermometer"); console.log(" celsius : ", this.thermometer.celsius); console.log(" fahrenheit : ", this.thermometer.fahrenheit); console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("accelerometer"); + console.log("Accelerometer"); console.log(" x : ", this.accelerometer.x); console.log(" y : ", this.accelerometer.y); console.log(" z : ", this.accelerometer.z); @@ -45,7 +45,7 @@ board.on("ready", function() { console.log(" orientation : ", this.accelerometer.orientation); console.log("--------------------------------------"); - console.log("gyro"); + console.log("Gyroscope"); console.log(" x : ", this.gyro.x); console.log(" y : ", this.gyro.y); console.log(" z : ", this.gyro.z); diff --git a/eg/imu-mpu6050.js b/eg/imu-mpu6050.js index baa13da87..843fe163b 100644 --- a/eg/imu-mpu6050.js +++ b/eg/imu-mpu6050.js @@ -7,13 +7,13 @@ board.on("ready", function() { }); imu.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("accelerometer"); + console.log("Accelerometer"); console.log(" x : ", this.accelerometer.x); console.log(" y : ", this.accelerometer.y); console.log(" z : ", this.accelerometer.z); @@ -24,7 +24,7 @@ board.on("ready", function() { console.log(" orientation : ", this.accelerometer.orientation); console.log("--------------------------------------"); - console.log("gyro"); + console.log("Gyroscope"); console.log(" x : ", this.gyro.x); console.log(" y : ", this.gyro.y); console.log(" z : ", this.gyro.z); diff --git a/eg/keypad-QTOUCH.js b/eg/keypad-QTOUCH.js index 2f72dc20e..c6293cca5 100644 --- a/eg/keypad-QTOUCH.js +++ b/eg/keypad-QTOUCH.js @@ -41,12 +41,12 @@ board.on("ready", function() { }); -// @markdown -// For this program, you'll need: -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// [![Grove - Q Touch Sensor](http://www.seeedstudio.com/depot/images/product/Grove-Q%20Touch%20Sensor_02.jpg)](http://www.seeedstudio.com/depot/GroveQ-Touch-Sensor-p-1854.html) -// -// -// @markdown +/* @markdown +For this program, you'll need: + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +[![Grove - Q Touch Sensor](http://www.seeedstudio.com/depot/images/product/Grove-Q%20Touch%20Sensor_02.jpg)](http://www.seeedstudio.com/depot/GroveQ-Touch-Sensor-p-1854.html) + + +@markdown */ diff --git a/eg/lcd-autoscroll-16x2-PCF8574T.js b/eg/lcd-autoscroll-16x2-PCF8574T.js new file mode 100644 index 000000000..06bf1c25d --- /dev/null +++ b/eg/lcd-autoscroll-16x2-PCF8574T.js @@ -0,0 +1,20 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + var l = new five.LCD({ + controller: "PCF8574T" + }); + + l.cursor(0, 0); + l.autoscroll(); + + var number = 0; + var interval = setInterval(_ => { + l.print(number++); + + if (number === 10) { + number = 0; + } + }, 100); +}); diff --git a/eg/lcd-enumeratechars.js b/eg/lcd-enumeratechars.js index 603df1dce..aa9071357 100644 --- a/eg/lcd-enumeratechars.js +++ b/eg/lcd-enumeratechars.js @@ -13,7 +13,7 @@ board.on("ready", function() { var k = 0; var i = 0; - var keys = Object.keys(five.LCD.Characters); + var keys = Object.keys(five.LCD.Characters.DEFAULT); var length = keys.length; var eights = []; @@ -44,7 +44,7 @@ board.on("ready", function() { }); }); -// @markdown -// - [16 x 2 LCD White on Blue](http://www.hacktronics.com/LCDs/16-x-2-LCD-White-on-Blue/flypage.tpl.html) -// - [20 x 4 LCD White on Blue](http://www.hacktronics.com/LCDs/20-x-4-LCD-White-on-Blue/flypage.tpl.html) -// @markdown +/* @markdown +- [16 x 2 LCD White on Blue](http://www.hacktronics.com/LCDs/16-x-2-LCD-White-on-Blue/flypage.tpl.html) +- [20 x 4 LCD White on Blue](http://www.hacktronics.com/LCDs/20-x-4-LCD-White-on-Blue/flypage.tpl.html) +@markdown */ diff --git a/eg/lcd-i2c.js b/eg/lcd-i2c.js index 55293e78a..435e669cb 100644 --- a/eg/lcd-i2c.js +++ b/eg/lcd-i2c.js @@ -17,7 +17,7 @@ board.on("ready", function() { }); -// @markdown -// [Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/depot/grove-lcd-rgb-backlight-p-1643.html) -// ![Grove LCD RGB](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) -// @markdown +/* @markdown +[Grove - LCD RGB w/ Backlight](http://www.seeedstudio.com/depot/grove-lcd-rgb-backlight-p-1643.html) +![Grove LCD RGB](http://www.seeedstudio.com/wiki/images/0/03/Serial_LEC_RGB_Backlight_Lcd.jpg) +@markdown */ diff --git a/eg/lcd-runner-20x4.js b/eg/lcd-runner-20x4.js index cee51a124..3960297c3 100644 --- a/eg/lcd-runner-20x4.js +++ b/eg/lcd-runner-20x4.js @@ -40,7 +40,7 @@ board.on("ready", function() { }); }); -// @markdown -// - [16 x 2 LCD White on Blue](http://www.hacktronics.com/LCDs/16-x-2-LCD-White-on-Blue/flypage.tpl.html) -// - [20 x 4 LCD White on Blue](http://www.hacktronics.com/LCDs/20-x-4-LCD-White-on-Blue/flypage.tpl.html) -// @markdown +/* @markdown +- [16 x 2 LCD White on Blue](http://www.hacktronics.com/LCDs/16-x-2-LCD-White-on-Blue/flypage.tpl.html) +- [20 x 4 LCD White on Blue](http://www.hacktronics.com/LCDs/20-x-4-LCD-White-on-Blue/flypage.tpl.html) +@markdown */ diff --git a/eg/lcd.js b/eg/lcd.js index 0adbfe808..28bc6c9b7 100644 --- a/eg/lcd.js +++ b/eg/lcd.js @@ -44,7 +44,7 @@ board.on("ready", function() { }); -// @markdown -// [16 x 2 LCD White on Blue](http://www.hacktronics.com/LCDs/16-x-2-LCD-White-on-Blue/flypage.tpl.html) -// [20 x 4 LCD White on Blue](http://www.hacktronics.com/LCDs/20-x-4-LCD-White-on-Blue/flypage.tpl.html) -// @markdown +/* @markdown +[16 x 2 LCD White on Blue](http://www.hacktronics.com/LCDs/16-x-2-LCD-White-on-Blue/flypage.tpl.html) +[20 x 4 LCD White on Blue](http://www.hacktronics.com/LCDs/20-x-4-LCD-White-on-Blue/flypage.tpl.html) +@markdown */ diff --git a/eg/led-array.js b/eg/led-array.js index 49f0a24ab..327b2206a 100644 --- a/eg/led-array.js +++ b/eg/led-array.js @@ -7,10 +7,10 @@ board.on("ready", function() { array.pulse(); }); -// @markdown -// -// Control multiple LEDs at once by creating an LED collection (`Leds`). -// All must be on PWM pins if you want to use methods such -// as `pulse()` or `fade()` -// -// @markdown +/* @markdown + +Control multiple LEDs at once by creating an LED collection (`Leds`). +All must be on PWM pins if you want to use methods such +as `pulse()` or `fade()` + +@markdown */ diff --git a/eg/led-digits-clock-HT16K33.js b/eg/led-digits-clock-HT16K33.js index bb1b89697..0dd602e79 100644 --- a/eg/led-digits-clock-HT16K33.js +++ b/eg/led-digits-clock-HT16K33.js @@ -20,10 +20,10 @@ function time(showColon) { ); return display.slice(-5); } -// @markdown -// -// Learn More: -// -// - [JavaScript: A Digital Clock with Johnny-Five](http://bocoup.com/weblog/javascript-arduino-digital-clock-johnny-five/) -// -// @markdown +/* @markdown + +Learn More: + +- [JavaScript: A Digital Clock with Johnny-Five](http://bocoup.com/weblog/javascript-arduino-digital-clock-johnny-five/) + +@markdown */ diff --git a/eg/led-digits-clock-dual.js b/eg/led-digits-clock-dual.js index 60a6de840..87ad5c931 100644 --- a/eg/led-digits-clock-dual.js +++ b/eg/led-digits-clock-dual.js @@ -30,10 +30,10 @@ board.on("ready", function() { seconds.print(" " + now.format("ss.SSSS")); }, 200); }); -// @markdown -// -// Learn More: -// -// - [JavaScript: A Digital Clock with Johnny-Five](http://bocoup.com/weblog/javascript-arduino-digital-clock-johnny-five/) -// -// @markdown +/* @markdown + +Learn More: + +- [JavaScript: A Digital Clock with Johnny-Five](http://bocoup.com/weblog/javascript-arduino-digital-clock-johnny-five/) + +@markdown */ diff --git a/eg/led-digits-clock.js b/eg/led-digits-clock.js index a8447bb31..6e52bd162 100644 --- a/eg/led-digits-clock.js +++ b/eg/led-digits-clock.js @@ -35,10 +35,10 @@ function time() { } -// @markdown +/* @markdown // // Learn More: // // - [JavaScript: A Digital Clock with Johnny-Five](http://bocoup.com/weblog/javascript-arduino-digital-clock-johnny-five/) // -// @markdown +@markdown */ diff --git a/eg/led-rainbow.js b/eg/led-rainbow.js index ce24755ce..2b3bca8d0 100644 --- a/eg/led-rainbow.js +++ b/eg/led-rainbow.js @@ -7,9 +7,9 @@ board.on("ready", function() { var rainbow = ["FF0000", "FF7F00", "FFFF00", "00FF00", "0000FF", "4B0082", "8F00FF"]; this.loop(1000, function() { - if (index + 1 === rainbow.length) { + rgb.color(rainbow[index++]); + if (index === rainbow.length) { index = 0; } - rgb.color(rainbow[index++]); }); }); diff --git a/eg/led.js b/eg/led.js index 40a7211cc..6296b0dd8 100644 --- a/eg/led.js +++ b/eg/led.js @@ -14,16 +14,16 @@ board.on("ready", function() { led.blink(); }); -// @markdown -// This script will make `led` available in the REPL, by default on pin 13. -// Now you can try, e.g.: -// -// ```js -// >> led.stop() // to stop blinking -// // then -// >> led.off() // to shut it off (stop doesn't mean "off") -// // then -// >> led.on() // to turn on, but not blink -// ``` -// -// @markdown +/* @markdown +This script will make `led` available in the REPL, by default on pin 13. +Now you can try, e.g.: + +```js +>> led.stop() // to stop blinking +then +>> led.off() // to shut it off (stop doesn't mean "off") +then +>> led.on() // to turn on, but not blink +``` + +@markdown */ diff --git a/eg/light-ambient-TSL2561.js b/eg/light-ambient-TSL2561.js index af4b12e47..eb6e898bc 100644 --- a/eg/light-ambient-TSL2561.js +++ b/eg/light-ambient-TSL2561.js @@ -3,10 +3,10 @@ var board = new five.Board(); board.on("ready", function() { var light = new five.Light({ - controller: "TSL2561" + controller: "TSL2561", }); - light.on("change", function() { - console.log("Ambient Light Level: ", this.level); + light.on("data", function() { + console.log("Lux: ", this.lux); }); }); diff --git a/eg/motobot.js b/eg/motobot.js index c5041c5c5..162dbee6f 100644 --- a/eg/motobot.js +++ b/eg/motobot.js @@ -57,10 +57,10 @@ board.on("ready", function() { process.stdin.resume(); }); -// @markdown -// -// ![Chassis](https://cdn.sparkfun.com//assets/parts/9/7/3/8/12866-01.jpg) -// -// ![ArduMoto](https://cdn.sparkfun.com//assets/parts/3/8/4/9/09815-01.jpg) -// -// @markdown +/* @markdown + +![Chassis](https://cdn.sparkfun.com//assets/parts/9/7/3/8/12866-01.jpg) + +![ArduMoto](https://cdn.sparkfun.com//assets/parts/3/8/4/9/09815-01.jpg) + +@markdown */ diff --git a/eg/motor-GROVE_I2C.js b/eg/motor-GROVE_I2C.js index bef488fd5..eb3dba1c1 100644 --- a/eg/motor-GROVE_I2C.js +++ b/eg/motor-GROVE_I2C.js @@ -36,16 +36,16 @@ board.on("ready", function() { b.fwd(127); }); -// @markdown -// For this program, you'll need: -// -// ![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) -// -// -// ![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) -// -// (Or similiar Grove shield and platform) -// -// ![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Intel Edison Arduino Breakout](https://cdn.sparkfun.com//assets/parts/1/0/1/3/9/13097-06.jpg) + + +![Grove Base Shield v2](http://www.seeedstudio.com/depot/images/product/base%20shield%20V2_01.jpg) + +(Or similiar Grove shield and platform) + +![Grove - I2C Motor Driver](http://www.seeedstudio.com/depot/images/product/12Cmotor_01.jpg) + +@markdown */ diff --git a/eg/motor-TB6612FNG.js b/eg/motor-TB6612FNG.js new file mode 100644 index 000000000..e566c7cdf --- /dev/null +++ b/eg/motor-TB6612FNG.js @@ -0,0 +1,38 @@ +var five = require("johnny-five"); +var Tessel = require("tessel-io"); +var board = new five.Board({ + io: new Tessel() +}); + +board.on("ready", function() { + var spdt = new five.Switch("a0"); + var throttle = new five.Sensor("b0"); + + // See the comments below for more information about + // the pins shown in this pin array argument. + var motor = new five.Motor([ "a5", "a4", "a3" ]); + + spdt.on("open", () => { + motor.stop().forward(motor.speed()); + }); + + spdt.on("close", () => { + motor.stop().reverse(motor.speed()); + }); + + throttle.on("change", () => { + motor.speed(throttle.value >> 2); + }); +}); +/* @markdown + +Here's a breakdown of the pins used by these motor drivers, their corresponding Johnny-Five Motor class pin name, and capabilities: + +| Control Type/Role | Johnny-Five Motor Pin Name | Breakout Printed Pin | +| ----------------- | -------------------------- | -------------------- | +| PWM | `pwm` | `PWMA` or `PWMB` | +| Counter Direction | `cdir` | `AIN2` or `BIN2` | +| Direction | `dir` | `AIN1` or `BIN1` | + + +@markdown */ diff --git a/eg/motor-hbridge-dual.js b/eg/motor-hbridge-dual.js new file mode 100644 index 000000000..1d3e8e3ec --- /dev/null +++ b/eg/motor-hbridge-dual.js @@ -0,0 +1,58 @@ +/** + * This example is intended for dual H-bridge (quad half H-bridge) motor + * driver ICs, like the Texas Instruments SN754410. It isn't intended for + * motor driver breakout boards or more sophisticated drivers, which handle + * the PWM inversion for you. + */ + +var five = require("../lib/johnny-five.js"), + board = new five.Board(); + +board.on("ready", function() { + /** + * Motor A: PWM 11, dir 12 + * Motor B: PWM 5, dir 4 + */ + var motors = new five.Motors([ + { pins: { dir: 12, pwm: 11 }, invertPWM: true }, + { pins: { dir: 4, pwm: 5}, invertPWM: true } + ]); + + board.repl.inject({ + motors: motors + }); + + // Go forward at full speed for 5 seconds + console.log("Full speed ahead!"); + motors.forward(255); + board.wait(5000, function () { + motors.stop(); + }); + + // Go backwards at full speed for 5 seconds + console.log("Now backwards!"); + motors.reverse(255); + board.wait(5000, function () { + motors.stop(); + }); + + // Go left... + console.log("To the left!"); + motors[0].reverse(200); + motors[1].forward(200); + board.wait(5000, function () { + motors.stop(); + }); + + // Go right... + console.log("To the right!"); + motors[0].forward(200); + motors[1].reverse(200); + board.wait(5000, function () { + motors.stop(); + }); + + // Use REPL if you want to go further + console.log("Done auto-driving! Use `motors` to control motors in REPL"); + +}); diff --git a/eg/multi-BME280.js b/eg/multi-BME280.js new file mode 100644 index 000000000..171e7b7da --- /dev/null +++ b/eg/multi-BME280.js @@ -0,0 +1,29 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "BME280" + }); + + multi.on("data", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Barometer"); + console.log(" pressure : ", this.barometer.pressure); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + + console.log("Altimeter"); + console.log(" feet : ", this.altimeter.feet); + console.log(" meters : ", this.altimeter.meters); + console.log("--------------------------------------"); + }); +}); diff --git a/eg/multi-BMP280.js b/eg/multi-BMP280.js index cd6c11a81..53d48e4ed 100644 --- a/eg/multi-BMP280.js +++ b/eg/multi-BMP280.js @@ -7,17 +7,17 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("thermometer"); + console.log("Thermometer"); console.log(" celsius : ", this.thermometer.celsius); console.log(" fahrenheit : ", this.thermometer.fahrenheit); console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); diff --git a/eg/multi-DHT11_I2C_NANO_BACKPACK.js b/eg/multi-DHT11_I2C_NANO_BACKPACK.js index 96d1227aa..a95c3fb48 100644 --- a/eg/multi-DHT11_I2C_NANO_BACKPACK.js +++ b/eg/multi-DHT11_I2C_NANO_BACKPACK.js @@ -7,10 +7,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); diff --git a/eg/multi-DHT21_I2C_NANO_BACKPACK.js b/eg/multi-DHT21_I2C_NANO_BACKPACK.js new file mode 100644 index 000000000..d68c65377 --- /dev/null +++ b/eg/multi-DHT21_I2C_NANO_BACKPACK.js @@ -0,0 +1,21 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "DHT21_I2C_NANO_BACKPACK", + pin: 2, + }); + + multi.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + }); +}); diff --git a/eg/multi-DHT22_I2C_NANO_BACKPACK.js b/eg/multi-DHT22_I2C_NANO_BACKPACK.js new file mode 100644 index 000000000..b6e5b7999 --- /dev/null +++ b/eg/multi-DHT22_I2C_NANO_BACKPACK.js @@ -0,0 +1,21 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "DHT22_I2C_NANO_BACKPACK", + pin: 2, + }); + + multi.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + }); +}); diff --git a/eg/multi-HIH6130.js b/eg/multi-HIH6130.js new file mode 100644 index 000000000..3aef65fa7 --- /dev/null +++ b/eg/multi-HIH6130.js @@ -0,0 +1,20 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "HIH6130" + }); + + multi.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + }); +}); diff --git a/eg/multi-MS5611.js b/eg/multi-MS5611.js index 83bc814f4..db0fb377d 100644 --- a/eg/multi-MS5611.js +++ b/eg/multi-MS5611.js @@ -11,17 +11,17 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); diff --git a/eg/multi-SI7020.js b/eg/multi-SI7020.js index 4b866fd44..7df9afe3a 100644 --- a/eg/multi-SI7020.js +++ b/eg/multi-SI7020.js @@ -7,10 +7,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); @@ -19,6 +19,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [SI7020 - Climate](http://start.tessel.io/modules/climate) -// @markdown +/* @markdown +- [SI7020 - Climate](http://start.tessel.io/modules/climate) +@markdown */ diff --git a/eg/multi-SI7021.js b/eg/multi-SI7021.js new file mode 100644 index 000000000..235f61745 --- /dev/null +++ b/eg/multi-SI7021.js @@ -0,0 +1,20 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var multi = new five.Multi({ + controller: "SI7021" + }); + + multi.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); + console.log("--------------------------------------"); + + console.log("Hygrometer"); + console.log(" relative humidity : ", this.hygrometer.relativeHumidity); + console.log("--------------------------------------"); + }); +}); diff --git a/eg/multi-TH02.js b/eg/multi-TH02.js index 0e398ec89..7ffb6a70f 100644 --- a/eg/multi-TH02.js +++ b/eg/multi-TH02.js @@ -7,10 +7,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("Temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); diff --git a/eg/multi-bmp085.js b/eg/multi-bmp085.js index 006ffa75f..7b11d0d60 100644 --- a/eg/multi-bmp085.js +++ b/eg/multi-bmp085.js @@ -7,17 +7,17 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("thermometer"); + console.log("Thermometer"); console.log(" celsius : ", this.thermometer.celsius); console.log(" fahrenheit : ", this.thermometer.fahrenheit); console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); diff --git a/eg/multi-bmp180.js b/eg/multi-bmp180.js index 5868576d8..4a328377c 100644 --- a/eg/multi-bmp180.js +++ b/eg/multi-bmp180.js @@ -7,17 +7,17 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("thermometer"); + console.log("Thermometer"); console.log(" celsius : ", this.thermometer.celsius); console.log(" fahrenheit : ", this.thermometer.fahrenheit); console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); diff --git a/eg/multi-htu21d.js b/eg/multi-htu21d.js index 355359c74..e804c3935 100644 --- a/eg/multi-htu21d.js +++ b/eg/multi-htu21d.js @@ -7,10 +7,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); @@ -19,6 +19,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [HTU21D - Humidity Sensor](https://www.adafruit.com/products/1899) -// @markdown +/* @markdown +- [HTU21D - Humidity Sensor](https://www.adafruit.com/products/1899) +@markdown */ diff --git a/eg/multi-mpl115a2.js b/eg/multi-mpl115a2.js index b10533061..a35ec3d53 100644 --- a/eg/multi-mpl115a2.js +++ b/eg/multi-mpl115a2.js @@ -7,13 +7,13 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); }); diff --git a/eg/multi-mpl3115a2.js b/eg/multi-mpl3115a2.js index 9c5efef4e..d93ba55cf 100644 --- a/eg/multi-mpl3115a2.js +++ b/eg/multi-mpl3115a2.js @@ -11,26 +11,26 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); - console.log("barometer"); + console.log("Barometer"); console.log(" pressure : ", this.barometer.pressure); console.log("--------------------------------------"); - console.log("altimeter"); + console.log("Altimeter"); console.log(" feet : ", this.altimeter.feet); console.log(" meters : ", this.altimeter.meters); console.log("--------------------------------------"); }); }); -// @markdown -// - [MPL3115A2 - I2C Barometric Pressure/Altimiter/Temperature Sensor](https://www.adafruit.com/products/1893) -// - [SparkFun Altitude/Pressure Sensor Breakout - MPL3115A2](https://www.sparkfun.com/products/11084) -// - [SparkFun Weather Shield](https://www.sparkfun.com/products/12081) -// - [SparkFun Photon Weather Shield](https://www.sparkfun.com/products/13630) -// @markdown +/* @markdown +- [MPL3115A2 - I2C Barometric Pressure/Altimiter/Temperature Sensor](https://www.adafruit.com/products/1893) +- [SparkFun Altitude/Pressure Sensor Breakout - MPL3115A2](https://www.sparkfun.com/products/11084) +- [SparkFun Weather Shield](https://www.sparkfun.com/products/12081) +- [SparkFun Photon Weather Shield](https://www.sparkfun.com/products/13630) +@markdown */ diff --git a/eg/multi-sht31d.js b/eg/multi-sht31d.js index 78bf46793..e6956a16a 100644 --- a/eg/multi-sht31d.js +++ b/eg/multi-sht31d.js @@ -7,10 +7,10 @@ board.on("ready", function() { }); multi.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.thermometer.celsius); + console.log(" fahrenheit : ", this.thermometer.fahrenheit); + console.log(" kelvin : ", this.thermometer.kelvin); console.log("--------------------------------------"); console.log("Hygrometer"); @@ -19,6 +19,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [SHT31D - Humidity Sensor](https://www.adafruit.com/products/2857) -// @markdown +/* @markdown +- [SHT31D - Humidity Sensor](https://www.adafruit.com/products/2857) +@markdown */ diff --git a/eg/pcduino-io.js b/eg/pcduino-io.js index 2229fc81f..d7b9b8dc8 100644 --- a/eg/pcduino-io.js +++ b/eg/pcduino-io.js @@ -9,16 +9,16 @@ board.on("ready", function() { led.blink(); }); -// @markdown -// -// In order to use the pcduino-io library, you will need to install node.js (0.10.x or better) -// and npm on your pcduino. Once the environment is created, install Johnny-Five and pcDuino-IO. -// -// [Setup environment](https://github.com/rwaldron/pcduino-io#install-a-compatible-version-of-nodenpm) -// -// ```sh -// npm install johnny-five pcduino-io -// ``` -// -// -// @markdown +/* @markdown + +In order to use the pcduino-io library, you will need to install node.js (0.10.x or better) +and npm on your pcduino. Once the environment is created, install Johnny-Five and pcDuino-IO. + +[Setup environment](https://github.com/rwaldron/pcduino-io#install-a-compatible-version-of-nodenpm) + +```sh +npm install johnny-five pcduino-io +``` + + +@markdown */ diff --git a/eg/raspi-io.js b/eg/raspi-io.js index 3d5631912..fbf36f845 100644 --- a/eg/raspi-io.js +++ b/eg/raspi-io.js @@ -9,14 +9,14 @@ board.on("ready", function() { led.blink(); }); -// @markdown -// -// In order to use the Raspi-IO library, it is recommended that you use -// the Raspbian OS. Others may work, but are untested. -// -// ```sh -// npm install johnny-five raspi-io -// ``` -// -// -// @markdown +/* @markdown + +In order to use the Raspi-IO library, it is recommended that you use +the Raspbian OS. Others may work, but are untested. + +```sh +npm install johnny-five raspi-io +``` + + +@markdown */ diff --git a/eg/relay.js b/eg/relay.js index 7bc00d174..673ab1768 100644 --- a/eg/relay.js +++ b/eg/relay.js @@ -15,8 +15,8 @@ board.on("ready", function() { relay: relay }); }); -// @markdown -// -// - [JavaScript: Relay Control with Johnny-Five on Node.js](http://bocoup.com/weblog/javascript-relay-with-johnny-five/) -// -// @markdown +/* @markdown + +- [JavaScript: Relay Control with Johnny-Five on Node.js](http://bocoup.com/weblog/javascript-relay-with-johnny-five/) + +@markdown */ diff --git a/eg/repl.js b/eg/repl.js index 1db35c67b..b0a8ff98b 100644 --- a/eg/repl.js +++ b/eg/repl.js @@ -19,14 +19,14 @@ board.on("ready", function() { }); -// @markdown -// This script will make `on()` and `off()` functions -// available in the REPL: -// -// ```js -// >> on() // will turn on the LED -// // or -// >> off() // will turn off the LED -// ``` -// -// @markdown +/* @markdown +This script will make `on()` and `off()` functions +available in the REPL: + +```js +>> on() // will turn on the LED +or +>> off() // will turn off the LED +``` + +@markdown */ diff --git a/eg/sensor-digital-microwave.js b/eg/sensor-digital-microwave.js new file mode 100644 index 000000000..7d24c35ca --- /dev/null +++ b/eg/sensor-digital-microwave.js @@ -0,0 +1,10 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", () => { + var microwave = new five.Sensor.Digital(7); + + microwave.on("change", () => { + console.log(microwave.value); + }); +}); diff --git a/eg/sensor-photon-weather-shield-moisture.js b/eg/sensor-photon-weather-shield-moisture.js index 5f1202f91..7ce4f0cb5 100644 --- a/eg/sensor-photon-weather-shield-moisture.js +++ b/eg/sensor-photon-weather-shield-moisture.js @@ -34,13 +34,13 @@ board.on("ready", function() { }); }); -// @markdown -// For this program, you'll need: -// -// ![Particle Photon](https://docs.particle.io/assets/images/photon_vector2_600.png) -// -// ![SparkFun Photon Weather Shield](https://cdn.sparkfun.com//assets/parts/1/1/0/1/7/13630-01a.jpg) -// -// ![SparkFun Soil Moisture Sensor](https://cdn.sparkfun.com//assets/parts/1/0/6/1/0/13322-01.jpg) -// -// @markdown +/* @markdown +For this program, you'll need: + +![Particle Photon](https://docs.particle.io/assets/images/photon_vector2_600.png) + +![SparkFun Photon Weather Shield](https://cdn.sparkfun.com//assets/parts/1/1/0/1/7/13630-01a.jpg) + +![SparkFun Soil Moisture Sensor](https://cdn.sparkfun.com//assets/parts/1/0/6/1/0/13322-01.jpg) + +@markdown */ diff --git a/eg/servo.js b/eg/servo.js index d71eb3505..65c8084dc 100644 --- a/eg/servo.js +++ b/eg/servo.js @@ -15,9 +15,6 @@ board.on("ready", function() { invert: false, // Invert all specified positions startAt: 90, // Immediately move to a degree center: true, // overrides startAt if true and moves the servo to the center of the range - specs: { // Is it running at 5V or 3.3V? - speed: five.Servo.Continuous.speeds["@5.0V"] - } }); */ diff --git a/eg/spark-io.js b/eg/spark-io.js index ba8030612..8f03daba6 100644 --- a/eg/spark-io.js +++ b/eg/spark-io.js @@ -21,25 +21,25 @@ board.on("ready", function() { }); -// @markdown -// -// In order to use the spark-io library, you will need to load the special -// [voodoospark](https://github.com/voodootikigod/voodoospark) firmware onto your -// device. We recommend you review [VoodooSpark's Getting Started](https://github.com/voodootikigod/voodoospark#getting-started) before continuing. -// -// We also recommend storing your Spark token and device ID in a dot file so they can be accessed as properties of `process.env`. Create a file in your home directory called `.sparkrc` that contains: -// -// ```sh -// export SPARK_TOKEN="your spark token" -// export SPARK_DEVICE_ID="your device id" -// ``` -// -// Then add the following to your dot-rc file of choice: -// -// ```sh -// source ~/.sparkrc -// ``` -// -// Ensure your host computer (where you're running your Node.js application) and the Spark are on the same local network. -// -// @markdown +/* @markdown + +In order to use the spark-io library, you will need to load the special +[voodoospark](https://github.com/voodootikigod/voodoospark) firmware onto your +device. We recommend you review [VoodooSpark's Getting Started](https://github.com/voodootikigod/voodoospark#getting-started) before continuing. + +We also recommend storing your Spark token and device ID in a dot file so they can be accessed as properties of `process.env`. Create a file in your home directory called `.sparkrc` that contains: + +```sh +export SPARK_TOKEN="your spark token" +export SPARK_DEVICE_ID="your device id" +``` + +Then add the following to your dot-rc file of choice: + +```sh +source ~/.sparkrc +``` + +Ensure your host computer (where you're running your Node.js application) and the Spark are on the same local network. + +@markdown */ diff --git a/eg/stepper-driver.js b/eg/stepper-driver.js index 9eeb3a0ae..6d6b2b74b 100644 --- a/eg/stepper-driver.js +++ b/eg/stepper-driver.js @@ -37,11 +37,11 @@ board.on("ready", function() { }); }); -// @markdown -// - [A4988 Stepper Motor Driver Carrier](http://www.pololu.com/catalog/product/1182) -// - [100uf 35v electrolytic cap](http://www.amazon.com/100uF-Radial-Mini-Electrolytic-Capacitor/dp/B0002ZP530) -// - [Stepper Motor (4 wire, bipolar)](https://www.sparkfun.com/products/9238) -// -// ![docs/breadboard/stepper-driver-A4988.png](breadboard/stepper-driver-A4988.png) -// -// @markdown +/* @markdown +- [A4988 Stepper Motor Driver Carrier](http://www.pololu.com/catalog/product/1182) +- [100uf 35v electrolytic cap](http://www.amazon.com/100uF-Radial-Mini-Electrolytic-Capacitor/dp/B0002ZP530) +- [Stepper Motor (4 wire, bipolar)](https://www.sparkfun.com/products/9238) + +![docs/breadboard/stepper-driver-A4988.png](breadboard/stepper-driver-A4988.png) + +@markdown */ diff --git a/eg/temperature-BMP180.js b/eg/temperature-BMP180.js index e14ba00a2..a0fe321f0 100644 --- a/eg/temperature-BMP180.js +++ b/eg/temperature-BMP180.js @@ -2,13 +2,13 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "BMP180", freq: 250 }); - temperature.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/eg/temperature-DHT11_I2C_NANO_BACKPACK.js b/eg/temperature-DHT11_I2C_NANO_BACKPACK.js index 26332cd93..c2c651828 100644 --- a/eg/temperature-DHT11_I2C_NANO_BACKPACK.js +++ b/eg/temperature-DHT11_I2C_NANO_BACKPACK.js @@ -2,12 +2,12 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temp = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "DHT11_I2C_NANO_BACKPACK" }); - temp.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/eg/temperature-DHT21_I2C_NANO_BACKPACK.js b/eg/temperature-DHT21_I2C_NANO_BACKPACK.js new file mode 100644 index 000000000..df3d79509 --- /dev/null +++ b/eg/temperature-DHT21_I2C_NANO_BACKPACK.js @@ -0,0 +1,17 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var thermometer = new five.Thermometer({ + controller: "DHT21_I2C_NANO_BACKPACK" + }); + + thermometer.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); + console.log("--------------------------------------"); + }); +}); + diff --git a/eg/temperature-DHT22_I2C_NANO_BACKPACK.js b/eg/temperature-DHT22_I2C_NANO_BACKPACK.js new file mode 100644 index 000000000..3c69fd5bc --- /dev/null +++ b/eg/temperature-DHT22_I2C_NANO_BACKPACK.js @@ -0,0 +1,17 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var thermometer = new five.Thermometer({ + controller: "DHT22_I2C_NANO_BACKPACK" + }); + + thermometer.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); + console.log("--------------------------------------"); + }); +}); + diff --git a/eg/temperature-HIH6130.js b/eg/temperature-HIH6130.js new file mode 100644 index 000000000..54f4f09e2 --- /dev/null +++ b/eg/temperature-HIH6130.js @@ -0,0 +1,17 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var thermometer = new five.Thermometer({ + controller: "HIH6130" + }); + + thermometer.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); + console.log("--------------------------------------"); + }); +}); + diff --git a/eg/temperature-MCP9808.js b/eg/temperature-MCP9808.js index 5542b71ff..958cc50f2 100644 --- a/eg/temperature-MCP9808.js +++ b/eg/temperature-MCP9808.js @@ -2,12 +2,12 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temp = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MCP9808" }); - temp.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/eg/temperature-MS5611.js b/eg/temperature-MS5611.js index 637af3658..76cd510de 100644 --- a/eg/temperature-MS5611.js +++ b/eg/temperature-MS5611.js @@ -2,12 +2,12 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temp = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MS5611" }); - temp.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); diff --git a/eg/temperature-SI7021.js b/eg/temperature-SI7021.js new file mode 100644 index 000000000..e7babc3bd --- /dev/null +++ b/eg/temperature-SI7021.js @@ -0,0 +1,16 @@ +var five = require("../"); +var Tessel = require("tessel-io"); +var board = new five.Board({ + io: new Tessel() +}); + +board.on("ready", function() { + var temp = new five.Thermometer({ + controller: "SI7021", + port: "A" + }); + + temp.on("change", function() { + console.log(this.celsius + "°C", this.fahrenheit + "°F"); + }); +}); diff --git a/eg/temperature-TH02.js b/eg/temperature-TH02.js index becb749ef..411bc094e 100644 --- a/eg/temperature-TH02.js +++ b/eg/temperature-TH02.js @@ -2,15 +2,15 @@ var five = require("../"); var board = new five.Board(); board.on("ready", function() { - var temp = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "TH02" }); - temp.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + thermometer.on("change", function() { + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); console.log("--------------------------------------"); }); }); diff --git a/eg/temperature-bmp085.js b/eg/temperature-bmp085.js index ebbab4da5..590810efd 100644 --- a/eg/temperature-bmp085.js +++ b/eg/temperature-bmp085.js @@ -7,10 +7,10 @@ board.on("ready", function() { }); temp.on("change", function() { - console.log("temperature"); - console.log(" celsius : ", this.temperature.celsius); - console.log(" fahrenheit : ", this.temperature.fahrenheit); - console.log(" kelvin : ", this.temperature.kelvin); + console.log("Thermometer"); + console.log(" celsius : ", this.celsius); + console.log(" fahrenheit : ", this.fahrenheit); + console.log(" kelvin : ", this.kelvin); console.log("--------------------------------------"); }); }); diff --git a/eg/temperature-ds18b20.js b/eg/temperature-ds18b20.js index 837442d45..e15745668 100644 --- a/eg/temperature-ds18b20.js +++ b/eg/temperature-ds18b20.js @@ -1,18 +1,19 @@ var five = require("../lib/johnny-five"); +var board = new five.Board(); -five.Board().on("ready", function() { +board.on("ready", function() { // This requires OneWire support using the ConfigurableFirmata - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "DS18B20", pin: 2 }); - temperature.on("change", function() { + thermometer.on("change", function() { console.log(this.celsius + "°C"); // console.log("0x" + this.address.toString(16)); }); }); -// @markdown -// - [DS18B20 - Temperature Sensor](http://www.maximintegrated.com/en/products/analog/sensors-and-sensor-interface/DS18S20.html) -// @markdown +/* @markdown +- [DS18B20 - Temperature Sensor](http://www.maximintegrated.com/en/products/analog/sensors-and-sensor-interface/DS18S20.html) +@markdown */ diff --git a/eg/temperature-dual-ds18b20.js b/eg/temperature-dual-ds18b20.js index 903931962..b827ed00f 100644 --- a/eg/temperature-dual-ds18b20.js +++ b/eg/temperature-dual-ds18b20.js @@ -1,29 +1,30 @@ var five = require("../lib/johnny-five"); +var board = new five.Board(); -five.Board().on("ready", function() { +board.on("ready", function() { // This requires OneWire support using the ConfigurableFirmata - var temperatureA = new five.Thermometer({ + var thermometerA = new five.Thermometer({ controller: "DS18B20", pin: 2, address: 0x687f1fe }); - var temperatureB = new five.Thermometer({ + var thermometerB = new five.Thermometer({ controller: "DS18B20", pin: 2, address: 0x6893a41 }); - temperatureA.on("change", function() { + thermometerA.on("change", function() { console.log("A", this.celsius + "°C"); }); - temperatureB.on("change", function(err, data) { + thermometerB.on("change", function(err, data) { console.log("B", this.celsius + "°C"); }); }); -// @markdown +/* @markdown // - [DS18B20 - Temperature Sensor](http://www.maximintegrated.com/en/products/analog/sensors-and-sensor-interface/DS18S20.html) -// @markdown +@markdown */ diff --git a/eg/temperature-htu21d.js b/eg/temperature-htu21d.js index 5ab93cef0..06280a6f3 100644 --- a/eg/temperature-htu21d.js +++ b/eg/temperature-htu21d.js @@ -2,15 +2,15 @@ var five = require("../lib/johnny-five.js"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "HTU21D" }); - temperature.on("change", function() { + thermometer.on("change", function() { console.log(this.celsius + "°C", this.fahrenheit + "°F"); }); }); -// @markdown -// - [HTU21D - Humidity Sensor](https://www.adafruit.com/products/1899) -// @markdown +/* @markdown +- [HTU21D - Humidity Sensor](https://www.adafruit.com/products/1899) +@markdown */ diff --git a/eg/temperature-lm335.js b/eg/temperature-lm335.js index d73f8886f..ad81bde55 100644 --- a/eg/temperature-lm335.js +++ b/eg/temperature-lm335.js @@ -1,16 +1,17 @@ var five = require("../lib/johnny-five"); +var board = new five.Board(); -five.Board().on("ready", function() { - var temperature = new five.Thermometer({ +board.on("ready", function() { + var thermometer = new five.Thermometer({ controller: "LM335", pin: "A0" }); - temperature.on("change", function() { + thermometer.on("change", function() { console.log(this.celsius + "°C", this.fahrenheit + "°F"); }); }); -// @markdown -// - [LM335 - Temperature Sensor](http://www.ti.com/product/lm335) -// @markdown +/* @markdown +- [LM335 - Temperature Sensor](http://www.ti.com/product/lm335) +@markdown */ diff --git a/eg/temperature-lm35.js b/eg/temperature-lm35.js index 6344b22dc..9b85c48f7 100644 --- a/eg/temperature-lm35.js +++ b/eg/temperature-lm35.js @@ -11,6 +11,6 @@ five.Board().on("ready", function() { }); }); -// @markdown -// - [LM35 - Temperature Sensor](http://www.ti.com/product/lm35) -// @markdown +/* @markdown +- [LM35 - Temperature Sensor](http://www.ti.com/product/lm35) +@markdown */ diff --git a/eg/temperature-max31850k.js b/eg/temperature-max31850k.js index 60ffd1120..c45a09961 100644 --- a/eg/temperature-max31850k.js +++ b/eg/temperature-max31850k.js @@ -17,6 +17,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [MAX31850K - Thermocouple Amplifier](https://www.adafruit.com/products/1727) -// @markdown +/* @markdown +- [MAX31850K - Thermocouple Amplifier](https://www.adafruit.com/products/1727) +@markdown */ diff --git a/eg/temperature-mpl115a2.js b/eg/temperature-mpl115a2.js index 4f59a780d..5edd2a3f0 100644 --- a/eg/temperature-mpl115a2.js +++ b/eg/temperature-mpl115a2.js @@ -2,12 +2,12 @@ var five = require("../lib/johnny-five.js"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MPL115A2" }); - temperature.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); @@ -15,6 +15,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [MPL115A2 - I2C Barometric Pressure/Temperature Sensor](https://www.adafruit.com/product/992) -// @markdown +/* @markdown +- [MPL115A2 - I2C Barometric Pressure/Temperature Sensor](https://www.adafruit.com/product/992) +@markdown */ diff --git a/eg/temperature-mpl3115a2.js b/eg/temperature-mpl3115a2.js index 687269b66..a34d96db8 100644 --- a/eg/temperature-mpl3115a2.js +++ b/eg/temperature-mpl3115a2.js @@ -2,12 +2,12 @@ var five = require("../lib/johnny-five.js"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MPL3115A2" }); - temperature.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); @@ -15,9 +15,9 @@ board.on("ready", function() { }); }); -// @markdown -// - [MPL3115A2 - I2C Barometric Pressure/Altimiter/Temperature Sensor](https://www.adafruit.com/products/1893) -// - [SparkFun Altitude/Pressure Sensor Breakout - MPL3115A2](https://www.sparkfun.com/products/11084) -// - [SparkFun Weather Shield](https://www.sparkfun.com/products/12081) -// - [SparkFun Photon Weather Shield](https://www.sparkfun.com/products/13630) -// @markdown +/* @markdown +- [MPL3115A2 - I2C Barometric Pressure/Altimiter/Temperature Sensor](https://www.adafruit.com/products/1893) +- [SparkFun Altitude/Pressure Sensor Breakout - MPL3115A2](https://www.sparkfun.com/products/11084) +- [SparkFun Weather Shield](https://www.sparkfun.com/products/12081) +- [SparkFun Photon Weather Shield](https://www.sparkfun.com/products/13630) +@markdown */ diff --git a/eg/temperature-mpu6050.js b/eg/temperature-mpu6050.js index df7a0f267..2757b4e37 100644 --- a/eg/temperature-mpu6050.js +++ b/eg/temperature-mpu6050.js @@ -2,12 +2,12 @@ var five = require("../lib/johnny-five.js"); var board = new five.Board(); board.on("ready", function() { - var temperature = new five.Thermometer({ + var thermometer = new five.Thermometer({ controller: "MPU6050" }); - temperature.on("change", function() { - console.log("temperature"); + thermometer.on("change", function() { + console.log("Thermometer"); console.log(" celsius : ", this.celsius); console.log(" fahrenheit : ", this.fahrenheit); console.log(" kelvin : ", this.kelvin); @@ -15,6 +15,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [MPU-6050 - IMU with Temperature Sensor](http://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/) -// @markdown +/* @markdown +- [MPU6050 - IMU with Temperature Sensor](http://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/) +@markdown */ diff --git a/eg/temperature-sht31d.js b/eg/temperature-sht31d.js index 0c33b43f9..43fd9b1d3 100644 --- a/eg/temperature-sht31d.js +++ b/eg/temperature-sht31d.js @@ -11,6 +11,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [SHT31D - Humidity Sensor](https://www.adafruit.com/products/2857) -// @markdown +/* @markdown +- [SHT31D - Humidity Sensor](https://www.adafruit.com/products/2857) +@markdown */ diff --git a/eg/temperature-tmp102.js b/eg/temperature-tmp102.js index 9cee14584..001d70dde 100644 --- a/eg/temperature-tmp102.js +++ b/eg/temperature-tmp102.js @@ -11,6 +11,6 @@ board.on("ready", function() { }); }); -// @markdown -// - [TMP102 - Temperature Sensor](https://www.sparkfun.com/products/11931) -// @markdown +/* @markdown +- [TMP102 - Temperature Sensor](https://www.sparkfun.com/products/11931) +@markdown */ diff --git a/eg/temperature-tmp36.js b/eg/temperature-tmp36.js index a19a9872d..3ea58a001 100644 --- a/eg/temperature-tmp36.js +++ b/eg/temperature-tmp36.js @@ -11,6 +11,6 @@ five.Board().on("ready", function() { }); }); -// @markdown -// - [TMP36 - Temperature Sensor](https://www.sparkfun.com/products/10988) -// @markdown +/* @markdown +- [TMP36 - Temperature Sensor](https://www.sparkfun.com/products/10988) +@markdown */ diff --git a/firmwares/dht_i2c_nano_backpack.ino b/firmwares/dht_i2c_nano_backpack.ino new file mode 100644 index 000000000..8ded20f62 --- /dev/null +++ b/firmwares/dht_i2c_nano_backpack.ino @@ -0,0 +1,110 @@ +#include +#include "DHT.h" + +#define DEBUG_MODE 0 + +// Address Pins +#define AD0 11 +#define AD1 12 + +// I2C Defaults +#define I2C_DEFAULT_ADDRESS 0x0A +#define I2C_BUFFER_SIZE 4 +// +// 0 H LSB +// 1 H MSB +// 2 T LSB +// 3 T MSB +// +byte buffer[I2C_BUFFER_SIZE]; + +int addressPins[] = { AD0, AD1 }; +int address = I2C_DEFAULT_ADDRESS; + +int dhtPin = -1; +int dhtType = -1; + +void resetState() { + digitalWrite(dhtPin, LOW); + pinMode(dhtPin, INPUT); +} + +void setup() { + + int offset = 0; + + for (int i = 0; i < 2; i++) { + pinMode(addressPins[i], INPUT); + if (digitalRead(addressPins[i])) { + offset |= 1 << i; + } + } + + address += offset; + + #if DEBUG_MODE + Serial.begin(9600); + #endif + + resetState(); + + Wire.begin(address); + Wire.onRequest(onRequest); + Wire.onReceive(onReceive); +} + +void loop() { + if (dhtPin != -1 && dhtType != -1) { + DHT dht(dhtPin, dhtType); + dht.begin(); + + int h = (int)((float)dht.readHumidity() * 100); + int c = (int)((float)dht.readTemperature() * 100); + + buffer[0] = h >> 8; + buffer[1] = h & 0xFF; + buffer[2] = c >> 8; + buffer[3] = c & 0xFF; + + #if DEBUG_MODE + Serial.print("h: "); + Serial.println(h); + Serial.print("c: "); + Serial.println(c); + #endif + + delay(250); + + #if DEBUG_MODE + Serial.print("free ram: "); + Serial.println(freeRam()); + #endif + + } +} + +#if DEBUG_MODE +int freeRam() { + extern int __heap_start, *__brkval; + int v; + return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); +} +#endif + +void onRequest() { + Wire.write(buffer, I2C_BUFFER_SIZE); +} + +void onReceive(int howMany) { + // Order: [ pin, type ] + // Default: [ 2, 11 ] + dhtPin = (byte)Wire.read(); + dhtType = (byte)Wire.read(); + + #if DEBUG_MODE + Serial.print("dhtPin: "); + Serial.println(dhtPin); + Serial.print("dhtType: "); + Serial.println(dhtType); + #endif +} diff --git a/lib/accelerometer.js b/lib/accelerometer.js index 1d90263c1..389e00c0d 100644 --- a/lib/accelerometer.js +++ b/lib/accelerometer.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Expander = require("./expander"); var Emitter = require("events").EventEmitter; @@ -200,29 +199,18 @@ var Controllers = { /* Page 4 - Sensitivity at XOUT YOUT ZOUT + Sensitivity at Min Typ Max ±2 g, 10-bit resolution 230 256 282 ±4 g, 10-bit resolution 115 128 141 ±8 g, 10-bit resolution 57 64 71 ±16 g, 10-bit resolution 29 32 35 */ - state.sensitivity = [{ - x: 230, - y: 256, - z: 282 - }, { - x: 115, - y: 128, - z: 141 - }, { - x: 57, - y: 64, - z: 71 - }, { - x: 29, - y: 32, - z: 35 - }][range]; + state.sensitivity = [ + 256, + 128, + 64, + 32, + ][range]; // Merge the format and range bits to set the DATA_FORMAT @@ -238,9 +226,9 @@ var Controllers = { }, }, toGravity: { - value: function(raw, axis) { + value: function(raw) { var state = priv.get(this); - return raw / state.sensitivity[axis]; + return raw / state.sensitivity; } } }, @@ -862,7 +850,6 @@ var Controllers = { }; // Otherwise known as... -Controllers["MPU-6050"] = Controllers.MPU6050; Controllers.TINKERKIT = Controllers.ANALOG; Controllers.MMA8452Q = Controllers.MMA8452; @@ -1037,7 +1024,7 @@ function Accelerometer(opts) { Object.defineProperties(this, { hasAxis: { - writable: IS_TEST_MODE ? true : /* istanbul ignore next */ false, + writable: true, value: function(axis) { /* istanbul ignore next */ return state[axis] ? state[axis].stash.length > 0 : false; @@ -1166,7 +1153,8 @@ function Accelerometer(opts) { util.inherits(Accelerometer, Emitter); /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + Accelerometer.Controllers = Controllers; Accelerometer.purge = function() { priv.clear(); }; diff --git a/lib/altimeter.js b/lib/altimeter.js index 87589bdad..4d0b7467a 100644 --- a/lib/altimeter.js +++ b/lib/altimeter.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Fn = require("./fn"); var Emitter = require("events").EventEmitter; @@ -110,16 +109,16 @@ Controllers["BMP085"] = Controllers["BMP-085"] = Controllers.BMP180; var priv = new Map(); function Altimeter(opts) { - var controller; + if (!(this instanceof Altimeter)) { + return new Altimeter(opts); + } + + var controller = null; var freq; var last = null; var raw = null; var state = {}; - if (!(this instanceof Altimeter)) { - return new Altimeter(opts); - } - Board.Component.call( this, opts = Board.Options(opts) ); @@ -137,6 +136,8 @@ function Altimeter(opts) { throw new Error("Altimeter expects a valid controller"); } + priv.set(this, state); + Board.Controller.call(this, controller, opts); if (!this.toMeters) { @@ -163,7 +164,6 @@ function Altimeter(opts) { Object.defineProperties(this, descriptors); - priv.set(this, state); /* istanbul ignore else */ if (typeof this.initialize === "function") { @@ -194,7 +194,8 @@ function Altimeter(opts) { util.inherits(Altimeter, Emitter); /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + Altimeter.Controllers = Controllers; Altimeter.purge = function() { priv.clear(); }; diff --git a/lib/animation.js b/lib/animation.js index 0bdacd28e..fd038dff9 100644 --- a/lib/animation.js +++ b/lib/animation.js @@ -550,7 +550,6 @@ Animation.prototype.normalizeKeyframes = function() { source[i] = keyFrame; }, this); - }); this.normalizedKeyFrames = keyFrameSet; diff --git a/lib/barometer.js b/lib/barometer.js index f926dac29..6a5d9f8ba 100644 --- a/lib/barometer.js +++ b/lib/barometer.js @@ -117,7 +117,7 @@ var Controllers = { }, }; -Controllers["BMP085"] = Controllers["BMP-085"] = Controllers.BMP180; +Controllers.BMP085 = Controllers.BMP180; /** * Barometer @@ -201,7 +201,12 @@ function Barometer(opts) { }.bind(this), freq); } - util.inherits(Barometer, Emitter); +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Barometer.Controllers = Controllers; + Barometer.purge = function() {}; +} + module.exports = Barometer; diff --git a/lib/board.js b/lib/board.js index 511d6de30..18851b119 100644 --- a/lib/board.js +++ b/lib/board.js @@ -16,9 +16,9 @@ var util = require("util"); var chalk = require("chalk"); var Collection = require("./mixins/collection"); var Fn = require("./fn"); -var Repl = require("./repl.js"); -var Options = require("./board.options.js"); -var Pins = require("./board.pins.js"); +var Repl = require("./repl"); +var Options = require("./board.options"); +var Pins = require("./board.pins"); var Expander; //var temporal = require("temporal"); @@ -26,6 +26,11 @@ var Expander; var boards = []; var rport = /usb|acm|^com/i; +// const things to const when 0.10.x is dropped +// This string appears over 20 times in this file. +var UNDEFINED = "undefined"; + + var Serial = { used: [], attempts: [], @@ -92,7 +97,7 @@ var Serial = { return; } - this.info("Device(s)", chalk.grey(ports)); + this.info("Available", chalk.grey(ports)); // Get the first available device path // from the list of detected ports @@ -227,17 +232,17 @@ function Board(opts) { } // If no debug flag, default to true - if (typeof this.debug === "undefined") { + if (typeof this.debug === UNDEFINED) { this.debug = true; } // If no repl flag, default to true - if (typeof this.repl === "undefined") { + if (typeof this.repl === UNDEFINED) { this.repl = true; } // If no sigint flag, default to true - if (typeof this.sigint === "undefined") { + if (typeof this.sigint === UNDEFINED) { this.sigint = true; } @@ -295,7 +300,7 @@ function Board(opts) { // Either an IO instance was provided or isOnBoard is true if (!opts.port && this.io !== null) { /* istanbul ignore next */ - this.info("Device(s)", chalk.grey(this.io.name || "unknown")); + this.info("Available", chalk.grey(this.io.name || "unknown")); ["connect", "ready"].forEach(function(type) { this.io.once(type, function() { @@ -407,12 +412,12 @@ function finalizeAndBroadcast(data, type, io) { this.pins = Board.Pins(this); this.MODES = this.io.MODES; - if (typeof io.debug !== "undefined" && + if (typeof io.debug !== UNDEFINED && io.debug === false) { this.debug = false; } - if (typeof io.repl !== "undefined" && + if (typeof io.repl !== UNDEFINED && io.repl === false) { this.repl = false; } @@ -433,7 +438,12 @@ function finalizeAndBroadcast(data, type, io) { process.on("SIGINT", function() { this.emit("exit"); this.warn("Board", "Closing."); - process.nextTick(process.reallyExit); + var interval = setInterval(function() { + if (!this.io.pending) { + clearInterval(interval); + process.nextTick(process.reallyExit); + } + }.bind(this), 1); }.bind(this)); } } @@ -489,7 +499,7 @@ Board.prototype.snapshot = function(reducer) { return this.register.reduce(function(accum, component) { // Don't include collections or multi/imu wrappers - if (typeof component.components === "undefined") { + if (typeof component.components === UNDEFINED) { accum.push( Object.getOwnPropertyNames(component).reduce(function(data, prop) { var value = component[prop]; @@ -784,11 +794,11 @@ Board.mount = function(arg) { */ Board.Component = function(opts, componentOpts) { - if (typeof opts === "undefined") { + if (typeof opts === UNDEFINED) { opts = {}; } - if (typeof componentOpts === "undefined") { + if (typeof componentOpts === UNDEFINED) { componentOpts = {}; } @@ -820,15 +830,23 @@ Board.Component = function(opts, componentOpts) { } } - if (!Expander) { - Expander = require("./expander"); - } - if (opts.controller && Expander.hasController(opts.controller)) { - componentOpts = { - normalizePin: false, - requestPin: false, - }; + if (opts.controller) { + + if (typeof opts.controller === "string") { + opts.controller = opts.controller.replace(/-/g, ""); + } + + if (!Expander) { + Expander = require("./expander"); + } + + if (Expander.hasController(opts.controller)) { + componentOpts = { + normalizePin: false, + requestPin: false, + }; + } } componentOpts = Board.Component.initialization(componentOpts); @@ -837,127 +855,127 @@ Board.Component = function(opts, componentOpts) { opts = Board.Pins.normalize(opts, this.board); } - var requesting = []; + // var requesting = []; - if (typeof opts.pins !== "undefined") { + if (typeof opts.pins !== UNDEFINED) { this.pins = opts.pins || []; - if (Array.isArray(this.pins)) { - requesting = requesting.concat( - this.pins.map(function(pin) { - return { - value: pin, - type: "pin" - }; - }) - ); - } else { - requesting = requesting.concat( - Object.keys(this.pins).map(function(key) { - return { - value: this.pins[key], - type: "pin" - }; - }, this) - ); - } + // if (Array.isArray(this.pins)) { + // requesting = requesting.concat( + // this.pins.map(function(pin) { + // return { + // value: pin, + // type: "pin" + // }; + // }) + // ); + // } else { + // requesting = requesting.concat( + // Object.keys(this.pins).map(function(key) { + // return { + // value: this.pins[key], + // type: "pin" + // }; + // }, this) + // ); + // } } - if (typeof opts.pin !== "undefined") { + if (typeof opts.pin !== UNDEFINED) { this.pin = opts.pin; - requesting.push({ - value: this.pin, - type: "pin" - }); + // requesting.push({ + // value: this.pin, + // type: "pin" + // }); } // TODO: Figure out what is using this /* istanbul ignore if */ - if (typeof opts.emitter !== "undefined") { + if (typeof opts.emitter !== UNDEFINED) { /* istanbul ignore next */ this.emitter = opts.emitter; - requesting.push({ - value: this.emitter, - type: "emitter" - }); + // requesting.push({ + // value: this.emitter, + // type: "emitter" + // }); } - if (typeof opts.address !== "undefined") { + if (typeof opts.address !== UNDEFINED) { this.address = opts.address; - requesting.forEach(function(request) { - request.address = this.address; - }, this); + // requesting.forEach(function(request) { + // request.address = this.address; + // }, this); } - if (typeof opts.controller !== "undefined") { + if (typeof opts.controller !== UNDEFINED) { this.controller = opts.controller; - requesting.forEach(function(request) { - request.controller = this.controller; - }, this); + // requesting.forEach(function(request) { + // request.controller = this.controller; + // }, this); } // TODO: Figure out what is using this /* istanbul ignore if */ - if (typeof opts.bus !== "undefined") { + if (typeof opts.bus !== UNDEFINED) { /* istanbul ignore next */ this.bus = opts.bus; - requesting.forEach(function(request) { - request.bus = this.bus; - }, this); + // requesting.forEach(function(request) { + // request.bus = this.bus; + // }, this); } - if (componentOpts.requestPin) { - // With the pins being requested for use by this component, - // compare with the list of pins that are already known to be - // in use by other components. If any are known to be in use, - // produce a warning for the user. - requesting.forEach(function(request, index) { - var hasController = typeof request.controller !== "undefined"; - var hasAddress = typeof request.address !== "undefined"; - var isOccupied = false; - var message = ""; - - request.value = originalPins[index]; - - if (this.board.occupied.length) { - isOccupied = this.board.occupied.some(function(occupied) { - var isPinOccupied = request.value === occupied.value && request.type === occupied.type; - - if (typeof occupied.controller !== "undefined") { - if (hasController) { - return isPinOccupied && (request.controller === occupied.controller); - } - return false; - } - - if (typeof occupied.address !== "undefined") { - if (hasAddress) { - return isPinOccupied && (request.address === occupied.address); - } - return false; - } - - return isPinOccupied; - }); - } - - if (isOccupied) { - message = request.type + ": " + request.value; - - if (hasController) { - message += ", controller: " + request.controller; - } - - if (hasAddress) { - message += ", address: " + request.address; - } - - this.board.warn("Component", message + " is already in use"); - } else { - this.board.occupied.push(request); - } - }, this); - } + // if (componentOpts.requestPin) { + // // With the pins being requested for use by this component, + // // compare with the list of pins that are already known to be + // // in use by other components. If any are known to be in use, + // // produce a warning for the user. + // requesting.forEach(function(request, index) { + // var hasController = typeof request.controller !== UNDEFINED; + // var hasAddress = typeof request.address !== UNDEFINED; + // var isOccupied = false; + // var message = ""; + + // request.value = originalPins[index]; + + // if (this.board.occupied.length) { + // isOccupied = this.board.occupied.some(function(occupied) { + // var isPinOccupied = request.value === occupied.value && request.type === occupied.type; + + // if (typeof occupied.controller !== UNDEFINED) { + // if (hasController) { + // return isPinOccupied && (request.controller === occupied.controller); + // } + // return false; + // } + + // if (typeof occupied.address !== UNDEFINED) { + // if (hasAddress) { + // return isPinOccupied && (request.address === occupied.address); + // } + // return false; + // } + + // return isPinOccupied; + // }); + // } + + // if (isOccupied) { + // message = request.type + ": " + request.value; + + // if (hasController) { + // message += ", controller: " + request.controller; + // } + + // if (hasAddress) { + // message += ", address: " + request.address; + // } + + // this.board.warn("Component", message + " is already in use"); + // } else { + // this.board.occupied.push(request); + // } + // }, this); + // } this.board.register.push(this); }; @@ -1004,7 +1022,7 @@ Board.Controller = function(controller, options) { } }, */ - if (typeof options[key] === "undefined" || + if (typeof options[key] === UNDEFINED || typeof options[key] !== requirements.options[key].typeof) { if (requirements.options[key].throws) { throw new Error(requirements.options[key].message); @@ -1046,7 +1064,7 @@ Object.defineProperty(Board, "cache", { */ Board.Event = function(event) { - if (typeof event === "undefined") { + if (typeof event === UNDEFINED) { throw new Error("Board.Event missing Event object"); } @@ -1101,11 +1119,11 @@ function Boards(opts) { throw new Error("Expected ports to be an array"); } - if (typeof opts.debug === "undefined") { + if (typeof opts.debug === UNDEFINED) { opts.debug = true; } - if (typeof opts.repl === "undefined") { + if (typeof opts.repl === UNDEFINED) { opts.repl = true; } diff --git a/lib/button.js b/lib/button.js index 4fd890cda..86ab82a9b 100644 --- a/lib/button.js +++ b/lib/button.js @@ -1,10 +1,9 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Collection = require("./mixins/collection"); var EVS = require("./evshield"); var Pins = Board.Pins; var Fn = require("./fn"); -var events = require("events"); +var Emitter = require("events").EventEmitter; var util = require("util"); // Button instance private data @@ -35,6 +34,11 @@ var Controllers = { this.io.digitalWrite(this.pin, this.io.HIGH); } + // Enable the pulldown resistor after setting pin mode + if (this.pulldown) { + this.io.digitalWrite(this.pin, this.io.LOW); + } + this.io.digitalRead(this.pin, function(data) { if (data !== state.last) { dataHandler(data); @@ -217,6 +221,8 @@ function Button(opts) { // phase out "isFoo" options properties this.pullup = opts.pullup || opts.isPullup || false; + this.pulldown = opts.pulldown || opts.isPulldown || false; + // Turns out some button circuits will send // 0 for up and 1 for down, and some the inverse, // so we can invert our function with this option. @@ -316,7 +322,7 @@ function Button(opts) { } } -util.inherits(Button, events.EventEmitter); +util.inherits(Button, Emitter); /** @@ -361,11 +367,7 @@ function Buttons(numsOrObjects) { Collection.Emitter.call(this, numsOrObjects); } -Buttons.prototype = Object.create(Collection.Emitter.prototype, { - constructor: { - value: Buttons - } -}); +util.inherits(Buttons, Collection.Emitter); Collection.installMethodForwarding( Buttons.prototype, Button.prototype @@ -375,7 +377,8 @@ Collection.installMethodForwarding( Button.Collection = Buttons; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + Button.Controllers = Controllers; Button.purge = function() { priv.clear(); }; diff --git a/lib/color.js b/lib/color.js index 69ace8205..f2b198964 100644 --- a/lib/color.js +++ b/lib/color.js @@ -2,33 +2,15 @@ var Board = require("./board"); var EVS = require("./evshield"); var Emitter = require("events").EventEmitter; var util = require("util"); -var __ = require("./fn"); +var Fn = require("./fn"); 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)); -} - function pad(value, length) { return Array(length - String(value).length + 1).join("0") + value; } var Controllers = { - // This is a placeholder... - DEFAULT: { - initialize: { - value: analogHandler - }, - toRGB: { - value: function(raw) { - return raw; - } - } - }, EVS_EV3: { initialize: { value: function(opts, dataHandler) { @@ -214,7 +196,7 @@ var Controllers = { var b = (data[5] << 8) | data[4]; var rgb = [r >> 2, g >> 2, b >> 2].map(function(value) { - return __.constrain(value, 0, 255); + return Fn.constrain(value, 0, 255); }); for (var i = 0; i < 3; i++) { @@ -265,9 +247,15 @@ function Color(opts) { if (typeof opts.controller === "string") { controller = Controllers[opts.controller]; } else { - controller = opts.controller || Controllers.DEFAULT; + controller = opts.controller; + } + + if (controller == null) { + throw new Error("Color expects a valid controller"); } + priv.set(this, state); + Board.Controller.call(this, controller, opts); if (!this.toRGB) { @@ -276,8 +264,6 @@ function Color(opts) { }; } - priv.set(this, state); - Object.defineProperties(this, { value: { get: function() { @@ -330,6 +316,12 @@ Color.hexCode = function(rgb) { }; - +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Color.Controllers = Controllers; + Color.purge = function() { + priv.clear(); + }; +} module.exports = Color; diff --git a/lib/compass.js b/lib/compass.js index c034ed372..9304d5aaf 100644 --- a/lib/compass.js +++ b/lib/compass.js @@ -492,8 +492,8 @@ function Compass(opts) { controller = opts.controller; } - if (controller === null || typeof controller !== "object") { - throw new Error("Missing valid Compass controller"); + if (controller == null) { + throw new Error("Compass expects a valid controller"); } Board.Controller.call(this, controller, opts); @@ -560,7 +560,7 @@ function Compass(opts) { bearing: { get: function() { var length = Compass.Points.length; - var heading = Math.floor(state.heading); + var heading = Math.floor(this.heading); var point; for (var i = 0; i < length; i++) { @@ -891,6 +891,14 @@ Compass.Points.forEach(function(point, k) { */ +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Compass.Controllers = Controllers; + Compass.purge = function() { + priv.clear(); + }; +} + module.exports = Compass; diff --git a/lib/distance.js b/lib/distance.js deleted file mode 100644 index 9b2da63ea..000000000 --- a/lib/distance.js +++ /dev/null @@ -1,179 +0,0 @@ -var Sensor = require("./sensor"); -var util = require("util"); -var Fn = require("./fn"); - -var toFixed = Fn.toFixed; - - -// References -// - http://www.acroname.com/articles/linearizing-sharp-ranger.html -// - http://luckylarry.co.uk/arduino-projects/arduino-using-a-sharp-ir-sensor-for-distance-calculation/ -// - http://forum.arduino.cc/index.php?topic=63433.0 -// - https://github.com/pjwerneck/Diaspar/blob/master/robots/sensors/sharp_table.py -// -// -var Controllers = { - GP2Y0A21YK: { - // https://www.sparkfun.com/products/242 - initialize: { - value: function(opts) { - Sensor.call(this, opts); - } - }, - toCm: { - value: function(raw) { - return toFixed(12343.85 * Math.pow(raw, -1.15), 2); - } - } - }, - GP2D120XJ00F: { - // https://www.sparkfun.com/products/8959 - initialize: { - value: function(opts) { - Sensor.call(this, opts); - } - }, - toCm: { - value: function(raw) { - return toFixed((2914 / (raw + 5)) - 1, 2); - } - } - }, - GP2Y0A02YK0F: { - // https://www.sparkfun.com/products/8958 - // 15cm - 150cm - initialize: { - value: function(opts) { - Sensor.call(this, opts); - } - }, - toCm: { - value: function(raw) { - return toFixed(10650.08 * Math.pow(raw, -0.935) - 10, 2); - } - } - }, - GP2Y0A41SK0F: { - // https://www.sparkfun.com/products/12728 - // 4cm - 30cm - initialize: { - value: function(opts) { - Sensor.call(this, opts); - } - }, - toCm: { - value: function(raw) { - return toFixed(2076 / (raw - 11), 2); - } - } - } -}; - -// Otherwise known as... -Controllers["2Y0A21"] = Controllers.GP2Y0A21YK; -Controllers["2D120X"] = Controllers.GP2D120XJ00F; -Controllers["2Y0A02"] = Controllers.GP2Y0A02YK0F; -Controllers["OA41SK"] = Controllers.GP2Y0A41SK0F; - -// As shown here: http://www.acroname.com/articles/sharp.html -Controllers["0A21"] = Controllers.GP2Y0A21YK; -Controllers["0A02"] = Controllers.GP2Y0A02YK0F; - -/** - * IR.Distance - * - * @deprecated - * @constructor - * - * five.IR.Distance("A0"); - * - * five.IR.Distance({ - * device: "GP2Y0A41SK0F", - * pin: "A0", - * freq: 100 - * }); - * - * - * @param {Object} opts [description] - * - */ - -function Distance(opts) { - - if (!(this instanceof Distance)) { - return new Distance(opts); - } - - var controller = null; - - if (typeof opts.controller === "string") { - controller = Controllers[opts.controller]; - } else { - controller = opts.controller; - } - - if (controller == null) { - 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(this.value); - } - }, - cm: { - get: function() { - return this.centimeters; - } - }, - /** - * [read-only] Calculated inch value - * @property inches - * @type Number - */ - inches: { - get: function() { - return toFixed(this.centimeters * 0.39, 2); - } - }, - in : { - get: function() { - return this.inches; - } - }, - }); - - if (typeof this.initialize === "function") { - this.initialize(opts); - } -} - -Distance.Controllers = [ - "2Y0A21", "GP2Y0A21YK", - "2D120X", "GP2D120XJ00F", - "2Y0A02", "GP2Y0A02YK0F", - "OA41SK", "GP2Y0A41SK0F", - "0A21", "GP2Y0A21YK", - "0A02", "GP2Y0A02YK0F", -]; - -util.inherits(Distance, Sensor); - -module.exports = Distance; - - -// http://www.acroname.com/robotics/info/articles/sharp/sharp.html diff --git a/lib/esc.js b/lib/esc.js index cc7d2671b..79877fb13 100644 --- a/lib/esc.js +++ b/lib/esc.js @@ -1,11 +1,10 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Expander = require("./expander"); var Pins = Board.Pins; -var Emitter = require("events").EventEmitter; -var util = require("util"); var Collection = require("./mixins/collection"); var Fn = require("./fn"); +var Emitter = require("events").EventEmitter; +var util = require("util"); var priv = new Map(); @@ -136,9 +135,9 @@ function ESC(opts) { return new ESC(opts); } + var controller = null; var pinValue; var device; - var controller; var state = { // All speed history for this ESC // history = [ @@ -426,11 +425,7 @@ function ESCs(numsOrObjects) { Collection.call(this, numsOrObjects); } -ESCs.prototype = Object.create(Collection.prototype, { - constructor: { - value: ESCs - } -}); +util.inherits(ESCs, Collection); /** * @@ -470,7 +465,8 @@ ESC.Array = ESCs; ESC.Collection = ESCs; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + ESC.Controllers = Controllers; ESC.purge = function() { priv.clear(); }; diff --git a/lib/evshield.js b/lib/evshield.js index 5cb77504d..03053b7ff 100644 --- a/lib/evshield.js +++ b/lib/evshield.js @@ -1,4 +1,5 @@ var Emitter = require("events").EventEmitter; +var util = require("util"); var shared; function Bank(options) { @@ -94,11 +95,7 @@ EVS.isRawSensor = function(port) { return port.analog === EVS.S1_ANALOG || port.analog === EVS.S2_ANALOG; }; -EVS.prototype = Object.create(Emitter.prototype, { - constructor: { - value: EVS - } -}); +util.inherits(EVS, Emitter); EVS.prototype.setup = function(port, type) { this.bank[port.bank].write(port.mode, [type]); diff --git a/lib/expander.js b/lib/expander.js index ca77e1b6b..89c80c2a4 100644 --- a/lib/expander.js +++ b/lib/expander.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Emitter = require("events").EventEmitter; var util = require("util"); @@ -1813,6 +1812,10 @@ Object.keys(Controllers).forEach(function(name) { }); }); +var nonAddressable = [ + "74HC595" +]; + function Expander(opts) { if (!(this instanceof Expander)) { return new Expander(opts); @@ -1837,6 +1840,11 @@ function Expander(opts) { } ); + if (nonAddressable.includes(opts.controller) && + typeof this.address === "undefined") { + this.address = Fn.uid(); + } + expander = active.get(this.address); if (expander) { @@ -1912,7 +1920,7 @@ Expander.byAddress = function(address) { }; Expander.byController = function(name) { - var controller; + var controller = null; active.forEach(function(value) { if (value.name === name.toUpperCase()) { @@ -1927,7 +1935,8 @@ Expander.hasController = function(key) { }; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + Expander.Controllers = Controllers; Expander.purge = function() { priv.clear(); active.clear(); diff --git a/lib/fn.js b/lib/fn.js index ad6b51404..d50dd73ca 100644 --- a/lib/fn.js +++ b/lib/fn.js @@ -3,77 +3,106 @@ var Fn = { cloneDeep: require("lodash.clonedeep"), }; -// Fn.fmap( val, fromLow, fromHigh, toLow, toHigh ) -// -// Re-maps a number from one range to another. -// Based on arduino map() -// -// Return float -// +/** + * Format a number such that it has a given number of digits after the + * decimal point. + * + * @param {Number} number - The number to format + * @param {Number} [digits = 0] - The number of digits after the decimal point + * @return {Number} Formatted number + * @example + * Fn.toFixed(5.4564, 2); // -> 5.46 + * @example + * Fn.toFixed(1.5, 2); // -> 1.5 + */ Fn.toFixed = function(number, digits) { // Guard against error when number is null or undefined + // Cast result as number return +(number || 0).toFixed(digits); }; -// Fn.fmap( val, fromLow, fromHigh, toLow, toHigh ) -// -// Re-maps a number from one range to another. -// Based on arduino map() -// -// Return Float32 -// + +/** + * Map a value (number) from one range to another. Based on Arduino's map(). + * + * @param {Number} value - value to map + * @param {Number} fromLow - low end of originating range + * @param {Number} fromHigh - high end of originating range + * @param {Number} toLow - low end of target range + * @param {Number} toHigh - high end of target range + * @return {Number} mapped value (integer) + * @example + * Fn.map(500, 0, 1000, 0, 255); // -> + */ + +Fn.map = function(value, fromLow, fromHigh, toLow, toHigh) { + return ((value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow) | 0; +}; +// Alias +Fn.scale = Fn.map; + +/** + * Like map, but returns a Float32 + * + * For @param info, @see Fn.map + * @return {Float32} + */ var f32A = new Float32Array(1); Fn.fmap = function(value, fromLow, fromHigh, toLow, toHigh) { f32A[0] = (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow; return f32A[0]; }; - - - // Alias Fn.fscale = Fn.fmap; -// Fn.map( val, fromLow, fromHigh, toLow, toHigh ) -// -// Re-maps a number from one range to another. -// Based on arduino map() -// -// Retun int -// -Fn.map = function(value, fromLow, fromHigh, toLow, toHigh) { - return ((value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow) | 0; -}; - -// Alias -Fn.scale = Fn.map; - -// Fn.constrain( val, lower, upper ) -// -// Constrains a number to be within a range. -// Based on arduino constrain() -// +/** + * Constrains a number to be within a range. Based on Arduino's constrain() + * + * @param {Number} value + * @param {Number} lower - lower bound of range for constraint + * @param {Number} upper - upper bound of range for constraint + * @return {Number | NaN} constrained number or NaN if any of the provided + * parameters are not a {Number}. + */ Fn.constrain = function(value, lower, upper) { return Math.min(upper, Math.max(lower, value)); }; - -// Fn.inRange( val, lower, upper ) -// -// Constrains a number to be within a range. -// Based on arduino constrain() -// +/** + * Is value between the bounds of lower and upper? + * + * @param {Number} value + * @param {Number} lower - Lower end of bounds to check + * @param {Number} upper - Upper ends of bounds to check + * @return {Boolean} + */ Fn.inRange = function(value, lower, upper) { return value >= lower && value <= upper; }; - -// Fn.range( upper ) -// Fn.range( lower, upper ) -// Fn.range( lower, upper, tick ) -// -// Returns a new array range -// +/** + * Generate an Array of Numbers with values between lower and upper; the + * step (increment/decrement) between each defined by tick. + * + * @param {Number} lower - The value of the lowest element in the resulting + * Array. If `Fn.range` invoked with only one + * argument, this parameter will instead define the + * length of the Array, which will start from 0. + * @param {Number} upper - The value of the final element of the Array. + * @param {Number} [tick = 1] - The difference between each element in the + * Array. This value may be negative. + * @return {Array} of {Numbers} + * + * @example + * Fn.range(5, 10); // -> [5, 6, 7, 8, 9, 10]; + * @example + * Fn.range(5); // -> [0, 1, 2, 3, 4]; + * @example + * Fn.range(3, 27, 3); // -> [3, 6, 9, 12, 15, 18, 21, 24, 27]; + * @example + * Fn.range(0, -9, -3); // -> [0, -3, -6, -9]; + */ Fn.range = function(lower, upper, tick) { if (arguments.length === 1) { @@ -97,22 +126,30 @@ Fn.range = function(lower, upper, tick) { return range; }; -// Fn.range.prefixed( prefix, upper ) -// Fn.range.prefixed( prefix, lower, upper ) -// Fn.range.prefixed( prefix, lower, upper, tick ) -// -// Returns a new array range, each value prefixed -// +/** + * Adds prefix to each element in the range Array returned by Fn.range. + * + * Fn.range.prefixed( prefix, upper ) + * Fn.range.prefixed( prefix, lower, upper ) + * Fn.range.prefixed( prefix, lower, upper, tick ) + * + * @param {*} prefix - You probably want to use a string, but you don't have to. + * @return Array per range parameters, each element prefixed. + * @see Fn.range + * @example + * Fn.range.prefixed("A", 0, 10, 2); // -> ["A0", "A2", "A4", "A6", "A8", "A10"] + */ Fn.range.prefixed = function(prefix) { return Fn.range.apply(null, [].slice.call(arguments, 1)).map(function(val) { return prefix + val; }); }; -// Fn.uid() -// -// Returns a reasonably unique id string -// +/** + * Generate a reasonably-unique ID string + * + * @return {String} - 36-character random-ish string + */ Fn.uid = function() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(chr) { var rnd = Math.random() * 16 | 0; @@ -120,18 +157,27 @@ Fn.uid = function() { }).toUpperCase(); }; -// Fn.square() -// -// Returns squared x -// + +/** + * Square your x! + * + * @param {Number} x + * @return {Number| Nan} - x^2—unless you were goofy enough to provide a + * non-numeric x, in which case it's NaN for you! + */ Fn.square = function(x) { return x * x; }; -// Fn.sum( values ) -// -// Returns the sum of all values from array -// +/** + * Get a sum for all the values in an Array. This works best if the elements + * in the Array are Numbers. + * + * @param {Array} values + * @return {Number | String} - You probably want a Number so you'll want to + * pass a values Array entirely consisting of + * numeric elements. + */ Fn.sum = function sum(values) { var vals; if (Array.isArray(values)) { @@ -144,6 +190,9 @@ Fn.sum = function sum(values) { }, 0); }; +/** + * Fused multiply-add for precise floating-point calculations. + */ // fma function // Copyright (c) 2012, Jens Nockert // All rights reserved. @@ -192,35 +241,34 @@ Fn.fma = function(a, b, c) { }; // end fma function copyright - -// Fn._BV(bit) -// -// (from avr/io.h; "BV" => Bit Value) -// -// Return byte value with that bit set. -// +/** + * Return a value with the bit at the position indicated set (to 1). + * From avr/io.h "BV" => Bit Value + * + * An example: logically OR these bits together: + * var ORed = _BV(0) | _BV(2) | _BV(7); + * + * BIT 7 6 5 4 3 2 1 0 + * --------------------------------------------------------- + * _BV(0) = 0 0 0 0 0 0 0 1 + * _BV(2) = 0 0 0 0 0 1 0 0 + * _BV(7) = 1 0 0 0 0 0 0 0 + * ORed = 1 0 0 0 0 1 0 1 + * + * ORed === 133; + * + * @param {Number} bit - bit position to set + * @return {Number} + * @example + * Fn.bitValue(0); // --> 1 + * @example + * Fn.bitValue(4); // --> 16 + * + */ Fn._BV = Fn.bitValue = Fn.bv = function(bit) { return 1 << bit; }; -/* - Example of _BV/bitValue usage... - - Logically OR these bits together: - var ORed = _BV(0) | _BV(2) | _BV(7); - - BIT 7 6 5 4 3 2 1 0 - --------------------------------------------------------- - _BV(0) = 0 0 0 0 0 0 0 1 - _BV(2) = 0 0 0 0 0 1 0 0 - _BV(7) = 1 0 0 0 0 0 0 0 - ORed = 1 0 0 0 0 1 0 1 - - ORed === 133; - -*/ - - /** * int16 Combine two bytes to make an signed 16-bit integer * @param {byte} msb Most signifcant byte @@ -238,7 +286,7 @@ Fn.int16 = function(msb, lsb) { * uint16 Combine two bytes to make an unsigned 16-bit integer * @param {byte} msb Most signifcant byte * @param {byte} lsb Least signifcant byte - * @return {word} Signed 16-bit integer + * @return {word} unsigned 16-bit integer */ Fn.uint16 = function(msb, lsb) { return (msb << 8) | lsb; @@ -279,21 +327,25 @@ Fn.uint24 = function(b16, b8, b0) { */ Fn.int32 = function(b24, b16, b8, b0) { var result = (b24 << 24) | (b16 << 16) | (b8 << 8) | b0; - // Check highest bit for sign. If on, value is negative return result >> 31 ? ((result ^ 0xFFFFFFFF) + 1) * -1 : result; }; /** - * int32 Combine four bytes to make a signed 24-bit integer + * int32 Combine four bytes to make an unsigned 32-bit integer * @param {byte} b24 b[24:31] * @param {byte} b16 b[16:23] * @param {byte} b8 b[8:15] * @param {byte} b0 b[0:7] - * @return {word} Signed 32-bit integer + * @return {Number} unsigned 32-bit integer */ Fn.uint32 = function(b24, b16, b8, b0) { - return (b24 << 24) | (b16 << 16) | (b8 << 8) | b0; + // Note: If you left-shift a byte by 24 in JS and that byte's + // MSbit is 1, the resulting value will be negative because JS casts + // bitwise operands (temporarily) to SIGNED 32-bit numbers. The + // final >>> 0 causes the sign bit to be disregarded, making sure our + // result is non-negative. + return ((b24 << 24) | (b16 << 16) | (b8 << 8) | b0) >>> 0; }; /** @@ -305,27 +357,66 @@ Fn.bitSize = function(n) { return Math.round(Math.log2(n)); }; +/** + * The following generates functions and constants for utility when working + * with binary numbers: + * - Fn.POW_2_0 through Fn.POW_2_53 + * - Fn.u4(value) through Fn.u32(value) + * - Fn.s4(value) through Fn.s32(value) + */ var POW = "POW_2_"; var U = "u"; var S = "s"; var MAX = Fn.bitSize(Number.MAX_SAFE_INTEGER) + 1; +var bitSizes = [ 4, 8, 10, 12, 16, 20, 24, 32 ]; +/** + * Generate "constants" that represent powers of 2. Available for powers + * 0 through 53. + * @example + * Fn.POW_2_17; // -> 131072 + */ for (var i = 0; i < MAX; i++) { Fn[POW + i] = Math.pow(2, i); } -[ 4, 8, 10, 12, 16, 20, 24, 32 ].forEach(function(bitSize) { +bitSizes.forEach(function(bitSize) { var decimal = Fn[POW + bitSize]; var half = decimal / 2 >>> 0; var halfMinusOne = half - 1; + /** + * The function Fn["u" + bitSize] will constrain a value to an unsigned + * value of that bit size. + * + * @param {Number} value + * @return {Number} constrained to an unsigned int + * @example + * Fn.u8(255); // --> 255 + * Fn.u8(256); // --> 255 + * Fn.u8(-255); // --> 0 + * Fn.u8(-254); // -- 1 + */ Fn[U + bitSize] = function(value) { if (value < 0) { value += decimal; } - return Fn.constrain(value, 0, decimal); + return Fn.constrain(value, 0, decimal - 1); }; + /** + * The function Fn["s" + bitSize] will constrain a value to a signed value + * of that bit size. Remember that, e.g., range for signed 8-bit numbers + * is -128 to 127. + * + * @param {Number} value + * @return {Number} constrained to a SIGNED integer in bitsize range + * @example + * Fn.s8(100); // --> 100 + * Fn.s8(128); // --> -128 + * Fn.s8(127); // --> 127 + * Fn.s8(255); // --> -1 + */ Fn[S + bitSize] = function(value) { if (value > halfMinusOne) { value -= decimal; diff --git a/lib/gps.js b/lib/gps.js index 0804ef4f7..e9fa8a946 100644 --- a/lib/gps.js +++ b/lib/gps.js @@ -1,4 +1,3 @@ -//var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var events = require("events"); var util = require("util"); @@ -467,4 +466,13 @@ function getNmeaChecksum(string) { return cksum; } +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + GPS.Breakouts = Breakouts; + GPS.Chips = Chips; + GPS.Receivers = Receivers; + GPS.purge = function() { + priv.clear(); + }; +} module.exports = GPS; diff --git a/lib/gyro.js b/lib/gyro.js index 99b56f433..69ce8f2a2 100644 --- a/lib/gyro.js +++ b/lib/gyro.js @@ -114,9 +114,6 @@ var Controllers = { }, }; -// Otherwise known as... -Controllers["MPU-6050"] = Controllers.MPU6050; - function Gyro(opts) { if (!(this instanceof Gyro)) { return new Gyro(opts); @@ -329,4 +326,11 @@ Gyro.prototype.recalibrate = function() { this.isCalibrated = false; }; +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Gyro.Controllers = Controllers; + Gyro.purge = function() { + priv.clear(); + }; +} module.exports = Gyro; diff --git a/lib/hygrometer.js b/lib/hygrometer.js index 41e801c9a..699dd653f 100644 --- a/lib/hygrometer.js +++ b/lib/hygrometer.js @@ -4,9 +4,8 @@ var Emitter = require("events").EventEmitter; var util = require("util"); var toFixed = Fn.toFixed; +var priv = new Map(); -// References -// var Controllers = { // https://cdn-shop.adafruit.com/product-files/2857/Sensirion_Humidity_SHT3x_Datasheet_digital-767294.pdf SHT31D: { @@ -58,11 +57,30 @@ var Controllers = { } }, - DHT11_I2C_NANO_BACKPACK: { + HIH6130: { + initialize: { + value: function(opts, dataHandler) { + var Multi = require("./imu"); + var driver = Multi.Drivers.get(this.board, "HIH6130", opts); + driver.on("data", function(data) { + dataHandler(data.humidity); + }); + } + }, + toRelativeHumidity: { + value: function(raw) { + // Page 3 + // Equation 1: Humidity Conversion Function + return toFixed(raw * 100 / (Fn.POW_2_14 - 1), 2); + } + } + }, + + DHT_I2C_NANO_BACKPACK: { initialize: { value: function(opts, dataHandler) { var Multi = require("./imu"); - var driver = Multi.Drivers.get(this.board, "DHT11_I2C_NANO_BACKPACK", opts); + var driver = Multi.Drivers.get(this.board, "DHT_I2C_NANO_BACKPACK", opts); driver.on("data", function(data) { dataHandler(data.humidity); }); @@ -90,7 +108,7 @@ var Controllers = { if (raw > 100) { raw = 0; } - return Number((raw || 0, 4)); + return toFixed(raw || 0, 2); } } }, @@ -135,17 +153,21 @@ var Controllers = { } }; -var priv = new Map(); +Controllers.DHT11_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; +Controllers.DHT21_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; +Controllers.DHT22_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; +Controllers.SI7021 = Controllers.SI7020; -function Hygrometer(opts) { - var controller; - var last = null; - var raw = null; +function Hygrometer(opts) { if (!(this instanceof Hygrometer)) { return new Hygrometer(opts); } + var controller = null; + var last = null; + var raw = null; + Board.Component.call( this, opts = Board.Options(opts) ); @@ -213,4 +235,12 @@ function Hygrometer(opts) { util.inherits(Hygrometer, Emitter); +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Hygrometer.Controllers = Controllers; + Hygrometer.purge = function() { + priv.clear(); + }; +} + module.exports = Hygrometer; diff --git a/lib/imu.js b/lib/imu.js index 03c35f79c..9b3966e56 100644 --- a/lib/imu.js +++ b/lib/imu.js @@ -2,14 +2,6 @@ var Board = require("./board"); var Emitter = require("events").EventEmitter; var util = require("util"); var Fn = require("./fn"); -var Accelerometer = require("./accelerometer"); -var Altimeter = require("./altimeter"); -var Barometer = require("./barometer"); -var Compass = require("./compass"); -var Hygrometer = require("./hygrometer"); -var Thermometer = require("./thermometer"); -var Orientation = require("./orientation"); -var Gyro = require("./gyro"); var int16 = Fn.int16; var uint16 = Fn.uint16; var uint24 = Fn.uint24; @@ -17,15 +9,62 @@ var uint24 = Fn.uint24; var priv = new Map(); var activeDrivers = new Map(); -// The presense of this magic number is for computing meters from pressure and elevation (in meters) -// 0.0000225577 +// TODO: make real const +var ACCELEROMETER = "accelerometer"; +var ALTIMETER = "altimeter"; +var BAROMETER = "barometer"; +var GYRO = "gyro"; +var HYGROMETER = "hygrometer"; +var MAGNETOMETER = "magnetometer"; +var ORIENTATION = "orientation"; +var THERMOMETER = "thermometer"; + + +function Components(controller, options) { + var state = priv.get(this); + var descriptors = Object.create(null); + + this.components.forEach(function(component) { + + // TODO: Can this be put inside the get accessor? + // - Lazy init? + state[component] = new Components[component]( + Object.assign({ + controller: options.controller || controller, + freq: options.freq, + board: this.board, + }, options) + ); + + descriptors[component] = { + get: function() { + return state[component]; + } + }; + + if (backwardCompatibilityGarbageHacks[component]) { + descriptors[backwardCompatibilityGarbageHacks[component]] = descriptors[component]; + } + }); + + Object.defineProperties(this, descriptors); +} + +Components.accelerometer = require("./accelerometer"); +Components.altimeter = require("./altimeter"); +Components.barometer = require("./barometer"); +Components.gyro = require("./gyro"); +Components.hygrometer = require("./hygrometer"); +Components.magnetometer = require("./compass"); +Components.orientation = require("./orientation"); +Components.thermometer = require("./thermometer"); + +var backwardCompatibilityGarbageHacks = { + thermometer: "temperature", +}; var Drivers = { // https://cdn-shop.adafruit.com/product-files/2857/Sensirion_Humidity_SHT3x_Datasheet_digital-767294.pdf - // Based on the AdaFruit Arduino driver - // https://github.com/adafruit/Adafruit_SHT31 - // https://www.adafruit.com/products/2857 - // Inspirated by https://github.com/ControlEverythingCommunity/SHT31/blob/master/Java/SHT31.java SHT31D: { ADDRESSES: { value: [0x44] @@ -60,26 +99,32 @@ var Drivers = { this.REGISTER.SOFT_RESET & 0xFF, ]); - - // Page 10 - // Table 8 - // Send high repeatability measurement command - io.i2cWrite(address, [ - this.REGISTER.MEASURE_HIGH_REPEATABILITY >> 8, - this.REGISTER.MEASURE_HIGH_REPEATABILITY & 0xFF, - ]); - var computed = { temperature: null, humidity: null, }; - // temp msb, temp lsb, temp CRC, humidity msb, humidity lsb, humidity CRC - io.i2cRead(address, READLENGTH, function(data) { - computed.temperature = int16(data[0], data[1]); - computed.humidity = int16(data[3], data[4]); - this.emit("data", computed); - }.bind(this)); + // temp msb, temp lsb, temp CRC, humidity msb, humidity lsb, humidity CRC + var readCycle = function() { + // Page 10 + // Table 8 + // Send high repeatability measurement command + io.i2cWrite(address, [ + this.REGISTER.MEASURE_HIGH_REPEATABILITY >> 8, + this.REGISTER.MEASURE_HIGH_REPEATABILITY & 0xFF, + ]); + + setTimeout(function() { + io.i2cReadOnce(address, READLENGTH, function(data) { + computed.temperature = uint16(data[0], data[1]); + computed.humidity = uint16(data[3], data[4]); + this.emit("data", computed); + readCycle(); + }.bind(this)); + }.bind(this), 16); + }.bind(this); + + readCycle(); } }, identifier: { @@ -133,9 +178,9 @@ var Drivers = { io.i2cReadOnce(address, register, 2, function(data) { if (isTemperatureCycle) { - computed.temperature = int16(data[0], data[1]); + computed.temperature = uint16(data[0], data[1]); } else { - computed.humidity = int16(data[0], data[1]); + computed.humidity = uint16(data[0], data[1]); } if (++cycle === 2) { @@ -157,7 +202,92 @@ var Drivers = { } } }, - DHT11_I2C_NANO_BACKPACK: { + // http://www.phanderson.com/arduino/I2CCommunications.pdf + // http://www.phanderson.com/arduino/CommandModeInstructions.pdf + // http://cdn.sparkfun.com/datasheets/Prototyping/1443945.pdf + HIH6130: { + ADDRESSES: { + value: [0x27] + }, + initialize: { + value: function(board, opts) { + var io = board.io; + var address = opts.address || this.ADDRESSES[0]; + + opts.address = address; + + io.i2cConfig(opts); + + var computed = { + humidity: null, + temperature: null, + }; + + var delay = 36.65; + + var measureCycle = function() { + // The most common use cases involve continuous + // sampling of sensor data, so that's what this + // controller-driver will provide. + io.i2cWrite(address, 0xA0, [0x00, 0x00]); + + setTimeout(function() { + io.i2cWrite(address, 0x80, [0x00, 0x00]); + io.i2cReadOnce(address, 4, function(data) { + // Page 2 + // Figure 4. Humidity and Temperature Data Fetch, Four Byte Data Read + // B7:6 Contain status bits + var status = data[0] >> 6; + // Mask out B7:6 status bits from H MSB + computed.humidity = int16(data[0] & 0x3F, data[1]); + // Shift off B1:0 (which are empty) + computed.temperature = int16(data[2], data[3] >> 2); + + // Page 3 + // 2.6 Status Bits + // + // 0 0 Normal + // 0 1 Stale + // 1 0 Command Mode + // 1 1 Diagnostic Condition + // + // When the two status bits read "01", "stale" data is + // indicated. This means that the data that already + // exists in the sensor's output buffer has already + // been fetched by the Master, and has not yet been + // updated with the next data from the current measurement + // cycle. This can happen when the Master polls the + // data quicker than the sensor can update the output buffer. + if (status === 0) { + delay--; + } + + if (status === 1) { + delay++; + } + + this.emit("data", computed); + + measureCycle(); + }.bind(this)); + // Page 3 + // 3.0 Measurement Cycle + // The measurement cycle duration is typically + // 36.65 ms for temperature and humidity readings. + }.bind(this), delay); + }.bind(this); + + measureCycle(); + } + }, + identifier: { + value: function(opts) { + var address = opts.address || Drivers.HIH6130.ADDRESSES.value[0]; + return "hih6130-" + address; + } + } + }, + DHT_I2C_NANO_BACKPACK: { ADDRESSES: { value: [0x0A] }, @@ -170,17 +300,31 @@ var Drivers = { value: function(board, opts) { var io = board.io; var address = opts.address || this.ADDRESSES[0]; + // Correspond to firmware variables + var dhtPin = 2; + var dhtType = 11; opts.address = address; io.i2cConfig(opts); - // http://cdn.sparkfun.com/datasheets/BreakoutBoards/HTU21D.pdf + var dhtVariantExec = /(\d{2})/.exec(opts.controller); + var dhtVariant = dhtVariantExec && dhtVariantExec.length && dhtVariantExec[0]; + + if (dhtVariant) { + dhtType = +dhtVariant; + + if (Number.isNaN(dhtType)) { + dhtType = 11; + } + } + var computed = { temperature: null, humidity: null, }; + io.i2cWrite(address, [dhtPin, dhtType]); io.i2cRead(address, 4, function(data) { computed.humidity = int16(data[0], data[1]); computed.temperature = int16(data[2], data[3]); @@ -190,8 +334,8 @@ var Drivers = { }, identifier: { value: function(opts) { - var address = opts.address || Drivers.DHT11_I2C_NANO_BACKPACK.ADDRESSES.value[0]; - return "dht11_i2c_nano_backpack-" + address; + var address = opts.address || Drivers.DHT_I2C_NANO_BACKPACK.ADDRESSES.value[0]; + return "dht_i2c_nano_backpack-" + address; } } }, @@ -360,7 +504,7 @@ var Drivers = { var address = opts.address || this.ADDRESSES[0]; - // AF. p.67 4.3.54 + // AF. Page 67 4.3.54 //a value for what we use to consider the system calibrated, 0xC0 represents the just fusion algorithm/system var calibrationMask = opts.calibrationMask || 0xC0; @@ -399,13 +543,6 @@ var Drivers = { calibration: null, }; - // var calibrated = { - // accelerometer: false, - // gyro: false, - // magnetometer: false, - // temperature: true, - // }; - io.i2cConfig(opts); // Put chip into CONFIG operation mode @@ -414,7 +551,7 @@ var Drivers = { // Set register page to 0 io.i2cWriteReg(address, this.REGISTER.PAGE_ID_ADDR, this.REGISTER.PAGE_STATES.ZERO); - // AF p.70, 4.3.63 SYS_TRIGGER + // AF Page 70, 4.3.63 SYS_TRIGGER // // RST_SYS (Set to reset system) // @@ -429,7 +566,7 @@ var Drivers = { // Normal power mode io.i2cWriteReg(address, this.REGISTER.PWR_MODE_ADDR, this.REGISTER.PWR_MODES.NORMAL); - // AF p.70, 4.3.63 SYS_TRIGGER + // AF Page 70, 4.3.63 SYS_TRIGGER // // CLK_SEL: // @@ -440,7 +577,7 @@ var Drivers = { // do we want to enable an external crystal?? io.i2cWriteReg(address, this.REGISTER.SYS_TRIGGER, opts.enableExternalCrystal ? 0x80 : 0x00); - //AF p.24 3.4, Axis remap + //AF Page 24 3.4, Axis remap // // AXIS_MAP_CONFIG: // @@ -450,12 +587,12 @@ var Drivers = { // // x axis = 00, y axis = 01, z axis = 10 // - // see also the defaults starting on AF p.50 + // see also the defaults starting on AF Page 50 // var axisMap = opts.axisMap || 0x24; io.i2cWriteReg(address, this.REGISTER.AXIS_MAP_CONFIG_ADDR, axisMap); - //AF p.24 3.4, Axis remap + //AF Page 24 3.4, Axis remap // // AXIS_MAP_CONFIG: // @@ -476,7 +613,7 @@ var Drivers = { }.bind(this), 10); // OPERATING CONDITIONS BNO055 - // AF p.13, 1.2, OPERATING CONDITIONS BNO055 + // AF Page 13, 1.2, OPERATING CONDITIONS BNO055 // From reset to config mode }.bind(this), 650); }.bind(this)); @@ -486,11 +623,11 @@ var Drivers = { var readCalibration = function() { io.i2cReadOnce(address, this.REGISTER.CALIBRATION, 1, function(data) { - var state = data[0]; - var didCalibrationChange = computed.calibration !== state; + var calibration = data[0]; + var didCalibrationChange = computed.calibration !== calibration; - computed.calibration = state; + computed.calibration = calibration; // it is useful, possibly to know when the calibration state changes // some of the calibrations are a little picky to get right, so emitting @@ -500,7 +637,7 @@ var Drivers = { this.emit("calibration", computed.calibration); } - if ((state & calibrationMask) === calibrationMask) { + if ((calibration & calibrationMask) === calibrationMask) { // emit the calibration state so we can work out in our userspace if // we are good to go, and for when we are performing the calibration steps @@ -704,6 +841,8 @@ var Drivers = { value: [0x60] }, REGISTER: { + // Page 18 + // 13 Register descriptions value: { STATUS: 0x00, PRESSURE: 0x01, @@ -1816,12 +1955,12 @@ var Drivers = { // 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]); + computed.temperature = uint16(data[0], data[1]); this.emit("data", computed); }.bind(this)); io.i2cRead(address, this.REGISTER.HUMIDITY, 2, function(data) { - computed.humidity = int16(data[0], data[1]); + computed.humidity = uint16(data[0], data[1]); this.emit("data", computed); }.bind(this)); } @@ -2111,26 +2250,26 @@ var Drivers = { opts.address = address; - var cof = { - // Table 10. Linearization Coefficients - A0: -4.7844, - A1: 0.4008, - A2: -0.00393, - - // Table 11. Linearization Coefficients - Q0: 0.1973, - Q1: 0.00237, - }; + // var cof = { + // // Table 10. Linearization Coefficients + // A0: -4.7844, + // A1: 0.4008, + // A2: -0.00393, - var linear = { - temperature: null, - humidity: null, - }; + // // Table 11. Linearization Coefficients + // Q0: 0.1973, + // Q1: 0.00237, + // }; - var actual = { - temperature: null, - humidity: null, - }; + // var linear = { + // temperature: null, + // humidity: null, + // }; + + // var actual = { + // temperature: null, + // humidity: null, + // }; var computed = { temperature: null, @@ -2155,23 +2294,23 @@ var Drivers = { this.COMMAND.MEASURE_HUMIDITY; - // 2. Send the appropriate measurement/conversion - // command for this read cycle. - io.i2cWrite(address, this.REGISTER.CONFIG, command); - - // 3. Await an affirmative status result. This signifies that - // measurement and conversion are complete and values may - // be read from the peripheral register.get - // - // Register design like this is really painful to work - // with. These peripherals have ample space to store data - // in different registers, but do not. var conversion = new Promise(function(resolve) { + // 2. Send the appropriate measurement/conversion + // command for this read cycle. + io.i2cWrite(address, this.REGISTER.CONFIG, command); + + // 3. Await an affirmative status result. This signifies that + // measurement and conversion are complete and values may + // be read from the peripheral register.get + // + // Register design like this is really painful to work + // with. These peripherals have ample space to store data + // in different registers, but do not. var requestStatus = function() { io.i2cReadOnce(address, this.REGISTER.STATUS, 1, function(data) { var status = data[0]; - if (status === 0) { + if (!(status & 0x01)) { resolve(); } else { requestStatus(); @@ -2199,47 +2338,23 @@ var Drivers = { // One might assume that we could then read 2 bytes from 0x02, // but that also produces garbage, so in the end we need to read // 3 bytes from 0x01. - io.i2cReadOnce(address, this.REGISTER.READ, 3, function(data) { - var value = uint16(data[1], data[2]); + Promise.all([ + new Promise(function(resolve) { + io.i2cReadOnce(address, 0x01, 1, function(data) { + resolve(data[0]); + }); + }), + new Promise(function(resolve) { + io.i2cReadOnce(address, 0x02, 1, function(data) { + resolve(data[0]); + }); + }) + ]).then(function(data) { if (isTemperatureCycle) { - /* - | DATA MSB | DATA LSB | - | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | 14-Bit Temperature Code | 0 | 0 | - */ - - computed.temperature = ((value >> 2) / 32) - 50; + computed.temperature = ((uint16(data[0], data[1]) >> 2) / 32) - 50; } else { - /* - | DATA MSB | DATA LSB | - | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | 12-Bit Humidity Code | 0 | 0 | 0 | 0 | - */ - - /* - Typical %RH Measurements - - | %RH | 12 Bit Value | - | --- | ------------- | - | 0 | 384 | - | 10 | 544 | - | 20 | 704 | - | 30 | 864 | - | 40 | 1024 | - | 50 | 1184 | - | 60 | 1344 | - | 70 | 1504 | - | 80 | 1664 | - | 90 | 1824 | - | 100 | 1984 | - */ - - actual.humidity = ((value >> 4) / 16) - 24; - linear.humidity = actual.humidity - (Math.pow(actual.humidity, 2) * cof.A2 + actual.humidity * cof.A1 + cof.A0); - computed.humidity = linear.humidity + (computed.temperature - 30) * (linear.humidity * cof.Q1 + cof.Q0); + computed.humidity = ((uint16(data[0], data[1]) >> 4) / 16) - 24; } if (++cycle === 2) { @@ -2266,7 +2381,12 @@ var Drivers = { // Otherwise known as... Drivers.BMP085 = Drivers.BMP180; -Drivers["MPU-6050"] = Drivers.MPU6050; +Drivers.GY521 = Drivers.MPU6050; +Drivers.SI7021 = Drivers.SI7020; +Drivers.DHT11_I2C_NANO_BACKPACK = Drivers.DHT_I2C_NANO_BACKPACK; +Drivers.DHT21_I2C_NANO_BACKPACK = Drivers.DHT_I2C_NANO_BACKPACK; +Drivers.DHT22_I2C_NANO_BACKPACK = Drivers.DHT_I2C_NANO_BACKPACK; + Drivers.get = function(board, driverName, opts) { var drivers, driverKey, driver; @@ -2296,65 +2416,19 @@ Drivers.clear = function() { var Controllers = { /** - * MPU-6050 3-axis Gyro/Accelerometer and Thermometer + * MPU6050 3-axis Gyro/Accelerometer and Thermometer * - * http://playground.arduino.cc/Main/MPU-6050 + * http://playground.arduino.cc/Main/MPU6050 */ MPU6050: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "MPU6050"; - - state.accelerometer = new Accelerometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.gyro = new Gyro( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "MPU6050", opts); } }, components: { - value: ["accelerometer", "thermometer", "gyro"] - }, - accelerometer: { - get: function() { - return priv.get(this).accelerometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } - }, - gyro: { - get: function() { - return priv.get(this).gyro; - } + value: [ACCELEROMETER, GYRO, THERMOMETER] }, }, @@ -2369,7 +2443,7 @@ var Controllers = { // here we want to catch the events coming out of the driver and re-emit them // not sure what is cleaner here, picking these up from a data event // in the sub controllers, or this - var driver = IMU.Drivers.get(this.board, CONTROLLER, opts); + var driver = Drivers.get(this.board, CONTROLLER, opts); driver.on("calibrated", function() { this.emit("calibrated"); }.bind(this)); @@ -2378,75 +2452,11 @@ var Controllers = { this.emit("calibration", state); }.bind(this)); - state.accelerometer = new Accelerometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.gyro = new Gyro( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.magnetometer = new Compass( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.orientation = new Orientation( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - + Components.call(this, CONTROLLER, opts); } }, components: { - value: ["accelerometer", "gyro", "magnetometer", "thermometer", "orientation"] - }, - accelerometer: { - get: function() { - return priv.get(this).accelerometer; - } - }, - gyro: { - get: function() { - return priv.get(this).gyro; - } - }, - magnetometer: { - get: function() { - return priv.get(this).magnetometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } - }, - orientation: { - get: function() { - return priv.get(this).orientation; - } + value: [ACCELEROMETER, GYRO, MAGNETOMETER, ORIENTATION, THERMOMETER] }, calibration: { get: function() { @@ -2464,566 +2474,136 @@ var Controllers = { MPL115A2: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "MPL115A2"; - - state.barometer = new Barometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "MPL115A2", opts); } }, components: { - value: ["barometer", "thermometer"] - }, - barometer: { - get: function() { - return priv.get(this).barometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [BAROMETER, THERMOMETER] }, }, SHT31D: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "SHT31D"; - - state.hygrometer = new Hygrometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "SHT31D", opts); } }, components: { - value: ["hygrometer", "thermometer"] - }, - hygrometer: { - get: function() { - return priv.get(this).hygrometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [HYGROMETER, THERMOMETER] }, }, HTU21D: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "HTU21D"; - - state.hygrometer = new Hygrometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "HTU21D", opts); } }, components: { - value: ["hygrometer", "thermometer"] - }, - hygrometer: { - get: function() { - return priv.get(this).hygrometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [HYGROMETER, THERMOMETER] }, }, - DHT11_I2C_NANO_BACKPACK: { + HIH6130: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "DHT11_I2C_NANO_BACKPACK"; - - state.hygrometer = new Hygrometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "HIH6130", opts); } }, components: { - value: ["hygrometer", "thermometer"] + value: [HYGROMETER, THERMOMETER] }, - hygrometer: { - get: function() { - return priv.get(this).hygrometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; + }, + DHT_I2C_NANO_BACKPACK: { + initialize: { + value: function(opts) { + Components.call(this, "DHT_I2C_NANO_BACKPACK", opts); } }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + components: { + value: [HYGROMETER, THERMOMETER] }, }, MPL3115A2: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "MPL3115A2"; - - state.barometer = new Barometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.altimeter = new Altimeter( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "MPL3115A2", opts); } }, components: { - value: ["barometer", "altimeter", "thermometer"] - }, - barometer: { - get: function() { - return priv.get(this).barometer; - } - }, - altimeter: { - get: function() { - return priv.get(this).altimeter; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [ALTIMETER, BAROMETER, THERMOMETER] }, }, + // This controller and driver pair are used for both + // BMP180 and BMP085 BMP180: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "BMP180"; - - // This controller and driver pair are used for both - // BMP180 and BMP085 - - state.altimeter = new Altimeter( - Object.assign({ - controller: opts.controller || CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.barometer = new Barometer( - Object.assign({ - controller: opts.controller || CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: opts.controller || CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "BMP180", opts); } }, components: { - value: ["altimeter", "barometer", "thermometer"] - }, - altimeter: { - get: function() { - return priv.get(this).altimeter; - } - }, - barometer: { - get: function() { - return priv.get(this).barometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [ALTIMETER, BAROMETER, THERMOMETER] }, }, - BMP280: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "BMP280"; - - state.altimeter = new Altimeter( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.barometer = new Barometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "BMP280", opts); } }, components: { - value: ["altimeter", "barometer", "thermometer"] - }, - altimeter: { - get: function() { - return priv.get(this).altimeter; - } - }, - barometer: { - get: function() { - return priv.get(this).barometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [ALTIMETER, BAROMETER, THERMOMETER] }, }, BME280: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "BME280"; - - state.altimeter = new Altimeter( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.barometer = new Barometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.hygrometer = new Hygrometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "BME280", opts); } }, components: { - value: ["altimeter", "barometer", "hygrometer", "thermometer"] - }, - altimeter: { - get: function() { - return priv.get(this).altimeter; - } - }, - barometer: { - get: function() { - return priv.get(this).barometer; - } - }, - hygrometer: { - get: function() { - return priv.get(this).hygrometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [ALTIMETER, BAROMETER, HYGROMETER, THERMOMETER] }, }, SI7020: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "SI7020"; - - state.hygrometer = new Hygrometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "SI7020", opts); } }, components: { - value: ["hygrometer", "thermometer"] - }, - hygrometer: { - get: function() { - return priv.get(this).hygrometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [HYGROMETER, THERMOMETER] }, }, MS5611: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "MS5611"; - - - state.altimeter = new Altimeter( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.barometer = new Barometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "MS5611", opts); } }, components: { - value: ["barometer", "altimeter", "thermometer"] - }, - barometer: { - get: function() { - return priv.get(this).barometer; - } - }, - altimeter: { - get: function() { - return priv.get(this).altimeter; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [ALTIMETER, BAROMETER, THERMOMETER] }, }, TH02: { initialize: { value: function(opts) { - var state = priv.get(this); - var CONTROLLER = "TH02"; - - state.hygrometer = new Hygrometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); - - state.thermometer = new Thermometer( - Object.assign({ - controller: CONTROLLER, - freq: opts.freq, - board: this.board, - }, opts) - ); + Components.call(this, "TH02", opts); } }, components: { - value: ["hygrometer", "thermometer"] - }, - hygrometer: { - get: function() { - return priv.get(this).hygrometer; - } - }, - // Deprecated - temperature: { - get: function() { - return priv.get(this).thermometer; - } - }, - thermometer: { - get: function() { - return priv.get(this).thermometer; - } + value: [HYGROMETER, THERMOMETER] }, }, }; // Otherwise known as... -Controllers["MPU-6050"] = Controllers.MPU6050; -Controllers["GY521"] = Controllers["GY-521"] = Controllers.MPU6050; -Controllers["BMP085"] = Controllers["BMP-085"] = Controllers.BMP180; +Controllers.BMP085 = Controllers.BMP180; +Controllers.GY521 = Controllers.MPU6050; +Controllers.SI7021 = Controllers.SI7020; +Controllers.DHT11_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; +Controllers.DHT21_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; +Controllers.DHT22_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; + function IMU(opts) { @@ -3102,4 +2682,12 @@ util.inherits(IMU, Emitter); IMU.Drivers = Drivers; +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + IMU.Controllers = Controllers; + IMU.purge = function() { + priv.clear(); + }; +} + module.exports = IMU; diff --git a/lib/ir.js b/lib/ir.js deleted file mode 100644 index 4c3417dc2..000000000 --- a/lib/ir.js +++ /dev/null @@ -1,182 +0,0 @@ -var Board = require("./board"), - events = require("events"), - util = require("util"); - -var priv = new Map(), - Devices; - -Devices = { - /** - * Sharp GP2Y0D805Z0F IR Sensor - * 0×20, 0×22, 0×24, 0×26 - * - * http://osepp.com/products/sensors-arduino-compatible/osepp-ir-proximity-sensor-module/ - * - * - * http://sharp-world.com/products/device/lineup/data/pdf/datasheet/gp2y0d805z_e.pdf - * - */ - - /* @deprecated */ - "GP2Y0D805Z0F": { - type: "proximity", - address: 0x26, - bytes: 1, - delay: 250, - - // read request data handler - data: function(read, data) { - var state = priv.get(this).state, - value = data[0], - timestamp = new Date(); - - if (value !== state && value === 1) { - this.emit("motionstart", timestamp); - } - - if (state === 1 && value === 3) { - this.emit("motionend", timestamp); - } - - priv.set(this, { - state: value - }); - }, - - // These are added to the property descriptors defined - // within the constructor - descriptor: { - value: { - get: function() { - return priv.get(this).state; - } - } - }, - setup: [ - // CRA - [0x3, 0xFE] - ], - preread: [ - [0x0] - ] - }, - - "QRE1113GR": { - // http://www.pololu.com/file/0J117/QRE1113GR.pdf - type: "reflect", - address: 0x4B, - bytes: 2, - delay: 100, - - // read request data handler - data: function(data) { - var temp = { - left: data[0], - right: data[1] - }; - - // if ( temp.left < 200 ) { - // this.emit( "left", timestamp ); - // } - - // if ( temp.right < 200 ) { - // this.emit( "right", timestamp ); - // } - - - priv.set(this, temp); - }, - - descriptor: { - left: { - get: function() { - return priv.get(this).left; - } - }, - right: { - get: function() { - return priv.get(this).right; - } - } - }, - - setup: [ - // Reset the ADC (analog-to-digital converter) - // NXP PCA969 - [0x0, 0x0] - ], - preread: [ - // left, right - [0x0, 0x1] - ] - } -}; - - - -function IR(opts) { - - if (!(this instanceof IR)) { - return new IR(opts); - } - - var address, bytes, data, device, delay, descriptor, - preread, setup; - - Board.Component.call( - this, opts = Board.Options(opts) - ); - - device = Devices[opts.device]; - - address = opts.address || device.address; - bytes = device.bytes; - data = device.data; - delay = device.delay; - setup = device.setup; - descriptor = device.descriptor; - preread = device.preread; - - // Read event throttling - this.freq = opts.freq || 500; - - // Make private data entry - priv.set(this, { - state: 0 - }); - - // Set up I2C data connection - this.io.i2cConfig(opts); - - // Enumerate and write each set of setup instructions - setup.forEach(function(byteArray) { - this.io.i2cWrite(address, byteArray); - }, this); - - // Read Request Loop - setInterval(function() { - // Set pointer to X most signficant byte/register - this.io.i2cWrite(address, preread); - - // Read from register - this.io.i2cReadOnce(address, bytes, data.bind(this)); - - }.bind(this), delay); - - // Continuously throttled "read" event - setInterval(function() { - // @DEPRECATE - this.emit("read"); - // The "read" event has been deprecated in - // favor of a "data" event. - this.emit("data"); - }.bind(this), this.freq); - - if (descriptor) { - Object.defineProperties(this, descriptor); - } -} - -util.inherits(IR, events.EventEmitter); - -module.exports = IR; diff --git a/lib/johnny-five.js b/lib/johnny-five.js index a557372e2..fb808c748 100644 --- a/lib/johnny-five.js +++ b/lib/johnny-five.js @@ -1,13 +1,13 @@ +/* istanbul ignore if */ if (!Array.from || !Object.assign || !Map) { require("es6-shim"); } +/* istanbul ignore if */ if (!Array.prototype.includes) { require("./array-includes-shim"); } -var util = require("util"); - module.exports = { // extract-start:apinames Accelerometer: require("./accelerometer"), @@ -19,7 +19,6 @@ module.exports = { Color: require("./color"), Collection: require("./mixins/collection"), Compass: require("./compass"), - Distance: require("./distance"), ESC: require("./esc"), Expander: require("./expander"), Fn: require("./fn"), @@ -28,7 +27,6 @@ module.exports = { Gyro: require("./gyro"), Hygrometer: require("./hygrometer"), IMU: require("./imu"), - IR: require("./ir"), Keypad: require("./keypad"), LCD: require("./lcd"), Led: require("./led"), @@ -39,7 +37,6 @@ module.exports = { Motor: require("./motor"), Piezo: require("./piezo"), Ping: require("./ping"), - Pir: require("./pir"), Pin: require("./pin"), Proximity: require("./proximity"), Relay: require("./relay"), @@ -108,58 +105,46 @@ module.exports.Sensor.Digital = module.exports.Digital; */ module.exports.Temperature = module.exports.Thermometer; + /** - * @deprecated Will be deleted in version 1.0.0. Use Proximity instead. + * @deprecated Will be deleted in version 1.0.0. Use Motion or Proximity instead. */ -module.exports.IR.Distance = util.deprecate(function(opts) { - return new module.exports.Distance(opts); -}, "IR.Distance is deprecated. Use Proximity instead"); +module.exports.IR = function() { + throw new Error("IR has been removed. Use Motion or Proximity instead."); +}; /** - * @deprecated Will be deleted in version 1.0.0. Use Motion instead. + * @deprecated Will be deleted in version 1.0.0. Use Proximity instead. */ -module.exports.IR.Motion = util.deprecate(function(opt) { - return new module.exports.Pir( - typeof opt === "number" ? opt : ( - opt.pin === undefined ? 7 : opt.pin - ) - ); -}, "IR.Motion is deprecated. Use Motion instead"); +module.exports.IR.Distance = function() { + throw new Error("IR.Distance has been removed. Use Proximity instead."); +}; /** * @deprecated Will be deleted in version 1.0.0. Use Proximity instead. */ -module.exports.IR.Proximity = util.deprecate(function(opts) { - // Fix a naming mistake. - if (module.exports.Distance.Controllers.includes(opts.controller)) { - return new module.exports.Distance(opts); - } - - return new module.exports.IR({ - device: opts || "GP2Y0D805Z0F", - freq: 50 - }); -}, "IR.Proximity is deprecated. Use Proximity instead"); - -module.exports.IR.Proximity.Controllers = module.exports.Distance.Controllers; +module.exports.IR.Proximity = function() { + throw new Error("IR.Proximity has been removed. Use Proximity instead."); +}; -module.exports.IR.Reflect = function(model) { - return new module.exports.IR({ - device: model || "QRE1113GR", - freq: 50 - }); +/** + * @deprecated Will be deleted in version 1.0.0. Use Motion instead. + */ +module.exports.IR.Motion = function() { + throw new Error("IR.Motion has been removed. Use Motion instead."); }; // TODO: Eliminate .Array for 1.0.0 +module.exports.IR.Reflect = {}; module.exports.IR.Reflect.Array = require("./reflectancearray"); -module.exports.IR.Reflect.Collection = require("./reflectancearray"); - -module.exports.Magnetometer = function() { - return new module.exports.Compass({ - controller: "HMC5883L", - freq: 100, - gauss: 1.3 - }); +module.exports.IR.Reflect.Collection = module.exports.IR.Reflect.Array; + +module.exports.Luxmeter = function(options) { + return new module.exports.Light(options); +}; + +module.exports.Magnetometer = function(options) { + return new module.exports.Compass(options); }; // Short-handing, Aliases diff --git a/lib/joystick.js b/lib/joystick.js index b49855c1a..db39b244e 100644 --- a/lib/joystick.js +++ b/lib/joystick.js @@ -169,7 +169,7 @@ function Joystick(opts) { } if (controller == null) { - controller = Controllers["ANALOG"]; + controller = Controllers.ANALOG; } Board.Controller.call(this, controller, opts); @@ -253,4 +253,12 @@ function Joystick(opts) { util.inherits(Joystick, Emitter); +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Joystick.Controllers = Controllers; + Joystick.purge = function() { + priv.clear(); + }; +} + module.exports = Joystick; diff --git a/lib/keypad.js b/lib/keypad.js index 376da305f..8b4f6c8e9 100644 --- a/lib/keypad.js +++ b/lib/keypad.js @@ -469,6 +469,73 @@ var Controllers = { } } }, + SX1509: { + ADDRESSES: { + value: [0x0A, 0x0B, 0x0C, 0x0D] + }, + REGISTER: { + value: { + PULLUP: 0x03, + OPEN_DRAIN: 0x05, + DIR: 0x07, + DIR_B: 0x0E, + DIR_A: 0x0F, + // OPEN_DRAIN_B: 0x0E, + // OPEN_DRAIN_A: 0x0F, + }, + }, + initialize: { + value: function(opts, dataHandler) { + var state = priv.get(this); + var address = opts.address || this.ADDRESSES[0]; + var keys = flatKeys(opts); + var mapping = [1, 2, 3, 4, 5, 6, 7, 8, 9, "*", 0, "#"]; + var length = 0; + + if (!keys.length) { + keys = mapping; + } + + length = mapping.length; + + state.length = length; + state.touches = touches(length); + state.mapping = mapping; + state.keys = keys; + state.isMultitouch = true; + + opts.address = address; + + this.io.i2cConfig(opts); + + this.io.i2cWriteReg(address, this.REGISTER.DIR, 0xF0); + this.io.i2cWriteReg(address, this.REGISTER.OPEN_DRAIN, 0x0F); + this.io.i2cWriteReg(address, this.REGISTER.PULLUP, 0xF0); + + this.io.i2cRead(address, 2, function(bytes) { + dataHandler(uint16(bytes[0], bytes[1])); + }); + } + }, + toAlias: { + value: function(index) { + var state = priv.get(this); + return state.keys[index]; + } + }, + toIndices: { + value: function(raw) { + var state = priv.get(this); + var indices = []; + for (var i = 0; i < state.length; i++) { + if (raw & (1 << i)) { + indices.push(i); + } + } + return indices; + } + } + }, }; @@ -614,4 +681,12 @@ function Keypad(opts) { util.inherits(Keypad, Emitter); +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Keypad.Controllers = Controllers; + Keypad.purge = function() { + priv.clear(); + }; +} + module.exports = Keypad; diff --git a/lib/lcd.js b/lib/lcd.js index a0837029f..259827870 100644 --- a/lib/lcd.js +++ b/lib/lcd.js @@ -183,6 +183,7 @@ var Controllers = { blocking: { var lines = this.REGISTER.DIMENSIONS | this.REGISTER.LINE[2]; // Copied from Grove Studio lib. + // https://www.sparkfun.com/datasheets/LCD/HD44780.pdf // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! // according to datasheet, we need at least 40ms after // power rises above 2.7V before sending commands. @@ -210,11 +211,16 @@ var Controllers = { } // Backlight initialization - this.io.i2cWrite(this.address.rgb, [0, 0]); - this.io.i2cWrite(this.address.rgb, [1, 0]); - this.io.i2cWrite(this.address.rgb, [0x08, 0xAA]); - this.bgColor(opts.color || "white"); + + + this.bgOn(); + + if (opts.color) { + this.bgColor(opts.color); + } else { + this.bgColor("black"); + } }, }, clear: { @@ -229,16 +235,32 @@ var Controllers = { }, bgColor: { value: function(red, green, blue) { - var registers = [0x04, 0x03, 0x02]; var rgb = RGB.ToRGB(red, green, blue); + var address = this.address.rgb; - RGB.colors.forEach(function(color, index) { - this.io.i2cWrite(this.address.rgb, [registers[index], rgb[color]]); - }, this); + this.io.i2cWrite(address, [0x00, 0]); + this.io.i2cWrite(address, [0x01, 0]); + + // TRY THIS IN ONE CALL! + this.io.i2cWrite(address, [0x04, rgb.red]); + this.io.i2cWrite(address, [0x03, rgb.green]); + this.io.i2cWrite(address, [0x02, rgb.blue]); return this; } }, + bgOn: { + value: function() { + this.io.i2cWrite(this.address.rgb, [this.REGISTER.BACKLIGHT_ON, 0xAA]); + return this; + } + }, + bgOff: { + value: function() { + this.io.i2cWrite(this.address.rgb, [this.REGISTER.BACKLIGHT_ON, 0x00]); + return this; + } + }, command: { value: function(mode, value) { if (arguments.length === 1) { @@ -288,7 +310,6 @@ var Controllers = { initialize: { value: function(opts) { - this.io.i2cConfig(opts); this.bitMode = opts.bitMode || 4; this.lines = opts.lines || 2; @@ -316,6 +337,8 @@ var Controllers = { */ } + this.io.i2cConfig(opts); + this.address = { lcd: opts.address }; @@ -365,32 +388,44 @@ var Controllers = { priv.set(this, state); + var toggle = 0x03 << this.REGISTER.SHIFT_LEFT; + // Operations within the following labelled block are init-only, // but _do_ block the process for negligible number of milliseconds. blocking: { // - // Toggle wrte/pulse to reset the LCD component. + // Toggle write/pulse to reset the LCD component. // - this.expander.portWrite(0x03 << this.REGISTER.SHIFT_LEFT); - this.pulse(0x03 << this.REGISTER.SHIFT_LEFT); + this.expander.portWrite(toggle); + this.pulse(toggle); sleep(4); - this.expander.portWrite(0x03 << this.REGISTER.SHIFT_LEFT); - this.pulse(0x03 << this.REGISTER.SHIFT_LEFT); + this.expander.portWrite(toggle); + this.pulse(toggle); sleep(4); - this.expander.portWrite(0x03 << this.REGISTER.SHIFT_LEFT); - this.pulse(0x03 << this.REGISTER.SHIFT_LEFT); + this.expander.portWrite(toggle); + this.pulse(toggle); - this.expander.portWrite(0x02 << this.REGISTER.SHIFT_LEFT); - this.pulse(0x02 << this.REGISTER.SHIFT_LEFT); + toggle = 0x02 << this.REGISTER.SHIFT_LEFT; + + this.expander.portWrite(toggle); + this.pulse(toggle); // Initialize the reset component this.command(this.REGISTER.DIMENSIONS | dimensions); + + // Set display details + this.command(state.display); + + // Now that the initial display is set, + // overwrite with the "entry" bits + state.display = entry; + + this.command(this.REGISTER.ENTRY | state.display); + this.on(); this.clear(); - - this.command(this.REGISTER.ENTRY | entry); this.backlight(); } }, @@ -464,6 +499,26 @@ var Controllers = { this.backlight(0); } }, + on: { + value: function() { + var state = priv.get(this); + + state.display |= this.REGISTER.DISPLAYON; + this.command(this.REGISTER.DISPLAY | state.display); + + return this; + } + }, + off: { + value: function() { + var state = priv.get(this); + + state.display &= ~this.REGISTER.DISPLAYON; + this.command(this.REGISTER.DISPLAY | state.display); + + return this; + } + }, hilo: { value: function(callback) { callback.call(this); @@ -630,11 +685,7 @@ var Controllers = { } }; - // Alias controllers -Controllers.HD44780 = Controllers.JHD1313M1; - - Controllers.LCM1602 = Controllers.LCD1602 = Controllers.LCM1602IIC = Controllers.LCD2004 = Controllers.PCF8574A = Controllers.PCF8574AT = Controllers.PCF8574T = Controllers.PCF8574; Controllers.MJKDZ = Object.assign({}, Controllers.PCF8574, { @@ -699,15 +750,15 @@ function LCD(opts) { this, opts = Board.Options(opts) ); - var controller; + var controller = null; - if (opts.controller) { - controller = typeof opts.controller === "string" ? - Controllers[opts.controller.toUpperCase()] : - opts.controller; + if (opts.controller && typeof opts.controller === "string") { + controller = Controllers[opts.controller.toUpperCase()]; + } else { + controller = opts.controller; } - if (!controller) { + if (controller == null) { controller = Controllers.PARALLEL; } @@ -718,6 +769,14 @@ function LCD(opts) { if (this.initialize) { this.initialize(opts); } + + Object.defineProperties(this, { + characters: { + get: function() { + return Object.assign({}, priv.get(this).characters); + }, + }, + }); } LCD.prototype.command = function(mode, value) { @@ -988,10 +1047,21 @@ LCD.prototype.createChar = function(name, charMap) { LCD.prototype.useChar = function(name) { var state = priv.get(this); - if (!state.characters[name]) { + if (typeof state.characters[name] === "undefined") { // Create the character in LCD memory and + var newCharIndex = this.createChar(name, this.CHARS[name]); + + // If character's index already used, remove this character in current LCD character map + // because it's not in LCD memory anymore. + for (var oldName in state.characters) { + if (name !== oldName && state.characters[oldName] === newCharIndex) { + delete state.characters[oldName]; + break; + } + } + // Add character to current LCD character map - state.characters[name] = this.createChar(name, this.CHARS[name]); + state.characters[name] = newCharIndex; } return this; diff --git a/lib/led/led.js b/lib/led/led.js index c19c5165d..89b07da2a 100644 --- a/lib/led/led.js +++ b/lib/led/led.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("../board"); var Animation = require("../animation"); var Expander = require("../expander"); @@ -139,7 +138,7 @@ function Led(opts) { } var pinValue = typeof opts === "object" ? opts.pin : opts; - var controller; + var controller = null; Board.Component.call( this, opts = Board.Options(opts) @@ -508,7 +507,8 @@ Led.prototype.stop = function() { }; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + Led.Controllers = Controllers; Led.purge = function() { priv.clear(); }; diff --git a/lib/led/ledcontrol.js b/lib/led/ledcontrol.js index 0920aa8e9..ef5c61f4e 100644 --- a/lib/led/ledcontrol.js +++ b/lib/led/ledcontrol.js @@ -32,7 +32,6 @@ OTHER DEALINGS IN THE SOFTWARE. */ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var util = require("util"); var Board = require("../board"); var ledCharacters = require("./led-chars"); @@ -69,7 +68,7 @@ function LedControl(opts) { device instance uses an interface from Controllers: either MAX 7219 (default) or HT16K33 */ - var controller; + var controller = null; if (typeof opts.controller === "string") { controller = Controllers[opts.controller]; @@ -1107,10 +1106,12 @@ LedControl.MATRIX_CHARS = ledCharacters.MATRIX_CHARS; LedControl.DIGIT_CHARS = ledCharacters.DIGIT_CHARS; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + LedControl.Controllers = Controllers; LedControl.purge = function() { addresses = new Set([0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77]); priv.clear(); }; } + module.exports = LedControl; diff --git a/lib/led/leds.js b/lib/led/leds.js index 43b56420e..d753f0fa2 100644 --- a/lib/led/leds.js +++ b/lib/led/leds.js @@ -2,6 +2,7 @@ var Animation = require("../animation"); var Led = require("./led"); var callbacks = require("./callbacks"); var Collection = require("../mixins/collection"); +var util = require("util"); /** * Leds() @@ -24,11 +25,7 @@ function Leds(numsOrObjects) { Collection.call(this, numsOrObjects); } -Leds.prototype = Object.create(Collection.prototype, { - constructor: { - value: Leds - } -}); +util.inherits(Leds, Collection); Collection.installMethodForwarding( Leds.prototype, Led.prototype diff --git a/lib/led/rgb.js b/lib/led/rgb.js index f397adf0e..f7262daa0 100644 --- a/lib/led/rgb.js +++ b/lib/led/rgb.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("../board"); var Animation = require("../animation"); var Expander = require("../expander"); @@ -148,8 +147,7 @@ function RGB(opts) { return new RGB(opts); } - var state; - var controller; + var controller = null; if (Array.isArray(opts)) { // RGB([Byte, Byte, Byte]) shorthand @@ -176,10 +174,9 @@ function RGB(opts) { controller = Controllers.DEFAULT; } - Object.defineProperties(this, controller); // The default color is #ffffff, but the light will be off - state = { + var state = { red: 255, green: 255, blue: 255, @@ -198,6 +195,8 @@ function RGB(opts) { priv.set(this, state); + Board.Controller.call(this, controller, opts); + Object.defineProperties(this, { isOn: { get: function() { @@ -300,7 +299,7 @@ RGB.ToRGB = function(red, green, blue) { } else if (typeof input === "string") { // color("#ffffff") or color("ffffff") - if (input.match(/^#?[0-9A-Fa-f]{6}$/)) { + if (/^#?[0-9A-Fa-f]{6}$/.test(input)) { // remove the leading # if there is one if (input.length === 7 && input[0] === "#") { @@ -312,19 +311,39 @@ RGB.ToRGB = function(red, green, blue) { green: parseInt(input.slice(2, 4), 16), blue: parseInt(input.slice(4, 6), 16) }; - } else if (/^rgb/.test(input)) { - var args = input.match(/^rgba?\(([^)]+)\)$/)[1].split(/[\s,]+/); - update = { - red: parseInt(args[0], 10), - green: parseInt(args[1], 10), - blue: parseInt(args[2], 10) - }; - if (args.length > 3) { - update = RGB.ToScaledRGB(100 * parseFloat(args[3]), update); - } } else { - // color name - return RGB.ToRGB(converter.keyword.rgb(input.toLowerCase())); + // color("rgba(r, g, b, a)") or color("rgb(r, g, b)") + // color("rgba(r g b a)") or color("rgb(r g b)") + if (/^rgb/.test(input)) { + var args = input.match(/^rgba?\(([^)]+)\)$/)[1].split(/[\s,]+/); + + // If the values were %... + if (isPercentString(args[0])) { + args.forEach(function(value, index) { + // Only convert the first 3 values + if (index <= 2) { + args[index] = Math.round((parseInt(value, 10) / 100) * 255); + } + }); + } + + update = { + red: parseInt(args[0], 10), + green: parseInt(args[1], 10), + blue: parseInt(args[2], 10) + }; + + // If rgba(...) + if (args.length > 3) { + if (isPercentString(args[3])) { + args[3] = parseInt(args[3], 10) / 100; + } + update = RGB.ToScaledRGB(100 * parseFloat(args[3]), update); + } + } else { + // color name + return RGB.ToRGB(converter.keyword.rgb(input.toLowerCase())); + } } } } else { @@ -338,6 +357,10 @@ RGB.ToRGB = function(red, green, blue) { return update; }; + +function isPercentString(input) { + return typeof input === "string" && input.endsWith("%"); +} /** * color * @@ -560,11 +583,11 @@ RGB.prototype[Animation.render] = function(frames) { RGB.prototype[Animation.keys] = RGB.colors; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + RGB.Controllers = Controllers; RGB.purge = function() { priv.clear(); }; } - module.exports = RGB; diff --git a/lib/led/rgbs.js b/lib/led/rgbs.js index a060091a1..86512ba5e 100644 --- a/lib/led/rgbs.js +++ b/lib/led/rgbs.js @@ -2,6 +2,7 @@ var Animation = require("../animation"); var callbacks = require("./callbacks"); var Collection = require("../mixins/collection"); var RGB = require("./rgb"); +var util = require("util"); /** * RGBs() @@ -24,11 +25,7 @@ function RGBs(numsOrObjects) { Collection.call(this, numsOrObjects); } -RGBs.prototype = Object.create(Collection.prototype, { - constructor: { - value: RGBs - } -}); +util.inherits(RGBs, Collection); Collection.installMethodForwarding( RGBs.prototype, RGB.prototype diff --git a/lib/light.js b/lib/light.js index bd7bd9cb6..898884d74 100644 --- a/lib/light.js +++ b/lib/light.js @@ -5,21 +5,17 @@ var Fn = require("./fn"); var Emitter = require("events").EventEmitter; var util = require("util"); var priv = new Map(); -var int16 = Fn.int16; +// var int16 = Fn.int16; +var uint16 = Fn.uint16; var toFixed = Fn.toFixed; - -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 = { DEFAULT: { initialize: { - value: analogHandler + value: function(opts, dataHandler) { + this.io.pinMode(this.pin, this.io.MODES.ANALOG); + this.io.analogRead(this.pin, dataHandler); + }, }, toIntensityLevel: { value: function(raw) { @@ -84,97 +80,362 @@ var Controllers = { } } }, + // http://www.adafruit.com/datasheets/TSL2561.pdf TSL2561: { ADDRESSES: { value: [0x29, 0x39, 0x49] }, REGISTER: { value: { - CONTROL: 0x00, TIMING: 0x01, - READ: 0x8C, - } + READ: 0x2C, + }, }, + initialize: { value: function(opts, dataHandler) { var address = opts.address || 0x39; - // var read = (address & 0x0F) | 0x80; - var gain = opts.gain || 0; - var time = opts.time || 0; - - var iMs = [13.7, 101, 402][time]; - - // Default value of timing register - // http://www.adafruit.com/datasheets/TSL2561.pdf - // Page 15 - var timing = 0x02; - - // gain [ 0 => 1X, 1 => 16X] - if (gain) { - timing |= 0x10; - } else { - timing &= ~0x10; - } - - // time [ 0 => 13.7, 1 => 101, 2 => 402 ] ms - timing &= ~0x03; - timing |= (time & 0x03); + var command = function(byte) { + // byte | 0b10000000; + return byte | 0x80; + }; opts.address = address; - this.io.i2cConfig(); - - // Write the "power on" byte to the control register - this.io.i2cWriteReg(address, this.REGISTER.CONTROL, 0x03); - - // Configure the timing and gain - this.io.i2cWriteReg(address, this.REGISTER.TIMING, timing); - - this.io.i2cRead(address, this.REGISTER.READ, 4, function(data) { - var ch0 = int16(data[1], data[0]); - var ch1 = int16(data[3], data[2]); - var value = 0; - var ratio = 0; + this.io.i2cConfig(opts); - // http://www.adafruit.com/datasheets/TSL2561.pdf - // Page 23 - if (ch0 === 0xFFFF || ch1 === 0xFFFF) { - value = 0; - } else { + // Page 15 + // Control Register (0h) + // RESV 7:2 + // POWER 1:0 + // + // Power up/power down. + // By writing a 03h to this register, the device is powered up. + // By writing a 00h to this register, the device is powered down. + // + // 0b00000011 = 0x03 + // 0b00000000 = 0x00 + this.io.i2cWriteReg(address, command(this.REGISTER.CONTROL), 0x03); + + // Gain & Integration + // var isAutoGain = false; + + // Page 24 + // Integration time scaling factors + var LUX_SCALE = 14; // scale by (2 ** 14) + var RATIO_SCALE = 9; // scale ratio by (2 ** 9) + + // Page 24 + // T, FN, and CL Package coefficients + var K1T = 0x0040; // 0.125 * (2 ** RATIO_SCALE) + var B1T = 0x01F2; // 0.0304 * (2 ** LUX_SCALE) + var M1T = 0x01BE; // 0.0272 * (2 ** LUX_SCALE) + var K2T = 0x0080; // 0.250 * (2 ** RATIO_SCALE) + var B2T = 0x0214; // 0.0325 * (2 ** LUX_SCALE) + var M2T = 0x02D1; // 0.0440 * (2 ** LUX_SCALE) + var K3T = 0x00C0; // 0.375 * (2 ** RATIO_SCALE) + var B3T = 0x023F; // 0.0351 * (2 ** LUX_SCALE) + var M3T = 0x037B; // 0.0544 * (2 ** LUX_SCALE) + var K4T = 0x0100; // 0.50 * (2 ** RATIO_SCALE) + var B4T = 0x0270; // 0.0381 * (2 ** LUX_SCALE) + var M4T = 0x03FE; // 0.0624 * (2 ** LUX_SCALE) + var K5T = 0x0138; // 0.61 * (2 ** RATIO_SCALE) + var B5T = 0x016F; // 0.0224 * (2 ** LUX_SCALE) + var M5T = 0x01FC; // 0.0310 * (2 ** LUX_SCALE) + var K6T = 0x019A; // 0.80 * (2 ** RATIO_SCALE) + var B6T = 0x00D2; // 0.0128 * (2 ** LUX_SCALE) + var M6T = 0x00FB; // 0.0153 * (2 ** LUX_SCALE) + var K7T = 0x029A; // 1.3 * (2 ** RATIO_SCALE) + var B7T = 0x0018; // 0.00146 * (2 ** LUX_SCALE) + var M7T = 0x0012; // 0.00112 * (2 ** LUX_SCALE) + var K8T = 0x029A; // 1.3 * (2 ** RATIO_SCALE) + var B8T = 0x0000; // 0.000 * (2 ** LUX_SCALE) + var M8T = 0x0000; // 0.000 * (2 ** LUX_SCALE) + + // Auto-gain thresholds + // Max value at Ti 13ms = 5047 + // var AGT_LO_13MS = 100; + // var AGT_HI_13MS = 4850; + + // // Max value at Ti 101ms = 37177 + // var AGT_LO_101MS = 200; + // var AGT_HI_101MS = 36000; + + // // Max value at Ti 402ms = 65535 + // var AGT_LO_402MS = 500; + // var AGT_HI_402MS = 63000; + + // var agtRanges = [ + // // 0, TI_13MS + // [100, 4850], + // // 1, TI_101MS + // [200, 36000], + // // 2, TI_402MS + // [500, 63000], + // ]; + + // var CLIPPING_13MS = 4900; + // var CLIPPING_101MS = 37000; + // var CLIPPING_402MS = 65000; + + // var clipping = [ + // // 0, TI_13MS + // 4900, + // // 1, TI_101MS + // 37000, + // // 2, TI_402MS + // 65000, + // ]; + + + var GAIN_1X = 0x00; + var GAIN_16X = 0x10; + + // var TI_13MS = 0x00; + // var TI_101MS = 0x01; + // var TI_402MS = 0x02; + + var TintMs = [ + // 0, TI_13MS + 13, + // 1, TI_101MS + 101, + // 2, TI_402MS + 402, + ]; + + var TintDelayMs = [ + // 0, TI_13MS + 15, + // 1, TI_101MS + 120, + // 2, TI_402MS + 450, + ]; + + // Page 23 - 28 + // Simplified Lux Calculation + // var CH_SCALE_D = 0x0010; + // var CH_SCALE_0 = 0x7517; + // var CH_SCALE_1 = 0x0FE7; + + var chScales = [ + // 0, TI_13MS + 0x07517, + // 1, TI_101MS + 0x00FE7, + // 2, TI_402MS + 0x10000, + ]; + + // Gain and Tint defaults; + var gain = GAIN_1X; + var TintIndex = 2; + var Tint = TintMs[TintIndex]; + var lux = 0; + + // if (typeof opts.gain !== "undefined") { + // isAutoGain = false; + // gain = opts.gain; + // } + + // if (typeof opts.integration !== "undefined") { + // isAutoGain = false; + // Tint = opts.integration; + // } + + + // TODO: reduce duplication here + Object.defineProperties(this, { + gain: { + get: function() { + return gain; + }, + set: function(value) { + if (value !== GAIN_1X && value !== GAIN_16X) { + throw new RangeError("Invalid gain. Expected one of: 0, 16"); + } + gain = value; + + this.io.i2cWriteReg(address, command(this.REGISTER.TIMING), TintIndex | gain); + } + }, + integration: { + get: function() { + return Tint; + }, + set: function(value) { + TintIndex = TintMs.indexOf(value); - ratio = ch1 / ch0; + if (TintIndex === -1) { + throw new RangeError("Invalid integration. Expected one of: 13, 101, 402"); + } - ch0 *= 402 / iMs; - ch1 *= 402 / iMs; + Tint = value; - if (!gain) { - ch0 *= 16; - ch1 *= 16; + this.io.i2cWriteReg(address, command(this.REGISTER.TIMING), TintIndex | gain); } - - if (ratio < 0.5) { - value = 0.0304 * ch0 - 0.062 * ch0 * Math.pow(ratio, 1.4); - } else if (ratio < 0.61) { - value = 0.0224 * ch0 - 0.031 * ch1; - } else if (ratio < 0.80) { - value = 0.0128 * ch0 - 0.0153 * ch1; - } else if (ratio < 1.30) { - value = 0.00146 * ch0 - 0.00112 * ch1; - } else { - value = 0; + }, + lux: { + get: function() { + return lux; } } - - dataHandler(value); }); + + // Assign the default gain and integration values + // These are validated and written to the device. + // These will invoke the accessors above. + this.gain = gain; + this.integration = Tint; + + // Page 1 + // Description + // Page 2 + // Functional Block Diagram + // var data = { + // broadband: null, + // infrared: null, + // }; + + var read = function() { + setTimeout(function() { + // Page 19 + // Read ADC Channels Using Read Word Protocol − RECOMMENDED + this.io.i2cReadOnce(address, command(this.REGISTER.READ), 4, function(data) { + // Page 23 - 28 + // Simplified Lux Calculation + var ch0 = uint16(data[1], data[0]); + var ch1 = uint16(data[3], data[2]); + var b = 0; + var m = 0; + + // Page 26 + // CalculateLux(...) + var scale = chScales[TintIndex]; + + + if (!gain) { + scale = scale << 4; + } + + // Page 27 + // CalculateLux(...) + ch0 = (ch0 * scale) >> 10; + ch1 = (ch1 * scale) >> 10; + + var ratio1 = 0; + + if (ch0) { + ratio1 = (ch1 << (RATIO_SCALE + 1)) / ch0; + } + + ratio1 = Math.round(ratio1); + + var ratio = (ratio1 + 1) >> 1; + + if (ratio >= 0 && ratio <= K1T) { + b = B1T; + m = M1T; + } else if (ratio <= K2T) { + b = B2T; + m = M2T; + } else if (ratio <= K3T) { + b = B3T; + m = M3T; + } else if (ratio <= K4T) { + b = B4T; + m = M4T; + } else if (ratio <= K5T) { + b = B5T; + m = M5T; + } else if (ratio <= K6T) { + b = B6T; + m = M6T; + } else if (ratio <= K7T) { + b = B7T; + m = M7T; + } else if (ratio > K8T) { + b = B8T; + m = M8T; + } + // I followed the datasheet and it had no else clause here. + + var temp = (ch0 * b) - (ch1 * m); + + if (temp < 0) { + temp = 0; + } + + temp += 1 << (LUX_SCALE - 1); + + // Updating the `lux` binding + // in the outer scope. + lux = temp >>> LUX_SCALE; + + dataHandler(lux); + read(); + }); + }.bind(this), TintDelayMs[TintIndex]); + }.bind(this); + + read(); } }, + toLux: { + value: function(raw) { + return raw; + }, + }, toIntensityLevel: { value: function(raw) { - return toFixed(Fn.scale(raw, 0.1, 40000, 0, 100) / 100, 2); - } - } + return toFixed(Fn.scale(raw, 0, 17000, 0, 100) / 100, 2); + }, + }, + }, + BH1750: { + // http://cpre.kmutnb.ac.th/esl/learning/bh1750-light-sensor/bh1750fvi-e_datasheet.pdf + // https://www.mysensors.org/dl/57cc6e4595afb8801e529dab/design/bh1750fvi-e.pdf + // + // code based on Arduino library https://github.com/claws/BH1750 + // currently only "continuous H-resolution" mode supported + ADDRESSES: { + value: [0x23, 0x5C] + }, + initialize: { + value: function(opts, dataHandler) { + var address = opts.address || 0x23; + var mode = opts.mode || 0x10; + opts.address = address; + this.io.i2cConfig(opts); + this.io.i2cWrite(address, mode); + var read = function() { + setTimeout(function() { + this.io.i2cReadOnce(address, 2, function(data) { + var raw = data[0]; + raw <<= 8; + raw |= data[1]; + dataHandler(raw); + read(); + }); + }.bind(this), 120); + }.bind(this); + read(); + }, + }, + toLux: { + value: function(raw) { + // Page 2. + // H-Resolution Mode Resolution rHR - 1 - lx + return Math.round(raw / 1.2); + }, + }, + toIntensityLevel: { + value: function(raw) { + return toFixed(Fn.scale(raw / 1.2, 0, 65535, 0, 100) / 100, 2); + }, + }, }, }; @@ -217,44 +478,55 @@ function Light(opts) { }; } - priv.set(this, state); + if (!this.toLux) { + this.toLux = opts.toLux || function(x) { + return x; + }; + } Object.defineProperties(this, { value: { get: function() { return raw; - } + }, }, level: { get: function() { return this.toIntensityLevel(raw); - } + }, }, - // TODO: - // - // lux? - // }); + priv.set(this, state); + + /* istanbul ignore else */ if (typeof this.initialize === "function") { this.initialize(opts, function(data) { raw = data; }); } - setInterval(function() { - if (raw === undefined) { - return; - } + if (typeof this.lux === "undefined") { + Object.defineProperty(this, "lux", { + get: function() { + return this.toLux(raw); + }, + }); + } - var data = { - level: this.level - }; + var data = { + level: 0, + lux: 0, + }; + + setInterval(function() { + data.level = this.level; + data.lux = this.lux; this.emit("data", data); - if (this.level !== last) { - last = this.level; + if (raw !== last) { + last = raw; this.emit("change", data); } }.bind(this), freq); @@ -264,4 +536,14 @@ util.inherits(Light, Emitter); Object.assign(Light.prototype, within); + +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Light.Controllers = Controllers; + Light.purge = function() { + priv.clear(); + }; +} + module.exports = Light; + diff --git a/lib/mixins/collection.js b/lib/mixins/collection.js index 40a153bb8..e6b937520 100644 --- a/lib/mixins/collection.js +++ b/lib/mixins/collection.js @@ -1,5 +1,6 @@ var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Emitter = require("events").EventEmitter; +var util = require("util"); var priv = new Map(); /** @@ -225,11 +226,7 @@ Collection.Emitter = function(numsOrObjects) { }); }; -Collection.Emitter.prototype = Object.create(Collection.prototype, { - constructor: { - value: Collection.Emitter - } -}); +util.inherits(Collection.Emitter, Collection); Object.assign(Collection.Emitter.prototype, Emitter.prototype); diff --git a/lib/motion.js b/lib/motion.js index f214dd837..9c9aae80f 100644 --- a/lib/motion.js +++ b/lib/motion.js @@ -17,6 +17,7 @@ function analogInitializer(opts, dataHandler) { this.io.analogRead(opts.pin, dataHandler); } + var Controllers = { PIR: { initialize: { @@ -239,15 +240,19 @@ Motion.Collection = function(numsOrObjects) { Collection.Emitter.call(this, numsOrObjects); }; -Motion.Collection.prototype = Object.create(Collection.Emitter.prototype, { - constructor: { - value: Motion.Collection - } -}); +util.inherits(Motion.Collection, Collection.Emitter); Collection.installMethodForwarding( Motion.Collection.prototype, Motion.prototype ); +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Motion.Controllers = Controllers; + Motion.purge = function() { + priv.clear(); + }; +} + module.exports = Motion; diff --git a/lib/motor.js b/lib/motor.js index dfe833dcc..902fb0490 100644 --- a/lib/motor.js +++ b/lib/motor.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Expander = require("./expander.js"); var EVS = require("./evshield"); @@ -1104,11 +1103,7 @@ function Motors(numsOrObjects) { Collection.call(this, numsOrObjects); } -Motors.prototype = Object.create(Collection.prototype, { - constructor: { - value: Motors - } -}); +util.inherits(Motors, Collection); /* @@ -1148,7 +1143,8 @@ Motor.Array = Motors; Motor.Collection = Motors; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + Motor.Controllers = Controllers; Motor.purge = function() { priv.clear(); registers.clear(); diff --git a/lib/orientation.js b/lib/orientation.js index b59cbb652..f6bab0beb 100644 --- a/lib/orientation.js +++ b/lib/orientation.js @@ -199,7 +199,6 @@ Object.defineProperties(Orientation.prototype, { return this.toScaledQuarternion(state); } } - }); diff --git a/lib/piezo.js b/lib/piezo.js index 6f0e29e31..9e681be75 100644 --- a/lib/piezo.js +++ b/lib/piezo.js @@ -136,7 +136,7 @@ function Piezo(opts) { this, opts = Board.Options(opts) ); - var controller; + var controller = null; if (opts.controller && typeof opts.controller === "string") { controller = Controllers[opts.controller.toUpperCase()]; diff --git a/lib/pin.js b/lib/pin.js index 4179f56a8..0fade6c7f 100644 --- a/lib/pin.js +++ b/lib/pin.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Emitter = require("events").EventEmitter; var util = require("util"); @@ -326,12 +325,7 @@ function Pins(numsOrObjects) { Collection.call(this, numsOrObjects); } -Pins.prototype = Object.create(Collection.prototype, { - constructor: { - value: Pins - } -}); - +util.inherits(Pins, Collection); [ "high", "low", "write" @@ -353,7 +347,7 @@ Pin.Array = Pins; Pin.Collection = Pins; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { Pin.purge = function() { priv.clear(); }; diff --git a/lib/pir.js b/lib/pir.js deleted file mode 100644 index 839e112b1..000000000 --- a/lib/pir.js +++ /dev/null @@ -1,73 +0,0 @@ -var Board = require("./board"), - events = require("events"), - util = require("util"); - -/** - * Pir, IR.Motion - * @deprecated - * @param {Object} opts Options: pin, type, id, range - */ - -function Pir(opts) { - - if (!(this instanceof Pir)) { - return new Pir(opts); - } - - Board.Component.call( - this, opts = Board.Options(opts) - ); - - // Set the pin to INPUT mode - this.mode = this.io.MODES.INPUT; - this.io.pinMode(this.pin, this.mode); - - // PIR instance properties - this.value = null; - this.isCalibrated = false; - this.freq = opts.freq || 25; - - // Analog Read event loop - // TODO: make this "throttle-able" - this.io.digitalRead(this.pin, function(data) { - var timestamp = Date.now(); - - // If this is not a calibration event - if (this.value != null && this.value !== +data) { - - // Update current value of PIR instance - this.value = +data; - - // "motionstart" event fired when motion occurs - // within the observable range of the PIR sensor - if (data) { - this.emit("motionstart", timestamp); - } - - // "motionend" event fired when motion has ceased - // within the observable range of the PIR sensor - if (!data) { - this.emit("motionend", timestamp); - } - } - - // "calibrated" event fired when PIR sensor is - // ready to detect movement/motion in observable range - if (!this.isCalibrated) { - this.isCalibrated = true; - this.value = +data; - this.emit("calibrated", timestamp); - } - }.bind(this)); - - setInterval(function() { - this.emit("data", Date.now()); - }.bind(this), this.freq); -} - -util.inherits(Pir, events.EventEmitter); - -module.exports = Pir; - -// More information: -// http://www.ladyada.net/learn/sensors/pir.html diff --git a/lib/proximity.js b/lib/proximity.js index 67f0b995e..7c0a356cb 100644 --- a/lib/proximity.js +++ b/lib/proximity.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Collection = require("./mixins/collection"); var EVS = require("./evshield"); @@ -172,6 +171,7 @@ var Controllers = { initialize: { value: function(opts, dataHandler) { var pinValue = opts.pinValue; + var msToNextRead = 65; if (Pins.isFirmata(this)) { if (typeof pinValue === "string" && pinValue[0] === "A") { @@ -197,7 +197,7 @@ var Controllers = { var read = function() { this.io.pingRead(settings, function(microseconds) { dataHandler(microseconds); - setTimeout(read, 65); + setTimeout(read, msToNextRead); }); }.bind(this); @@ -529,22 +529,18 @@ Proximity.Collection = function(numsOrObjects) { Collection.Emitter.call(this, numsOrObjects); }; -Proximity.Collection.prototype = Object.create(Collection.Emitter.prototype, { - constructor: { - value: Proximity.Collection - } -}); +util.inherits(Proximity.Collection, Collection.Emitter); Collection.installMethodForwarding( Proximity.Collection.prototype, Proximity.prototype ); /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + Proximity.Controllers = Controllers; Proximity.purge = function() { priv.clear(); }; } - module.exports = Proximity; diff --git a/lib/relay.js b/lib/relay.js index ff8fd6c99..2e257af7a 100644 --- a/lib/relay.js +++ b/lib/relay.js @@ -1,6 +1,6 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Collection = require("./mixins/collection"); +var util = require("util"); var priv = new Map(); function Relay(opts) { @@ -98,7 +98,7 @@ Relay.prototype.toggle = function() { * Relays() * new Relays() * - * Constructs an Array-like instance of all servos + * Constructs an Array-like instance of all relays */ function Relays(numsOrObjects) { if (!(this instanceof Relays)) { @@ -112,12 +112,7 @@ function Relays(numsOrObjects) { Collection.call(this, numsOrObjects); } -Relays.prototype = Object.create(Collection.prototype, { - constructor: { - value: Relays - } -}); - +util.inherits(Relays, Collection); /* * Relays, on() @@ -165,7 +160,7 @@ Relay.Array = Relays; Relay.Collection = Relays; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { Relay.purge = function() { priv.clear(); }; diff --git a/lib/repl.js b/lib/repl.js index 0df1d5418..6b414a0cb 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -1,6 +1,6 @@ -var repl = require("repl"), - events = require("events"), - util = require("util"); +var Emitter = require("events").EventEmitter; +var repl = require("repl"); +var util = require("util"); var priv = new Map(); @@ -41,7 +41,7 @@ function Repl(opts) { } // Inherit event api -util.inherits(Repl, events.EventEmitter); +util.inherits(Repl, Emitter); Repl.isActive = false; Repl.isBlocked = false; @@ -81,11 +81,19 @@ Repl.prototype.initialize = function(callback) { cmd.on("exit", function() { state.board.emit("exit"); state.board.warn("Board", "Closing."); - process.nextTick(process.reallyExit); + + var interval = setInterval(function() { + /* istanbul ignore else */ + if (!state.board.io.pending) { + clearInterval(interval); + process.nextTick(process.reallyExit); + } + }, 1); }); this.inject(state.opts); + /* istanbul ignore else */ if (callback) { process.nextTick(callback); } diff --git a/lib/sensor.js b/lib/sensor.js index c40b898a5..6af9bc8a0 100644 --- a/lib/sensor.js +++ b/lib/sensor.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Fn = require("./fn"); var events = require("events"); @@ -54,6 +53,8 @@ function Sensor(opts) { return new Sensor(opts); } + // Defaults to 10-bit resolution + var resolution = 0x3FF; var raw = null; var last = -1; var samples = []; @@ -66,6 +67,12 @@ function Sensor(opts) { opts.type = "analog"; } + if (this.io.RESOLUTION && + (this.io.RESOLUTION.ADC && + (this.io.RESOLUTION.ADC !== resolution))) { + resolution = this.io.RESOLUTION.ADC; + } + // Set the pin to ANALOG (INPUT) mode this.mode = opts.type === "digital" ? this.io.MODES.INPUT : @@ -89,7 +96,7 @@ function Sensor(opts) { priv.set(this, state); // Sensor instance properties - this.range = opts.range || [0, 1023]; + this.range = opts.range || [0, resolution]; this.limit = opts.limit || null; this.threshold = opts.threshold === undefined ? 1 : opts.threshold; this.isScaled = false; @@ -117,6 +124,7 @@ function Sensor(opts) { if (opts.type === "digital") { this.emit("data", raw); + /* istanbul ignore else */ if (last !== raw) { this.emit("change", raw); last = raw; @@ -176,8 +184,8 @@ function Sensor(opts) { } return raw === null ? 0 : - Fn.map(this.raw, 0, 1023, 0, 255) | 0; - } + Fn.map(this.raw, 0, resolution, 0, 255) | 0; + }, }, constrained: { get: function() { @@ -193,7 +201,7 @@ function Sensor(opts) { get: function() { var state = priv.get(this); var booleanBarrier = state.booleanBarrier; - var scale = state.scale || [0, 1023]; + var scale = state.scale || [0, resolution]; if (booleanBarrier === null) { booleanBarrier = scale[0] + (scale[1] - scale[0]) / 2; @@ -247,10 +255,16 @@ function Sensor(opts) { return raw; } + }, + resolution: { + get: function() { + return resolution; + } } }); - if (IS_TEST_MODE) { + /* istanbul ignore else */ + if (!!process.env.IS_TEST_MODE) { Object.defineProperties(this, { state: { get: function() { @@ -296,6 +310,7 @@ Object.assign(Sensor.prototype, within); Sensor.prototype.enable = function() { var state = priv.get(this); + /* istanbul ignore else */ if (!state.enabled) { this.freq = state.freq || state.previousFreq; } @@ -312,6 +327,7 @@ Sensor.prototype.enable = function() { Sensor.prototype.disable = function() { var state = priv.get(this); + /* istanbul ignore else */ if (state.enabled) { state.enabled = false; state.previousFreq = state.freq; @@ -341,14 +357,30 @@ Sensor.prototype.scale = function(low, high) { return this; }; +/** + * scaleTo Scales value to integer representation + * @param {Number} low An array containing a lower and upper bound + * + * @param {Number} low A number to use as a lower bound + * @param {Number} high A number to use as an upper bound + * @return {Number} The scaled value + */ Sensor.prototype.scaleTo = function(low, high) { var scale = Array.isArray(low) ? low : [low, high]; - return Fn.map(this.raw, 0, 1023, scale[0], scale[1]); + return Fn.map(this.raw, 0, this.resolution, scale[0], scale[1]); }; +/** + * fscaleTo Scales value to single precision float representation + * @param {Number} low An array containing a lower and upper bound + * + * @param {Number} low A number to use as a lower bound + * @param {Number} high A number to use as an upper bound + * @return {Number} The scaled value + */ Sensor.prototype.fscaleTo = function(low, high) { var scale = Array.isArray(low) ? low : [low, high]; - return Fn.fmap(this.raw, 0, 1023, scale[0], scale[1]); + return Fn.fmap(this.raw, 0, this.resolution, scale[0], scale[1]); }; /** @@ -359,7 +391,6 @@ Sensor.prototype.fscaleTo = function(low, high) { * @return {Object} instance * */ - Sensor.prototype.booleanAt = function(barrier) { priv.get(this).booleanBarrier = barrier; return this; @@ -385,11 +416,7 @@ function Sensors(numsOrObjects) { Collection.Emitter.call(this, numsOrObjects); } -Sensors.prototype = Object.create(Collection.Emitter.prototype, { - constructor: { - value: Sensors - } -}); +util.inherits(Sensors, Collection.Emitter); Collection.installMethodForwarding( @@ -400,7 +427,7 @@ Collection.installMethodForwarding( Sensor.Collection = Sensors; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { Sensor.purge = function() { priv.clear(); }; diff --git a/lib/servo.js b/lib/servo.js index 21b036a01..a10a8d2b9 100644 --- a/lib/servo.js +++ b/lib/servo.js @@ -1,4 +1,3 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Pins = Board.Pins; var Expander = require("./expander"); @@ -32,11 +31,11 @@ var Controllers = { this.pin = state.expander.normalize(opts.pin); } }, - servoWrite: { + update: { writable: true, - value: function(pin, degrees) { + value: function(degrees) { var state = priv.get(this); - state.expander.servoWrite(pin, degrees); + state.expander.servoWrite(this.pin, degrees); } } }, @@ -60,8 +59,9 @@ var Controllers = { } } }, - servoWrite: { - value: function(pin, degrees) { + update: { + writable: true, + value: function(degrees) { // Servo is restricted to integers degrees |= 0; @@ -84,15 +84,14 @@ var Controllers = { */ function Servo(opts) { - var history = []; - var pinValue; - var controller; if (!(this instanceof Servo)) { return new Servo(opts); } - pinValue = typeof opts === "object" ? opts.pin : opts; + var history = []; + var pinValue = typeof opts === "object" ? opts.pin : opts; + var controller = null; Board.Component.call( this, opts = Board.Options(opts) @@ -140,11 +139,6 @@ function Servo(opts) { } this.invert = opts.isInverted || opts.invert || false; - // Specification config - this.specs = opts.specs || { - speed: Servo.Continuous.speeds["@5.0V"] - }; - // Allow "setup"instructions to come from // constructor options properties this.startAt = 90; @@ -157,18 +151,23 @@ function Servo(opts) { // } // ]; + if (opts.controller && typeof opts.controller === "string") { + controller = Controllers[opts.controller.toUpperCase()]; + } else { + controller = opts.controller; + } + + if (controller == null) { + controller = Controllers.Standard; + } + priv.set(this, { history: history }); + Board.Controller.call(this, controller, opts); - /** - * Used for adding special controllers (i.e. PCA9685) - **/ - controller = typeof opts.controller === "string" ? - Controllers[opts.controller] : Controllers.Standard; - - Object.defineProperties(this, Object.assign({}, controller, { + Object.defineProperties(this, { history: { get: function() { return history.slice(-5); @@ -184,19 +183,15 @@ function Servo(opts) { return history.length ? history[history.length - 1].degrees : -1; } } - })); + }); this.initialize(opts); - // If "startAt" is defined and center is falsy // set servo to min or max degrees if (opts.startAt !== undefined) { this.startAt = opts.startAt; - - if (!opts.center) { - this.to(opts.startAt); - } + this.to(opts.startAt); } // If "center" true set servo to 90deg @@ -207,7 +202,6 @@ function Servo(opts) { if (opts.type === "continuous") { this.stop(); } - } util.inherits(Servo, Emitter); @@ -231,24 +225,33 @@ util.inherits(Servo, Emitter); Servo.prototype.to = function(degrees, time, rate) { - var options = {}; var state = priv.get(this); + var options = {}; if (typeof degrees === "object") { - options = { - duration: degrees.duration || degrees.interval || 1000, - cuePoints: [0, 1.0], - keyFrames: [null, { - degrees: typeof degrees.degrees === "number" ? degrees.degrees : this.startAt - }], - oncomplete: function() { - process.nextTick(this.emit.bind(this, "move:complete")); - }.bind(this) - }; - Object.assign(options, degrees); + options.duration = degrees.duration || degrees.interval || 1000; + options.cuePoints = degrees.cuePoints || [0, 1.0]; + options.keyFrames = degrees.keyFrames || [ + null, + { + value: typeof degrees.degrees === "number" ? degrees.degrees : this.startAt + } + ]; + + options.oncomplete = function() { + // Enforce async execution for user "oncomplete" + process.nextTick(function() { + if (typeof degrees.oncomplete === "function") { + degrees.oncomplete(); + } + this.emit("move:complete"); + }.bind(this)); + }.bind(this); + + state.isRunning = true; state.animation = state.animation || new Animation(this); state.animation.enqueue(options); @@ -273,18 +276,16 @@ Servo.prototype.to = function(degrees, time, rate) { if (typeof time !== "undefined") { - options = { - duration: time, - keyFrames: [null, { - degrees: degrees - }], - fps: rate || this.fps - }; + options.duration = time; + options.keyFrames = [null, { + degrees: degrees + }]; + options.fps = rate || this.fps; this.to(options); } else { - this.servoWrite(this.pin, degrees); + this.update(degrees); if (state.history.length > 5) { state.history.shift(); @@ -319,20 +320,34 @@ Servo.prototype[Animation.normalize] = function(keyFrames) { value: last }; } + return keyFrames.map(function(frame) { + var value = frame; + + /* istanbul ignore else */ + if (frame !== null) { + // frames that are just numbers represent _step_ + if (typeof frame === "number") { + frame = { + step: value, + }; + } else { + if (typeof frame.degrees === "number") { + frame.value = frame.degrees; + delete frame.degrees; + } + if (typeof frame.copyDegrees === "number") { + frame.copyValue = frame.copyDegrees; + delete frame.copyDegrees; + } + } - // There are a couple of properties that are device type sepcific - // that we need to convert to something generic - keyFrames.forEach(function(keyFrame) { - if (typeof keyFrame.degrees !== "undefined") { - keyFrame.value = keyFrame.degrees; - } - if (typeof keyFrame.copyDegrees !== "undefined") { - keyFrame.copyValue = keyFrame.copyDegrees; + /* istanbul ignore else */ + if (!frame.easing) { + frame.easing = "linear"; + } } + return frame; }); - - return keyFrames; - }; /** @@ -340,7 +355,6 @@ Servo.prototype[Animation.normalize] = function(keyFrames) { * * @position [number] value to set the servo to */ - Servo.prototype[Animation.render] = function(position) { return this.to(position[0]); }; @@ -419,9 +433,9 @@ Servo.prototype.sweep = function(opts) { var options = { keyFrames: [{ - degrees: this.range[0] + value: this.range[0] }, { - degrees: this.range[1] + value: this.range[1] }], metronomic: true, loop: true, @@ -434,6 +448,7 @@ Servo.prototype.sweep = function(opts) { } else { if (typeof opts === "object" && opts !== null) { Object.assign(options, opts); + /* istanbul ignore else */ if (Array.isArray(options.range)) { options.keyFrames = rangeToKeyFrames(options.range); } @@ -444,8 +459,8 @@ Servo.prototype.sweep = function(opts) { }; function rangeToKeyFrames(range) { - return range.map(function(degrees) { - return { degrees: degrees }; + return range.map(function(value) { + return { value: value }; }); } @@ -478,6 +493,7 @@ Servo.prototype.stop = function() { Servo.prototype[api] = function(rate) { var range; rate = rate === undefined ? 1 : rate; + /* istanbul ignore if */ if (this.type !== "continuous") { this.board.error( "Servo", @@ -537,12 +553,7 @@ function Servos(numsOrObjects) { Collection.call(this, numsOrObjects); } -Servos.prototype = Object.create(Collection.prototype, { - constructor: { - value: Servos - } -}); - +util.inherits(Servos, Collection); /* * Servos, center() @@ -582,11 +593,8 @@ Collection.installMethodForwarding( * * @param [number || object] keyFrames An array of step values or a keyFrame objects */ - Servos.prototype[Animation.normalize] = function(keyFrameSet) { - - keyFrameSet.forEach(function(keyFrames, index) { - + return keyFrameSet.map(function(keyFrames, index) { if (keyFrames !== null) { var servo = this[index]; @@ -612,21 +620,10 @@ Servos.prototype[Animation.normalize] = function(keyFrameSet) { } } - keyFrames.forEach(function(keyFrame) { - if (keyFrame != null && typeof keyFrame.degrees !== "undefined") { - keyFrame.value = keyFrame.degrees; - } - if (keyFrame != null && typeof keyFrame.copyDegrees !== "undefined") { - keyFrame.copyValue = keyFrame.copyDegrees; - } - }); - + return this[index][Animation.normalize](keyFrames); } - + return keyFrames; }, this); - - return keyFrameSet; - }; /** @@ -634,12 +631,10 @@ Servos.prototype[Animation.normalize] = function(keyFrameSet) { * * @position [number] array of values to set the servos to */ - Servos.prototype[Animation.render] = function(position) { - this.each(function(servo, i) { + return this.each(function(servo, i) { servo.to(position[i]); }); - return this; }; @@ -653,7 +648,8 @@ Servo.Collection = Servos; Servo.prototype.write = Servo.prototype.move; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { + Servo.Controllers = Controllers; Servo.purge = function() { priv.clear(); }; diff --git a/lib/shiftregister.js b/lib/shiftregister.js index 486889071..18f4723f0 100644 --- a/lib/shiftregister.js +++ b/lib/shiftregister.js @@ -1,7 +1,6 @@ -var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Collection = require("./mixins/collection"); - +var util = require("util"); var priv = new Map(); function ShiftRegister(opts) { @@ -186,11 +185,7 @@ function ShiftRegisters(numsOrObjects) { Collection.call(this, numsOrObjects); } -ShiftRegisters.prototype = Object.create(Collection.prototype, { - constructor: { - value: ShiftRegisters - } -}); +util.inherits(ShiftRegisters, Collection); /* @@ -219,7 +214,7 @@ Collection.installMethodForwarding( ShiftRegister.Collection = ShiftRegisters; /* istanbul ignore else */ -if (IS_TEST_MODE) { +if (!!process.env.IS_TEST_MODE) { ShiftRegister.purge = function() { priv.clear(); }; diff --git a/lib/switch.js b/lib/switch.js index f40232000..20616fa45 100644 --- a/lib/switch.js +++ b/lib/switch.js @@ -161,11 +161,7 @@ function Switches(numsOrObjects) { Collection.Emitter.call(this, numsOrObjects); } -Switches.prototype = Object.create(Collection.Emitter.prototype, { - constructor: { - value: Switches - } -}); +util.inherits(Switches, Collection.Emitter); Collection.installMethodForwarding( Switches.prototype, Switch.prototype diff --git a/lib/thermometer.js b/lib/thermometer.js index 3be34eb27..ce1d31d90 100644 --- a/lib/thermometer.js +++ b/lib/thermometer.js @@ -308,7 +308,7 @@ var Controllers = { // VOUT = 250 mV at 25°C // VOUT = –550 mV at –55°C - var mV = this.aref * 1000 * raw / 1024; + var mV = this.aref * 1000 * raw / 1023; // 10mV = 1°C // @@ -327,7 +327,7 @@ var Controllers = { value: function(raw) { // OUTPUT 10mV/°K - var mV = this.aref * 1000 * raw / 1024; + var mV = this.aref * 1000 * raw / 1023; // Page 1 return Math.round((mV / 10) - CELSIUS_TO_KELVIN); @@ -343,7 +343,7 @@ var Controllers = { toCelsius: { value: function(raw) { // Analog Reference Voltage - var mV = this.aref * 1000 * raw / 1024; + var mV = this.aref * 1000 * raw / 1023; // tempC = (mV / 10) - 50 // http://ctms.engin.umich.edu/CTMS/Content/Activities/TMP35_36_37.pdf @@ -553,13 +553,37 @@ var Controllers = { } } }, + // http://www.phanderson.com/arduino/I2CCommunications.pdf + // http://cdn.sparkfun.com/datasheets/Prototyping/1443945.pdf + HIH6130: { + initialize: { + value: function(opts, dataHandler) { + var Multi = require("./imu"); + var driver = Multi.Drivers.get(this.board, "HIH6130", opts); + driver.on("data", function(data) { + dataHandler(data.temperature); + }); + } + }, + toCelsius: { + value: function(raw) { + // Page 3 + // 5.0 Calculation of Optional Temperature + // from the Digital Output + // + // -40 C = 0 + // 125 C = 2 ** 14 - 1 + return Math.round(raw / 1000); + } + } + }, // http://akizukidenshi.com/download/ds/aosong/DHT11.pdf - DHT11_I2C_NANO_BACKPACK: { + DHT_I2C_NANO_BACKPACK: { initialize: { value: function(opts, dataHandler) { var Multi = require("./imu"); - var driver = Multi.Drivers.get(this.board, "DHT11_I2C_NANO_BACKPACK", opts); + var driver = Multi.Drivers.get(this.board, "DHT_I2C_NANO_BACKPACK", opts); driver.on("data", function(data) { dataHandler(data.temperature); }); @@ -880,20 +904,26 @@ var Controllers = { }, }; -Controllers["BMP085"] = Controllers["BMP-085"] = Controllers.BMP180; -Controllers["MPU-6050"] = Controllers.MPU6050; +Controllers.BMP085 = Controllers.BMP180; +Controllers.GY521 = Controllers.MPU6050; +Controllers.SI7021 = Controllers.SI7020; +Controllers.DHT11_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; +Controllers.DHT21_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; +Controllers.DHT22_I2C_NANO_BACKPACK = Controllers.DHT_I2C_NANO_BACKPACK; + var priv = new Map(); function Thermometer(opts) { - var controller; - var last = null; - var raw = null; if (!(this instanceof Thermometer)) { return new Thermometer(opts); } + var controller = null; + var last = null; + var raw = null; + Board.Component.call( this, opts = Board.Options(opts) ); @@ -976,4 +1006,12 @@ util.inherits(Thermometer, Emitter); Thermometer.Drivers = Drivers; +/* istanbul ignore else */ +if (!!process.env.IS_TEST_MODE) { + Thermometer.Controllers = Controllers; + Thermometer.purge = function() { + priv.clear(); + }; +} + module.exports = Thermometer; diff --git a/package.json b/package.json index 816868d53..3e246e231 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@code-dot-org/johnny-five", "description": "The JavaScript Robotics and Hardware Programming Framework. Use with: Arduino (all models), Electric Imp, Beagle Bone, Intel Galileo & Edison, Linino One, Pinoccio, pcDuino3, Raspberry Pi, Particle/Spark Core & Photon, Tessel 2, TI Launchpad and more!", - "version": "0.9.62-cdo.2", + "version": "0.10.10-cdo.0", "homepage": "https://johnny-five.io", "author": { "name": "Rick Waldron ", @@ -106,7 +106,11 @@ "Ashley Williams ", "kilida ", "Rhys van der Waerden ", - "eiji.ienaga " + "eiji.ienaga ", + "Doug Cone ", + "Andrew Nicolaou ", + "shimnex ", + "Brad Buchanan " ], "keywords": [ "arduino", @@ -267,12 +271,12 @@ }, "optionalDependencies": { "browser-serialport": "latest", - "firmata": "^0.12.0", + "firmata": "latest", "serialport": "^4.0.0" }, "devDependencies": { "async": "~0.9.0", - "copy-paste": "~0.3.0", + "copy-paste": "^1.3.0", "coveralls": "^2.11.9", "grunt": "~0.4.5", "grunt-cli": "~0.1.13", @@ -281,17 +285,17 @@ "grunt-contrib-watch": "~0.6.1", "grunt-jsbeautifier": "~0.2.10", "grunt-jscs": "~2.3.0", - "istanbul": "^0.4.4", "keypress": "latest", "mock-firmata": "latest", + "nyc": "^10.2.0", "optimist": "~0.6.1", "shelljs": "^0.3.0", "sinon": "~1.10.2" }, "scripts": { "test": "grunt", - "test-cover": "grunt jshint && istanbul cover node_modules/grunt-cli/bin/grunt nodeunit", - "coveralls": "cat ./coverage/lcov.info | coveralls" + "test-cover": "nyc grunt nodeunit", + "coveralls": "nyc --reporter=lcov grunt nodeunit && cat ./coverage/lcov.info | coveralls" }, "browser": { "galileo-io": false diff --git a/test/.jshintrc b/test/.jshintrc index e137d71f5..c67f60fa6 100644 --- a/test/.jshintrc +++ b/test/.jshintrc @@ -33,6 +33,8 @@ "MockSerialPort": true, "five": true, "Accelerometer": true, + "addControllerTest": true, + "Analog": true, "Animation": true, "Altimeter": true, "Barometer": true, @@ -42,6 +44,7 @@ "Buttons": true, "Color": true, "Compass": true, + "Digital": true, "Distance": true, "ESC": true, "ESCs": true, @@ -60,7 +63,9 @@ "Leds": true, "LedControl": true, "Light": true, + "Luxmeter": true, "Joystick": true, + "Magnetometer": true, "Motion": true, "Motor": true, "Multi": true, @@ -83,6 +88,7 @@ "Sonar": true, "Stepper": true, "Switch": true, + "temporal": true, "Thermometer": true, "Virtual": true, "Wii": true, diff --git a/test/accelerometer.js b/test/accelerometer.js index b04a15df0..f4f0a5471 100644 --- a/test/accelerometer.js +++ b/test/accelerometer.js @@ -578,7 +578,7 @@ exports["Accelerometer -- ADXL345"] = { test.deepEqual(changeSpy.args[0], [{ x: 0.01, y: 0.02, - z: 0.9 + z: 0.99 }]); test.done(); @@ -630,7 +630,7 @@ exports["Accelerometer -- ADXL345"] = { }]); test.ok(changeSpy.calledOnce); - test.deepEqual(changeSpy.args[0], [{ x: 0.1, y: 0.16, z: 7.26 }]); + test.deepEqual(changeSpy.args[0], [{ x: 0.09, y: 0.16, z: 7.94 }]); test.done(); }, @@ -1442,3 +1442,10 @@ exports["Accelerometer -- User toGravity"] = { test.done(); }, }; + +Object.keys(Accelerometer.Controllers).forEach(function(name) { + exports["Accelerometer - Controller, " + name] = addControllerTest(Accelerometer, Accelerometer.Controllers[name], { + controller: name, + pins: [] + }); +}); diff --git a/test/altimeter.js b/test/altimeter.js index 2878a446e..ca4f82782 100644 --- a/test/altimeter.js +++ b/test/altimeter.js @@ -103,7 +103,7 @@ exports["Altimeter"] = { }; -exports["Altimeter -- User toMeters"] = { +exports["Altimeter - User toMeters"] = { setUp: function(done) { this.altimeter = new Altimeter({ @@ -150,7 +150,7 @@ exports["Altimeter -- User toMeters"] = { }; -exports["Altimeter -- MPL3115A2"] = { +exports["Altimeter - MPL3115A2"] = { setUp: function(done) { this.warn = this.sandbox.stub(this.board, "warn"); @@ -306,7 +306,7 @@ exports["Altimeter -- MPL3115A2"] = { }; -exports["Altimeter -- MS5611"] = { +exports["Altimeter - MS5611"] = { setUp: function(done) { this.altimeter = new Altimeter({ @@ -391,7 +391,7 @@ exports["Altimeter -- MS5611"] = { }, }; -exports["Altimeter -- BMP180"] = { +exports["Altimeter - BMP180"] = { setUp: function(done) { this.altimeter = new Altimeter({ @@ -476,7 +476,7 @@ exports["Altimeter -- BMP180"] = { }, }; -exports["Altimeter -- BMP280"] = { +exports["Altimeter - BMP280"] = { setUp: function(done) { this.altimeter = new Altimeter({ @@ -561,7 +561,7 @@ exports["Altimeter -- BMP280"] = { }, }; -exports["Altimeter -- BME280"] = { +exports["Altimeter - BME280"] = { setUp: function(done) { this.altimeter = new Altimeter({ diff --git a/test/animation.js b/test/animation.js index 7915e4609..2bfee4450 100644 --- a/test/animation.js +++ b/test/animation.js @@ -133,7 +133,6 @@ exports["Animation -- Servo"] = { test.equal(this.animation.normalizedKeyFrames[0][1].value, 90); test.equal(this.animation.normalizedKeyFrames[0][2].value, 45); test.equal(this.animation.normalizedKeyFrames[0][3].value, 78); - test.done(); }, @@ -244,7 +243,10 @@ exports["Animation -- Servo"] = { }, keyframeEasing: function(test) { - + // Don't allow time to advance in this test. Otherwise it's possible for + // the animation to progress between setup and the assertion, causing flaky + // failures. + this.sandbox.useFakeTimers(); this.animation = new Animation(this.a); test.expect(1); @@ -261,7 +263,8 @@ exports["Animation -- Servo"] = { var indices = this.animation.findIndices(progress); var val = this.animation.tweenedValue(indices, progress); - test.ok(Math.abs(val - 74.843 < 0.01)); + test.ok(Math.abs(val - 74.843) < 0.01, + "Expected " + val + " to be within 0.01 of 74.843"); test.done(); }, diff --git a/test/barometer.js b/test/barometer.js index bdf64ce64..d7850b914 100644 --- a/test/barometer.js +++ b/test/barometer.js @@ -402,3 +402,9 @@ exports["Barometer -- MPL3115A2"] = { test.done(); } }; + +Object.keys(Barometer.Controllers).forEach(function(name) { + exports["Barometer - Controller, " + name] = addControllerTest(Barometer, Barometer.Controllers[name], { + controller: name, + }); +}); diff --git a/test/board.component.js b/test/board.component.js index e03a3217e..bc970b0f0 100644 --- a/test/board.component.js +++ b/test/board.component.js @@ -183,405 +183,405 @@ exports["Board.Component"] = { test.done(); }, - componentDoesNotDirectlyRequestPinOccupancy: function(test) { - test.expect(2); + // componentDoesNotDirectlyRequestPinOccupancy: function(test) { + // test.expect(2); - var component = {}; + // var component = {}; - Board.Component.call(component, { - pin: 1 - }, { - requestPin: false - }); + // Board.Component.call(component, { + // pin: 1 + // }, { + // requestPin: false + // }); - var spy = this.sandbox.spy(component.board, "warn"); + // var spy = this.sandbox.spy(component.board, "warn"); - Board.Component.call(component, { - pin: 1 - }); + // Board.Component.call(component, { + // pin: 1 + // }); - test.equal(component.board.occupied.length, 1); - test.equal(spy.notCalled, true); + // test.equal(component.board.occupied.length, 1); + // test.equal(spy.notCalled, true); - test.done(); - }, + // test.done(); + // }, - componentPinOccupiedWarning: function(test) { - test.expect(5); + // componentPinOccupiedWarning: function(test) { + // test.expect(5); - var component = {}; - - Board.Component.call(component, { - pin: 1 - }); + // var component = {}; - var spy = this.sandbox.spy(component.board, "warn"); + // Board.Component.call(component, { + // pin: 1 + // }); - test.equal(component.board.occupied.length, 1); - test.deepEqual(component.board.occupied[0], { - value: 1, - type: "pin" - }); + // var spy = this.sandbox.spy(component.board, "warn"); - Board.Component.call(component, { - pin: 1 - }); + // test.equal(component.board.occupied.length, 1); + // test.deepEqual(component.board.occupied[0], { + // value: 1, + // type: "pin" + // }); - test.equal(spy.calledOnce, true); - test.deepEqual(spy.getCall(0).args, ["Component", "pin: 1 is already in use"]); - test.equal(component.board.occupied.length, 1); + // Board.Component.call(component, { + // pin: 1 + // }); - test.done(); - }, + // test.equal(spy.calledOnce, true); + // test.deepEqual(spy.getCall(0).args, ["Component", "pin: 1 is already in use"]); + // test.equal(component.board.occupied.length, 1); - componentPinAnalogDigitalNormalizedValueNoConflict: function(test) { - test.expect(1); + // test.done(); + // }, - var component = {}; + // componentPinAnalogDigitalNormalizedValueNoConflict: function(test) { + // test.expect(1); - Board.Component.call(component, Board.Options(2)); - Board.Component.call(component, Board.Options("A2")); + // var component = {}; - test.equal(component.board.occupied.length, 2); + // Board.Component.call(component, Board.Options(2)); + // Board.Component.call(component, Board.Options("A2")); - test.done(); - }, - componentPinAnalogDigitalNormalizedValueArrayNoConflict: function(test) { - test.expect(1); + // test.equal(component.board.occupied.length, 2); - var component = {}; + // test.done(); + // }, + // componentPinAnalogDigitalNormalizedValueArrayNoConflict: function(test) { + // test.expect(1); - Board.Component.call(component, Board.Options(2)); - Board.Component.call(component, Board.Options(["A2"])); + // var component = {}; - test.equal(component.board.occupied.length, 2); + // Board.Component.call(component, Board.Options(2)); + // Board.Component.call(component, Board.Options(["A2"])); - test.done(); - }, - componentPinAnalogDigitalNormalizedValueSinglePinObjectNoConflict: function(test) { - test.expect(1); + // test.equal(component.board.occupied.length, 2); - var component = {}; + // test.done(); + // }, + // componentPinAnalogDigitalNormalizedValueSinglePinObjectNoConflict: function(test) { + // test.expect(1); - Board.Component.call(component, Board.Options(2)); - Board.Component.call(component, Board.Options({ - pin: "A2" - })); + // var component = {}; - test.equal(component.board.occupied.length, 2); + // Board.Component.call(component, Board.Options(2)); + // Board.Component.call(component, Board.Options({ + // pin: "A2" + // })); - test.done(); - }, + // test.equal(component.board.occupied.length, 2); - componentPinAnalogDigitalNormalizedValueMultiPinObjectNoConflict: function(test) { - test.expect(1); + // test.done(); + // }, - var component = {}; + // componentPinAnalogDigitalNormalizedValueMultiPinObjectNoConflict: function(test) { + // test.expect(1); - Board.Component.call(component, Board.Options(2)); - Board.Component.call(component, Board.Options({ - pins: { - a: "A2", - b: "A3" - } - })); + // var component = {}; - test.equal(component.board.occupied.length, 3); + // Board.Component.call(component, Board.Options(2)); + // Board.Component.call(component, Board.Options({ + // pins: { + // a: "A2", + // b: "A3" + // } + // })); - test.done(); - }, - componentPinAnalogDigitalNormalizedArraySinglePinObjectNoConflict: function(test) { - test.expect(1); + // test.equal(component.board.occupied.length, 3); - var component = {}; + // test.done(); + // }, + // componentPinAnalogDigitalNormalizedArraySinglePinObjectNoConflict: function(test) { + // test.expect(1); - Board.Component.call(component, Board.Options([2])); - Board.Component.call(component, Board.Options({ - pin: "A2" - })); + // var component = {}; - test.equal(component.board.occupied.length, 2); + // Board.Component.call(component, Board.Options([2])); + // Board.Component.call(component, Board.Options({ + // pin: "A2" + // })); - test.done(); - }, + // test.equal(component.board.occupied.length, 2); - componentPinAnalogDigitalNormalizedArrayMultiPinObjectNoConflict: function(test) { - test.expect(1); + // test.done(); + // }, - var component = {}; + // componentPinAnalogDigitalNormalizedArrayMultiPinObjectNoConflict: function(test) { + // test.expect(1); - Board.Component.call(component, Board.Options([2])); - Board.Component.call(component, Board.Options({ - pins: { - a: "A2" - } - })); + // var component = {}; - test.equal(component.board.occupied.length, 2); + // Board.Component.call(component, Board.Options([2])); + // Board.Component.call(component, Board.Options({ + // pins: { + // a: "A2" + // } + // })); - test.done(); - }, + // test.equal(component.board.occupied.length, 2); - componentPinAnalogDigitalNormalizedMultiPinObjectConflict: function(test) { - test.expect(1); + // test.done(); + // }, - var component = {}; + // componentPinAnalogDigitalNormalizedMultiPinObjectConflict: function(test) { + // test.expect(1); - Board.Component.call(component, Board.Options({ - pins: { - a: "A2", - b: "A2" - } - })); + // var component = {}; - test.equal(component.board.occupied.length, 1); + // Board.Component.call(component, Board.Options({ + // pins: { + // a: "A2", + // b: "A2" + // } + // })); - test.done(); - }, + // test.equal(component.board.occupied.length, 1); - componentPinAnalogDigitalNormalizedMultiPinObjectConflictNoConflictSameComponent: function(test) { - test.expect(1); + // test.done(); + // }, - var component = {}; + // componentPinAnalogDigitalNormalizedMultiPinObjectConflictNoConflictSameComponent: function(test) { + // test.expect(1); - Board.Component.call(component, Board.Options({ - pins: { - a: "A2", - b: 2 - } - })); + // var component = {}; - test.equal(component.board.occupied.length, 2); + // Board.Component.call(component, Board.Options({ + // pins: { + // a: "A2", + // b: 2 + // } + // })); - test.done(); - }, + // test.equal(component.board.occupied.length, 2); - componentPinAddressOccupiedWarning: function(test) { - test.expect(7); + // test.done(); + // }, - var component = {}; + // componentPinAddressOccupiedWarning: function(test) { + // test.expect(7); - Board.Component.call(component, { - pin: 2, - address: 0x00 - }); + // var component = {}; - var spy = this.sandbox.spy(component.board, "warn"); + // Board.Component.call(component, { + // pin: 2, + // address: 0x00 + // }); - test.equal(component.board.occupied.length, 1); - test.deepEqual(component.board.occupied[0], { - value: 2, - type: "pin", - address: 0x00 - }); + // var spy = this.sandbox.spy(component.board, "warn"); - // This SHOULD NOT interfere with the above pin request, - // as it's a controller specific pin - Board.Component.call(component, { - pin: 2 - }); + // test.equal(component.board.occupied.length, 1); + // test.deepEqual(component.board.occupied[0], { + // value: 2, + // type: "pin", + // address: 0x00 + // }); - test.equal(spy.called, false); - test.equal(component.board.occupied.length, 2); + // // This SHOULD NOT interfere with the above pin request, + // // as it's a controller specific pin + // Board.Component.call(component, { + // pin: 2 + // }); - // This will be rejected since the pin is already - // occupied for this address. - Board.Component.call(component, { - pin: 2, - address: 0x00 - }); + // test.equal(spy.called, false); + // test.equal(component.board.occupied.length, 2); - test.equal(spy.calledOnce, true); - test.deepEqual(spy.getCall(0).args, ["Component", "pin: 2, address: 0 is already in use"]); - test.equal(component.board.occupied.length, 2); + // // This will be rejected since the pin is already + // // occupied for this address. + // Board.Component.call(component, { + // pin: 2, + // address: 0x00 + // }); - test.done(); - }, + // test.equal(spy.calledOnce, true); + // test.deepEqual(spy.getCall(0).args, ["Component", "pin: 2, address: 0 is already in use"]); + // test.equal(component.board.occupied.length, 2); - componentPinControllerOccupiedWarning: function(test) { - test.expect(7); + // test.done(); + // }, - var component = {}; + // componentPinControllerOccupiedWarning: function(test) { + // test.expect(7); - Board.Component.call(component, { - pin: 3, - controller: "FOO" - }); + // var component = {}; - var spy = this.sandbox.spy(component.board, "warn"); + // Board.Component.call(component, { + // pin: 3, + // controller: "FOO" + // }); - test.equal(component.board.occupied.length, 1); - test.deepEqual(component.board.occupied[0], { - value: 3, - type: "pin", - controller: "FOO" - }); + // var spy = this.sandbox.spy(component.board, "warn"); - // This SHOULD NOT interfere with the above pin request, - // as it's a controller specific pin - Board.Component.call(component, { - pin: 3 - }); + // test.equal(component.board.occupied.length, 1); + // test.deepEqual(component.board.occupied[0], { + // value: 3, + // type: "pin", + // controller: "FOO" + // }); - test.equal(spy.called, false); - test.equal(component.board.occupied.length, 2); + // // This SHOULD NOT interfere with the above pin request, + // // as it's a controller specific pin + // Board.Component.call(component, { + // pin: 3 + // }); - // This will be rejected since the pin is already - // occupied for this controller. - Board.Component.call(component, { - pin: 3, - controller: "FOO" - }); + // test.equal(spy.called, false); + // test.equal(component.board.occupied.length, 2); - test.equal(spy.calledOnce, true); - test.deepEqual(spy.getCall(0).args, ["Component", "pin: 3, controller: FOO is already in use"]); - test.equal(component.board.occupied.length, 2); + // // This will be rejected since the pin is already + // // occupied for this controller. + // Board.Component.call(component, { + // pin: 3, + // controller: "FOO" + // }); - test.done(); - }, - - componentPinAddressControllerOccupiedWarning: function(test) { - test.expect(7); - - var component = {}; - - Board.Component.call(component, { - pin: 4, - controller: "FOO", - address: 0x01 - }); - - var spy = this.sandbox.spy(component.board, "warn"); - - test.equal(component.board.occupied.length, 1); - test.deepEqual(component.board.occupied[0], { - value: 4, - type: "pin", - controller: "FOO", - address: 0x01 - }); - - // This SHOULD NOT interfere with the above pin request, - // as it's a controller specific pin - Board.Component.call(component, { - pin: 4 - }); - - test.equal(spy.called, false); - test.equal(component.board.occupied.length, 2); - - // This will be rejected since the pin is already - // occupied for this controller. - Board.Component.call(component, { - pin: 4, - controller: "FOO", - address: 0x01 - }); - - test.equal(spy.calledOnce, true); - test.deepEqual(spy.getCall(0).args, ["Component", "pin: 4, controller: FOO, address: 1 is already in use"]); - test.equal(component.board.occupied.length, 2); - - test.done(); - }, - - componentAddressControllerNoWarning: function(test) { - test.expect(3); - - var component = {}; - - Board.Component.call(component, { - controller: "FOO", - address: 0x01 - }); - - var spy = this.sandbox.spy(component.board, "warn"); - - // No pins to occupy - test.equal(component.board.occupied.length, 0); - - Board.Component.call(component, { - controller: "FOO", - address: 0x01 - }); - - test.equal(spy.called, false); - test.equal(component.board.occupied.length, 0); - test.done(); - }, - - componentPinsOccupiedWarning: function(test) { - test.expect(12); - - var component = {}; - - Board.Component.call(component, { - pins: { - a: 1, - b: 2, - c: 3 - } - }); - - var spy = this.sandbox.spy(component.board, "warn"); - - test.equal(component.board.occupied.length, 3); - test.deepEqual(component.board.occupied[0], { - value: 1, - type: "pin" - }); - - test.deepEqual(component.board.occupied[1], { - value: 2, - type: "pin" - }); - - test.deepEqual(component.board.occupied[2], { - value: 3, - type: "pin" - }); - - // This will be rejected since the pin is already - // occupied for this controller. - Board.Component.call(component, { - pin: 1 - }); - - // This will be rejected since the pin is already - // occupied for this controller. - Board.Component.call(component, { - pin: 2 - }); - - // This will be rejected since the pin is already - // occupied for this controller. - Board.Component.call(component, { - pin: 3 - }); - - // This will be rejected since the pin is already - // occupied for this controller. - Board.Component.call(component, { - pins: { - a: 1, - b: 2, - c: 3 - } - }); - - // 1, 2, 3 + 3 - test.equal(spy.callCount, 6); - test.deepEqual(spy.getCall(0).args, ["Component", "pin: 1 is already in use"]); - test.deepEqual(spy.getCall(1).args, ["Component", "pin: 2 is already in use"]); - test.deepEqual(spy.getCall(2).args, ["Component", "pin: 3 is already in use"]); - test.deepEqual(spy.getCall(3).args, ["Component", "pin: 1 is already in use"]); - test.deepEqual(spy.getCall(4).args, ["Component", "pin: 2 is already in use"]); - test.deepEqual(spy.getCall(5).args, ["Component", "pin: 3 is already in use"]); - - test.equal(component.board.occupied.length, 3); - - test.done(); - }, + // test.equal(spy.calledOnce, true); + // test.deepEqual(spy.getCall(0).args, ["Component", "pin: 3, controller: FOO is already in use"]); + // test.equal(component.board.occupied.length, 2); + + // test.done(); + // }, + + // componentPinAddressControllerOccupiedWarning: function(test) { + // test.expect(7); + + // var component = {}; + + // Board.Component.call(component, { + // pin: 4, + // controller: "FOO", + // address: 0x01 + // }); + + // var spy = this.sandbox.spy(component.board, "warn"); + + // test.equal(component.board.occupied.length, 1); + // test.deepEqual(component.board.occupied[0], { + // value: 4, + // type: "pin", + // controller: "FOO", + // address: 0x01 + // }); + + // // This SHOULD NOT interfere with the above pin request, + // // as it's a controller specific pin + // Board.Component.call(component, { + // pin: 4 + // }); + + // test.equal(spy.called, false); + // test.equal(component.board.occupied.length, 2); + + // // This will be rejected since the pin is already + // // occupied for this controller. + // Board.Component.call(component, { + // pin: 4, + // controller: "FOO", + // address: 0x01 + // }); + + // test.equal(spy.calledOnce, true); + // test.deepEqual(spy.getCall(0).args, ["Component", "pin: 4, controller: FOO, address: 1 is already in use"]); + // test.equal(component.board.occupied.length, 2); + + // test.done(); + // }, + + // componentAddressControllerNoWarning: function(test) { + // test.expect(3); + + // var component = {}; + + // Board.Component.call(component, { + // controller: "FOO", + // address: 0x01 + // }); + + // var spy = this.sandbox.spy(component.board, "warn"); + + // // No pins to occupy + // test.equal(component.board.occupied.length, 0); + + // Board.Component.call(component, { + // controller: "FOO", + // address: 0x01 + // }); + + // test.equal(spy.called, false); + // test.equal(component.board.occupied.length, 0); + // test.done(); + // }, + + // componentPinsOccupiedWarning: function(test) { + // test.expect(12); + + // var component = {}; + + // Board.Component.call(component, { + // pins: { + // a: 1, + // b: 2, + // c: 3 + // } + // }); + + // var spy = this.sandbox.spy(component.board, "warn"); + + // test.equal(component.board.occupied.length, 3); + // test.deepEqual(component.board.occupied[0], { + // value: 1, + // type: "pin" + // }); + + // test.deepEqual(component.board.occupied[1], { + // value: 2, + // type: "pin" + // }); + + // test.deepEqual(component.board.occupied[2], { + // value: 3, + // type: "pin" + // }); + + // // This will be rejected since the pin is already + // // occupied for this controller. + // Board.Component.call(component, { + // pin: 1 + // }); + + // // This will be rejected since the pin is already + // // occupied for this controller. + // Board.Component.call(component, { + // pin: 2 + // }); + + // // This will be rejected since the pin is already + // // occupied for this controller. + // Board.Component.call(component, { + // pin: 3 + // }); + + // // This will be rejected since the pin is already + // // occupied for this controller. + // Board.Component.call(component, { + // pins: { + // a: 1, + // b: 2, + // c: 3 + // } + // }); + + // // 1, 2, 3 + 3 + // test.equal(spy.callCount, 6); + // test.deepEqual(spy.getCall(0).args, ["Component", "pin: 1 is already in use"]); + // test.deepEqual(spy.getCall(1).args, ["Component", "pin: 2 is already in use"]); + // test.deepEqual(spy.getCall(2).args, ["Component", "pin: 3 is already in use"]); + // test.deepEqual(spy.getCall(3).args, ["Component", "pin: 1 is already in use"]); + // test.deepEqual(spy.getCall(4).args, ["Component", "pin: 2 is already in use"]); + // test.deepEqual(spy.getCall(5).args, ["Component", "pin: 3 is already in use"]); + + // test.equal(component.board.occupied.length, 3); + + // test.done(); + // }, componentCustomReservedSpace: function(test) { test.expect(8); @@ -644,4 +644,16 @@ exports["Board.Component"] = { test.done(); }, + componentControllerWithDash: function(test) { + test.expect(1); + + var d = {}; + Board.Component.call(d, { + controller: "FOO-BAR-BAZ" + }); + + test.equal(d.controller, "FOOBARBAZ"); + test.done(); + }, + }; diff --git a/test/board.js b/test/board.js index 295ac4026..828af0971 100644 --- a/test/board.js +++ b/test/board.js @@ -302,9 +302,11 @@ exports["Board"] = { emitExitNoRepl: function(test) { test.expect(2); + var clock = this.sandbox.useFakeTimers(); var io = new MockFirmata(); io.name = "Foo"; + io.pending = 0; var board = new Board({ io: io, @@ -324,6 +326,50 @@ exports["Board"] = { test.ok(true); }); process.emit("SIGINT"); + clock.tick(1); + }); + + io.emit("connect"); + io.emit("ready"); + }, + + exitAwaitsPending: function(test) { + test.expect(2); + + var clock = this.sandbox.useFakeTimers(); + var io = new MockFirmata(); + + io.name = "Foo"; + io.pending = 5; + + var board = new Board({ + io: io, + debug: false, + repl: false, + sigint: true, + }); + + var reallyExit = this.sandbox.stub(process, "reallyExit", function() { + reallyExit.restore(); + test.ok(true); + test.done(); + }); + + board.on("ready", function() { + this.on("exit", function() { + test.ok(true); + }); + process.emit("SIGINT"); + clock.tick(1); + io.pending--; + clock.tick(1); + io.pending--; + clock.tick(1); + io.pending--; + clock.tick(1); + io.pending--; + clock.tick(1); + io.pending--; }); io.emit("connect"); @@ -588,6 +634,7 @@ exports["Board"] = { value: null, scaled: 0, range: [0, 1023], + resolution: 1023, analog: 0, limit: null, threshold: 1, @@ -610,9 +657,6 @@ exports["Board"] = { position: -1, type: "standard", history: [], - specs: { - speed: 0.17 - }, offset: 0, invert: false, custom: {}, diff --git a/test/button.js b/test/button.js index 380cfaaf0..3383fa53d 100644 --- a/test/button.js +++ b/test/button.js @@ -55,7 +55,7 @@ exports["Button"] = { }, }; -exports["Button -- Digital Pin"] = { +exports["Button - Digital Pin"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.clock = this.sandbox.useFakeTimers(); @@ -173,7 +173,7 @@ exports["Button -- Digital Pin"] = { }, }; -exports["Button -- Analog Pin"] = { +exports["Button - Analog Pin"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); @@ -255,7 +255,7 @@ exports["Button -- Analog Pin"] = { }, }; -exports["Button -- Value Inversion"] = { +exports["Button - Value Inversion & Explicit Pullup/Pulldown"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); @@ -263,6 +263,7 @@ exports["Button -- Value Inversion"] = { return fn; }); this.digitalRead = this.sandbox.spy(MockFirmata.prototype, "digitalRead"); + this.digitalWrite = this.sandbox.spy(MockFirmata.prototype, "digitalWrite"); this.button = new Button({ pin: 8, board: this.board @@ -304,8 +305,8 @@ exports["Button -- Value Inversion"] = { test.done(); }, - pullupInversion: function(test) { - test.expect(6); + pullup: function(test) { + test.expect(9); this.button = new Button({ pin: 8, @@ -313,6 +314,10 @@ exports["Button -- Value Inversion"] = { board: this.board }); + test.equal(this.digitalWrite.callCount, 1); + test.equal(this.digitalWrite.lastCall.args[0], 8); + test.equal(this.digitalWrite.lastCall.args[1], 1); + test.equal(this.button.downValue, 0); test.equal(this.button.upValue, 1); @@ -329,6 +334,35 @@ exports["Button -- Value Inversion"] = { test.done(); }, + pulldown: function(test) { + test.expect(9); + + this.button = new Button({ + pin: 8, + pulldown: true, + board: this.board + }); + + test.equal(this.digitalWrite.callCount, 1); + test.equal(this.digitalWrite.lastCall.args[0], 8); + test.equal(this.digitalWrite.lastCall.args[1], 0); + + test.equal(this.button.downValue, 1); + test.equal(this.button.upValue, 0); + + this.button.downValue = 0; + + test.equal(this.button.downValue, 0); + test.equal(this.button.upValue, 1); + + this.button.upValue = 0; + + test.equal(this.button.downValue, 1); + test.equal(this.button.upValue, 0); + + test.done(); + }, + inlineInversion: function(test) { test.expect(14); @@ -370,7 +404,7 @@ exports["Button -- Value Inversion"] = { }; -exports["Button -- EVS_EV3"] = { +exports["Button - EVS_EV3"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); @@ -464,7 +498,7 @@ exports["Button -- EVS_EV3"] = { }, }; -exports["Button -- EVS_NXT"] = { +exports["Button - EVS_NXT"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); @@ -704,7 +738,7 @@ exports["Button.Collection"] = { }, }; -exports["Button -- TINKERKIT"] = { +exports["Button - TINKERKIT"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); @@ -789,3 +823,14 @@ exports["Button -- TINKERKIT"] = { callback(511); }, }; + +Object.keys(Button.Controllers).forEach(function(name) { + + if (name.startsWith("EVS")) { + return; + } + + exports["Button - Controller, " + name] = addControllerTest(Button, Button.Controllers[name], { + controller: name, + }); +}); diff --git a/test/collections.js b/test/collections.js index 28c907e62..a42b0f151 100644 --- a/test/collections.js +++ b/test/collections.js @@ -1,5 +1,7 @@ require("./common/bootstrap"); +var util = require("util"); + function Output(opts) { if (typeof opts === "number") { opts = { @@ -25,11 +27,7 @@ function Outputs(numsOrObjects) { Collection.call(this, numsOrObjects); } -Outputs.prototype = Object.create(Collection.prototype, { - constructor: { - value: Outputs - } -}); +util.inherits(Outputs, Collection); Collection.installMethodForwarding( Outputs.prototype, Output.prototype @@ -81,12 +79,7 @@ function Inputs(numsOrObjects) { Collection.Emitter.call(this, numsOrObjects); } -Inputs.prototype = Object.create(Collection.Emitter.prototype, { - constructor: { - value: Inputs - } -}); - +util.inherits(Inputs, Collection.Emitter); Collection.installMethodForwarding( Inputs.prototype, Input.prototype diff --git a/test/color.js b/test/color.js index d4c7b7eaf..693978c21 100644 --- a/test/color.js +++ b/test/color.js @@ -10,7 +10,7 @@ var instance = [{ }]; -exports["Color: EVS_EV3"] = { +exports["Color - EVS_EV3"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); @@ -28,7 +28,7 @@ exports["Color: EVS_EV3"] = { this.color = new Color({ controller: "EVS_EV3", pin: "BAS1", - freq: 100, + freq: 10, board: this.board }); @@ -37,6 +37,7 @@ exports["Color: EVS_EV3"] = { tearDown: function(done) { Board.purge(); + Color.purge(); this.sandbox.restore(); done(); }, @@ -60,7 +61,7 @@ exports["Color: EVS_EV3"] = { test.expect(1); this.color.on("data", spy); - this.clock.tick(100); + this.clock.tick(10); test.equal(spy.callCount, 1); test.done(); }, @@ -72,7 +73,7 @@ exports["Color: EVS_EV3"] = { this.color.on("change", spy); - this.clock.tick(100); + this.clock.tick(10); test.ok(spy.called); test.done(); @@ -80,7 +81,7 @@ exports["Color: EVS_EV3"] = { }; -exports["Color: EVS_NXT"] = { +exports["Color - EVS_NXT"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); @@ -98,7 +99,7 @@ exports["Color: EVS_NXT"] = { this.color = new Color({ controller: "EVS_NXT", pin: "BAS1", - freq: 100, + freq: 10, board: this.board }); @@ -107,6 +108,7 @@ exports["Color: EVS_NXT"] = { tearDown: function(done) { Board.purge(); + Color.purge(); this.sandbox.restore(); done(); }, @@ -130,7 +132,7 @@ exports["Color: EVS_NXT"] = { test.expect(1); this.color.on("data", spy); - this.clock.tick(100); + this.clock.tick(10); test.equal(spy.callCount, 1); test.done(); }, @@ -142,7 +144,7 @@ exports["Color: EVS_NXT"] = { this.color.on("change", spy); - this.clock.tick(100); + this.clock.tick(10); test.ok(spy.called); test.done(); @@ -150,15 +152,12 @@ exports["Color: EVS_NXT"] = { }; -exports["Color: ISL29125"] = { +exports["Color - ISL29125"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); this.clock = this.sandbox.useFakeTimers(); - this.evssetup = this.sandbox.spy(EVS.prototype, "setup"); - this.evsread = this.sandbox.spy(EVS.prototype, "read"); - this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); this.i2cWrite = this.sandbox.spy(MockFirmata.prototype, "i2cWrite"); this.i2cRead = this.sandbox.stub(MockFirmata.prototype, "i2cRead", function(address, register, numBytes, callback) { @@ -167,7 +166,7 @@ exports["Color: ISL29125"] = { this.color = new Color({ controller: "ISL29125", - freq: 100, + freq: 10, board: this.board }); @@ -176,6 +175,7 @@ exports["Color: ISL29125"] = { tearDown: function(done) { Board.purge(); + Color.purge(); this.sandbox.restore(); done(); }, @@ -199,7 +199,7 @@ exports["Color: ISL29125"] = { test.expect(1); this.color.on("data", spy); - this.clock.tick(100); + this.clock.tick(10); test.equal(spy.callCount, 1); test.done(); }, @@ -211,10 +211,17 @@ exports["Color: ISL29125"] = { this.color.on("change", spy); - this.clock.tick(100); + this.clock.tick(10); test.ok(spy.called); test.done(); }, }; + +Object.keys(Color.Controllers).forEach(function(name) { + exports["Color - Controller, " + name] = addControllerTest(Color, Color.Controllers[name], { + controller: name, + pin: "BAS1" + }); +}); diff --git a/test/common/bootstrap.js b/test/common/bootstrap.js index 395ba9138..9fa5991ed 100644 --- a/test/common/bootstrap.js +++ b/test/common/bootstrap.js @@ -14,6 +14,7 @@ global.EVS = require("../../lib/evshield"); global.converter = require("color-convert"); global.SerialPort = require("serialport"); global.Firmata = require("firmata"); +global.temporal = require("temporal"); // Third Party (test) global.mocks = require("mock-firmata"); @@ -33,7 +34,6 @@ global.Button = five.Button; global.Buttons = five.Buttons; global.Color = five.Color; global.Compass = five.Compass; -global.Distance = five.Distance; global.ESC = five.ESC; global.ESCs = five.ESCs; global.Expander = five.Expander; @@ -60,7 +60,6 @@ global.Motors = five.Motors; global.Nodebot = five.Nodebot; global.Piezo = five.Piezo; global.Ping = five.Ping; -global.Pir = five.Pir; global.Pin = five.Pin; global.Proximity = five.Proximity; global.Relay = five.Relay; @@ -70,6 +69,7 @@ global.Repl = five.Repl; global.Sensor = five.Sensor; global.Serial = five.Board.Serial; global.Servo = five.Servo; +global.Servos = five.Servos; global.ShiftRegister = five.ShiftRegister; global.Sonar = five.Sonar; global.Stepper = five.Stepper; @@ -79,6 +79,12 @@ global.Virtual = five.Board.Virtual; global.Wii = five.Wii; +// Used for alias tests +global.Analog = five.Analog; +global.Digital = five.Digital; +global.Luxmeter = five.Luxmeter; +global.Magnetometer = five.Magnetometer; + function newBoard(pins) { @@ -127,3 +133,35 @@ var digits = { }; global.digits = digits; + + +global.addControllerTest = function(Constructor, Controller, options) { + return { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + this.Controller = this.sandbox.spy(Board, "Controller"); + this.component = new Constructor(Object.assign({}, options, { + board: this.board + })); + done(); + }, + + tearDown: function(done) { + Board.purge(); + this.sandbox.restore(); + done(); + }, + + controller: function(test) { + test.expect(2); + // Board.Controller may called more than once, for example: Servo -> Expander + test.equal(this.Controller.called, true); + // We can only test for the FIRST call to Board.Controller, since + // we can't generically know which componant class controllers will + // instantiate an Expander + test.equal(this.Controller.firstCall.args[0], Controller); + test.done(); + }, + }; +}; diff --git a/test/compass.js b/test/compass.js index 7aaa86bc1..95b3e71e9 100644 --- a/test/compass.js +++ b/test/compass.js @@ -157,6 +157,7 @@ exports["Compass - MAG3110"] = { tearDown: function(done) { Board.purge(); + Compass.purge(); this.sandbox.restore(); done(); }, @@ -250,26 +251,192 @@ exports["Compass - MAG3110"] = { }, }; -exports["Invalid or missing controller"] = { - missing: function(test) { - test.expect(1); - test.throws(function() { - new Compass({ - board: newBoard() - }); +exports["Compass - BNO055"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.clock = this.sandbox.useFakeTimers(); + this.board = newBoard(); + + this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); + this.i2cWrite = this.sandbox.spy(MockFirmata.prototype, "i2cWrite"); + this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); + + this.compass = new Compass({ + board: this.board, + controller: "BNO055", + offsets: { + x: [-819, -335], + y: [702, 1182], + z: [-293, -13], + }, + }); + + this.properties = [{ + name: "bearing" + }, { + name: "heading" + }]; + + done(); + }, + + tearDown: function(done) { + Board.purge(); + Compass.purge(); + this.sandbox.restore(); + done(); + }, + + shape: function(test) { + test.expect(this.properties.length); + + this.properties.forEach(function(property) { + test.notEqual(typeof this.compass[property.name], "undefined"); + }, this); + test.done(); + }, + + fwdOptionsToi2cConfig: function(test) { + test.expect(3); + + this.i2cConfig.reset(); + + new Compass({ + controller: "BNO055", + address: 0xff, + bus: "i2c-1", + board: this.board }); + var forwarded = this.i2cConfig.lastCall.args[0]; + + test.equal(this.i2cConfig.callCount, 1); + test.equal(forwarded.address, 0xff); + test.equal(forwarded.bus, "i2c-1"); + test.done(); }, - invalid: function(test) { + + dataAndChange: function(test) { + test.expect(4); + + var driver = IMU.Drivers.get(this.board, "BNO055"); + var data = this.sandbox.spy(); + var change = this.sandbox.spy(); + + this.compass.on("data", data); + this.compass.on("change", change); + + driver.emit("data", { + magnetometer: { + x: -52, + y: -417, + z: -200, + }, + }); + this.clock.tick(20); + + driver.emit("data", { + magnetometer: { + x: -52, + y: -0, + z: -200, + }, + }); + this.clock.tick(20); + + test.equal(data.callCount, 1); + test.equal(change.callCount, 1); + + test.equal(this.compass.heading, 180); + test.deepEqual(this.compass.bearing, { + name: "South", + abbr: "S", + low: 174.38, + high: 185.62, + heading: 180, + }); + test.done(); + }, + +}; + + +exports["Missing controller"] = { + setUp: function(done) { + this.board = newBoard(); + done(); + }, + tearDown: function(done) { + Board.purge(); + done(); + }, + missing: function(test) { test.expect(1); test.throws(function() { new Compass({ - board: newBoard(), - controller: 1 + board: this.board }); - }); + }.bind(this)); test.done(); }, }; + +exports["Compass.Scale"] = { + expectedRegistersAndScales: function(test) { + var expects = [{ + gauss: 0.88, + register: 0x00 << 5, + scale: 0.73, + }, { + gauss: 1.3, + register: 0x01 << 5, + scale: 0.92, + }, { + gauss: 1.9, + register: 0x02 << 5, + scale: 1.22, + }, { + gauss: 2.5, + register: 0x03 << 5, + scale: 1.52, + }, { + gauss: 4.0, + register: 0x04 << 5, + scale: 2.27, + }, { + gauss: 4.7, + register: 0x05 << 5, + scale: 2.56, + }, { + gauss: 5.6, + register: 0x06 << 5, + scale: 3.03, + }, { + gauss: 8.1, + register: 0x07 << 5, + scale: 4.35, + }, { + gauss: undefined, + register: 0x00 << 5, + scale: 1, + }]; + + test.expect(expects.length * 2); + + expects.forEach(function(expect) { + var cs = new Compass.Scale(expect.gauss); + + test.equal(cs.register, expect.register); + test.equal(cs.scale, expect.scale); + }); + test.done(); + } +}; + +Object.keys(Compass.Controllers).forEach(function(name) { + exports["Compass - Controller, " + name] = addControllerTest(Compass, Compass.Controllers[name], { + controller: name, + }); +}); diff --git a/test/expander.js b/test/expander.js index f1f6a369c..1aeeb5487 100644 --- a/test/expander.js +++ b/test/expander.js @@ -2905,6 +2905,32 @@ exports["Expander - 74HC595"] = { test.done(); }, + multipleInstancesOfNonAddressableExpanders: function(test) { + test.expect(1); + + test.doesNotThrow(function() { + new five.Expander({ + controller: "74HC595", + pins: { + data: 6, + clock: 7, + latch: 8, + } + }); + + new five.Expander({ + controller: "74HC595", + pins: { + data: 9, + clock: 10, + latch: 11, + } + }); + }); + + test.done(); + }, + normalize: function(test) { test.expect(8); diff --git a/test/extended/animation.js b/test/extended/animation.js index 3d90f5e92..c8ac9ed25 100644 --- a/test/extended/animation.js +++ b/test/extended/animation.js @@ -1,3 +1,5 @@ +require("../common/bootstrap"); + exports["Animation"] = { setUp: function(done) { this.board = newBoard(); diff --git a/test/extended/led.js b/test/extended/led.js index 3a5f03641..ecd665330 100644 --- a/test/extended/led.js +++ b/test/extended/led.js @@ -1,3 +1,5 @@ +require("../common/bootstrap"); + exports["Led - PWM"] = { setUp: function(done) { this.board = newBoard(); @@ -10,63 +12,19 @@ exports["Led - PWM"] = { board: this.board }); - this.proto = [{ - name: "on" - }, { - name: "off" - }, { - name: "toggle" - }, { - name: "brightness" - }, { - name: "pulse" - }, { - name: "fade" - }, { - name: "fadeIn" - }, { - name: "fadeOut" - }, { - name: "strobe" - }, { - name: "blink" - }, { - name: "stop" - }]; - - this.instance = [{ - name: "id" - }, { - name: "pin" - }, { - name: "value" - }]; - done(); }, tearDown: function(done) { - Board.purge(); - this.sandbox.restore(); - if (this.led.animation) { + if (this.led && this.led.animation) { this.led.animation.stop(); } + Board.purge(); + Led.purge(); + this.sandbox.restore(); done(); }, - shape: function(test) { - test.expect(this.proto.length + this.instance.length); - - this.proto.forEach(function(method) { - test.equal(typeof this.led[method.name], "function"); - }, this); - - this.instance.forEach(function(property) { - test.notEqual(typeof this.led[property.name], "undefined"); - }, this); - - test.done(); - }, pulse: function(test) { var renderSpy = this.sandbox.spy(this.led, "@@render"); @@ -248,7 +206,7 @@ exports["Led - PWM"] = { }, autoMode: function(test) { - test.expect(4); + test.expect(3); this.led.mode = 1; this.led.brightness(255); @@ -262,9 +220,6 @@ exports["Led - PWM"] = { this.led.fade(); test.equal(this.led.mode, 3); - this.led.strobe(); - test.equal(this.led.mode, 3); - test.done(); } diff --git a/test/extended/piezo.js b/test/extended/piezo.js index d581d2a7b..953789627 100644 --- a/test/extended/piezo.js +++ b/test/extended/piezo.js @@ -1,3 +1,5 @@ +require("../common/bootstrap"); + exports["Piezo"] = { setUp: function(done) { diff --git a/test/extended/servo.js b/test/extended/servo.js index f9b32148d..c7e7496f4 100644 --- a/test/extended/servo.js +++ b/test/extended/servo.js @@ -1,93 +1,30 @@ -var MockFirmata = mocks.Firmata; -var five = require("../../lib/johnny-five.js"); -var sinon = require("sinon"); -var Board = five.Board; -var Servo = five.Servo; - -function newBoard() { - var io = new MockFirmata(); - var board = new Board({ - io: io, - debug: false, - repl: false - }); - - io.emit("ready"); - - return board; -} +require("../common/bootstrap"); exports["Servo"] = { setUp: function(done) { - this.board = newBoard(); - - this.servoWrite = sinon.spy(this.board.io, "servoWrite"); - - this.proto = [{ - name: "to" - }, { - name: "step" - }, { - name: "move" - }, { - name: "min" - }, { - name: "max" - }, { - name: "center" - }, { - name: "sweep" - }, { - name: "stop" - }, { - name: "clockWise" - }, { - name: "cw" - }, { - name: "counterClockwise" - }, { - name: "ccw" - }, { - name: "write" - }]; - - this.instance = [{ - name: "id" - }, { - name: "pin" - }, { - name: "mode" - }, { - name: "range" - }, { - name: "invert" - }, { - name: "type" - }, { - name: "specs" - }, { - name: "interval" - }, { - name: "value" - }]; + this.sandbox = sinon.sandbox.create(); + this.servoWrite = this.sandbox.spy(MockFirmata.prototype, "servoWrite"); done(); }, tearDown: function(done) { - Board.purge(); - if (this.servo.animation) { + if (this.servo && this.servo.animation) { this.servo.animation.stop(); } - this.servoWrite.restore(); + + Board.purge(); + Servo.purge(); + this.sandbox.restore(); + done(); }, center: function(test) { - test.expect(5); + test.expect(4); - this.spy = sinon.spy(Servo.prototype, "center"); + this.spy = this.sandbox.spy(Servo.prototype, "center"); this.servo = new Servo({ pin: 11, @@ -98,10 +35,10 @@ exports["Servo"] = { // constructor called .center() test.ok(this.spy.called); + // and servo is actually centered test.equal(this.servo.position, 90); - this.spy.restore(); this.servo.to(180); this.servo.center(1000, 100); @@ -113,10 +50,8 @@ exports["Servo"] = { // it fired a move:complete event when finished this.servo.on("move:complete", function() { test.equal(this.servo.position, 90); - test.ok(1, "event fired"); test.done(); }.bind(this)); - }, min: function(test) { diff --git a/test/fn.js b/test/fn.js index fee79fdbf..af53000da 100644 --- a/test/fn.js +++ b/test/fn.js @@ -25,19 +25,20 @@ exports["Fn"] = { }, constrain: function(test) { - test.expect(5); + test.expect(6); test.equal(Fn.constrain(100, 0, 255), 100); test.equal(Fn.constrain(-1, 0, 255), 0); test.equal(Fn.constrain(0, 0, 255), 0); test.equal(Fn.constrain(256, 0, 255), 255); test.equal(Fn.constrain(255, 0, 255), 255); + test.ok(isNaN(Fn.constrain("finger", 0, 255))); test.done(); }, inRange: function(test) { - test.expect(6); + test.expect(10); var a = Fn.inRange(5, 4, 6); var b = Fn.inRange(5, 4.5, 5.5); @@ -45,6 +46,10 @@ exports["Fn"] = { var d = Fn.inRange(0, -9, -1); var e = Fn.inRange(0, -9, -3); var f = Fn.inRange(0, -10, -2); + var g = Fn.inRange(0, 5, 1); + var h = Fn.inRange("finger", 0, 5); + var i = Fn.inRange(1, "finger", 5); + var j = Fn.inRange(1, 0, "finger"); test.equal(a, true); test.equal(b, true); @@ -52,13 +57,17 @@ exports["Fn"] = { test.equal(d, false); test.equal(e, false); test.equal(f, false); + test.equal(g, false); + test.equal(h, false); + test.equal(i, false); + test.equal(j, false); test.done(); }, range: function(test) { - test.expect(6); + test.expect(7); var a = Fn.range(5); var b = Fn.range(5, 10); @@ -66,6 +75,7 @@ exports["Fn"] = { var d = Fn.range(0, -9, -1); var e = Fn.range(0, -9, -3); var f = Fn.range(0, -10, -2); + var g = Fn.range(); test.deepEqual(a, [0, 1, 2, 3, 4]); test.deepEqual(b, [5, 6, 7, 8, 9, 10]); @@ -76,17 +86,22 @@ exports["Fn"] = { test.deepEqual(e, [0, -3, -6, -9]); test.deepEqual(f, [0, -2, -4, -6, -8, -10]); + // Weird Range + test.deepEqual(g, [0]); + test.done(); }, prefixed: function(test) { - test.expect(4); + test.expect(6); test.deepEqual(Fn.range.prefixed("A", 3), ["A0", "A1", "A2"]); test.deepEqual(Fn.range.prefixed("A", 0, 3), ["A0", "A1", "A2", "A3"]); test.deepEqual(Fn.range.prefixed("A", 0, 10, 2), ["A0", "A2", "A4", "A6", "A8", "A10"]); test.deepEqual(Fn.range.prefixed("A", 0, 9, 3), ["A0", "A3", "A6", "A9"]); + test.deepEqual(Fn.range.prefixed(1, 3), [1, 2, 3]); + test.deepEqual(Fn.range.prefixed({foo: "bar"}, 2), ["[object Object]0", "[object Object]1"]); test.done(); }, @@ -113,34 +128,50 @@ exports["Fn"] = { test.done(); }, + square: function(test) { + test.expect(3); + + test.equal(Fn.square(2), 4); + test.equal(Fn.square(-2), 4); + test.ok(isNaN(Fn.square("finger"))); + + test.done(); + }, + sum: function(test) { - test.expect(4); + test.expect(6); var a = 0, b = 1, c = [], - d = [0, 1]; + d = [0, 1], + e = ["finger", 3, 4], + f = [{foo: "bar"}, 2, 3]; test.equal(Fn.sum(a), 0); test.equal(Fn.sum(b), 1); test.equal(Fn.sum(c), 0); test.equal(Fn.sum(d), 1); + test.equal(Fn.sum(e), "0finger34"); + test.equal(Fn.sum(f), "0[object Object]23"); test.done(); }, bitValue: function(test) { - test.expect(4); + test.expect(5); var a = Fn.bitValue(0); var b = Fn.bitValue(2); var c = Fn.bitValue(7); var d = Fn.bitValue(8); + var e = Fn.bitValue("finger"); test.equal(a, 1); test.equal(b, 4); test.equal(c, 128); test.equal(d, 256); + test.equal(e, 1); test.done(); }, @@ -158,6 +189,71 @@ exports["Fn"] = { test.done(); }, + uint16fromtwobytes: function(test) { + test.expect(6); + + test.equal(Fn.uint16(0, 0), 0); + test.equal(Fn.uint16(0, 1), 1); + test.equal(Fn.uint16(1, 4), 260); + test.equal(Fn.uint16(8, 0), 2048); + test.equal(Fn.uint16(255, 255), 65535); + test.equal(Fn.uint16(240, 240), 61680); + + test.done(); + }, + + int24fromthreebytes: function(test) { + test.expect(5); + + test.equal(Fn.int24(0, 0, 0), 0); + test.equal(Fn.int24(0, 0, 1), 1); + test.equal(Fn.int24(255, 255, 255), -1); + test.equal(Fn.int24(127, 255, 255), 8388607); + test.equal(Fn.int24(0, 255, 255), 65535); + + test.done(); + }, + + uint24fromthreebytes: function(test) { + test.expect(5); + + test.equal(Fn.uint24(0, 0, 0), 0); + test.equal(Fn.uint24(0, 0, 1), 1); + test.equal(Fn.uint24(255, 255, 255), 16777215); + test.equal(Fn.uint24(127, 255, 255), 8388607); + test.equal(Fn.uint24(0, 255, 255), 65535); + + test.done(); + }, + + int32fromfourbytes: function(test) { + test.expect(7); + + test.equal(Fn.int32(0, 0, 0, 0), 0); + test.equal(Fn.int32(0, 0, 0, 1), 1); + test.equal(Fn.int32(255, 0, 0, 0), -16777216); + test.equal(Fn.int32(255, 255, 255, 255), -1); + test.equal(Fn.int32(200, 255, 255, 255), -922746881); + test.equal(Fn.int32(127, 255, 255, 255), 2147483647); + test.equal(Fn.int32(0, 255, 255, 255), 16777215); + + test.done(); + }, + + uint32fromfourbytes: function(test) { + test.expect(7); + + test.equal(Fn.uint32(0, 0, 0, 0), 0); + test.equal(Fn.uint32(0, 0, 0, 1), 1); + test.equal(Fn.uint32(255, 0, 0, 0), 4278190080); + test.equal(Fn.uint32(255, 255, 255, 255), 4294967295); + test.equal(Fn.uint32(200, 255, 255, 255), 3372220415); + test.equal(Fn.uint32(127, 255, 255, 255), 2147483647); + test.equal(Fn.uint32(0, 255, 255, 255), 16777215); + + test.done(); + }, + bitSize: function(test) { test.expect(5); @@ -171,12 +267,14 @@ exports["Fn"] = { }, toFixed: function(test) { - test.expect(4); + test.expect(6); test.equal(typeof Fn.toFixed(0.123456789), "number"); test.equal(Fn.toFixed(0.123456789), 0); test.equal(Fn.toFixed(0.123456789, 2), 0.12); test.equal(Fn.toFixed(3 / 7, 1), 0.4); + test.equal(Fn.toFixed(1, 2), 1); + test.equal(Fn.toFixed(1.5, 2), 1.5); test.done(); }, toFixedDoesNotThrow: function(test) { @@ -233,13 +331,14 @@ exports["Fn.s*"] = { }, cast: function(test) { - test.expect(24); + test.expect(bitSizes.length * 4); bitSizes.forEach(function(bits) { var decimal = Fn["POW_2_" + bits]; var half = decimal / 2 >>> 0; - test.equal(Fn["s" + bits](decimal - 1), decimal - decimal - 1); + test.equal(Fn["s" + bits](decimal - 1), -1); test.equal(Fn["s" + bits](half), -half); + test.equal(Fn["s" + bits](half -1), half - 1); test.equal(Fn["s" + bits](half + 1), -half + 1); }); @@ -247,6 +346,7 @@ exports["Fn.s*"] = { }, }; + exports["Fn.u*"] = { setUp: function(done) { done(); @@ -257,11 +357,17 @@ exports["Fn.u*"] = { }, cast: function(test) { - test.expect(bitSizes.length); + test.expect(bitSizes.length * 7); bitSizes.forEach(function(bits) { var decimal = Fn["POW_2_" + bits]; + test.equal(Fn["u" + bits](decimal), decimal - 1); test.equal(Fn["u" + bits](decimal - 1), decimal - 1); + test.equal(Fn["u" + bits](-1), decimal - 1); + test.equal(Fn["u" + bits](decimal + 1), decimal - 1); + test.equal(Fn["u" + bits](-1 * decimal), 0); + test.equal(Fn["u" + bits](-1 * decimal + 1), 1); + test.equal(Fn["u" + bits](0), 0); }); test.done(); diff --git a/test/gyro.js b/test/gyro.js index 600f317c3..b1989d7ff 100644 --- a/test/gyro.js +++ b/test/gyro.js @@ -234,3 +234,10 @@ exports["Gyro -- MPU6050"] = { test.done(); } }; + +Object.keys(Gyro.Controllers).forEach(function(name) { + exports["Gyro - Controller, " + name] = addControllerTest(Gyro, Gyro.Controllers[name], { + controller: name, + sensitivity: 1 + }); +}); diff --git a/test/hygrometer.js b/test/hygrometer.js index f595f4d81..0548c108e 100644 --- a/test/hygrometer.js +++ b/test/hygrometer.js @@ -33,7 +33,7 @@ exports["Hygrometer -- SHT31D"] = { 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: "SHT31D", @@ -76,6 +76,33 @@ exports["Hygrometer -- SHT31D"] = { test.done(); }, + + oneHundredPercentHumidity: function(test) { + test.expect(5); + var readOnce; + var spy = this.sandbox.spy(); + + this.hygrometer.on("data", spy); + + this.clock.tick(20); + + test.equal(this.i2cReadOnce.callCount, 1); + test.equal(this.i2cReadOnce.lastCall.args[0], 0x44); + test.equal(this.i2cReadOnce.lastCall.args[1], 6); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ + 0, 0, // temperature + 0, // crc + 0xff, 0xff, // 100% humidity + 0 // crc + ]); + this.clock.tick(10); + + test.equal(spy.callCount, 1); + test.equal(this.hygrometer.relativeHumidity, 100); + test.done(); + } }; exports["Hygrometer -- HTU21D"] = { @@ -189,8 +216,39 @@ exports["Hygrometer -- HTU21D"] = { test.equal(Math.round(this.hygrometer.relativeHumidity), 40); test.done(); - } + }, + + oneHundredPercentHumidity: function(test) { + test.expect(8); + var readOnce; + var spy = this.sandbox.spy(); + + this.hygrometer.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); + + // The two numbers in the array passed to readOnce represent the two bytes + // of unsigned 16 bit integer which should convert to approximately 100% + // relative humidity. + // See https://github.com/rwaldron/johnny-five/issues/1278 + readOnce = this.i2cReadOnce.lastCall.args[3]; + readOnce([ 0xd9, 0 ]); + this.clock.tick(10); + test.equal(spy.callCount, 1); + test.equal(Math.round(this.hygrometer.relativeHumidity), 100); + test.done(); + } }; @@ -306,3 +364,131 @@ exports["Hygrometer -- SI7020"] = { test.done(); } }; + +exports["Hygrometer -- HIH6130"] = { + + setUp: function(done) { + this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); + this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); + this.i2cWrite = this.sandbox.spy(MockFirmata.prototype, "i2cWrite"); + + this.hygrometer = new Hygrometer({ + controller: "HIH6130", + board: this.board, + freq: 10 + }); + + this.instance = [{ + name: "relativeHumidity" + }]; + + done(); + }, + + tearDown: function(done) { + Board.purge(); + this.sandbox.restore(); + done(); + }, + + testShape: testShape, + + fwdOptionsToi2cConfig: function(test) { + test.expect(3); + + this.i2cConfig.reset(); + + new Hygrometer({ + controller: "HIH6130", + address: 0xff, + bus: "i2c-1", + board: this.board + }); + + var forwarded = this.i2cConfig.lastCall.args[0]; + + test.equal(this.i2cConfig.callCount, 1); + test.equal(forwarded.address, 0xff); + test.equal(forwarded.bus, "i2c-1"); + + test.done(); + }, + + data: function(test) { + test.expect(12); + var readOnce; + var spy = this.sandbox.spy(); + + this.hygrometer.on("data", spy); + + this.clock.tick(40); + + test.equal(this.i2cWrite.callCount, 2); + test.equal(this.i2cWrite.lastCall.args[1], 0x80); + test.equal(this.i2cWrite.lastCall.args[2][0], 0x00); + test.equal(this.i2cWrite.lastCall.args[2][1], 0x00); + + test.equal(this.i2cReadOnce.callCount, 1); + test.equal(this.i2cReadOnce.lastCall.args[0], 0x27); + test.equal(this.i2cReadOnce.lastCall.args[1], 4); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 38, 81, 96, 40 ]); + this.clock.tick(40); + + test.equal(this.i2cReadOnce.callCount, 2); + test.equal(this.i2cReadOnce.lastCall.args[0], 0x27); + test.equal(this.i2cReadOnce.lastCall.args[1], 4); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 102, 81, 96, 53 ]); + this.clock.tick(40); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 38, 81, 96, 12 ]); + this.clock.tick(40); + + test.equal(spy.callCount, 12); + test.equal(Math.round(this.hygrometer.relativeHumidity), 60); + test.done(); + }, + + change: function(test) { + test.expect(6); + + var readOnce; + var spy = this.sandbox.spy(); + + this.hygrometer.on("change", spy); + + this.clock.tick(40); + + test.equal(this.i2cReadOnce.callCount, 1); + test.equal(this.i2cReadOnce.lastCall.args[0], 0x27); + test.equal(this.i2cReadOnce.lastCall.args[1], 4); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 38, 81, 96, 12 ]); + this.clock.tick(40); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 50, 81, 96, 21 ]); + this.clock.tick(40); + + test.equal(Math.round(this.hygrometer.relativeHumidity), 79); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 38, 81, 102, 48 ]); + this.clock.tick(40); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 102, 81, 102, 53 ]); + this.clock.tick(40); + + test.equal(spy.callCount, 3); + test.equal(Math.round(this.hygrometer.relativeHumidity), 60); + + test.done(); + } + +}; diff --git a/test/imu.js b/test/imu.js index a9c22de24..0bddb2947 100644 --- a/test/imu.js +++ b/test/imu.js @@ -22,7 +22,7 @@ exports["IMU -- MPU6050"] = { }, { name: "accelerometer" }, { - name: "temperature" + name: "thermometer" }, { name: "gyro" }]; @@ -75,7 +75,7 @@ exports["IMU -- MPU6050"] = { components: function(test) { test.expect(1); - test.deepEqual(this.imu.components, ["accelerometer", "thermometer", "gyro"]); + test.deepEqual(this.imu.components, ["accelerometer", "gyro", "thermometer"]); test.done(); }, @@ -116,7 +116,7 @@ exports["IMU -- MPU6050"] = { test.equals(spy.args[0][0].accelerometer.x, 0.27); test.equals(spy.args[0][0].accelerometer.y, 0.53); test.equals(spy.args[0][0].accelerometer.z, 0.8); - test.equals(Math.round(spy.args[0][0].temperature.celsius), 49); + test.equals(Math.round(spy.args[0][0].thermometer.celsius), 49); test.equals(spy.args[0][0].gyro.x, 127); test.equals(spy.args[0][0].gyro.y, 128); test.equals(spy.args[0][0].gyro.z, 129); @@ -178,7 +178,7 @@ exports["Multi -- MPL115A2"] = { }, { name: "barometer" }, { - name: "temperature" + name: "thermometer" }]; done(); @@ -243,7 +243,7 @@ exports["Multi -- SHT31D"] = { this.clock = this.sandbox.useFakeTimers(); this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); this.i2cWrite = this.sandbox.spy(MockFirmata.prototype, "i2cWrite"); - this.i2cRead = this.sandbox.spy(MockFirmata.prototype, "i2cRead"); + this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); this.imu = new IMU({ controller: "SHT31D", freq: 100, @@ -257,7 +257,7 @@ exports["Multi -- SHT31D"] = { }, { name: "hygrometer" }, { - name: "temperature" + name: "thermometer" }]; done(); @@ -324,19 +324,22 @@ exports["Multi -- SHT31D"] = { test.ok(this.i2cWrite.calledTwice); test.deepEqual(this.i2cWrite.firstCall.args, [ 68, [ 48, 162 ] ]); test.deepEqual(this.i2cWrite.lastCall.args, [ 68, [ 36, 0 ] ]); - test.equal(this.i2cRead.callCount, 1); - var i2cRead = this.i2cRead.lastCall.args[2]; + this.clock.tick(100); + + test.equal(this.i2cReadOnce.callCount, 1); - i2cRead([ 100, 200, 169, 93, 90, 131 ]); + var i2cReadOnce = this.i2cReadOnce.lastCall.args[2]; + + i2cReadOnce([ 100, 200, 169, 93, 90, 131 ]); this.clock.tick(100); - i2cRead([ 100, 200, 169, 93, 90, 131 ]); + i2cReadOnce([ 100, 200, 169, 93, 90, 131 ]); this.clock.tick(100); - i2cRead([ 100, 200, 169, 93, 90, 131 ]); + i2cReadOnce([ 100, 200, 169, 93, 90, 131 ]); this.clock.tick(100); @@ -368,7 +371,7 @@ exports["Multi -- HTU21D"] = { }, { name: "hygrometer" }, { - name: "temperature" + name: "thermometer" }]; done(); @@ -449,7 +452,7 @@ exports["Multi -- MPL3115A2"] = { }, { name: "altimeter" }, { - name: "temperature" + name: "thermometer" }]; done(); @@ -501,7 +504,7 @@ exports["Multi -- MPL3115A2"] = { components: function(test) { test.expect(1); - test.deepEqual(this.imu.components, ["barometer", "altimeter", "thermometer"]); + test.deepEqual(this.imu.components, ["altimeter", "barometer", "thermometer"]); test.done(); }, @@ -600,7 +603,7 @@ exports["IMU -- BNO055"] = { components: function(test) { test.expect(1); - test.deepEqual(this.imu.components, ["accelerometer", "gyro", "magnetometer", "thermometer", "orientation"]); + test.deepEqual(this.imu.components, ["accelerometer", "gyro", "magnetometer", "orientation", "thermometer"]); test.done(); }, @@ -741,7 +744,7 @@ exports["IMU -- BNO055"] = { test.equal(this.imu.orientation.quarternion.x, iarg.orientation.quarternion.x); test.equal(this.imu.orientation.quarternion.y, iarg.orientation.quarternion.y); test.equal(this.imu.orientation.quarternion.z, iarg.orientation.quarternion.z); - test.equal(this.imu.temperature, iarg.temperature); + test.equal(this.imu.thermometer, iarg.thermometer); test.equal(this.imu.calibration, iarg.calibration); test.done(); @@ -793,7 +796,7 @@ exports["Multi -- TH02"] = { }, { name: "thermometer" }, { - name: "temperature" + name: "thermometer" }]; done(); @@ -931,7 +934,7 @@ exports["Multi -- DHT11_I2C_NANO_BACKPACK"] = { }, { name: "hygrometer" }, { - name: "temperature" + name: "thermometer" }]; done(); @@ -1103,8 +1106,6 @@ exports["Multi -- BME280"] = { name: "hygrometer" }, { name: "thermometer" - }, { - name: "temperature" }]; done(); diff --git a/test/johnny-five.js b/test/johnny-five.js new file mode 100644 index 000000000..4b5703dac --- /dev/null +++ b/test/johnny-five.js @@ -0,0 +1,172 @@ +require("./common/bootstrap"); + +exports["Alias: Analog"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + this.Sensor = this.sandbox.stub(five, "Sensor"); + done(); + }, + + tearDown: function(done) { + Board.purge(); + this.sandbox.restore(); + done(); + }, + + callWithPinNumber: function(test) { + test.expect(2); + + new Analog(1); + + test.equal(this.Sensor.callCount, 1); + test.equal(this.Sensor.lastCall.args[0], 1); + test.done(); + }, + + callWithOptions: function(test) { + test.expect(2); + var options = { pin: "A1" }; + + new Analog(options); + + test.equal(this.Sensor.callCount, 1); + test.equal(this.Sensor.lastCall.args[0], options); + test.done(); + }, +}; + +exports["Alias: Digital"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + this.Sensor = this.sandbox.stub(five, "Sensor"); + done(); + }, + + tearDown: function(done) { + Board.purge(); + this.sandbox.restore(); + done(); + }, + + callWithPinNumber: function(test) { + test.expect(4); + + new Digital(1); + + test.equal(this.Sensor.callCount, 1); + test.deepEqual(this.Sensor.lastCall.args[0], { type: "digital", pin: 1 }); + + new Digital("1"); + + test.equal(this.Sensor.callCount, 2); + test.deepEqual(this.Sensor.lastCall.args[0], { type: "digital", pin: "1" }); + test.done(); + }, + + callWithOptions: function(test) { + test.expect(2); + var options = { pin: "A1" }; + + new Digital(options); + + test.equal(this.Sensor.callCount, 1); + test.equal(this.Sensor.lastCall.args[0], options); + test.done(); + }, +}; + +exports["Alias: Luxmeter"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + this.Light = this.sandbox.stub(five, "Light"); + done(); + }, + + tearDown: function(done) { + Board.purge(); + this.sandbox.restore(); + done(); + }, + + callWithOptions: function(test) { + test.expect(2); + var options = { pin: "A1" }; + + new Luxmeter(options); + + test.equal(this.Light.callCount, 1); + test.equal(this.Light.lastCall.args[0], options); + test.done(); + }, +}; + +exports["Alias: Magnetometer"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + this.Compass = this.sandbox.stub(five, "Compass"); + done(); + }, + + tearDown: function(done) { + Board.purge(); + this.sandbox.restore(); + done(); + }, + + callWithOptions: function(test) { + test.expect(2); + var options = { pin: "A1" }; + + new Magnetometer(options); + + test.equal(this.Compass.callCount, 1); + test.equal(this.Compass.lastCall.args[0], options); + test.done(); + }, +}; + + +exports["Deprecated"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + done(); + }, + + tearDown: function(done) { + this.sandbox.restore(); + done(); + }, + + IR: function(test) { + test.expect(1); + test.throws(function() { + new five.IR(); + }); + test.done(); + }, + "IR.Distance": function(test) { + test.expect(1); + test.throws(function() { + new five.IR.Distance(); + }); + test.done(); + }, + "IR.Proximity": function(test) { + test.expect(1); + test.throws(function() { + new five.IR.Proximity(); + }); + test.done(); + }, + "IR.Motion": function(test) { + test.expect(1); + test.throws(function() { + new five.IR.Motion(); + }); + test.done(); + }, +}; diff --git a/test/joystick.js b/test/joystick.js index da73f97f3..586892534 100644 --- a/test/joystick.js +++ b/test/joystick.js @@ -653,3 +653,10 @@ exports["Joystick -- ESPLORA"] = { test.done(); } }; + +Object.keys(Joystick.Controllers).forEach(function(name) { + exports["Joystick - Controller, " + name] = addControllerTest(Joystick, Joystick.Controllers[name], { + controller: name, + pins: [] + }); +}); diff --git a/test/lcd.js b/test/lcd.js index bb827e34e..23880d681 100644 --- a/test/lcd.js +++ b/test/lcd.js @@ -245,6 +245,58 @@ exports["LCD"] = { test.done(); }, + useCharRestrictsTo8InMemory: function(test) { + test.expect(2); + + var ccSpy = this.sandbox.spy(this.lcd, "createChar"); + var characters = [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16", + "17", + "18", + "19", + "circle", + "cdot", + "donut", + "ball", + ]; + + characters.forEach(function(character) { + this.lcd.useChar(character); + }, this); + + // Only the last 8 "used" characters + // are stored in memory + test.deepEqual(this.lcd.characters, { + "16": 7, + "17": 6, + "18": 5, + "19": 4, + circle: 3, + cdot: 2, + donut: 1, + ball: 0 + }); + + test.equal(ccSpy.callCount, characters.length); + test.done(); + }, + printRegularTexts: function(test) { // No test.expect() as these are a bit cumbersome/coupled to obtain @@ -409,8 +461,42 @@ exports["LCD - I2C (JHD1313M1)"] = { test.done(); }, + bgOn: function(test) { + test.expect(2); + + var lcd = new LCD({ + controller: "JHD1313M1", + board: this.board + }); + + this.i2cWrite.reset(); + + lcd.bgOn(); + + test.equal(this.i2cWrite.callCount, 1); + test.deepEqual(this.i2cWrite.lastCall.args, [ 98, [ 0x08, 0xAA ] ]); + test.done(); + }, + + bgOff: function(test) { + test.expect(2); + + var lcd = new LCD({ + controller: "JHD1313M1", + board: this.board + }); + + this.i2cWrite.reset(); + + lcd.bgOff(); + + test.equal(this.i2cWrite.callCount, 1); + test.deepEqual(this.i2cWrite.lastCall.args, [ 98, [ 0x08, 0x00 ] ]); + test.done(); + }, + bgColor: function(test) { - test.expect(36); + test.expect(38); var lcd = new LCD({ controller: "JHD1313M1", @@ -425,9 +511,13 @@ exports["LCD - I2C (JHD1313M1)"] = { test.equal(this.ToRGB.callCount, 1); test.deepEqual(this.ToRGB.firstCall.args, [[0, 0, 0], undefined, undefined]); test.deepEqual(this.ToRGB.lastCall.returnValue, {red: 0, green: 0, blue: 0}); - test.deepEqual(this.i2cWrite.getCall(0).args, [ 98, [ 4, 0 ] ]); - test.deepEqual(this.i2cWrite.getCall(1).args, [ 98, [ 3, 0 ] ]); - test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 2, 0 ] ]); + + + test.deepEqual(this.i2cWrite.getCall(0).args, [ 98, [ 0, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(1).args, [ 98, [ 1, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 4, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(3).args, [ 98, [ 3, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(4).args, [ 98, [ 2, 0 ] ]); this.ToRGB.reset(); this.i2cWrite.reset(); @@ -437,9 +527,9 @@ exports["LCD - I2C (JHD1313M1)"] = { test.equal(this.ToRGB.callCount, 1); test.deepEqual(this.ToRGB.firstCall.args, [0xff, 0xff, 0xff]); test.deepEqual(this.ToRGB.lastCall.returnValue, {red: 0xFF, green: 0xFF, blue: 0xFF}); - test.deepEqual(this.i2cWrite.getCall(0).args, [ 98, [ 4, 0xFF ] ]); - test.deepEqual(this.i2cWrite.getCall(1).args, [ 98, [ 3, 0xFF ] ]); - test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 2, 0xFF ] ]); + test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 4, 0xFF ] ]); + test.deepEqual(this.i2cWrite.getCall(3).args, [ 98, [ 3, 0xFF ] ]); + test.deepEqual(this.i2cWrite.getCall(4).args, [ 98, [ 2, 0xFF ] ]); this.ToRGB.reset(); this.i2cWrite.reset(); @@ -449,9 +539,9 @@ exports["LCD - I2C (JHD1313M1)"] = { test.equal(this.ToRGB.callCount, 1); test.deepEqual(this.ToRGB.firstCall.args, ["ff0000", undefined, undefined]); test.deepEqual(this.ToRGB.lastCall.returnValue, {red: 0xFF, green: 0, blue: 0}); - test.deepEqual(this.i2cWrite.getCall(0).args, [ 98, [ 4, 0xFF ] ]); - test.deepEqual(this.i2cWrite.getCall(1).args, [ 98, [ 3, 0 ] ]); - test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 2, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 4, 0xFF ] ]); + test.deepEqual(this.i2cWrite.getCall(3).args, [ 98, [ 3, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(4).args, [ 98, [ 2, 0 ] ]); this.ToRGB.reset(); this.i2cWrite.reset(); @@ -461,9 +551,9 @@ exports["LCD - I2C (JHD1313M1)"] = { test.equal(this.ToRGB.callCount, 1); test.deepEqual(this.ToRGB.firstCall.args, ["#ff0000", undefined, undefined]); test.deepEqual(this.ToRGB.lastCall.returnValue, {red: 0xFF, green: 0, blue: 0}); - test.deepEqual(this.i2cWrite.getCall(0).args, [ 98, [ 4, 0xFF ] ]); - test.deepEqual(this.i2cWrite.getCall(1).args, [ 98, [ 3, 0 ] ]); - test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 2, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 4, 0xFF ] ]); + test.deepEqual(this.i2cWrite.getCall(3).args, [ 98, [ 3, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(4).args, [ 98, [ 2, 0 ] ]); this.ToRGB.reset(); this.i2cWrite.reset(); @@ -473,9 +563,9 @@ exports["LCD - I2C (JHD1313M1)"] = { test.equal(this.ToRGB.callCount, 1); test.deepEqual(this.ToRGB.firstCall.args, [{red: 0, green: 0xFF, blue: 0}, undefined, undefined]); test.deepEqual(this.ToRGB.lastCall.returnValue, {red: 0, green: 0xFF, blue: 0}); - test.deepEqual(this.i2cWrite.getCall(0).args, [ 98, [ 4, 0 ] ]); - test.deepEqual(this.i2cWrite.getCall(1).args, [ 98, [ 3, 0xFF ] ]); - test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 2, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 4, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(3).args, [ 98, [ 3, 0xFF ] ]); + test.deepEqual(this.i2cWrite.getCall(4).args, [ 98, [ 2, 0 ] ]); this.ToRGB.reset(); this.i2cWrite.reset(); @@ -486,9 +576,9 @@ exports["LCD - I2C (JHD1313M1)"] = { test.equal(this.ToRGB.callCount, 2); test.deepEqual(this.ToRGB.firstCall.args, ["blue", undefined, undefined]); test.deepEqual(this.ToRGB.lastCall.returnValue, {red: 0, green: 0, blue: 0xFF}); - test.deepEqual(this.i2cWrite.getCall(0).args, [ 98, [ 4, 0 ] ]); - test.deepEqual(this.i2cWrite.getCall(1).args, [ 98, [ 3, 0 ] ]); - test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 2, 0xFF ] ]); + test.deepEqual(this.i2cWrite.getCall(2).args, [ 98, [ 4, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(3).args, [ 98, [ 3, 0 ] ]); + test.deepEqual(this.i2cWrite.getCall(4).args, [ 98, [ 2, 0xFF ] ]); test.done(); }, @@ -542,7 +632,7 @@ exports["LCD - I2C (LCD2004)"] = { board: this.board }); - test.equal(this.i2cWrite.callCount, 30); + test.equal(this.i2cWrite.callCount, 34); test.done(); }, @@ -667,7 +757,7 @@ exports["LCD - I2C (LCM1602)"] = { board: this.board }); - test.equal(this.i2cWrite.callCount, 30); + test.equal(this.i2cWrite.callCount, 34); test.done(); }, @@ -791,41 +881,45 @@ exports["LCD - PCF8574"] = { board: this.board }); - test.equal(this.i2cWrite.callCount, 30); + test.equal(this.i2cWrite.callCount, 34); // This is the expected write sequence. // If this changes, the controller will not function. var sequence = [ - [39, 0], - [39, 48], - [39, 52], - [39, 48], - [39, 48], - [39, 52], - [39, 48], - [39, 48], - [39, 52], - [39, 48], - [39, 32], - [39, 36], - [39, 32], - [39, 36], - [39, 32], - [39, 132], - [39, 128], - [39, 4], - [39, 0], - [39, 196], - [39, 192], - [39, 4], - [39, 0], - [39, 20], - [39, 16], - [39, 4], - [39, 0], - [39, 100], - [39, 96], - [39, 8] + [ 39, 0 ], + [ 39, 48 ], + [ 39, 52 ], + [ 39, 48 ], + [ 39, 48 ], + [ 39, 52 ], + [ 39, 48 ], + [ 39, 48 ], + [ 39, 52 ], + [ 39, 48 ], + [ 39, 32 ], + [ 39, 36 ], + [ 39, 32 ], + [ 39, 36 ], + [ 39, 32 ], + [ 39, 132 ], + [ 39, 128 ], + [ 39, 4 ], + [ 39, 0 ], + [ 39, 196 ], + [ 39, 192 ], + [ 39, 4 ], + [ 39, 0 ], + [ 39, 100 ], + [ 39, 96 ], + [ 39, 4 ], + [ 39, 0 ], + [ 39, 228 ], + [ 39, 224 ], + [ 39, 4 ], + [ 39, 0 ], + [ 39, 20 ], + [ 39, 16 ], + [ 39, 8 ] ]; test.deepEqual(this.i2cWrite.args, sequence); @@ -952,43 +1046,46 @@ exports["LCD - MJKDZ"] = { board: this.board }); - test.equal(this.i2cWrite.callCount, 30); + test.equal(this.i2cWrite.callCount, 34); // This is the expected write sequence. // If this changes, the controller will not function. var sequence = [ - [39, 0], - [39, 3], - [39, 19], - [39, 3], - [39, 3], - [39, 19], - [39, 3], - [39, 3], - [39, 19], - [39, 3], - [39, 2], - [39, 18], - [39, 2], - [39, 18], - [39, 2], - [39, 24], - [39, 8], - [39, 16], - [39, 0], - [39, 28], - [39, 12], - [39, 16], - [39, 0], - [39, 17], - [39, 1], - [39, 16], - [39, 0], - [39, 22], - [39, 6], - [39, 8] + [ 39, 0 ], + [ 39, 3 ], + [ 39, 19 ], + [ 39, 3 ], + [ 39, 3 ], + [ 39, 19 ], + [ 39, 3 ], + [ 39, 3 ], + [ 39, 19 ], + [ 39, 3 ], + [ 39, 2 ], + [ 39, 18 ], + [ 39, 2 ], + [ 39, 18 ], + [ 39, 2 ], + [ 39, 24 ], + [ 39, 8 ], + [ 39, 16 ], + [ 39, 0 ], + [ 39, 28 ], + [ 39, 12 ], + [ 39, 16 ], + [ 39, 0 ], + [ 39, 22 ], + [ 39, 6 ], + [ 39, 16 ], + [ 39, 0 ], + [ 39, 30 ], + [ 39, 14 ], + [ 39, 16 ], + [ 39, 0 ], + [ 39, 17 ], + [ 39, 1 ], + [ 39, 8 ], ]; - test.deepEqual(this.i2cWrite.args, sequence); test.done(); }, diff --git a/test/light.js b/test/light.js index 1872fd195..f3553ff85 100644 --- a/test/light.js +++ b/test/light.js @@ -1,13 +1,15 @@ require("./common/bootstrap"); var proto = [{ - name: "within" + name: "within", }]; var instance = [{ - name: "value" + name: "value", }, { - name: "level" + name: "level", +}, { + name: "lux", }]; exports["Light"] = { @@ -15,18 +17,14 @@ exports["Light"] = { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); this.clock = this.sandbox.useFakeTimers(); - this.analogRead = this.sandbox.spy(MockFirmata.prototype, "analogRead"); - this.light = new Light({ - pin: "A1", - freq: 100, - board: this.board - }); + this.sandbox.spy(Board, "Component"); done(); }, tearDown: function(done) { Board.purge(); + Light.purge(); this.sandbox.restore(); done(); }, @@ -34,6 +32,12 @@ exports["Light"] = { shape: function(test) { test.expect(proto.length + instance.length); + this.light = new Light({ + pin: "A1", + freq: 100, + board: this.board + }); + proto.forEach(function(method) { test.equal(typeof this.light[method.name], "function"); }, this); @@ -45,11 +49,61 @@ exports["Light"] = { test.done(); }, + instanceof: function(test) { + test.expect(1); + test.equal(Light({ board: this.board }) instanceof Light, true); + test.done(); + }, + + component: function(test) { + test.expect(1); + + new Light({ board: this.board }); + + test.equal(Board.Component.callCount, 1); + test.done(); + }, + emitter: function(test) { test.expect(1); + + this.light = new Light({ + pin: "A1", + freq: 100, + board: this.board + }); + test.ok(this.light instanceof Emitter); test.done(); - } + }, + + customIntensityLevel: function(test) { + test.expect(2); + + this.light = new Light({ + board: this.board, + controller: {}, + toIntensityLevel: function(x) { + test.ok(true); + return x * x; + }, + }); + + test.equal(this.light.toIntensityLevel(2), 4); + test.done(); + }, + + fallbackIntensityLevel: function(test) { + test.expect(1); + + this.light = new Light({ + board: this.board, + controller: {}, + }); + + test.equal(this.light.toIntensityLevel(2), 2); + test.done(); + }, }; exports["Light: ALSPT19"] = { @@ -70,6 +124,7 @@ exports["Light: ALSPT19"] = { tearDown: function(done) { Board.purge(); + Light.purge(); this.sandbox.restore(); done(); }, @@ -95,6 +150,168 @@ exports["Light: ALSPT19"] = { } }; +exports["Light: BH1750"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + this.clock = this.sandbox.useFakeTimers(); + + this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); + this.i2cWrite = this.sandbox.spy(MockFirmata.prototype, "i2cWrite"); + this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); + + this.light = new Light({ + controller: "BH1750", + board: this.board + }); + + done(); + }, + + tearDown: function(done) { + Board.purge(); + Light.purge(); + this.sandbox.restore(); + done(); + }, + + fwdOptionsToi2cConfig: function(test) { + test.expect(3); + + this.i2cConfig.reset(); + + new Light({ + controller: "BH1750", + address: 0xff, + bus: "i2c-1", + board: this.board + }); + + var forwarded = this.i2cConfig.lastCall.args[0]; + + test.equal(this.i2cConfig.callCount, 1); + test.equal(forwarded.address, 0xff); + test.equal(forwarded.bus, "i2c-1"); + + test.done(); + }, + + initialization: function(test) { + test.expect(4); + test.equal(this.i2cConfig.callCount, 1); + test.equal(this.i2cWrite.callCount, 1); + test.equal(this.i2cWrite.lastCall.args[0], 0x23); + test.equal(this.i2cWrite.lastCall.args[1], 0x10); + test.done(); + }, + + data: function(test) { + test.expect(3); + + this.clock.tick(120); + + var read = this.i2cReadOnce.lastCall.args[2]; + var spy = this.sandbox.spy(); + + this.light.on("data", spy); + + read([ 3, 84 ]); + + this.clock.tick(25); + + test.equal(spy.callCount, 1); + test.equal(this.light.level, 0.01); + test.equal(this.light.lux, 710); + + test.done(); + }, + + change: function(test) { + test.expect(6); + + this.clock.tick(120); + + var read = this.i2cReadOnce.lastCall.args[2]; + var spy = this.sandbox.spy(); + + this.light.on("change", spy); + + read([ 3, 84 ]); + this.clock.tick(25); + test.equal(spy.callCount, 1); + test.equal(this.light.level, 0.01); + test.equal(this.light.lux, 710); + + this.clock.tick(120); + + read([ 3, 95 ]); + this.clock.tick(25); + test.equal(spy.callCount, 2); + test.equal(this.light.level, 0.01); + test.equal(this.light.lux, 719); + + test.done(); + }, +}; + +exports["Light: TSL2561"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + this.clock = this.sandbox.useFakeTimers(); + + this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); + this.i2cWrite = this.sandbox.spy(MockFirmata.prototype, "i2cWrite"); + this.i2cWriteReg = this.sandbox.spy(MockFirmata.prototype, "i2cWriteReg"); + this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); + + this.light = new Light({ + controller: "TSL2561", + board: this.board + }); + + done(); + }, + + tearDown: function(done) { + Board.purge(); + Light.purge(); + this.sandbox.restore(); + done(); + }, + + fwdOptionsToi2cConfig: function(test) { + test.expect(3); + + this.i2cConfig.reset(); + + new Light({ + controller: "TSL2561", + address: 0xff, + bus: "i2c-1", + board: this.board + }); + + var forwarded = this.i2cConfig.lastCall.args[0]; + + test.equal(this.i2cConfig.callCount, 1); + test.equal(forwarded.address, 0xff); + test.equal(forwarded.bus, "i2c-1"); + + test.done(); + }, + + initialization: function(test) { + test.expect(4); + test.equal(this.i2cConfig.callCount, 1); + test.equal(this.i2cWriteReg.callCount, 3); + test.equal(this.i2cWriteReg.lastCall.args[0], 0x39); + test.equal(this.i2cWriteReg.lastCall.args[1], 0x81); + test.done(); + }, + +}; + exports["Light: EVS_EV3, Ambient (Default)"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); @@ -123,6 +340,7 @@ exports["Light: EVS_EV3, Ambient (Default)"] = { tearDown: function(done) { Board.purge(); + Light.purge(); this.sandbox.restore(); done(); }, @@ -230,6 +448,7 @@ exports["Light: EVS_EV3, Reflected"] = { tearDown: function(done) { Board.purge(); + Light.purge(); this.sandbox.restore(); done(); }, @@ -336,6 +555,7 @@ exports["Light: EVS_NXT, Ambient (Default)"] = { tearDown: function(done) { Board.purge(); + Light.purge(); this.sandbox.restore(); done(); }, @@ -442,6 +662,7 @@ exports["Light: EVS_NXT, Reflected"] = { tearDown: function(done) { Board.purge(); + Light.purge(); this.sandbox.restore(); done(); }, @@ -518,3 +739,4 @@ exports["Light: EVS_NXT, Reflected"] = { test.done(); } }; + diff --git a/test/motion.js b/test/motion.js index 17ed76574..26c62f617 100644 --- a/test/motion.js +++ b/test/motion.js @@ -540,3 +540,9 @@ exports["Motion - GP2Y0A60SZLF"] = { test.done(); } }; + +Object.keys(Motion.Controllers).forEach(function(name) { + exports["Motion - Controller, " + name] = addControllerTest(Motion, Motion.Controllers[name], { + controller: name, + }); +}); diff --git a/test/motor.js b/test/motor.js index cafd7c046..5caaef08a 100644 --- a/test/motor.js +++ b/test/motor.js @@ -2382,3 +2382,16 @@ exports["Motor: GROVE_I2C_MOTOR_DRIVER"] = { test.done(); } }; + + +Object.keys(Motor.Controllers).forEach(function(name) { + + // These are duplicates + if (name.startsWith("GROVE_") || name.startsWith("EVS_") || name.startsWith("Shift")) { + return; + } + + exports["Motor - Controller, " + name] = addControllerTest(Motor, Motor.Controllers[name], { + controller: name, + }); +}); diff --git a/test/proximity.js b/test/proximity.js index 068ead7f3..0c6876adc 100644 --- a/test/proximity.js +++ b/test/proximity.js @@ -1635,6 +1635,19 @@ exports["Proximity.Collection"] = { }, }; +Object.keys(Proximity.Controllers).forEach(function(name) { + + // These are duplicates + if (name.startsWith("EVS_") || name.includes("MaxSonar") || name.startsWith("LIDAR")) { + return; + } + + exports["Proximity - Controller, " + name] = addControllerTest(Proximity, Proximity.Controllers[name], { + controller: name, + pin: 1 + }); +}); + // - GP2Y0A21YK // https://www.sparkfun.com/products/242 // - GP2D120XJ00F diff --git a/test/repl.js b/test/repl.js index 1806ca690..bc8d2a9ff 100644 --- a/test/repl.js +++ b/test/repl.js @@ -3,6 +3,7 @@ require("./common/bootstrap"); exports["Repl"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); done(); }, tearDown: function(done) { @@ -10,6 +11,11 @@ exports["Repl"] = { this.sandbox.restore(); done(); }, + instanceof: function(test) { + test.expect(1); + test.equal(Repl({ board: this.board }) instanceof Repl, true); + test.done(); + }, repl: function(test) { var io = new MockFirmata(); var board = new Board({ @@ -38,9 +44,16 @@ exports["Repl"] = { debug: false }); + // Extra-careful guard against calling test.done() twice here. + // This was causing "Cannot read property 'setUp' of undefined" errors + // See https://github.com/caolan/nodeunit/issues/234 + var calledTestDone = false; var reallyExit = this.sandbox.stub(process, "reallyExit", function() { reallyExit.restore(); - test.done(); + if (!calledTestDone) { + calledTestDone = true; + test.done(); + } }); board.on("ready", function() { diff --git a/test/rgb.js b/test/rgb.js index ff9dd180d..f0df8a450 100644 --- a/test/rgb.js +++ b/test/rgb.js @@ -1225,50 +1225,35 @@ exports["RGB.ToRGB"] = { "ToRGB([Byte, Byte, Byte])": function(test) { test.expect(2); - - var color = Led.RGB.ToRGB([0x00, 0x00, 0x00]); - - test.deepEqual(color, { red: 0, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB([0x00, 0x00, 0x00]), { red: 0, green: 0, blue: 0 }); test.equal(this.ToRGB.callCount, 1); test.done(); }, "ToRGB({ red, green, blue })": function(test) { test.expect(2); - - var color = Led.RGB.ToRGB({ red: 0, green: 0, blue: 0 }); - - test.deepEqual(color, { red: 0, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB({ red: 0, green: 0, blue: 0 }), { red: 0, green: 0, blue: 0 }); test.equal(this.ToRGB.callCount, 1); test.done(); }, "ToRGB('hex')": function(test) { test.expect(2); - - var color = Led.RGB.ToRGB("000000"); - - test.deepEqual(color, { red: 0, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("000000"), { red: 0, green: 0, blue: 0 }); test.equal(this.ToRGB.callCount, 1); test.done(); }, "ToRGB('#hex')": function(test) { test.expect(2); - - var color = Led.RGB.ToRGB("#000000"); - - test.deepEqual(color, { red: 0, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("#000000"), { red: 0, green: 0, blue: 0 }); test.equal(this.ToRGB.callCount, 1); test.done(); }, "ToRGB('name')": function(test) { test.expect(3); - - var color = Led.RGB.ToRGB("red"); - - test.deepEqual(color, { red: 0xFF, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("red"), { red: 0xFF, green: 0, blue: 0 }); // This is called TWICE because the name is // translated, and the resulting object is // passed as an argument to color(...) @@ -1279,11 +1264,45 @@ exports["RGB.ToRGB"] = { "ToRGB(red, green, blue)": function(test) { test.expect(2); + test.deepEqual(Led.RGB.ToRGB(0xFF, 0x00, 0x00), { red: 0xFF, green: 0, blue: 0 }); + test.equal(this.ToRGB.callCount, 1); + test.done(); + }, - var color = Led.RGB.ToRGB(0xFF, 0x00, 0x00); + "ToRGB('rgb(r, g, b)')": function(test) { + test.expect(4); - test.deepEqual(color, { red: 0xFF, green: 0, blue: 0 }); - test.equal(this.ToRGB.callCount, 1); + test.deepEqual(Led.RGB.ToRGB("rgb(255,0,0)"), { red: 255, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("rgb(255, 0, 0)"), { red: 255, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("rgb(100%, 0%, 0%)"), { red: 255, green: 0, blue: 0 }); + test.equal(this.ToRGB.callCount, 3); + test.done(); + }, + + "ToRGB('rgba(r, g, b, a)')": function(test) { + test.expect(5); + test.deepEqual(Led.RGB.ToRGB("rgb(255,0,0,1)"), { red: 255, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("rgb(255, 0, 0, 1)"), { red: 255, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("rgb(255, 0, 0, 0.5)"), { red: 128, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("rgb(100%, 0%, 0%, 50%)"), { red: 128, green: 0, blue: 0 }); + test.equal(this.ToRGB.callCount, 4); + test.done(); + }, + + "ToRGB('rgb(r g b)')": function(test) { + test.expect(3); + test.deepEqual(Led.RGB.ToRGB("rgb(255 0 0)"), { red: 255, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("rgb(100% 0% 0%)"), { red: 255, green: 0, blue: 0 }); + test.equal(this.ToRGB.callCount, 2); + test.done(); + }, + + "ToRGB('rgba(r g b a)')": function(test) { + test.expect(4); + test.deepEqual(Led.RGB.ToRGB("rgb(255 0 0 1)"), { red: 255, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("rgb(255 0 0 0.5)"), { red: 128, green: 0, blue: 0 }); + test.deepEqual(Led.RGB.ToRGB("rgb(100% 0% 0% 50%)"), { red: 128, green: 0, blue: 0 }); + test.equal(this.ToRGB.callCount, 3); test.done(); }, @@ -1312,3 +1331,10 @@ exports["RGB.ToScaledRGB"] = { test.done(); }, }; + +Object.keys(RGB.Controllers).forEach(function(name) { + exports["RGB - Controller, " + name] = addControllerTest(RGB, RGB.Controllers[name], { + controller: name, + pins: [1, 2, 3] + }); +}); diff --git a/test/sensor.js b/test/sensor.js index 5fed393a9..238cddbc3 100644 --- a/test/sensor.js +++ b/test/sensor.js @@ -7,6 +7,7 @@ function getShape(sensor) { mode: sensor.mode, freq: sensor.freq, range: sensor.range, + resolution: sensor.resolution, limit: sensor.limit, threshold: sensor.threshold, isScaled: sensor.isScaled, @@ -21,6 +22,54 @@ function getShape(sensor) { }; } +exports["Sensor - Resolution"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + this.clock = this.sandbox.useFakeTimers(); + this.analogRead = this.sandbox.spy(MockFirmata.prototype, "analogRead"); + // this.sensor = new Sensor({ + // pin: "A1", + // board: this.board + // }); + + done(); + }, // ./setUp: function(done) + + tearDown: function(done) { + Board.purge(); + this.sandbox.restore(); + done(); + }, // ./tearDown: function(done) + + defaultBitResolution: function(test) { + test.expect(1); + + this.sensor = new Sensor({ + pin: "A1", + board: this.board + }); + + test.equal(this.sensor.resolution, 1023); + test.done(); + }, // ./defaultBitResolution: function(test) + + ioPluginProvidesBitResolution: function(test) { + test.expect(1); + + this.board.io.RESOLUTION = { + ADC: 0xFFF, + }; + + this.sensor = new Sensor({ + pin: "A1", + board: this.board + }); + + test.equal(this.sensor.resolution, 4095); + test.done(); + }, // ./ioPluginProvidesBitResolution: function(test) +}; exports["Sensor - Analog"] = { setUp: function(done) { @@ -41,6 +90,7 @@ exports["Sensor - Analog"] = { mode: this.sensor.io.MODES.ANALOG, freq: 25, range: [0, 1023], + resolution: 1023, limit: null, threshold: 1, isScaled: false, @@ -86,6 +136,9 @@ exports["Sensor - Analog"] = { range: { type: "object" }, + resolution: { + type: "number" + }, threshold: { type: "number" }, @@ -134,6 +187,12 @@ exports["Sensor - Analog"] = { done(); }, // ./tearDown: function(done) + instanceof: function(test) { + test.expect(1); + test.equal(Sensor({}) instanceof Sensor, true); + test.done(); + }, + shape: function(test) { var propsActual, propsExpected, methodsActual; propsActual = Object.getOwnPropertyNames(this.sensor); @@ -710,6 +769,20 @@ exports["Sensor - Analog"] = { test.done(); }, // ./threshold: function(test) + + thresholdExplicit: function(test) { + this.sensor = new Sensor({ + pin: "A2", + board: this.board, + threshold: 5, + }); + + test.expect(1); + test.strictEqual(this.sensor.threshold, 5); + test.done(); + }, // ./thresholdExplicit: function(test) + + id: function(test) { var newShape, newId; test.expect(3); @@ -1088,10 +1161,10 @@ exports["Sensor - Analog"] = { scaleTo: function(test) { var callback = this.analogRead.args[0][1]; - test.expect(3); + test.expect(4); this.sensor.once("change", function() { - test.equal(this.scaleTo(50, 100), 100); + test.equal(this.scaleTo([50, 100]), 100); }); callback(1023); this.clock.tick(25); @@ -1106,6 +1179,7 @@ exports["Sensor - Analog"] = { this.sensor.scale([0, 102.3]); this.sensor.once("change", function() { test.equal(this.fscaleTo([0, 102.3]), 1.2000000476837158); + test.equal(this.fscaleTo(0, 102.3), 1.2000000476837158); }); callback(12); this.clock.tick(25); @@ -1275,6 +1349,31 @@ exports["Sensor - Analog"] = { callback(1023); this.clock.tick(25); + test.equal(spy.callCount, 2); + test.done(); + }, + + enableFalse: function(test) { + + this.sensor = new Sensor({ + pin: "A2", + board: this.board, + enabled: false, + }); + + var callback = this.analogRead.args[0][1]; + var spy = this.sandbox.spy(); + + test.expect(1); + + this.sensor.on("data", spy); + this.sensor.on("change", spy); + + this.sensor.enable(); + + callback(1023); + this.clock.tick(25); + test.equal(spy.callCount, 2); test.done(); } @@ -1482,6 +1581,12 @@ exports["Sensor.Collection"] = { done(); }, + instanceof: function(test) { + test.expect(1); + test.equal(Sensor.Collection({}) instanceof Sensor.Collection, true); + test.done(); + }, + data: function(test) { test.expect(4); diff --git a/test/servo.collection.js b/test/servo.collection.js new file mode 100644 index 000000000..e153e7964 --- /dev/null +++ b/test/servo.collection.js @@ -0,0 +1,211 @@ +require("./common/bootstrap"); + +exports["Servo.Collection"] = { + setUp: function(done) { + this.sandbox = sinon.sandbox.create(); + this.board = newBoard(); + + Servo.purge(); + + this.a = new Servo({ + pin: 3, + board: this.board + }); + + this.b = new Servo({ + pin: 6, + board: this.board + }); + + this.c = new Servo({ + pin: 9, + board: this.board + }); + + this.spies = [ + "to", "stop" + ]; + + this.spies.forEach(function(method) { + this[method] = this.sandbox.spy(Servo.prototype, method); + }.bind(this)); + + this.servoWrite = this.sandbox.spy(MockFirmata.prototype, "servoWrite"); + + done(); + }, + + tearDown: function(done) { + Board.purge(); + Servo.purge(); + this.sandbox.restore(); + done(); + }, + + instanceof: function(test) { + test.expect(1); + test.equal(Servos({}) instanceof Servos, true); + test.done(); + }, + + initFromServoNumbers: function(test) { + test.expect(1); + + var servos = new Servo.Collection([3, 6, 9]); + test.equal(servos.length, 3); + test.done(); + }, + + initFromServos: function(test) { + test.expect(1); + + var servos = new Servo.Collection([ + this.a, this.b, this.c + ]); + test.equal(servos.length, 3); + test.done(); + }, + + callForwarding: function(test) { + test.expect(3); + + var servos = new Servo.Collection([3, 6, 9]); + + servos.to(90); + test.equal(this.to.callCount, servos.length); + test.equal(this.to.getCall(0).args[0], 90); + + servos.stop(); + test.equal(this.stop.callCount, servos.length); + + test.done(); + }, + + home: function(test) { + test.expect(4); + + this.servos = new Servo.Collection([{ + pin: 9, + board: this.board, + startAt: 40 + }, { + pin: 11, + board: this.board, + startAt: 20 + }]); + + this.servos.to(180); + test.ok(this.servoWrite.calledWith(9, 180)); + test.ok(this.servoWrite.calledWith(11, 180)); + + this.servos.home(); + test.ok(this.servoWrite.calledWith(9, 40)); + test.ok(this.servoWrite.calledWith(11, 20)); + + test.done(); + }, + + collectionFromArray: function(test) { + test.expect(9); + + var servos = new Servo.Collection([this.a, this.b]); + var collectionFromArray = new Servo.Collection([servos, this.c]); + + collectionFromArray.to(90); + test.equal(this.to.callCount, 3); + test.equal(this.to.getCall(0).args[0], 90); + test.equal(this.to.getCall(1).args[0], 90); + test.equal(this.to.getCall(2).args[0], 90); + test.equal(collectionFromArray.length, 2); + test.equal(collectionFromArray[0][0], this.a); + test.equal(collectionFromArray[0][1], this.b); + test.equal(collectionFromArray[1], this.c); + + collectionFromArray.stop(); + test.equal(this.stop.callCount, 3); + + test.done(); + }, + + "Animation.normalize": function(test) { + test.expect(2); + + var servos = new Servo.Collection([ + this.a, this.b, this.c + ]); + + var normalized = servos[Animation.normalize]([ + [ + null, + 10, + ], + [ + null, + 10, + ], + [ + null, + 10, + ], + ]); + + test.deepEqual(normalized, [ + [ + { value: servos[0].startAt, easing: "linear" }, + { step: 10, easing: "linear" }, + ], + [ + { value: servos[1].startAt, easing: "linear" }, + { step: 10, easing: "linear" }, + ], + [ + { value: servos[2].startAt, easing: "linear" }, + { step: 10, easing: "linear" }, + ], + ]); + + normalized = servos[Animation.normalize]([ + null, + [ + null, + 10, + ], + [ + null, + 10, + ], + ]); + + test.deepEqual(normalized, [ + null, + [ + { value: servos[0].startAt, easing: "linear" }, + { step: 10, easing: "linear" }, + ], + [ + { value: servos[1].startAt, easing: "linear" }, + { step: 10, easing: "linear" }, + ], + ]); + + test.done(); + }, + + "Animation.render": function(test) { + test.expect(4); + + this.to.reset(); + + var servos = new Servo.Collection([ + this.a, this.b, this.c + ]); + + servos[Animation.render]([1, 1, 1]); + + test.equal(this.to.callCount, 3); + test.deepEqual(this.to.firstCall.args[0], 1); + test.deepEqual(this.to.secondCall.args[0], 1); + test.deepEqual(this.to.thirdCall.args[0], 1); + test.done(); + }, +}; diff --git a/test/servo.js b/test/servo.js index debf5355f..5de7782da 100644 --- a/test/servo.js +++ b/test/servo.js @@ -8,6 +8,12 @@ exports["Servo"] = { this.servoWrite = this.sandbox.spy(MockFirmata.prototype, "servoWrite"); this.servoConfig = this.sandbox.spy(MockFirmata.prototype, "servoConfig"); this.pinMode = this.sandbox.spy(MockFirmata.prototype, "pinMode"); + this.enqueue = this.sandbox.spy(Animation.prototype, "enqueue"); + this.next = this.sandbox.spy(Animation.prototype, "next"); + this.loop = this.sandbox.stub(temporal, "loop"); + + + this.servo = new Servo({ pin: 11, board: this.board @@ -53,8 +59,6 @@ exports["Servo"] = { name: "invert" }, { name: "type" - }, { - name: "specs" }, { name: "interval" }, { @@ -66,10 +70,17 @@ exports["Servo"] = { tearDown: function(done) { Board.purge(); + Servo.purge(); this.sandbox.restore(); done(); }, + instanceof: function(test) { + test.expect(1); + test.equal(Servo({}) instanceof Servo, true); + test.done(); + }, + shape: function(test) { test.expect(this.proto.length + this.instance.length); @@ -90,18 +101,73 @@ exports["Servo"] = { test.done(); }, - startAt: function(test) { + debug: function(test) { test.expect(1); + this.sandbox.stub(this.board.pins, "isServo").returns(false); + + test.throws(function() { + this.servo = new Servo({ + board: this.board, + debug: true, + pin: 11, + }); + }.bind(this)); + + test.done(); + }, + + doesNotWriteSameLastDegrees: function(test) { + test.expect(2); + + this.servoWrite.reset(); + + this.servo.to(100); + test.equal(this.servoWrite.callCount, 1); + + this.servo.to(100); + test.equal(this.servoWrite.callCount, 1); + test.done(); + }, + + startAt: function(test) { + test.expect(4); + this.to = this.sandbox.spy(Servo.prototype, "to"); + this.center = this.sandbox.spy(Servo.prototype, "center"); this.servo = new Servo({ + board: this.board, pin: 11, + startAt: 138, + }); + test.equal(this.to.callCount, 1); + test.equal(this.to.lastCall.args[0], 138); + test.equal(this.center.callCount, 0); + test.equal(this.servo.startAt, 138); + test.done(); + }, + + startAtOverriddenByCenter: function(test) { + test.expect(5); + + this.to = this.sandbox.spy(Servo.prototype, "to"); + this.center = this.sandbox.spy(Servo.prototype, "center"); + + this.servo = new Servo({ board: this.board, - startAt: 90 + center: true, + pin: 11, + startAt: 138, }); - test.ok(this.to.called); + test.equal(this.center.callCount, 1); + // The startAt position will be overridden + // by the `center: true` option. + test.equal(this.to.callCount, 2); + test.equal(this.to.firstCall.args[0], 138); + test.equal(this.to.lastCall.args[0], 90); + test.equal(this.servo.startAt, 138); test.done(); }, @@ -109,45 +175,56 @@ exports["Servo"] = { test.expect(3); this.servo = new Servo({ - pin: 11, board: this.board, - invert: true + invert: true, + pin: 11, }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 0)); this.servo.to(135); - test.ok(this.servoWrite.calledWith(11, 45)); this.servo.to(90); - test.ok(this.servoWrite.calledWith(11, 90)); test.done(); }, + isInvertedWarning: function(test) { + test.expect(2); + + this.consoleWarn = this.sandbox.stub(console, "warn"); + + this.servo = new Servo({ + board: this.board, + isInverted: true, + pin: 11, + }); + + test.equal(this.consoleWarn.callCount, 1); + test.equal(this.consoleWarn.firstCall.args[0], "The 'isInverted' property has been renamed 'invert'"); + + test.done(); + }, + range: function(test) { test.expect(3); this.servo = new Servo({ pin: 11, board: this.board, - range: [20, 160] + range: [20, 160], }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 160)); this.servo.to(135); - test.ok(this.servoWrite.calledWith(11, 135)); this.servo.to(10); - test.ok(this.servoWrite.calledWith(11, 20)); test.done(); @@ -164,15 +241,12 @@ exports["Servo"] = { }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 20)); this.servo.to(135); - test.ok(this.servoWrite.calledWith(11, 45)); this.servo.to(10); - test.ok(this.servoWrite.calledWith(11, 150)); test.done(); @@ -188,11 +262,9 @@ exports["Servo"] = { }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 180)); this.servo.home(); - test.ok(this.servoWrite.calledWith(11, 20)); test.done(); @@ -207,11 +279,9 @@ exports["Servo"] = { }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 180)); this.servo.home(); - test.ok(this.servoWrite.calledWith(11, 90)); test.done(); @@ -227,15 +297,12 @@ exports["Servo"] = { }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 170)); this.servo.to(135); - test.ok(this.servoWrite.calledWith(11, 125)); this.servo.to(10); - test.ok(this.servoWrite.calledWith(11, 0)); test.done(); @@ -252,15 +319,12 @@ exports["Servo"] = { }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 10)); this.servo.to(135); - test.ok(this.servoWrite.calledWith(11, 55)); this.servo.to(10); - test.ok(this.servoWrite.calledWith(11, 180)); test.done(); @@ -277,15 +341,12 @@ exports["Servo"] = { }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 140)); this.servo.to(135); - test.ok(this.servoWrite.calledWith(11, 125)); this.servo.to(10); - test.ok(this.servoWrite.calledWith(11, 10)); test.done(); @@ -303,15 +364,12 @@ exports["Servo"] = { }); this.servo.to(180); - test.ok(this.servoWrite.calledWith(11, 40)); this.servo.to(135); - test.ok(this.servoWrite.calledWith(11, 55)); this.servo.to(10); - test.ok(this.servoWrite.calledWith(11, 170)); test.done(); @@ -324,17 +382,34 @@ exports["Servo"] = { type: function(test) { test.expect(1); - test.equal(this.servo.type, "standard"); test.done(); }, + positionNoValue: function(test) { + test.expect(1); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + test.equal(this.servo.position, -1); + test.done(); + }, + + positionHasValue: function(test) { + test.expect(1); + this.servo.to(180); + test.equal(this.servo.position, 180); + + test.done(); + }, + value: function(test) { test.expect(1); this.servo.to(100); - test.equal(this.servo.value, 100); test.done(); @@ -349,12 +424,11 @@ exports["Servo"] = { // Default behaviour this.servo.sweep(); - test.equal(this.to.callCount, 1); args = this.to.lastCall.args[0]; - test.deepEqual(args.keyFrames, [ { degrees: 0 }, { degrees: 180 } ]); + test.deepEqual(args.keyFrames, [ { value: 0 }, { value: 180 } ]); test.equal(args.metronomic, true); test.equal(args.loop, true); test.equal(args.easing, "inOutSine"); @@ -364,7 +438,7 @@ exports["Servo"] = { args = this.to.lastCall.args[0]; - test.deepEqual(args.keyFrames, [ { degrees: 35 }, { degrees: 145 } ]); + test.deepEqual(args.keyFrames, [ { value: 35 }, { value: 145 } ]); test.equal(args.metronomic, true); test.equal(args.loop, true); test.equal(args.easing, "inOutSine"); @@ -378,7 +452,7 @@ exports["Servo"] = { args = this.to.lastCall.args[0]; - test.deepEqual(args.keyFrames, [ { degrees: 10 }, { degrees: 170 } ]); + test.deepEqual(args.keyFrames, [ { value: 10 }, { value: 170 } ]); test.equal(args.interval, 5000); test.equal(args.metronomic, true); test.equal(args.loop, true); @@ -394,7 +468,7 @@ exports["Servo"] = { args = this.to.lastCall.args[0]; - test.deepEqual(args.keyFrames, [ { degrees: 10 }, { degrees: 170 } ]); + test.deepEqual(args.keyFrames, [ { value: 10 }, { value: 170 } ]); test.equal(args.interval, 5000); test.equal(args.metronomic, true); test.equal(args.loop, true); @@ -421,11 +495,587 @@ exports["Servo"] = { this.servo.to(9); test.equal(this.servo.history.length, 5); test.done(); - } + }, + + move: function(test) { + test.expect(2); + this.consoleWarn = this.sandbox.stub(console, "warn"); + this.to = this.sandbox.spy(this.servo, "to"); + + this.servo.move(138); + + test.equal(this.to.callCount, 1); + test.equal(this.consoleWarn.callCount, 1); + test.done(); + }, + + to: function(test) { + test.expect(4); + this.servoWrite.reset(); + this.update = this.sandbox.spy(this.servo, "update"); + + this.servo.to(138); + test.equal(this.servoWrite.lastCall.args[0], 11); + test.equal(this.servoWrite.lastCall.args[1], 138); + test.equal(this.update.callCount, 1); + test.equal(this.update.lastCall.args[0], 138); + test.done(); + }, + + toOptionsAnimation: function(test) { + test.expect(2); + + this.servoWrite.reset(); + this.update = this.sandbox.spy(this.servo, "update"); + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + test.equal(typeof state.animation, "undefined"); + this.servo.to({}); + test.equal(state.animation instanceof Animation, true); + test.done(); + }, + + toOptionsDefaults: function(test) { + test.expect(26); + + this.servoWrite.reset(); + this.update = this.sandbox.spy(this.servo, "update"); + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + test.equal(Object.keys(state).length, 1); + test.equal(typeof state.isRunning, "undefined"); + + this.servo.to({}); + + test.notEqual(typeof state.isRunning, "undefined"); + + test.deepEqual(state.animation.cuePoints, [ 0, 1 ]); + + test.equal(state.animation.duration, 1000); + test.equal(state.animation.easing, "linear"); + test.equal(state.animation.loop, false); + test.equal(state.animation.loopback, 0); + test.equal(state.animation.metronomic, false); + test.equal(state.animation.currentSpeed, 1); + test.equal(state.animation.progress, 0); + test.equal(state.animation.fps, 60); + test.equal(Math.floor(state.animation.rate), 16); + test.equal(state.animation.paused, false); + test.equal(state.animation.onstart, null); + test.equal(state.animation.onpause, null); + test.equal(state.animation.onstop, null); + test.equal(state.animation.onloop, null); + +// console.log(state.animation); +// console.log(enqueued); + + test.equal(typeof state.animation.oncomplete, "function"); + test.equal(state.animation.defaultTarget, this.servo); + test.equal(state.animation.target, this.servo); + + // test.deepEqual( + // state.animation.normalizedKeyFrames, [ + // [{ + // value: 90, + // easing: "linear" + // }, { + // value: 90, + // easing: "linear" + // }] + // ] + // ); + + test.equal(state.animation.scaledDuration, 1000); + test.equal(state.animation.startTime, 0); + test.equal(state.animation.endTime, 1000); + test.equal(state.animation.fallBackTime, 5000); + test.equal(state.animation.frameCount, 0); + + this.servo.on("move:complete", function() { + test.done(); + }); + + state.animation.oncomplete(); + }, + + toOptionsDuration: function(test) { + test.expect(28); + + this.servoWrite.reset(); + this.update = this.sandbox.spy(this.servo, "update"); + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + test.equal(Object.keys(state).length, 1); + test.equal(typeof state.isRunning, "undefined"); + + this.servo.to({ + duration: 1500, + }); + + test.notEqual(typeof state.isRunning, "undefined"); + + test.deepEqual(state.animation.cuePoints, [ 0, 1 ]); + test.deepEqual(state.animation.segments, []); + + test.equal(state.animation.duration, 1500); + test.equal(state.animation.easing, "linear"); + test.equal(state.animation.loop, false); + test.equal(state.animation.loopback, 0); + test.equal(state.animation.metronomic, false); + test.equal(state.animation.currentSpeed, 1); + test.equal(state.animation.progress, 0); + test.equal(state.animation.fps, 60); + test.equal(state.animation.rate, 16); + test.equal(state.animation.paused, false); + test.equal(state.animation.onstart, null); + test.equal(state.animation.onpause, null); + test.equal(state.animation.onstop, null); + test.equal(state.animation.onloop, null); + + test.equal(typeof state.animation.oncomplete, "function"); + test.equal(state.animation.defaultTarget, this.servo); + test.equal(state.animation.target, this.servo); + + test.deepEqual( + state.animation.normalizedKeyFrames, [ + [{ + value: 90, + easing: "linear" + }, { + value: 90, + easing: "linear" + }] + ] + ); + + test.equal(state.animation.scaledDuration, 1500); + test.equal(state.animation.startTime, 0); + test.equal(state.animation.endTime, 1500); + test.equal(state.animation.fallBackTime, 5000); + test.equal(state.animation.frameCount, 0); + + this.servo.on("move:complete", function() { + test.done(); + }); + + state.animation.oncomplete(); + }, + + toOptionsInterval: function(test) { + test.expect(28); + + this.servoWrite.reset(); + this.update = this.sandbox.spy(this.servo, "update"); + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + test.equal(Object.keys(state).length, 1); + test.equal(typeof state.isRunning, "undefined"); + + this.servo.to({ + interval: 1500, + }); + + test.notEqual(typeof state.isRunning, "undefined"); + + test.deepEqual(state.animation.cuePoints, [ 0, 1 ]); + test.deepEqual(state.animation.segments, []); + + test.equal(state.animation.duration, 1500); + test.equal(state.animation.easing, "linear"); + test.equal(state.animation.loop, false); + test.equal(state.animation.loopback, 0); + test.equal(state.animation.metronomic, false); + test.equal(state.animation.currentSpeed, 1); + test.equal(state.animation.progress, 0); + test.equal(state.animation.fps, 60); + test.equal(state.animation.rate, 16); + test.equal(state.animation.paused, false); + test.equal(state.animation.onstart, null); + test.equal(state.animation.onpause, null); + test.equal(state.animation.onstop, null); + test.equal(state.animation.onloop, null); + + test.equal(typeof state.animation.oncomplete, "function"); + test.equal(state.animation.defaultTarget, this.servo); + test.equal(state.animation.target, this.servo); + + test.deepEqual( + state.animation.normalizedKeyFrames, [ + [{ + value: 90, + easing: "linear" + }, { + value: 90, + easing: "linear" + }] + ] + ); + + test.equal(state.animation.scaledDuration, 1500); + test.equal(state.animation.startTime, 0); + test.equal(state.animation.endTime, 1500); + test.equal(state.animation.fallBackTime, 5000); + test.equal(state.animation.frameCount, 0); + + this.servo.on("move:complete", function() { + test.done(); + }); + + state.animation.oncomplete(); + }, + + toOptionsDegrees: function(test) { + test.expect(28); + + this.servoWrite.reset(); + this.update = this.sandbox.spy(this.servo, "update"); + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + test.equal(Object.keys(state).length, 1); + test.equal(typeof state.isRunning, "undefined"); + + this.servo.to({ + degrees: 180, + }); + + test.notEqual(typeof state.isRunning, "undefined"); + + test.deepEqual(state.animation.cuePoints, [ 0, 1 ]); + test.deepEqual(state.animation.segments, []); + + test.equal(state.animation.duration, 1000); + test.equal(state.animation.easing, "linear"); + test.equal(state.animation.loop, false); + test.equal(state.animation.loopback, 0); + test.equal(state.animation.metronomic, false); + test.equal(state.animation.currentSpeed, 1); + test.equal(state.animation.progress, 0); + test.equal(state.animation.fps, 60); + test.equal(state.animation.rate, 16); + test.equal(state.animation.paused, false); + test.equal(state.animation.onstart, null); + test.equal(state.animation.onpause, null); + test.equal(state.animation.onstop, null); + test.equal(state.animation.onloop, null); + + test.equal(typeof state.animation.oncomplete, "function"); + test.equal(state.animation.defaultTarget, this.servo); + test.equal(state.animation.target, this.servo); + + test.deepEqual( + state.animation.normalizedKeyFrames, [ + [{ + value: 90, + easing: "linear", + }, { + value: 180, + easing: "linear", + }] + ] + ); + + test.equal(state.animation.scaledDuration, 1000); + test.equal(state.animation.startTime, 0); + test.equal(state.animation.endTime, 1000); + test.equal(state.animation.fallBackTime, 5000); + test.equal(state.animation.frameCount, 0); + + this.servo.on("move:complete", function() { + test.done(); + }); + + state.animation.oncomplete(); + }, + + toOptionsOncomplete: function(test) { + test.expect(29); + + this.servoWrite.reset(); + this.update = this.sandbox.spy(this.servo, "update"); + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + test.equal(Object.keys(state).length, 1); + test.equal(typeof state.isRunning, "undefined"); + + this.servo.to({ + oncomplete: function() { + test.ok(true); + }, + }); + + test.notEqual(typeof state.isRunning, "undefined"); + + test.deepEqual(state.animation.cuePoints, [ 0, 1 ]); + test.deepEqual(state.animation.segments, []); + + test.equal(state.animation.duration, 1000); + test.equal(state.animation.easing, "linear"); + test.equal(state.animation.loop, false); + test.equal(state.animation.loopback, 0); + test.equal(state.animation.metronomic, false); + test.equal(state.animation.currentSpeed, 1); + test.equal(state.animation.progress, 0); + test.equal(state.animation.fps, 60); + test.equal(state.animation.rate, 16); + test.equal(state.animation.paused, false); + test.equal(state.animation.onstart, null); + test.equal(state.animation.onpause, null); + test.equal(state.animation.onstop, null); + test.equal(state.animation.onloop, null); + + test.equal(typeof state.animation.oncomplete, "function"); + test.equal(state.animation.defaultTarget, this.servo); + test.equal(state.animation.target, this.servo); + + test.deepEqual( + state.animation.normalizedKeyFrames, [ + [{ + value: 90, + easing: "linear", + }, { + value: 90, + easing: "linear", + }] + ] + ); + + test.equal(state.animation.scaledDuration, 1000); + test.equal(state.animation.startTime, 0); + test.equal(state.animation.endTime, 1000); + test.equal(state.animation.fallBackTime, 5000); + test.equal(state.animation.frameCount, 0); + + this.servo.on("move:complete", function() { + test.done(); + }); + + state.animation.oncomplete(); + }, + + toDegreesAndTime: function(test) { + test.expect(6); + this.servoWrite.reset(); + this.update = this.sandbox.spy(this.servo, "update"); + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + this.servo.to(180, 1500); + + test.equal(state.animation.duration, 1500); + test.equal(state.animation.scaledDuration, 1500); + test.equal(state.animation.startTime, 0); + test.equal(state.animation.endTime, 1500); + test.equal(state.animation.fallBackTime, 5000); + test.equal(state.animation.frameCount, 0); + + test.done(); + }, + + step: function(test) { + test.expect(3); + + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + state.history.push({ + timestamp: Date.now(), + degrees: 0, + target: 0, + }); + + this.to = this.sandbox.stub(this.servo, "to"); + this.servo.step(45, 0); + + test.equal(this.to.callCount, 1); + test.equal(this.to.lastCall.args[0], 45); + test.equal(this.to.lastCall.args[1], 0); + test.done(); + }, + + stop: function(test) { + test.expect(1); + + this.clearInterval = this.sandbox.stub(global, "clearInterval"); + this.mapSet = this.sandbox.spy(Map.prototype, "set"); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var state = this.mapSet.lastCall.args[1]; + + this.servo.to({}); + + var stop = this.sandbox.stub(state.animation, "stop"); + + this.servo.stop(); + + test.equal(stop.callCount, 1); + test.done(); + }, + + min: function(test) { + test.expect(4); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + this.to = this.sandbox.stub(this.servo, "to"); + this.servo.min(1000, 100); + + test.equal(this.to.callCount, 1); + test.equal(this.to.lastCall.args[0], 0); + test.equal(this.to.lastCall.args[1], 1000); + test.equal(this.to.lastCall.args[2], 100); + test.done(); + }, + + max: function(test) { + test.expect(4); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + this.to = this.sandbox.stub(this.servo, "to"); + this.servo.max(1000, 100); + + test.equal(this.to.callCount, 1); + test.equal(this.to.lastCall.args[0], 180); + test.equal(this.to.lastCall.args[1], 1000); + test.equal(this.to.lastCall.args[2], 100); + test.done(); + }, + + + "Animation.normalize (without last, uses startAt)": function(test) { + test.expect(1); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + var normalized = this.servo[Animation.normalize]([ + null, + {value: 0, copyDegrees: 0}, + ]); + + test.equal(normalized[0].value, 90); + + test.done(); + }, + + "Animation.normalize (with last)": function(test) { + test.expect(1); + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + this.servo.to(180); + var normalized = this.servo[Animation.normalize]([ + null, + {value: 0, copyDegrees: 0}, + ]); + + test.equal(normalized[0].value, 180); + test.done(); + }, + + "Animation.normalize (first keyframe not null)": function(test) { + test.expect(1); + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + this.servo.to(180); + var normalized = this.servo[Animation.normalize]([ + {value: 0, copyDegrees: 0}, + ]); + + test.notEqual(normalized[0].value, 180); + test.done(); + }, + + "Animation.render": function(test) { + test.expect(2); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + this.to = this.sandbox.stub(this.servo, "to"); + this.servo[Animation.render]([180]); + + test.equal(this.to.callCount, 1); + test.equal(this.to.lastCall.args[0], 180); + test.done(); + }, }; -exports["Servo mode and config"] = { +exports["Servo - mode & config"] = { setUp: function(done) { this.sandbox = sinon.sandbox.create(); this.board = newBoard(); @@ -436,6 +1086,7 @@ exports["Servo mode and config"] = { tearDown: function(done) { Board.purge(); + Servo.purge(); this.sandbox.restore(); done(); }, @@ -447,7 +1098,6 @@ exports["Servo mode and config"] = { pin: 11, board: this.board }); - test.equal(this.servoConfig.callCount, 0); test.equal(this.pinMode.callCount, 1); test.done(); @@ -461,7 +1111,6 @@ exports["Servo mode and config"] = { board: this.board, pwmRange: [1000, 2000] }); - test.equal(this.servoConfig.callCount, 1); test.equal(this.pinMode.callCount, 0); test.done(); @@ -491,17 +1140,29 @@ exports["Servo - Continuous"] = { tearDown: function(done) { Board.purge(); + Servo.purge(); this.sandbox.restore(); done(); }, type: function(test) { test.expect(2); - test.equal(this.a.type, "continuous"); test.equal(this.b.type, "continuous"); + test.done(); + }, + pinAssignment: function(test) { + test.expect(2); + + this.servo = new Servo.Continuous(9); + test.equal(this.servo.pin, 9); + this.servo = new Servo.Continuous({ + pin: 11, + }); + + test.equal(this.servo.pin, 11); test.done(); }, @@ -511,6 +1172,23 @@ exports["Servo - Continuous"] = { test.done(); }, + nonContinuousErrors: function(test) { + test.expect(4); + + this.servo = new Servo({ + board: this.board, + pin: 11, + }); + + ["clockWise", "cw", "counterClockwise", "ccw"].forEach(function(api) { + test.throws(function() { + this.servo[api](); + }.bind(this)); + }, this); + + test.done(); + }, + cw: function(test) { test.expect(2); @@ -563,13 +1241,11 @@ exports["Servo - Continuous"] = { this.to = this.sandbox.stub(this.continuousServo, "to"); this.continuousServo.stop(); - test.equal(this.to.lastCall.args[0], 90); this.continuousServo.deadband = [100, 105]; this.continuousServo.stop(); - test.equal(this.to.lastCall.args[0], 103); test.done(); @@ -605,6 +1281,7 @@ exports["Servo - Allowed Pin Names"] = { }, tearDown: function(done) { Board.purge(); + Servo.purge(); this.sandbox.restore(); done(); }, @@ -615,17 +1292,14 @@ exports["Servo - Allowed Pin Names"] = { test.equal(new Servo(2).pin, 2); test.equal(new Servo(12).pin, 12); - test.equal(new Servo({ pin: 2 }).pin, 2); test.equal(new Servo({ pin: 12 }).pin, 12); - test.equal(new Servo("A0").pin, 14); test.equal(new Servo(14).pin, 14); - test.equal(new Servo({ pin: "A0" }).pin, 14); @@ -704,6 +1378,7 @@ exports["Servo - PCA9685"] = { tearDown: function(done) { Board.purge(); + Servo.purge(); this.sandbox.restore(); Expander.purge(); done(); @@ -739,7 +1414,6 @@ exports["Servo - PCA9685"] = { controller: "PCA9685", address: 0x41 }); - test.equal(Expander.byAddress(0x41).name, "PCA9685"); test.done(); }, @@ -757,7 +1431,6 @@ exports["Servo - PCA9685"] = { board: this.board, controller: "PCA9685" }); - test.equal(Expander.byAddress(0x40).name, "PCA9685"); test.done(); @@ -778,7 +1451,6 @@ exports["Servo - PCA9685"] = { controller: "PCA9685", board: this.board }); - test.equal(this.servo.frequency, 60); test.done(); }, @@ -794,7 +1466,6 @@ exports["Servo - PCA9685"] = { this.i2cWrite.reset(); this.servo.to(20); - test.equal(this.i2cWrite.args[0][0], 0x40); test.equal(this.i2cWrite.args[0][1][0], 6); test.equal(this.i2cWrite.args[0][1][1], 0); @@ -804,137 +1475,12 @@ exports["Servo - PCA9685"] = { test.done(); - } - -}; - -exports["Servo.Collection"] = { - setUp: function(done) { - this.sandbox = sinon.sandbox.create(); - this.board = newBoard(); - - Servo.purge(); - - this.a = new Servo({ - pin: 3, - board: this.board - }); - - this.b = new Servo({ - pin: 6, - board: this.board - }); - - this.c = new Servo({ - pin: 9, - board: this.board - }); - - this.spies = [ - "to", "stop" - ]; - - this.spies.forEach(function(method) { - this[method] = this.sandbox.spy(Servo.prototype, method); - }.bind(this)); - - this.servoWrite = this.sandbox.spy(MockFirmata.prototype, "servoWrite"); - - done(); - }, - - tearDown: function(done) { - Board.purge(); - this.sandbox.restore(); - done(); - }, - - initFromServoNumbers: function(test) { - test.expect(1); - - var servos = new Servo.Collection([3, 6, 9]); - - test.equal(servos.length, 3); - test.done(); - }, - - initFromServos: function(test) { - test.expect(1); - - var servos = new Servo.Collection([ - this.a, this.b, this.c - ]); - - test.equal(servos.length, 3); - test.done(); - }, - - callForwarding: function(test) { - test.expect(3); - - var servos = new Servo.Collection([3, 6, 9]); - - servos.to(90); - - test.equal(this.to.callCount, servos.length); - test.equal(this.to.getCall(0).args[0], 90); - - servos.stop(); - - test.equal(this.stop.callCount, servos.length); - - test.done(); - }, - - home: function(test) { - test.expect(4); - - this.servos = new Servo.Collection([{ - pin: 9, - board: this.board, - startAt: 40 - }, { - pin: 11, - board: this.board, - startAt: 20 - }]); - - this.servos.to(180); - - test.ok(this.servoWrite.calledWith(9, 180)); - test.ok(this.servoWrite.calledWith(11, 180)); - - this.servos.home(); - - test.ok(this.servoWrite.calledWith(9, 40)); - test.ok(this.servoWrite.calledWith(11, 20)); - - test.done(); }, - collectionFromArray: function(test) { - test.expect(9); - - var servos = new Servo.Collection([this.a, this.b]); - var collectionFromArray = new Servo.Collection([servos, this.c]); - - collectionFromArray.to(90); - - test.equal(this.to.callCount, 3); - test.equal(this.to.getCall(0).args[0], 90); - test.equal(this.to.getCall(1).args[0], 90); - test.equal(this.to.getCall(2).args[0], 90); - - test.equal(collectionFromArray.length, 2); - test.equal(collectionFromArray[0][0], this.a); - test.equal(collectionFromArray[0][1], this.b); - test.equal(collectionFromArray[1], this.c); - - collectionFromArray.stop(); - - test.equal(this.stop.callCount, 3); - - test.done(); - } - }; + +Object.keys(Servo.Controllers).forEach(function(name) { + exports["Servo - Controller, " + name] = addControllerTest(Servo, Servo.Controllers[name], { + controller: name + }); +}); diff --git a/test/thermometer.js b/test/thermometer.js index 1c7ab6a34..5592332d0 100644 --- a/test/thermometer.js +++ b/test/thermometer.js @@ -48,18 +48,18 @@ function makeTestAnalogConversion(opts) { var spy = this.sandbox.spy(); test.expect(15); if (opts.aref) { - this.temperature.aref = opts.aref; + this.thermometer.aref = opts.aref; } - this.temperature.on("data", spy); + this.thermometer.on("data", spy); this.analogRead.firstCall.yield(opts.raw); test.equal(spy.callCount, 0); - test.equal(Math.round(this.temperature.C), opts.C, "temp.C"); - test.equal(Math.round(this.temperature.celsius), opts.C, "temp.celsius"); - test.equal(Math.round(this.temperature.K), opts.K, "temp.K"); - test.equal(Math.round(this.temperature.kelvin), opts.K, "temp.kelvin"); - test.equal(Math.round(this.temperature.F), opts.F, "temp.F"); - test.equal(Math.round(this.temperature.fahrenheit), opts.F, "temp.fahrenheit"); + test.equal(Math.round(this.thermometer.C), opts.C, "temp.C"); + test.equal(Math.round(this.thermometer.celsius), opts.C, "temp.celsius"); + test.equal(Math.round(this.thermometer.K), opts.K, "temp.K"); + test.equal(Math.round(this.thermometer.kelvin), opts.K, "temp.kelvin"); + test.equal(Math.round(this.thermometer.F), opts.F, "temp.F"); + test.equal(Math.round(this.thermometer.fahrenheit), opts.F, "temp.fahrenheit"); this.clock.tick(this.freq); @@ -85,7 +85,7 @@ function testAnalogChange(test) { spy = this.sandbox.spy(); test.expect(1); - this.temperature.on("change", spy); + this.thermometer.on("change", spy); raw(100); this.clock.tick(this.freq); @@ -113,11 +113,11 @@ function testShape(test) { test.expect(this.proto.length + this.instance.length); this.proto.forEach(function testProtoMethods(method) { - test.equal(typeof this.temperature[method.name], "function", method.name); + test.equal(typeof this.thermometer[method.name], "function", method.name); }, this); this.instance.forEach(function testInstanceProperties(property) { - test.notEqual(typeof this.temperature[property.name], "undefined", property.name); + test.notEqual(typeof this.thermometer[property.name], "undefined", property.name); }, this); test.done(); @@ -151,25 +151,25 @@ exports["Thermometer -- ANY"] = { } }; - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: controller, board: this.board, freq: 1 }); - this.temperature.on("data", spy); + this.thermometer.on("data", spy); this.clock.tick(1); // No reading has occurred yet. - test.equal(this.temperature.C, null); + test.equal(this.thermometer.C, null); test.equal(spy.callCount, 0); // 2ms passed, a reading has occurred, safe // to emit the data and C is not null this.clock.tick(1); - test.equal(this.temperature.C, 25); + test.equal(this.thermometer.C, 25); test.equal(spy.callCount, 1); test.done(); @@ -190,16 +190,16 @@ exports["Thermometer -- ANALOG"] = { "picks aref from board.io": function(test) { this.board.io.aref = 3.3; - this.temperature = createAnalog.call(this); + this.thermometer = createAnalog.call(this); test.expect(1); - test.equal(this.temperature.aref, this.board.io.aref); + test.equal(this.thermometer.aref, this.board.io.aref); test.done(); }, "picks aref from options": function(test) { this.board.io.aref = 3.3; - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ aref: 1.8, pins: ["A0"], freq: this.freq, @@ -207,13 +207,13 @@ exports["Thermometer -- ANALOG"] = { }); test.expect(1); - test.equal(this.temperature.aref, 1.8); + test.equal(this.thermometer.aref, 1.8); test.done(); }, "no controller": { setUp: function(done) { - this.temperature = createAnalog.call(this); + this.thermometer = createAnalog.call(this); done(); }, @@ -231,7 +231,7 @@ exports["Thermometer -- ANALOG"] = { "custom toCelsius": { setUp: function(done) { this.toCelsius = this.sandbox.stub().returns(22); - this.temperature = createAnalog.call(this, this.toCelsius); + this.thermometer = createAnalog.call(this, this.toCelsius); done(); }, shape: testShape, @@ -252,13 +252,13 @@ exports["Thermometer -- ANALOG"] = { this.analogRead.yield(10); test.equal(this.toCelsius.callCount, 0); - test.equal(this.temperature.C, 22); + test.equal(this.thermometer.C, 22); test.equal(this.toCelsius.callCount, 1); test.equal(this.toCelsius.firstCall.args[0], 10); this.toCelsius.reset(); this.analogRead.yield(100); - test.equal(this.temperature.C, 22); + test.equal(this.thermometer.C, 22); test.equal(this.toCelsius.firstCall.args[0], 100); test.done(); }, @@ -266,7 +266,7 @@ exports["Thermometer -- ANALOG"] = { LM335: { setUp: function(done) { - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "LM335", pins: ["A0"], freq: 100, @@ -289,16 +289,22 @@ exports["Thermometer -- ANALOG"] = { F: -371, K: 49, }), + maxRawValue1023: makeTestAnalogConversion({ + raw: 763, + C: 100, + F: 212, + K: 373, + }), change: testAnalogChange, digits: function(test) { test.expect(1); - test.equal(digits.fractional(this.temperature.C), 0); + test.equal(digits.fractional(this.thermometer.C), 0); test.done(); } }, LM35: { setUp: function(done) { - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "LM35", pins: ["A0"], freq: 100, @@ -322,10 +328,16 @@ exports["Thermometer -- ANALOG"] = { F: 208, K: 371 }), + maxRawValue1023: makeTestAnalogConversion({ + raw: 214, + C: 105, + F: 221, + K: 378, + }), change: testAnalogChange, digits: function(test) { test.expect(1); - test.equal(digits.fractional(this.temperature.C), 0); + test.equal(digits.fractional(this.thermometer.C), 0); test.done(); } @@ -333,7 +345,7 @@ exports["Thermometer -- ANALOG"] = { TMP36: { setUp: function(done) { - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "TMP36", pins: ["A0"], freq: this.freq, @@ -359,16 +371,24 @@ exports["Thermometer -- ANALOG"] = { F: 73, K: 296 }), + + maxRawValue1023: makeTestAnalogConversion({ + raw: 306, + C: 100, + F: 212, + K: 373, + }), + digits: function(test) { test.expect(1); - test.equal(digits.fractional(this.temperature.C), 0); + test.equal(digits.fractional(this.thermometer.C), 0); test.done(); } }, GROVE: { setUp: function(done) { - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "GROVE", pin: "A0", freq: 100, @@ -394,14 +414,14 @@ exports["Thermometer -- ANALOG"] = { }), digits: function(test) { test.expect(1); - test.equal(digits.fractional(this.temperature.C), 0); + test.equal(digits.fractional(this.thermometer.C), 0); test.done(); } }, TINKERKIT: { setUp: function(done) { - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "TINKERKIT", pin: "A0", freq: 100, @@ -428,7 +448,7 @@ exports["Thermometer -- ANALOG"] = { digits: function(test) { test.expect(1); - test.equal(digits.fractional(this.temperature.C), 0); + test.equal(digits.fractional(this.thermometer.C), 0); test.done(); } }, @@ -469,7 +489,7 @@ exports["Thermometer -- MAX31850K"] = { test.expect(5); - this.temperature = createMAX31850K(this.pin); + this.thermometer = createMAX31850K(this.pin); search = this.sendOneWireSearch.args[0][1]; search(null, [device]); @@ -480,7 +500,7 @@ exports["Thermometer -- MAX31850K"] = { test.ok(this.sendOneWireSearch.calledOnce); test.equals(this.sendOneWireSearch.args[0][0], this.pin); - test.equals(this.temperature.address, 0x050403020100); + test.equals(this.thermometer.address, 0x050403020100); test.done(); }, @@ -492,8 +512,8 @@ exports["Thermometer -- MAX31850K"] = { test.expect(14); - this.temperature = createMAX31850K(this.pin); - this.temperature.on("data", spy); + this.thermometer = createMAX31850K(this.pin); + this.thermometer.on("data", spy); search = this.sendOneWireSearch.args[0][1]; search(null, [device]); @@ -533,13 +553,13 @@ exports["Thermometer -- MAX31850K"] = { test.expect(3); - this.temperature = createMAX31850K(this.pin, 0x554433221100); + this.thermometer = createMAX31850K(this.pin, 0x554433221100); search = this.sendOneWireSearch.args[0][1]; search(null, [device1, device2]); test.equals(this.sendOneWireWrite.args[0][1], device2); test.equals(this.sendOneWireWriteAndRead.args[0][1], device2); - test.equals(this.temperature.address, 0x554433221100); + test.equals(this.thermometer.address, 0x554433221100); test.done(); }, @@ -553,10 +573,10 @@ exports["Thermometer -- MAX31850K"] = { test.expect(3); - this.temperatureA = createMAX31850K(this.pin, 0x554433221100); - this.temperatureA.on("data", spyA); - this.temperatureB = createMAX31850K(this.pin, 0x050403020100); - this.temperatureB.on("data", spyB); + this.thermometerA = createMAX31850K(this.pin, 0x554433221100); + this.thermometerA.on("data", spyA); + this.thermometerB = createMAX31850K(this.pin, 0x050403020100); + this.thermometerB.on("data", spyB); search = this.sendOneWireSearch.args[0][1]; search(null, [deviceA, deviceB]); @@ -575,7 +595,7 @@ exports["Thermometer -- MAX31850K"] = { test.equals(Math.round(spyA.getCall(0).args[0].celsius), 32); test.equals(Math.round(spyB.getCall(0).args[0].celsius), 64); - test.equal(digits.fractional(this.temperatureA.C), 2); + test.equal(digits.fractional(this.thermometerA.C), 2); test.done(); }, @@ -585,7 +605,7 @@ exports["Thermometer -- MAX31850K"] = { test.expect(1); - this.temperature = createMAX31850K(this.pin); + this.thermometer = createMAX31850K(this.pin); try { createMAX31850K(this.pin); @@ -634,7 +654,7 @@ exports["Thermometer -- DS18B20"] = { test.expect(5); - this.temperature = createDS18B20(this.pin); + this.thermometer = createDS18B20(this.pin); search = this.sendOneWireSearch.args[0][1]; search(null, [device]); @@ -645,7 +665,7 @@ exports["Thermometer -- DS18B20"] = { test.ok(this.sendOneWireSearch.calledOnce); test.equals(this.sendOneWireSearch.args[0][0], this.pin); - test.equals(this.temperature.address, 0x050403020100); + test.equals(this.thermometer.address, 0x050403020100); test.done(); }, @@ -657,8 +677,8 @@ exports["Thermometer -- DS18B20"] = { test.expect(19); - this.temperature = createDS18B20(this.pin); - this.temperature.on("data", spy); + this.thermometer = createDS18B20(this.pin); + this.thermometer.on("data", spy); search = this.sendOneWireSearch.args[0][1]; search(null, [device]); @@ -692,7 +712,7 @@ exports["Thermometer -- DS18B20"] = { test.equals(Math.round(spy.getCall(0).args[0].fahrenheit), 90); test.equals(Math.round(spy.getCall(0).args[0].kelvin), 305); - test.equal(digits.fractional(this.temperature.C), 4); + test.equal(digits.fractional(this.thermometer.C), 4); test.done(); }, @@ -704,13 +724,13 @@ exports["Thermometer -- DS18B20"] = { test.expect(3); - this.temperature = createDS18B20(this.pin, 0x554433221100); + this.thermometer = createDS18B20(this.pin, 0x554433221100); search = this.sendOneWireSearch.args[0][1]; search(null, [device1, device2]); test.equals(this.sendOneWireWrite.args[0][1], device2); test.equals(this.sendOneWireWriteAndRead.args[0][1], device2); - test.equals(this.temperature.address, 0x554433221100); + test.equals(this.thermometer.address, 0x554433221100); test.done(); }, @@ -724,10 +744,10 @@ exports["Thermometer -- DS18B20"] = { test.expect(2); - this.temperatureA = createDS18B20(this.pin, 0x554433221100); - this.temperatureA.on("data", spyA); - this.temperatureB = createDS18B20(this.pin, 0x050403020100); - this.temperatureB.on("data", spyB); + this.thermometerA = createDS18B20(this.pin, 0x554433221100); + this.thermometerA.on("data", spyA); + this.thermometerB = createDS18B20(this.pin, 0x050403020100); + this.thermometerB.on("data", spyB); search = this.sendOneWireSearch.args[0][1]; search(null, [deviceA, deviceB]); @@ -750,7 +770,7 @@ exports["Thermometer -- DS18B20"] = { test.expect(1); - this.temperature = createDS18B20(this.pin); + this.thermometer = createDS18B20(this.pin); try { createDS18B20(this.pin); @@ -770,7 +790,7 @@ exports["Thermometer -- MPU6050"] = { this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); this.i2cWrite = this.sandbox.spy(MockFirmata.prototype, "i2cWrite"); this.i2cRead = this.sandbox.spy(MockFirmata.prototype, "i2cRead"); - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "MPU6050", freq: 100, board: this.board @@ -803,7 +823,7 @@ exports["Thermometer -- MPU6050"] = { var read, spy = this.sandbox.spy(); test.expect(13); - this.temperature.on("data", spy); + this.thermometer.on("data", spy); read = this.i2cRead.args[0][3]; read([ @@ -831,7 +851,7 @@ exports["Thermometer -- MPU6050"] = { test.equals(Math.round(spy.getCall(0).args[0].fahrenheit), 120); test.equals(Math.round(spy.getCall(0).args[0].kelvin), 322); - test.equal(digits.fractional(this.temperature.C), 0); + test.equal(digits.fractional(this.thermometer.C), 0); test.done(); } @@ -952,7 +972,7 @@ exports["Thermometer -- SI7020"] = { this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); this.i2cRead = this.sandbox.spy(MockFirmata.prototype, "i2cRead"); - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "SI7020", board: this.board, freq: 10 @@ -1014,7 +1034,7 @@ exports["Thermometer -- SI7020"] = { var spy = this.sandbox.spy(); var read = this.i2cRead.firstCall.args[3]; - this.temperature.on("data", spy); + this.thermometer.on("data", spy); read([103, 4, 63]); @@ -1025,19 +1045,83 @@ exports["Thermometer -- SI7020"] = { test.equals(Math.round(spy.getCall(0).args[0].fahrenheit), 75); test.equals(Math.round(spy.getCall(0).args[0].kelvin), 297); - test.equal(digits.fractional(this.temperature.C), 1); + test.equal(digits.fractional(this.thermometer.C), 1); test.done(); } }; +exports["Thermometer -- SHT31D"] = { + + setUp: function(done) { + this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); + this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); + + this.thermometer = new Thermometer({ + controller: "SHT31D", + board: this.board, + freq: 10 + }); + + done(); + }, + + fwdOptionsToi2cConfig: function(test) { + test.expect(3); + + this.i2cConfig.reset(); + + new Thermometer({ + controller: "SHT31D", + address: 0xff, + bus: "i2c-1", + board: this.board + }); + + var forwarded = this.i2cConfig.lastCall.args[0]; + + test.equal(this.i2cConfig.callCount, 1); + test.equal(forwarded.address, 0xff); + test.equal(forwarded.bus, "i2c-1"); + + test.done(); + }, + + oneHundredDegreesCelsius: function(test) { + test.expect(5); + var readOnce; + var spy = this.sandbox.spy(); + + this.thermometer.on("data", spy); + + this.clock.tick(20); + + test.equal(this.i2cReadOnce.callCount, 1); + test.equal(this.i2cReadOnce.lastCall.args[0], 0x44); + test.equal(this.i2cReadOnce.lastCall.args[1], 6); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ + 0xd4, 0x1d, // temperature (100 degrees celsius) + 0, // crc + 0, 0, // humidity + 0 // crc + ]); + this.clock.tick(10); + + test.equal(spy.callCount, 1); + test.equal(Math.round(this.thermometer.C), 100); + test.done(); + } +}; + exports["Thermometer -- HTU21D"] = { setUp: function(done) { this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "HTU21D", board: this.board, freq: 10 @@ -1090,7 +1174,7 @@ exports["Thermometer -- HTU21D"] = { var readOnce; var spy = this.sandbox.spy(); - this.temperature.on("data", spy); + this.thermometer.on("data", spy); test.equal(this.i2cReadOnce.callCount, 1); test.equal(this.i2cReadOnce.lastCall.args[0], 0x40); @@ -1113,7 +1197,7 @@ exports["Thermometer -- HTU21D"] = { this.clock.tick(10); test.equal(spy.callCount, 2); - test.equal(Math.round(this.temperature.C), 22); + test.equal(Math.round(this.thermometer.C), 22); test.done(); }, @@ -1123,7 +1207,7 @@ exports["Thermometer -- HTU21D"] = { var readOnce; var spy = this.sandbox.spy(); - this.temperature.on("change", spy); + this.thermometer.on("change", spy); test.equal(this.i2cReadOnce.callCount, 1); test.equal(this.i2cReadOnce.lastCall.args[0], 0x40); @@ -1148,7 +1232,154 @@ exports["Thermometer -- HTU21D"] = { test.equal(spy.callCount, 2); - test.equal(Math.round(this.temperature.C), 22); + test.equal(Math.round(this.thermometer.C), 22); + + test.done(); + }, + + oneHundredDegreesCelsius: function(test) { + test.expect(8); + var readOnce; + var spy = this.sandbox.spy(); + + this.thermometer.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); + + // The two numbers in the array passed to readOnce represent the two bytes + // of unsigned 16 bit integer which should convert to approximately 100 + // degrees celsius. + // See https://github.com/rwaldron/johnny-five/issues/1278 + readOnce = this.i2cReadOnce.lastCall.args[3]; + readOnce([ 0xd5, 0xf0 ]); + 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); + + test.equal(spy.callCount, 1); + test.equal(Math.round(this.thermometer.C), 100); + test.done(); + } +}; + +exports["Thermometer -- HIH6130"] = { + + setUp: function(done) { + this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); + this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); + this.i2cWrite = this.sandbox.spy(MockFirmata.prototype, "i2cWrite"); + + this.thermometer = new Thermometer({ + controller: "HIH6130", + board: this.board, + freq: 10 + }); + + done(); + }, + + fwdOptionsToi2cConfig: function(test) { + test.expect(3); + + this.i2cConfig.reset(); + + new Thermometer({ + controller: "HIH6130", + address: 0xff, + bus: "i2c-1", + board: this.board + }); + + var forwarded = this.i2cConfig.lastCall.args[0]; + + test.equal(this.i2cConfig.callCount, 1); + test.equal(forwarded.address, 0xff); + test.equal(forwarded.bus, "i2c-1"); + + test.done(); + }, + + data: function(test) { + test.expect(12); + var readOnce; + var spy = this.sandbox.spy(); + + this.thermometer.on("data", spy); + + this.clock.tick(40); + + test.equal(this.i2cWrite.callCount, 2); + test.equal(this.i2cWrite.lastCall.args[1], 0x80); + test.equal(this.i2cWrite.lastCall.args[2][0], 0x00); + test.equal(this.i2cWrite.lastCall.args[2][1], 0x00); + + test.equal(this.i2cReadOnce.callCount, 1); + test.equal(this.i2cReadOnce.lastCall.args[0], 0x27); + test.equal(this.i2cReadOnce.lastCall.args[1], 4); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 38, 81, 96, 40 ]); + this.clock.tick(40); + + test.equal(this.i2cReadOnce.callCount, 2); + test.equal(this.i2cReadOnce.lastCall.args[0], 0x27); + test.equal(this.i2cReadOnce.lastCall.args[1], 4); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 102, 81, 96, 53 ]); + this.clock.tick(40); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 38, 81, 96, 12 ]); + this.clock.tick(40); + + test.equal(spy.callCount, 12); + test.equal(Math.round(this.thermometer.C), 25); + test.done(); + }, + + change: function(test) { + test.expect(6); + + var readOnce; + var spy = this.sandbox.spy(); + + this.thermometer.on("change", spy); + + this.clock.tick(40); + + test.equal(this.i2cReadOnce.callCount, 1); + test.equal(this.i2cReadOnce.lastCall.args[0], 0x27); + test.equal(this.i2cReadOnce.lastCall.args[1], 4); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 38, 81, 96, 12 ]); + this.clock.tick(40); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 102, 81, 96, 21 ]); + this.clock.tick(40); + + test.equal(Math.round(this.thermometer.C), 25); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 38, 81, 102, 48 ]); + this.clock.tick(40); + + readOnce = this.i2cReadOnce.lastCall.args[2]; + readOnce([ 102, 81, 102, 53 ]); + this.clock.tick(40); + + test.equal(spy.callCount, 2); + test.equal(Math.round(this.thermometer.C), 26); test.done(); } @@ -1184,7 +1415,7 @@ exports["Thermometer -- MPL3115A2"] = { this.i2cWriteReg = this.sandbox.spy(MockFirmata.prototype, "i2cWriteReg"); this.i2cReadOnce = this.sandbox.spy(MockFirmata.prototype, "i2cReadOnce"); - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "MPL3115A2", board: this.board, freq: 10 @@ -1257,7 +1488,7 @@ exports["Thermometer -- MPL3115A2"] = { // ]); var spy = this.sandbox.spy(); - this.temperature.on("data", spy); + this.thermometer.on("data", spy); // Altitude Loop mpl3115aDataLoop.call(this, test, 0, [ @@ -1281,7 +1512,7 @@ exports["Thermometer -- MPL3115A2"] = { test.equals(Math.round(spy.getCall(0).args[0].fahrenheit), 75); test.equals(Math.round(spy.getCall(0).args[0].kelvin), 297); - test.equal(digits.fractional(this.temperature.C), 0); + test.equal(digits.fractional(this.thermometer.C), 0); test.done(); }, @@ -1289,7 +1520,7 @@ exports["Thermometer -- MPL3115A2"] = { test.expect(39); var spy = this.sandbox.spy(); - this.temperature.on("change", spy); + this.thermometer.on("change", spy); // First Pass -- initial mpl3115aDataLoop.call(this, test, 0, [ @@ -1360,7 +1591,7 @@ exports["Thermometer -- TMP102"] = { setUp: function(done) { this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); this.i2cRead = this.sandbox.spy(MockFirmata.prototype, "i2cRead"); - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "TMP102", freq: this.freq, board: this.board @@ -1403,8 +1634,8 @@ exports["Thermometer -- TMP102"] = { raw([100, 102]); - test.equals(this.temperature.celsius, 100.4); - test.equal(digits.fractional(this.temperature.C), 1); + test.equals(this.thermometer.celsius, 100.4); + test.equal(digits.fractional(this.thermometer.C), 1); test.done(); }, @@ -1414,10 +1645,10 @@ exports["Thermometer -- TMP102"] = { test.expect(2); raw([0xFF, 0x00]); - test.equals(this.temperature.celsius, -1); + test.equals(this.thermometer.celsius, -1); raw([0xE2, 0x44]); - test.equals(this.temperature.celsius, -29.8); + test.equals(this.thermometer.celsius, -29.8); test.done(); }, @@ -1427,7 +1658,7 @@ exports["Thermometer -- TMP102"] = { var raw = this.i2cRead.args[0][3]; test.expect(1); - this.temperature.on("change", changeHandler); + this.thermometer.on("change", changeHandler); raw([100, 0]); this.clock.tick(this.freq); @@ -1457,7 +1688,7 @@ exports["Thermometer -- MCP9808"] = { this.sandbox = sinon.sandbox.create(); this.i2cConfig = this.sandbox.spy(MockFirmata.prototype, "i2cConfig"); this.i2cRead = this.sandbox.spy(MockFirmata.prototype, "i2cRead"); - this.temperature = new Thermometer({ + this.thermometer = new Thermometer({ controller: "MCP9808", freq: this.freq, board: this.board @@ -1500,8 +1731,8 @@ exports["Thermometer -- MCP9808"] = { raw([193, 119]); - test.equals(this.temperature.celsius, 23.44); - test.equal(digits.fractional(this.temperature.C), 2); + test.equals(this.thermometer.celsius, 23.44); + test.equal(digits.fractional(this.thermometer.C), 2); test.done(); }, @@ -1511,7 +1742,7 @@ exports["Thermometer -- MCP9808"] = { var raw = this.i2cRead.args[0][3]; test.expect(1); - this.temperature.on("change", changeHandler); + this.thermometer.on("change", changeHandler); raw([100, 0]); this.clock.tick(this.freq); @@ -1536,6 +1767,12 @@ exports["Thermometer -- MCP9808"] = { } }; +Object.keys(Thermometer.Controllers).forEach(function(name) { + exports["Thermometer - Controller, " + name] = addControllerTest(Thermometer, Thermometer.Controllers[name], { + controller: name + }); +}); + // TODO: // SHT31D @@ -1543,6 +1780,8 @@ exports["Thermometer -- MCP9808"] = { // BMP180 // BMP280 // DHT11 +// DHT21 +// DHT22 // TH02 // MS5611 // diff --git a/tpl/.readme.md b/tpl/.readme.md index c0da71f36..724a10e57 100644 --- a/tpl/.readme.md +++ b/tpl/.readme.md @@ -119,6 +119,8 @@ To get you up and running quickly, we provide a variety of examples for using ea To interactively navigate the examples, visit the [Johnny-Five examples](http://johnny-five.io/examples/) page on the official website. If you want to link directly to the examples in this repo, you can use one of the following links. +**There are presently <%= egcount %> example programs with code and diagrams!** + <%= eglinks %> diff --git a/tpl/programs.json b/tpl/programs.json index 9b0c14091..513b44b4b 100644 --- a/tpl/programs.json +++ b/tpl/programs.json @@ -336,6 +336,14 @@ "title": "GPS - Default GPS", "description": "When using GPS class with an Arduino (or similar microcontroller), be sure to upload the StandardFirmataPlus firmware to your board." }, + { + "file": "gps-GP-20U7.js", + "title": "GPS - Sparkfun GP-20U7", + "description": "When using GPS class with an Arduino (or similar microcontroller), be sure to upload the StandardFirmataPlus firmware to your board.", + "externals": [ + { "title": "GPS Receiver - GP-20U7 (56 Channel)", "href": "https://www.sparkfun.com/products/13740"} + ] + }, { "file": "gps-adafruit.js", "title": "GPS - Adafruit Ultimate GPS Breakout", @@ -423,6 +431,14 @@ "file": "motor-hbridge.js", "title": "Motor - H-Bridge" }, + { + "file": "motor-TB6612FNG.js", + "title": "Motor - Sparkfun TB6612FNG" + }, + { + "file": "motor-hbridge-dual.js", + "title": "Motors - Dual H-Bridge" + }, { "file": "motor-PCA9685.js", "title": "Motor - PCA9685" @@ -954,6 +970,18 @@ { "title": "MPL3115A2 - I2C Barometric Pressure/Temperature Sensor", "href": "https://www.adafruit.com/product/1893"} ] }, + { + "file": "multi-BME280.js", + "title": "Multi - BME280", + "breadboards": [ + {"name": "multi-BME280-tessel", "title": "BME280 (Sparkfun)"}, + {"name": "multi-BME280-arduino", "title": "BME280 (Adafruit)"} + ], + "externals": [ + { "title": "SparkFun Atmospheric Sensor Breakout - BME280", "href": "https://www.sparkfun.com/products/13676"}, + { "title": "Adafruit BME280 I2C or SPI Temperature Humidity Pressure Sensor", "href": "https://www.adafruit.com/products/2652"} + ] + }, { "file": "multi-bmp180.js", "title": "Multi - BMP180", @@ -999,6 +1027,16 @@ { "title": "SHT31D Humidity/Temperature Sensor", "href": "https://www.adafruit.com/products/2857"} ] }, + { + "file": "multi-HIH6130.js", + "title": "Multi - HIH6130", + "breadboards": [ + {"name": "multi-HIH6130", "title": "HIH6130"} + ], + "externals": [ + { "title": "HIH6130 Humidity/Temperature Sensor", "href": "https://www.sparkfun.com/products/11295"} + ] + }, { "file": "multi-DHT11_I2C_NANO_BACKPACK.js", "title": "Multi - DHT11_I2C_NANO_BACKPACK", @@ -1006,7 +1044,27 @@ {"name": "multi-DHT11_I2C_NANO_BACKPACK", "title": "DHT11"} ], "externals": [ - { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht11_i2c_nano_backpack.ino"} + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} + ] + }, + { + "file": "multi-DHT21_I2C_NANO_BACKPACK.js", + "title": "Multi - DHT21_I2C_NANO_BACKPACK", + "breadboards": [ + {"name": "multi-DHT21_I2C_NANO_BACKPACK", "title": "DHT21"} + ], + "externals": [ + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} + ] + }, + { + "file": "multi-DHT22_I2C_NANO_BACKPACK.js", + "title": "Multi - DHT22_I2C_NANO_BACKPACK", + "breadboards": [ + {"name": "multi-DHT22_I2C_NANO_BACKPACK", "title": "DHT22"} + ], + "externals": [ + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} ] }, { @@ -1027,6 +1085,17 @@ { "title": "SI7020 - I2C Multi Sensor", "href": "https://tessel.io/docs/climate"} ] }, + { + "file": "multi-SI7021.js", + "title": "Multi - SI7021", + "breadboards": [ + {"name": "multi-SI7021", "title": "Tessel with SI7021"}, + {"name": "multi-SI7021-uno", "title": "Arduino with SI7021"} + ], + "externals": [ + { "title": "Si7021 Humidity and Temperature Sensor Hookup Guide", "href": "https://learn.sparkfun.com/tutorials/si7021-humidity-and-temperature-sensor-hookup-guide"} + ] + }, { "file": "multi-MS5611.js", "title": "Multi - MS5611" @@ -1049,6 +1118,14 @@ "file": "sensor-fsr.js", "title": "Sensor - Force sensitive resistor" }, + { + "file": "microphone.js", + "title": "Sensor - Microphone" + }, + { + "file": "sensor-digital-microwave.js", + "title": "Sensor - Digital Microwave" + }, { "file": "photoresistor.js", "title": "Sensor - Photoresistor" @@ -1057,10 +1134,6 @@ "file": "potentiometer.js", "title": "Sensor - Potentiometer" }, - { - "file": "microphone.js", - "title": "Sensor - Microphone" - }, { "file": "accelerometer.js", "title": "Accelerometer" @@ -1153,6 +1226,16 @@ { "title": "SHT31D Humidity/Temperature Sensor", "href": "https://www.adafruit.com/products/2857"} ] }, + { + "file": "temperature-HIH6130.js", + "title": "Thermometer - HIH6130", + "breadboards": [ + {"name": "multi-HIH6130", "title": "HIH6130"} + ], + "externals": [ + { "title": "HIH6130 Humidity/Temperature Sensor", "href": "https://www.sparkfun.com/products/11295"} + ] + }, { "file": "temperature-MCP9808.js", "title": "Thermometer - MCP9808", @@ -1256,6 +1339,16 @@ { "title": "HTU21D Humidity/Temperature Sensor", "href": "https://www.adafruit.com/products/1899"} ] }, + { + "file": "hygrometer-SI7021.js", + "title": "Hygrometer - SI7021", + "breadboards": [ + {"name": "multi-SI7021", "title": "SI7021"} + ], + "externals": [ + { "title": "Si7021 Humidity and Temperature Sensor Hookup Guide", "href": "https://learn.sparkfun.com/tutorials/si7021-humidity-and-temperature-sensor-hookup-guide"} + ] + }, { "file": "hygrometer-sht31d.js", "title": "Hygrometer - SHT31D", @@ -1266,6 +1359,17 @@ { "title": "SHT31D Humidity/Temperature Sensor", "href": "https://www.adafruit.com/products/2857"} ] }, + { + "file": "hygrometer-HIH6130.js", + "title": "Hygrometer - HIH6130", + "breadboards": [ + {"name": "multi-HIH6130", "title": "HIH6130"} + ], + "externals": [ + { "title": "HIH6130 Humidity/Temperature Sensor", "href": "https://www.sparkfun.com/products/11295"} + ] + }, + { "file": "temperature-BMP180.js", "title": "Thermometer - BMP180", @@ -1302,6 +1406,17 @@ { "title": "SI7020 - I2C Temperature Sensor", "href": "https://tessel.io/docs/climate"} ] }, + { + "file": "temperature-SI7021.js", + "title": "Thermometer - SI7021", + "breadboards": [ + {"name": "multi-SI7021", "title": "Tessel with SI7021"}, + {"name": "multi-SI7021-uno", "title": "Arduino with SI7021"} + ], + "externals": [ + { "title": "Si7021 Humidity and Temperature Sensor Hookup Guide", "href": "https://learn.sparkfun.com/tutorials/si7021-humidity-and-temperature-sensor-hookup-guide"} + ] + }, { "file": "temperature-MS5611.js", "title": "Thermometer - MS5611", @@ -1381,7 +1496,7 @@ {"name": "multi-DHT11_I2C_NANO_BACKPACK", "title": "Thermometer DHT11"} ], "externals": [ - { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht11_i2c_nano_backpack.ino"} + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} ] }, { @@ -1391,7 +1506,47 @@ {"name": "multi-DHT11_I2C_NANO_BACKPACK", "title": "Hygrometer DHT11"} ], "externals": [ - { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht11_i2c_nano_backpack.ino"} + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} + ] + }, + { + "file": "temperature-DHT21_I2C_NANO_BACKPACK.js", + "title": "Thermometer - DHT21_I2C_NANO_BACKPACK", + "breadboards": [ + {"name": "multi-DHT21_I2C_NANO_BACKPACK", "title": "Thermometer DHT21"} + ], + "externals": [ + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} + ] + }, + { + "file": "hygrometer-DHT21_I2C_NANO_BACKPACK.js", + "title": "Hygrometer - DHT21_I2C_NANO_BACKPACK", + "breadboards": [ + {"name": "multi-DHT21_I2C_NANO_BACKPACK", "title": "Hygrometer DHT21"} + ], + "externals": [ + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} + ] + }, + { + "file": "temperature-DHT22_I2C_NANO_BACKPACK.js", + "title": "Thermometer - DHT22_I2C_NANO_BACKPACK", + "breadboards": [ + {"name": "multi-DHT22_I2C_NANO_BACKPACK", "title": "Thermometer DHT22"} + ], + "externals": [ + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} + ] + }, + { + "file": "hygrometer-DHT22_I2C_NANO_BACKPACK.js", + "title": "Hygrometer - DHT22_I2C_NANO_BACKPACK", + "breadboards": [ + {"name": "multi-DHT22_I2C_NANO_BACKPACK", "title": "Hygrometer DHT22"} + ], + "externals": [ + { "title": "I2C Backback Firmare", "href": "https://github.com/rwaldron/johnny-five/blob/master/firmwares/dht_i2c_nano_backpack.ino"} ] } ]