diff --git a/JavaScript/README.md b/JavaScript/README.md new file mode 100644 index 0000000..9a82c9c --- /dev/null +++ b/JavaScript/README.md @@ -0,0 +1,7 @@ +Instructions +------------ + +1. Connect the Pulse Sensor to the "A0" pin of the Arduino +2. Burn Standard Firmata to Arduino memory +3. Navigate to the current directory on the console +4. Run 'node app.js' diff --git a/JavaScript/app.js b/JavaScript/app.js new file mode 100644 index 0000000..b35b1fa --- /dev/null +++ b/JavaScript/app.js @@ -0,0 +1,105 @@ +var rate = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + sampleCounter = 0, + lastBeatTime = 0, + P = 512, + T = 512, + thresh = 525, + amp = 100, + firstBeat = true, + secondBeat = false, + IBI = 600, + Pulse = false, + BPM, + Signal, + QS = false; + +var five = require('johnny-five'), + board, sensor; +board = new five.Board(); + +board.on('ready', function() { + sensor = new five.Sensor({ + pin: "A0", + freq: 2 + }); + + sensor.scale([0,1024]).on('read', function() { + Signal = this.scaled; + calculate_bpm(); + + if(QS === true) { + console.log('BPM : ', BPM); + QS = false; + } + }); +}); + +function calculate_bpm() { + + sampleCounter += 2; + N = sampleCounter - lastBeatTime; + + if(Signal < thresh && N > (IBI/5)*3) { + if (Signal < T) { + T = Signal; + } + } + + if(Signal > thresh && Signal > P) { + P = Signal; + } + + + if (N > 250) { + + if ((Signal > thresh) && (Pulse === false) && (N > (IBI/5)*3)) { + Pulse = true; + IBI = sampleCounter - lastBeatTime; + lastBeatTime = sampleCounter; + + if(secondBeat) { + secondBeat = false; + for(var i=0; i<=9; i++){ + rate[i] = IBI; + } + } + + if(firstBeat) { + firstBeat = false; + secondBeat = true; + return; + } + + + var runningTotal = 0; + + for(var i=0; i<=8; i++) { + rate[i] = rate[i+1]; + runningTotal += rate[i]; + } + + rate[9] = IBI; + runningTotal += rate[9]; + runningTotal /= 10; + BPM = 60000/runningTotal; + QS = true; + } + } + + if (Signal < thresh && Pulse === true){ + Pulse = false; + amp = P - T; + thresh = amp/2 + T; + P = thresh; + T = thresh; + } + + if (N > 2500) { + thresh = 512; + P = 512; + T = 512; + lastBeatTime = sampleCounter; + firstBeat = true; + secondBeat = false; + } +} diff --git a/JavaScript/node_modules/johnny-five/.jscsrc b/JavaScript/node_modules/johnny-five/.jscsrc new file mode 100644 index 0000000..f14917e --- /dev/null +++ b/JavaScript/node_modules/johnny-five/.jscsrc @@ -0,0 +1,29 @@ +{ + "requireCurlyBraces": [ + "if", + "else", + "for", + "while", + "do", + "try", + "catch" + ], + "disallowNewlineBeforeBlockStatements": true, + "requireSpaceBeforeBlockStatements": true, + "requireParenthesesAroundIIFE": true, + "requireSpacesInConditionalExpression": true, + "requireSpaceAfterKeywords": [ + "if", "else", + "switch", "case", + "try", "catch", + "do", "while", "for", + "return", "typeof", "void" + ], + "validateQuoteMarks": { + "mark": "\"", + "escape": true + }, + "excludeFiles": [ + "node_modules/**/*.js" + ] +} diff --git a/JavaScript/node_modules/johnny-five/.jshintrc b/JavaScript/node_modules/johnny-five/.jshintrc new file mode 100644 index 0000000..84f5eda --- /dev/null +++ b/JavaScript/node_modules/johnny-five/.jshintrc @@ -0,0 +1,26 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": false, + "newcap": false, + "noarg": true, + "sub": true, + "undef": true, + "boss": true, + "eqnull": true, + "node": true, + "strict": false, + "esnext": true, + "quotmark": "double", + "unused": true, + "globals": { + "exports": true, + "document": true, + "$": true, + "Radar": true, + "WeakMap": true, + "window": true, + "copy": true + } +} diff --git a/JavaScript/node_modules/johnny-five/.npmignore b/JavaScript/node_modules/johnny-five/.npmignore new file mode 100644 index 0000000..8366041 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/.npmignore @@ -0,0 +1,14 @@ +node_modules/ +assets/ +docs/ +tpl/ +util/ +wip/ +articles.yaml +articles.js +*.c +*.ino +*.py +*.cpp +*.h +release diff --git a/JavaScript/node_modules/johnny-five/.travis.yml b/JavaScript/node_modules/johnny-five/.travis.yml new file mode 100644 index 0000000..1e80c9a --- /dev/null +++ b/JavaScript/node_modules/johnny-five/.travis.yml @@ -0,0 +1,13 @@ +language: node_js +node_js: + - "0.10" +compiler: clang +before_script: + - grunt test-examples +notifications: + webhooks: + urls: + - "https://webhooks.gitter.im/e/2f6f94ff359a6445b59d" + on_success: change # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: false # default: false diff --git a/JavaScript/node_modules/johnny-five/CONTRIBUTING.md b/JavaScript/node_modules/johnny-five/CONTRIBUTING.md new file mode 100644 index 0000000..c4a1c60 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/CONTRIBUTING.md @@ -0,0 +1,94 @@ +Contribute to Johnny-Five! +===================== +Do you want to help out but don't know where to start? + +### Guideline Contents + +There are a lot of ways to get involved and help out: +- [Reporting an issue](#reporting-issues) +- [Requesting features](#requesting-features) +- [Requesting Support for new hardware](#hardware-support) +- [Submitting Pullrequests](#pullrequests) +- [Writing tests](#writing-tests) +- [Writing Documentation](#writing-docs) +- [Sample Projects](#sample-projects) + + +## Reporting An Issue + +Johnny-Five does it's [issue tracking](https://github.com/rwaldron/johnny-five/issues) through github. To report an issue first search the repo to make sure that it has not been reported before. If no one has reported the bug before, create a new issue and be sure to include the following information: + +**Board:** (e.g Arduino Uno, Intel Edison, etc) +**Shield:** (if you're using one, what kind) +**Hardware you are having an issue with:** (e.g. servos, leds, sensors, and what brand/type you are using) +**Version of Johnny-Five:** +**What your expectations are:** +**What the actual outcome is:** +**Steps to reproduce (including code samples):** + +Lastly, if you are able, including a video is incredibly helpful in a lot of cases of debugging issues. You can upload videos to [youtube](https://www.youtube.com/), [vine](https://vine.co/), or any site that lets you host videos. + +If the issue has been reported before but you have new information to help troubleshoot the issue, add a comment to the thread with the same information as requested above. + + + +## Requesting Features + +To request a new feature be added to one of the existing classes, create a [github issue](https://github.com/rwaldron/johnny-five/issues) and include: + +**What feature you'd like to see:** +**Why this is important to you:** (this is here because it's interesting knowing what cool things people are working on and also could help community members make suggestions for work-arounds until the feature is built) + + + + +## Hardware Support + +Often, people get a new cool toy and wonder "does Johnny-Five support this yet?" When requesting support for new hardware remember that the team working on johnny-five might not own that hardware. + +To submit a request to support new hardware, first create a [github issue](https://github.com/rwaldron/johnny-five/issues) and include a link to the specs of the hardware and where one can purchase it. Often, it might be suggested that you be the one to help implement the support yourself if you're already in possession of the product. + + +## Submitting Pull Requests + +To contribute code to Johnny-Five, fork the project onto your github account and do your work in a branch. Before you submit the PR, make sure to rebase master into your branch so that you have the most recent changes and nothing breaks or conflicts. Lint and test your code using [grunt](https://github.com/gruntjs/grunt). Also squash your commits to a reasonable size before submitting. + +All contributions must adhere to the [Idiomatic.js Style Guide](https://github.com/rwaldron/idiomatic.js), +by maintaining the existing coding style. + +If you are contributing code, it must include unit tests that fail if the working code isn't present and succeed when it is. Also make sure you run `grunt jsbeautifier` to fix any syntax issues. + +When contributing new features that support new hardware, you must include documentation. The docs need to have: + +- [ ] fritzing diagram +- [ ] anotated example script in the eg/ folder +- [ ] api documentation in the wiki + +It's very important that your pull requests include all of the above in order for users to be able to use your code. Pull requests with undocumented code will not be accepted. + + + +## Writing Tests + +Tests are written using [nodeunit](https://github.com/caolan/nodeunit) and [sinon](http://sinonjs.org/). If you are having issues making a test pass, ask for help in the Johnny-Five [gitter](https://gitter.im/) room. Tests can be the hardest part to write when contributing code, so don't be discouraged. + +If you're interested in just writing tests to learn more about the project, check out the [tests](https://github.com/rwaldron/johnny-five/labels/Tests) label in the issues. + +Tests that involve temporal elements (e.g. animations, tones/songs) can be troublesome on certain hardware and can cause failures for Travis CI builds. These tests can be put in `test/extended` to prevent them from breaking builds. + + +## Writing Documentation + +We are always looking to improve our docs. If you find that any are lacking information or have wrong information, fix and submit a PR. If you're looking for areas to start writing docs for, see the [docs](https://github.com/rwaldron/johnny-five/labels/DOCS) label in issues. + +Docs should have tested and working sample code, [fritzing diagrams](http://fritzing.org/), photos, and videos where applicable. Many people using Johnny-Five are learning how to work with hardware for the first time, so write for a beginner audience. + +The [wiki](https://github.com/rwaldron/johnny-five/wiki) contains documentation about the api, and contains code examples and fritzing diagrams. + +The [eg folder](https://github.com/rwaldron/johnny-five/tree/master/eg) contains working code examples that users can run out of the box. Each of these example files has an associated .md file in the [docs folder](https://github.com/rwaldron/johnny-five/tree/master/docs) that is generated from the eg files. When contributing documentation updates for those code examples, modify the one in the [eg folder](https://github.com/rwaldron/johnny-five/tree/master/eg) and run `grunt examples` to regenerate its [docs folder](https://github.com/rwaldron/johnny-five/tree/master/docs) counterpart, then submit both of them as part of your contribution/PR. If you add a new documentation file, remember you will need to add it to `tpl/program.json` as well. + + + +## Sample Projects + +Have you made something cool with Johnny-Five? Let us know! There are a lot of people out there hacking on similar projects and looking for ideas, help or code. We'd like to create a directory of cool projects. diff --git a/JavaScript/node_modules/johnny-five/Gruntfile.js b/JavaScript/node_modules/johnny-five/Gruntfile.js new file mode 100644 index 0000000..0151e00 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/Gruntfile.js @@ -0,0 +1,439 @@ +require("es6-shim"); +require("copy-paste"); + +var fs = require("fs"); +var exec = require("child_process").exec; +var shell = require("shelljs"); + +process.env.IS_TEST_MODE = true; + +module.exports = function(grunt) { + + var task = grunt.task; + var file = grunt.file; + var log = grunt.log; + var fail = grunt.fail; + var verbose = grunt.verbose; + var _ = grunt.util._; + + var templates = { + changelog: _.template(file.read("tpl/.changelog.md")), + eg: _.template(file.read("tpl/.eg.md")), + img: _.template(file.read("tpl/.img.md")), + breadboard: _.template(file.read("tpl/.breadboard.md")), + eglink: _.template(file.read("tpl/.readme.eglink.md")), + readme: _.template(file.read("tpl/.readme.md")), + embeds: { + youtube: _.template(file.read("tpl/.embed-youtube.html")), + }, + program: _.template(file.read("tpl/.eg-program-template.js")), + }; + + var noedit = file.read("tpl/.noedit.md"); + + // Project configuration. + grunt.initConfig({ + pkg: grunt.file.readJSON("package.json"), + examples: { + files: ["tpl/programs.json"] + }, + nodeunit: { + tests: [ + "test/bootstrap/*.js", + "test/*.js" + ] + }, + jshint: { + options: { + jshintrc: true + }, + files: { + src: [ + "Gruntfile.js", + "lib/**/!(johnny-five)*.js", + "test/**/*.js", + "eg/**/*.js", + "wip/autobot-2.js" + ] + } + }, + jscs: { + src: [ + "Gruntfile.js", + "lib/**/!(johnny-five)*.js", + "test/**/*.js", + "eg/**/*.js", + "util/**/*.js" + ], + options: { + config: ".jscsrc" + } + }, + jsbeautifier: { + files: ["lib/**/*.js", "eg/**/*.js", "test/**/*.js"], + options: { + js: { + braceStyle: "collapse", + breakChainedMethods: false, + e4x: false, + evalCode: false, + indentChar: " ", + indentLevel: 0, + indentSize: 2, + indentWithTabs: false, + jslintHappy: false, + keepArrayIndentation: false, + keepFunctionIndentation: false, + maxPreserveNewlines: 10, + preserveNewlines: true, + spaceBeforeConditional: true, + spaceInParen: false, + unescapeStrings: false, + wrapLineLength: 0 + } + } + }, + watch: { + src: { + files: [ + "Gruntfile.js", + "lib/**/!(johnny-five)*.js", + "test/**/*.js", + "eg/**/*.js" + ], + tasks: ["default"], + options: { + interrupt: true, + }, + } + } + }); + + grunt.registerTask("example", "Create an example program, usage: \"grunt expample:[.js]\"", function(fileName) { + + if (!fileName.endsWith(".js")) { + fileName += ".js"; + } + + var pathAndFile = "eg/" + fileName; + + if (file.exists(pathAndFile)) { + fail.warn(pathAndFile + " exists!"); + } else { + file.write(pathAndFile, templates.program()); + log.writeln("Example created: %s", pathAndFile); + } + }); + + // Support running a single test suite: + // grunt nodeunit:just:motor for example + grunt.registerTask("nodeunit:just", "Run a single test specified by a target; usage: \"grunt nodeunit:just:[.js]\"", function(file) { + if (file) { + grunt.config("nodeunit.tests", [ + "test/bootstrap/*.js", + "test/" + file + ".js", + ]); + } + + grunt.task.run("nodeunit"); + }); + + // 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"); + }); + + grunt.loadNpmTasks("grunt-contrib-watch"); + grunt.loadNpmTasks("grunt-contrib-nodeunit"); + grunt.loadNpmTasks("grunt-contrib-jshint"); + grunt.loadNpmTasks("grunt-jsbeautifier"); + grunt.loadNpmTasks("grunt-jscs"); + + grunt.registerTask("default", ["jshint", "jscs", "nodeunit"]); + // Explicit test task runs complete set of tests + grunt.registerTask("test", ["jshint", "jscs", "nodeunit:complete"]); + + grunt.registerMultiTask("examples", "Generate examples", function() { + // Concat specified files. + var entries = JSON.parse(file.read(file.expand(this.data))); + var readme = []; + + + entries.forEach(function(entry) { + var topic = entry.topic; + + log.writeln("Processing examples for: " + entry.topic); + + readme.push("\n### " + topic + "\n"); + + entry.examples.forEach(function(example) { + var markdown, filepath, eg, md, inMarkdown, + images, breadboards, embeds, name, imgMarkdown, values, primary; + + markdown = []; + filepath = "eg/" + example.file; + + if ( !example.file || !fs.existsSync(filepath) ) { + grunt.fail.fatal("Specified example file doesn't exist: " + filepath); + } + + eg = file.read(filepath); + name = (example.name || example.file).replace(".js", ""); + + md = "docs/" + name + ".md"; + inMarkdown = false; + + if (!example.title) { + grunt.fail.fatal("Invalid example (" + name + "): title required"); + } + + // Modify code in example to appear as it would if installed via npm + eg = eg.replace(/\.\.\/lib\/|\.js/g, "").split("\n").filter(function(line) { + if (/@markdown/.test(line)) { + inMarkdown = !inMarkdown; + return false; + } + + if (inMarkdown) { + line = line.trim(); + if (line) { + markdown.push( + line.replace(/^\/\//, "").trim() + ); + } + // Filter out the markdown lines + // from the main content. + return false; + } + + return true; + }).join("\n"); + + markdown = markdown.join("\n"); + + // If there are photo images to include + images = example.images || []; + + // Get list of breadboards diagrams to include (Default: same as file name) + breadboards = example.breadboards || [{ + "name": name, + "title": "Breadboard for \"" + example.title + "\"", + "auto": true + }]; + + embeds = (example.embeds || []).map(function(embed) { + return templates.embeds[embed.type]({ src: embed.src }); + }); + + // We'll combine markdown for images and breadboards + imgMarkdown = ""; + + primary = breadboards.shift(); + + images.forEach(function(img) { + if (!img.title || !img.file) { + grunt.fail.fatal("Invalid image: title and file required"); + } + + img.filepath = "docs/images/" + img.file; + var hasImg = fs.existsSync(img.filepath); + if (hasImg) { + imgMarkdown += templates.img({ img: img }); + } else { + // If it's specified but doesn't exist, we'll consider it an error + grunt.fail.fatal("Invalid image: " + img.file); + } + }); + + breadboards.forEach(function(breadboard) { + imgMarkdown += breadboardMarkdown(breadboard); + }); + + values = { + command: "node " + filepath, + description: example.description, + embeds: embeds, + example: eg, + externals: example.externals || [], + file: md, + images: imgMarkdown, + markdown: markdown, + primary: primary ? breadboardMarkdown(primary) : "", + title: example.title, + }; + + // Write the file to /docs/* + file.write(md, templates.eg(values)); + + // Push a rendered markdown link into the readme "index" + readme.push(templates.eglink(values)); + }); + }); + + // Write the readme with doc link index + file.write("README.md", + templates.readme({ + noedit: noedit, + eglinks: readme.join("") + }) + ); + + log.writeln("Examples created."); + }); + + + function breadboardMarkdown(breadboard) { + if (!breadboard.name) { + grunt.fail.fatal("Invalid breadboard: name required"); + } + + if (!breadboard.title) { + grunt.fail.fatal("Invalid breadboard (" + breadboard.name + "): title required"); + } + + breadboard.png = "docs/breadboard/" + breadboard.name + ".png"; + breadboard.fzz = "docs/breadboard/" + breadboard.name + ".fzz"; + + breadboard.hasPng = fs.existsSync(breadboard.png); + breadboard.hasFzz = fs.existsSync(breadboard.fzz); + + if (!breadboard.hasPng) { + if (breadboard.auto) { + // i.e. we tried to guess at a name but still doesn't exist + // We can just ignore and no breadboard shown + return; + } else { + // A breadboard was specified but doesn't exist - error + grunt.fail.fatal("Specified breadboard doesn't exist: " + breadboard.png); + } + } + + // FZZ is optional, but we'll warn at verbose + if (!breadboard.hasFzz) { + verbose.writeln("Missing FZZ: " + breadboard.fzz); + } + + return templates.breadboard({ breadboard: breadboard }); + } + + // run the examples task and fail if there are uncommitted changes to the docs directory + task.registerTask("test-examples", "Guard against out of date examples", ["examples", "fail-if-uncommitted-examples"]); + + task.registerTask("fail-if-uncommitted-examples", function() { + task.requires("examples"); + if (shell.exec("git diff --exit-code --name-status ./docs").code !== 0) { + grunt.fail.fatal("The generated examples don't match the committed examples. Please ensure you've run `grunt examples` before committing."); + } + }); + + grunt.registerTask("bump", "Bump the version", function(version) { + + // THIS IS SLIGHTLY INSANE. + // + // + // + // I don't want the whole package.json file reformatted, + // (because it makes the contributors section look insane) + // so we're going to look at lines and update the version + // line with either the next version of the specified version. + // + // It's either this or the whole contributors section + // changes from 1 line per contributor to 3 lines per. + // + + var pkg = grunt.file.read("package.json").split(/\n/).map(function(line) { + var replacement, minor, data; + + if (/version/.test(line)) { + data = line.replace(/"|,/g, "").split(":")[1].split("."); + + if (version) { + replacement = version; + } else { + minor = +data[2]; + data[2] = ++minor; + replacement = data.join(".").trim(); + } + + copy(replacement); + + return " \"version\": \"" + replacement + "\","; + } + + return line; + }); + + grunt.file.write("package.json", pkg.join("\n")); + + // TODO: + // + // - git commit with "vX.X.X" for commit message + // - npm publish + // + // + }); + + grunt.registerTask("changelog", "Generate a changelog. Range: changelog:v0.0.0--v0.0.2; Current: changelog:v0.0.2", function(version) { + var done = this.async(); + var temp = ""; + var previous = ""; + var thisPatch; + var lastPatch; + + if (!version) { + version = grunt.config("pkg.version"); + } + + if (version.includes("--")) { + /* + Example: + + grunt changelog:v0.8.71--v0.8.73 + + */ + temp = version.split("--"); + previous = temp[0]; + version = temp[1]; + } else { + /* + Example: + + grunt changelog + grunt changelog:v0.8.73 + + */ + thisPatch = version.replace(/^v/, "").split(".").pop(); + lastPatch = Number(thisPatch) - 1; + previous = version.replace(thisPatch, lastPatch); + version = "HEAD"; + } + + exec("git log --format='%H|%h|%an|%s' " + previous + ".." + version, function(error, result) { + if (error) { + console.log(error.message); + return; + } + + var commits = result.split("\n") + .filter(function(cmt) { return cmt.trim() !== ""; }) + .map(function(cmt) { return cmt.split("|"); }); + + var rows = commits.reduce(function(accum, commit) { + if (commit[3].indexOf("Merge") === 0) { + return accum; + } + accum += "| https://github.com/rwaldron/johnny-five/commit/" + commit[0] + " | " + commit[3] + " |\n"; + + return accum; + }, ""); + + log.writeln(templates.changelog({ rows: rows })); + + done(); + }); + }); +}; diff --git a/JavaScript/node_modules/johnny-five/LICENSE-MIT b/JavaScript/node_modules/johnny-five/LICENSE-MIT new file mode 100644 index 0000000..510d124 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/LICENSE-MIT @@ -0,0 +1,30 @@ +Copyright (c) 2012, 2013, 2014 Rick Waldron +Copyright (c) 2014, 2015 The Johnny-Five Authors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +==== + +All files located in the node_modules directory are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. diff --git a/JavaScript/node_modules/johnny-five/README.md b/JavaScript/node_modules/johnny-five/README.md new file mode 100644 index 0000000..a285dc5 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/README.md @@ -0,0 +1,439 @@ +![](https://github.com/rwaldron/johnny-five/raw/master/assets/sgier-johnny-five.png) + +# Johnny-Five +### The JavaScript Robotics Programming Framework + + + + +_Artwork by [Mike Sgier](http://msgierillustration.com)_ + +[![Build Status](https://travis-ci.org/rwaldron/johnny-five.svg?branch=master)](https://travis-ci.org/rwaldron/johnny-five) +[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/rwaldron/johnny-five?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + + +**Johnny-Five is an Open Source, Firmata Protocol based, IoT and Robotics programming framework, developed at [Bocoup](http://bocoup.com). Johnny-Five programs can be written for Arduino (all models), Electric Imp, Beagle Bone, Intel Galileo & Edison, Linino One, Pinoccio, pcDuino3, Raspberry Pi, Spark/Particle Core, TI Launchpad and more!** + +Johnny-Five has grown from a passion project into a tool for inspiring learning and creativity for people of all ages, backgrounds, and from all across the world. + +Just interested in learning and building awesome things? You might want to start with the official [Johnny-Five website](http://johnny-five.io). The website combines content from this repo, the wiki, tutorials from the Bocoup blog and several third-party websites into a single, easily-discoverable source: + +* If you want to find the API documentation, [that’s right here](http://johnny-five.io/api/). +* Need to figure out what platform to use for a project? We put that stuff [here](http://johnny-five.io/platform-support/). +* Need inspiration for your next NodeBot? Check out the [examples](http://johnny-five.io/examples/). +* Want to stay up-to-date with projects in the community? [Check this out](http://johnny-five.io/articles/). +* Need NodeBots community or Johnny-Five project updates and announcements? [This](http://johnny-five.io/news/) is what you’re looking for. + + +Johnny-Five does not attempt to provide "all the things", but instead focuses on delivering robust, reality tested, highly composable APIs that behave consistently across all supported hardware platforms. Johnny-Five wants to be a baseline control kit for hardware projects, allowing you the freedom to build, grow and experiment with diverse JavaScript libraries of your own choice. Johnny-Five couples comfortably with: + +- Popular application libraries such as [Express.js](http://expressjs.com/) and [Socket.io](http://socket.io/). +- Fellow hardware projects like [ar-drone](https://github.com/felixge/node-ar-drone), [Aerogel](https://github.com/ceejbot/aerogel) and [Spheron](https://github.com/alchemycs/spheron) +- Bluetooth game controllers like [XBox Controller](https://github.com/andrew/node-xbox-controller) and [DualShock](https://github.com/rdepena/node-dualshock-controller) +- IoT frameworks, such as [Octoblu](http://www.octoblu.com/) + +...And that's only a few of the many explorable possibilities. Check out these exciting projects: [node-pulsesensor](https://www.npmjs.org/package/node-pulsesensor), [footballbot-workshop-ui](https://www.npmjs.org/package/footballbot-workshop-ui), [nodebotui](https://www.npmjs.org/package/nodebotui), [dublin-disco](https://www.npmjs.org/package/dublin-disco), [node-slot-car-bot](https://www.npmjs.org/package/node-slot-car-bot), [servo-calibrator](https://www.npmjs.org/package/servo-calibrator), [node-ardx](https://www.npmjs.org/package/node-ardx), [nodebot-workshop](https://www.npmjs.org/package/nodebot-workshop), [phone-home](https://www.npmjs.org/package/phone-home), [purple-unicorn](https://www.npmjs.org/package/purple-unicorn), [webduino](https://www.npmjs.org/package/webduino), [leapduino](https://www.npmjs.org/package/leapduino), [lasercat-workshop](https://www.npmjs.org/package/lasercat-workshop), [simplesense](https://www.npmjs.org/package/simplesense), [five-redbot](https://www.npmjs.org/package/five-redbot), [robotnik](https://www.npmjs.org/package/robotnik), [the-blender](https://www.npmjs.org/package/the-blender) + + +**Why JavaScript?** +[NodeBots: The Rise of JavaScript Robotics](http://www.voodootikigod.com/nodebots-the-rise-of-js-robotics) + +## Hello Johnny + +The ubiquitous "Hello World" program of the microcontroller and SoC world is "blink an LED". The following code demonstrates how this is done using the Johnny-Five framework. + +```javascript +var five = require("johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + // Create an Led on pin 13 + var led = new five.Led(13); + // Blink every half second + led.blink(500); +}); +``` + + + +> Note: Node will crash if you try to run johnny-five in the node REPL, but board instances will create their own contextual REPL. Put your script in a file. + + +## Supported Hardware + +Johnny-Five has been tested on a variety of Arduino-compatible [Boards](https://github.com/rwaldron/johnny-five/wiki/Board). + +For non-Arduino based projects, a number of platform-specific [IO Plugins](https://github.com/rwaldron/johnny-five/wiki/IO-Plugins) are available. IO Plugins allow Johnny-Five code to communicate with any non-Arduino based hardware in whatever language that platforms speaks! + +## Documentation + +Documentation for the Johnny-Five API can be found [here](http://johnny-five.io/api/) and [example programs here](http://johnny-five.io/examples/). + +## Guidance + +Need help? Ask a question on the [NodeBots Community Forum](http://forums.nodebots.io). If you just have a quick question or are interested in ongoing design discussions, join us in the [Johnny-Five Gitter Chat](https://gitter.im/rwaldron/johnny-five). + +For step-by-step examples, including an electronics primer, check out [Arduino Experimenter's Guide for NodeJS](http://node-ardx.org/) by [@AnnaGerber](https://twitter.com/AnnaGerber) + +Here is a list of [prerequisites](https://github.com/rwaldron/johnny-five/wiki/Prerequites) for Linux, OSX or Windows. + +Check out the [bluetooth guide](https://github.com/rwaldron/johnny-five/wiki/JY-MCU-Bluetooth-Serial-Port-Module-Notes) if you want to remotely control your robot. + +## Setup and Assemble Arduino + +- Recommended Starting Kit: [Sparkfun Inventor's Kit](https://www.sparkfun.com/products/12001) +- Download [Arduino IDE](http://arduino.cc/en/main/software) +- Plug in your Arduino or Arduino compatible microcontroller via USB +- Open the Arduino IDE, select: File > Examples > Firmata > StandardFirmata +- Click the "Upload" button. + +If the upload was successful, the board is now prepared and you can close the Arduino IDE. + +For non-Arduino projects, each IO Plugin's repo will provide its own platform specific setup instructions. + + +## Hey you, here's Johnny! + +#### Source Code: + +``` bash +git clone git://github.com/rwaldron/johnny-five.git && cd johnny-five + +npm install +``` + +#### npm package: + +Install the module with: + +```bash +npm install johnny-five +``` + + +## Example Programs + +To get you up and running quickly, we provide a variety of examples for using each Johnny-Five component. One thing we’re especially excited about is the extensive collection of [Fritzing](http://fritzing.org/home/) diagrams you’ll find throughout the site. A huge part of doing any Johnny-Five project is handling the actual hardware, and we’ve included these as part of the documentation because we realised that instructions on how to write code to control a servo are insufficient without instructions on how to connect a servo! + +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. + + + +### Board +- [Basic Board initialization](https://github.com/rwaldron/johnny-five/blob/master/docs/board.md) +- [Board - Specify port](https://github.com/rwaldron/johnny-five/blob/master/docs/board-with-port.md) +- [Board - Multiple in one program](https://github.com/rwaldron/johnny-five/blob/master/docs/board-multi.md) +- [REPL](https://github.com/rwaldron/johnny-five/blob/master/docs/repl.md) +- [Pin](https://github.com/rwaldron/johnny-five/blob/master/docs/pin.md) + +### Expander +- [Expander - MCP23017](https://github.com/rwaldron/johnny-five/blob/master/docs/expander-MCP23017.md) +- [Expander - MCP23008](https://github.com/rwaldron/johnny-five/blob/master/docs/expander-MCP23008.md) +- [Expander - PCF8574](https://github.com/rwaldron/johnny-five/blob/master/docs/expander-PCF8574.md) +- [Expander - PCF8575](https://github.com/rwaldron/johnny-five/blob/master/docs/expander-PCF8575.md) +- [Expander - PCA9685](https://github.com/rwaldron/johnny-five/blob/master/docs/expander-PCA9685.md) +- [Expander - PCF8591](https://github.com/rwaldron/johnny-five/blob/master/docs/expander-PCF8591.md) + +### LED +- [LED](https://github.com/rwaldron/johnny-five/blob/master/docs/led.md) +- [LED - PCA9685](https://github.com/rwaldron/johnny-five/blob/master/docs/led-PCA9685.md) +- [LED - Blink](https://github.com/rwaldron/johnny-five/blob/master/docs/led-blink.md) +- [LED - Pulse](https://github.com/rwaldron/johnny-five/blob/master/docs/led-pulse.md) +- [LED - Pulse with animation](https://github.com/rwaldron/johnny-five/blob/master/docs/led-pulse-animation.md) +- [LED - Fade](https://github.com/rwaldron/johnny-five/blob/master/docs/led-fade.md) +- [LED - Fade callback](https://github.com/rwaldron/johnny-five/blob/master/docs/led-fade-callback.md) +- [LED - Fade with animation](https://github.com/rwaldron/johnny-five/blob/master/docs/led-fade-animation.md) +- [LED - Demo sequence](https://github.com/rwaldron/johnny-five/blob/master/docs/led-demo-sequence.md) +- [LED - Slider](https://github.com/rwaldron/johnny-five/blob/master/docs/led-slider.md) +- [LED - Array](https://github.com/rwaldron/johnny-five/blob/master/docs/led-array.md) +- [LED - RGB](https://github.com/rwaldron/johnny-five/blob/master/docs/led-rgb.md) +- [LED - RGB (Common Anode)](https://github.com/rwaldron/johnny-five/blob/master/docs/led-rgb-anode.md) +- [LED - RGB (Common Anode) PCA9685](https://github.com/rwaldron/johnny-five/blob/master/docs/led-rgb-anode-PCA9685.md) +- [LED - RGB Intensity](https://github.com/rwaldron/johnny-five/blob/master/docs/led-rgb-intensity.md) +- [LED - Rainbow](https://github.com/rwaldron/johnny-five/blob/master/docs/led-rainbow.md) +- [LED - Digital Clock](https://github.com/rwaldron/johnny-five/blob/master/docs/led-digits-clock.md) +- [LED - Matrix](https://github.com/rwaldron/johnny-five/blob/master/docs/led-matrix.md) +- [LED - Matrix Demo](https://github.com/rwaldron/johnny-five/blob/master/docs/led-matrix-tutorial.md) +- [LED - Matrix HT16K33](https://github.com/rwaldron/johnny-five/blob/master/docs/led-matrix-HT16K33.md) +- [LED - Matrix HT16K33 16x8](https://github.com/rwaldron/johnny-five/blob/master/docs/led-matrix-HT16K33-16x8.md) + +### Servo +- [Servo](https://github.com/rwaldron/johnny-five/blob/master/docs/servo.md) +- [Servo - PCA9685](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-PCA9685.md) +- [Servo - Continuous](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-continuous.md) +- [Servo - Slider control](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-slider.md) +- [Servo - Prompt](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-prompt.md) +- [Servo - Drive](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-drive.md) +- [Servo - Sweep](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-sweep.md) +- [Servo - Array of servos](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-array.md) + +### Servo Animation +- [Servo - Animation](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-animation.md) +- [Servo - Leg Animation](https://github.com/rwaldron/johnny-five/blob/master/docs/servo-animation-leg.md) + +### Motor +- [Motor](https://github.com/rwaldron/johnny-five/blob/master/docs/motor.md) +- [Motor - Directional](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-directional.md) +- [Motor - Brake](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-brake.md) +- [Motor - Current](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-current.md) +- [Motor - H-Bridge](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-hbridge.md) +- [Motor - PCA9685](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-PCA9685.md) +- [Motor - 3 pin](https://github.com/rwaldron/johnny-five/blob/master/docs/motor-3-pin.md) + +### Stepper Motor +- [Stepper - Driver](https://github.com/rwaldron/johnny-five/blob/master/docs/stepper-driver.md) +- [Stepper - Sweep](https://github.com/rwaldron/johnny-five/blob/master/docs/stepper-sweep.md) + +### ESC & Brushless Motor +- [ESC - Keypress](https://github.com/rwaldron/johnny-five/blob/master/docs/esc-keypress.md) +- [ESC - Dualshock](https://github.com/rwaldron/johnny-five/blob/master/docs/esc-dualshock.md) +- [ESC - PCA9685](https://github.com/rwaldron/johnny-five/blob/master/docs/esc-PCA9685.md) +- [ESC - Bidirectional](https://github.com/rwaldron/johnny-five/blob/master/docs/esc-bidirectional.md) +- [ESC - Bidirectional Forward-Reverse](https://github.com/rwaldron/johnny-five/blob/master/docs/esc-bidirectional-forward-reverse.md) + +### Sonar/Ultrasonic +- [Ping](https://github.com/rwaldron/johnny-five/blob/master/docs/ping.md) +- [Sonar](https://github.com/rwaldron/johnny-five/blob/master/docs/sonar.md) +- [Sonar - Scanner](https://github.com/rwaldron/johnny-five/blob/master/docs/sonar-scan.md) +- [Sonar - I2C SRF10](https://github.com/rwaldron/johnny-five/blob/master/docs/sonar-srf10.md) + +### Button / Switch +- [Button](https://github.com/rwaldron/johnny-five/blob/master/docs/button.md) +- [Button - Bumper](https://github.com/rwaldron/johnny-five/blob/master/docs/button-bumper.md) +- [Button - Options](https://github.com/rwaldron/johnny-five/blob/master/docs/button-options.md) +- [Button - Pullup](https://github.com/rwaldron/johnny-five/blob/master/docs/button-pullup.md) +- [Toggle Switch](https://github.com/rwaldron/johnny-five/blob/master/docs/toggle-switch.md) + +### Keypad +- [Keypad - VKEY](https://github.com/rwaldron/johnny-five/blob/master/docs/keypad-analog-vkey.md) +- [Keypad - Waveshare AD](https://github.com/rwaldron/johnny-five/blob/master/docs/keypad-analog-ad.md) +- [Keypad - MPR121](https://github.com/rwaldron/johnny-five/blob/master/docs/keypad-MPR121.md) +- [Keypad - MPR121QR2](https://github.com/rwaldron/johnny-five/blob/master/docs/keypad-MPR121QR2.md) + +### Relay +- [Relay](https://github.com/rwaldron/johnny-five/blob/master/docs/relay.md) + +### Shift Register +- [Shift Register](https://github.com/rwaldron/johnny-five/blob/master/docs/shift-register.md) +- [Shift Register - Seven segment controller](https://github.com/rwaldron/johnny-five/blob/master/docs/shift-register-seven-segment.md) +- [Shift Register - Seven segments, daisy chained](https://github.com/rwaldron/johnny-five/blob/master/docs/shift-register-daisy-chain.md) + +### Infrared (Proximity, Motion, Reflectance) +- [IR Motion](https://github.com/rwaldron/johnny-five/blob/master/docs/ir-motion.md) +- [IR Proximity](https://github.com/rwaldron/johnny-five/blob/master/docs/ir-proximity.md) +- [IR Reflectance](https://github.com/rwaldron/johnny-five/blob/master/docs/ir-reflect.md) +- [IR Reflectance Array](https://github.com/rwaldron/johnny-five/blob/master/docs/ir-reflect-array.md) + +### Proximity +- [Proximity](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity.md) +- [Proximity - GP2Y0A710K0F](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-GP2Y0A710K0F.md) +- [Proximity - SRF10](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-srf10.md) +- [Proximity - MB1000](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-mb1000.md) +- [Proximity - MB1010](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-mb1010.md) +- [Proximity - MB1003](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-mb1003.md) +- [Proximity - MB1230](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-mb1230.md) +- [Proximity - HC-SR04](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-hcsr04.md) +- [Proximity - LIDAR-Lite](https://github.com/rwaldron/johnny-five/blob/master/docs/proximity-lidarlite.md) + +### Motion +- [Motion](https://github.com/rwaldron/johnny-five/blob/master/docs/motion.md) +- [Motion - GP2Y0D805Z0F](https://github.com/rwaldron/johnny-five/blob/master/docs/motion-gp2y0d805z0f.md) +- [Motion - GP2Y0D810Z0F](https://github.com/rwaldron/johnny-five/blob/master/docs/motion-gp2y0d810z0f.md) +- [Motion - GP2Y0D810Z0F](https://github.com/rwaldron/johnny-five/blob/master/docs/motion-gp2y0d815z0f.md) +- [Motion - GP2Y0A60SZLF](https://github.com/rwaldron/johnny-five/blob/master/docs/motion-GP2Y0A60SZLF.md) + +### Joystick +- [Joystick](https://github.com/rwaldron/johnny-five/blob/master/docs/joystick.md) +- [Joystick - Esplora](https://github.com/rwaldron/johnny-five/blob/master/docs/joystick-esplora.md) +- [Joystick - Sparkfun Shield](https://github.com/rwaldron/johnny-five/blob/master/docs/joystick-shield.md) +- [Joystick - Pan + Tilt control](https://github.com/rwaldron/johnny-five/blob/master/docs/joystick-pantilt.md) + +### LCD +- [LCD](https://github.com/rwaldron/johnny-five/blob/master/docs/lcd.md) +- [LCD - Enumerate characters](https://github.com/rwaldron/johnny-five/blob/master/docs/lcd-enumeratechars.md) +- [LCD - Runner 20x4](https://github.com/rwaldron/johnny-five/blob/master/docs/lcd-runner-20x4.md) +- [LCD - Runner 16x2](https://github.com/rwaldron/johnny-five/blob/master/docs/lcd-runner.md) +- [LCD - I2C](https://github.com/rwaldron/johnny-five/blob/master/docs/lcd-i2c.md) +- [LCD - I2C PCF8574](https://github.com/rwaldron/johnny-five/blob/master/docs/lcd-i2c-PCF8574.md) +- [LCD - I2C Runner](https://github.com/rwaldron/johnny-five/blob/master/docs/lcd-i2c-runner.md) + +### Compass/Magnetometer +- [Compass / Magnetometer](https://github.com/rwaldron/johnny-five/blob/master/docs/magnetometer.md) +- [Compass - HMC6352](https://github.com/rwaldron/johnny-five/blob/master/docs/compass-hmc6352.md) +- [Compass - HMC5883L](https://github.com/rwaldron/johnny-five/blob/master/docs/compass-hmc5883l.md) +- [Compass - Logger](https://github.com/rwaldron/johnny-five/blob/master/docs/magnetometer-log.md) +- [Compass - Find north](https://github.com/rwaldron/johnny-five/blob/master/docs/magnetometer-north.md) + +### Piezo +- [Piezo](https://github.com/rwaldron/johnny-five/blob/master/docs/piezo.md) + +### IMU/Multi +- [IMU - MPU6050](https://github.com/rwaldron/johnny-five/blob/master/docs/imu-mpu6050.md) +- [Multi - MPL115A2](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-mpl115a2.md) +- [Multi - BMP180](https://github.com/rwaldron/johnny-five/blob/master/docs/multi-bmp180.md) + +### Sensors +- [Sensor](https://github.com/rwaldron/johnny-five/blob/master/docs/sensor.md) +- [Sensor - Slide potentiometer](https://github.com/rwaldron/johnny-five/blob/master/docs/sensor-slider.md) +- [Sensor - Force sensitive resistor](https://github.com/rwaldron/johnny-five/blob/master/docs/sensor-fsr.md) +- [Sensor - Photoresistor](https://github.com/rwaldron/johnny-five/blob/master/docs/photoresistor.md) +- [Sensor - Potentiometer](https://github.com/rwaldron/johnny-five/blob/master/docs/potentiometer.md) +- [Sensor - Microphone](https://github.com/rwaldron/johnny-five/blob/master/docs/microphone.md) +- [Accelerometer](https://github.com/rwaldron/johnny-five/blob/master/docs/accelerometer.md) +- [Accelerometer - ADXL345](https://github.com/rwaldron/johnny-five/blob/master/docs/accelerometer-adxl345.md) +- [Accelerometer - ADXL335](https://github.com/rwaldron/johnny-five/blob/master/docs/accelerometer-adxl335.md) +- [Accelerometer - MMA7361](https://github.com/rwaldron/johnny-five/blob/master/docs/accelerometer-mma7361.md) +- [Accelerometer - MPU6050](https://github.com/rwaldron/johnny-five/blob/master/docs/accelerometer-mpu6050.md) +- [Accelerometer - Pan + Tilt](https://github.com/rwaldron/johnny-five/blob/master/docs/accelerometer-pan-tilt.md) +- [Gyro](https://github.com/rwaldron/johnny-five/blob/master/docs/gyro.md) +- [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) +- [Temperature - TMP36](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-tmp36.md) +- [Temperature - LM35](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-lm35.md) +- [Temperature - DS18B20](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-ds18b20.md) +- [Temperature - MPU6050](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-mpu6050.md) +- [Barometer - MPL115A2](https://github.com/rwaldron/johnny-five/blob/master/docs/barometer-mpl115a2.md) +- [Temperature - MPL115A2](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-mpl115a2.md) +- [Barometer - BMP180](https://github.com/rwaldron/johnny-five/blob/master/docs/barometer-BMP180.md) +- [Temperature - BMP180](https://github.com/rwaldron/johnny-five/blob/master/docs/temperature-BMP180.md) + +### Grove IoT Kit (Seeed Studio) +- [Grove - LED](https://github.com/rwaldron/johnny-five/blob/master/docs/grove-led.md) +- [Grove - Button](https://github.com/rwaldron/johnny-five/blob/master/docs/grove-button.md) +- [Grove - Touch](https://github.com/rwaldron/johnny-five/blob/master/docs/grove-touch.md) +- [Grove - Sensor](https://github.com/rwaldron/johnny-five/blob/master/docs/grove-sensor.md) +- [Grove - LCD RGB](https://github.com/rwaldron/johnny-five/blob/master/docs/grove-lcd-rgb.md) +- [Grove - LCD RGB temperature display](https://github.com/rwaldron/johnny-five/blob/master/docs/grove-lcd-rgb-temperature-display.md) +- [Grove - Servo](https://github.com/rwaldron/johnny-five/blob/master/docs/grove-servo.md) + +### TinkerKit +- [TinkerKit - Accelerometer](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-accelerometer.md) +- [TinkerKit - Blink](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-blink.md) +- [TinkerKit - Button](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-button.md) +- [TinkerKit - Combo](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-combo.md) +- [TinkerKit - Continuous servo](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-continuous-servo.md) +- [TinkerKit - Gyro](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-gyroscope.md) +- [TinkerKit - Joystick](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-joystick.md) +- [TinkerKit - Linear potentiometer](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-linear-pot.md) +- [TinkerKit - Rotary potentiometer](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-rotary.md) +- [TinkerKit - Temperature](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-thermistor.md) +- [TinkerKit - Tilt](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-tilt.md) +- [TinkerKit - Touch](https://github.com/rwaldron/johnny-five/blob/master/docs/tinkerkit-touch.md) + +### Wii +- [Wii Nunchuck](https://github.com/rwaldron/johnny-five/blob/master/docs/nunchuk.md) +- [Wii Classic Controller](https://github.com/rwaldron/johnny-five/blob/master/docs/classic-controller.md) + +### Complete Bots / Projects +- [Line Follower](https://github.com/rwaldron/johnny-five/blob/master/docs/line-follower.md) +- [Motobot](https://github.com/rwaldron/johnny-five/blob/master/docs/motobot.md) +- [Navigator](https://github.com/rwaldron/johnny-five/blob/master/docs/navigator.md) +- [Nodebot](https://github.com/rwaldron/johnny-five/blob/master/docs/nodebot.md) +- [Whisker](https://github.com/rwaldron/johnny-five/blob/master/docs/whisker.md) +- [Phoenix Hexapod](https://github.com/rwaldron/johnny-five/blob/master/docs/phoenix.md) +- [BOE Bot](https://github.com/rwaldron/johnny-five/blob/master/docs/boe-test-servos.md) +- [Bug](https://github.com/rwaldron/johnny-five/blob/master/docs/bug.md) +- [Lynxmotion Biped BRAT](https://github.com/rwaldron/johnny-five/blob/master/docs/brat.md) +- [Robotic Claw](https://github.com/rwaldron/johnny-five/blob/master/docs/claw.md) +- [Kinect Robotic Arm Controller](https://github.com/rwaldron/johnny-five/blob/master/docs/kinect-arm-controller.md) +- [Laser Trip Wire](https://github.com/rwaldron/johnny-five/blob/master/docs/laser-trip-wire.md) +- [Radar](https://github.com/rwaldron/johnny-five/blob/master/docs/radar.md) + +### Component Plugin Template +- [Example plugin](https://github.com/rwaldron/johnny-five/blob/master/docs/plugin.md) + +### IO Plugins +- [Led Blink on Electric Imp](https://github.com/rwaldron/johnny-five/blob/master/docs/imp-io.md) +- [Led Blink on Spark Core](https://github.com/rwaldron/johnny-five/blob/master/docs/spark-io.md) +- [Led Blink on pcDuino3](https://github.com/rwaldron/johnny-five/blob/master/docs/pcduino-io.md) +- [Led Blink on Intel Galileo Gen 2](https://github.com/rwaldron/johnny-five/blob/master/docs/galileo-io.md) +- [Led Blink on Raspberry Pi](https://github.com/rwaldron/johnny-five/blob/master/docs/raspi-io.md) +- [Led Blink on Intel Edison Arduino Board](https://github.com/rwaldron/johnny-five/blob/master/docs/edison-io-arduino.md) +- [Led Blink on Intel Edison Mini Board](https://github.com/rwaldron/johnny-five/blob/master/docs/edison-io-miniboard.md) + + + +## Many fragments. Some large, some small. + +#### [Wireless Nodebot](http://jsfiddle.net/rwaldron/88M6b/show/light) +#### [Kinect Controlled Robot Arm](http://jsfiddle.net/rwaldron/XMsGQ/show/light/) +#### [Biped Nodebot](http://jsfiddle.net/rwaldron/WZkn5/show/light/) +#### [LCD Running Man](http://jsfiddle.net/rwaldron/xKwaU/show/light/) +#### [Slider Controlled Panning Servo](http://jsfiddle.net/rwaldron/kZakv/show/light/) +#### [Joystick Controlled Laser (pan/tilt) 1](http://jsfiddle.net/rwaldron/HPqms/show/light/) +#### [Joystick Controlled Laser (pan/tilt) 2](http://jsfiddle.net/rwaldron/YHb7A/show/light/) +#### [Joystick Controlled Claw](http://jsfiddle.net/rwaldron/6ZXFe/show/light/) +#### [Robot Claw](http://jsfiddle.net/rwaldron/CFSZJ/show/light/) +#### [Joystick, Motor & Led](http://jsfiddle.net/rwaldron/gADSz/show/light/) + + + +## Make: JavaScript Robotics + +[![](http://ecx.images-amazon.com/images/I/91ae8ZZDQ2L.jpg)](http://shop.oreilly.com/product/0636920031390.do) + + + + +## Contributing +All contributions must adhere to the [Idiomatic.js Style Guide](https://github.com/rwaldron/idiomatic.js), +by maintaining the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [grunt](https://github.com/gruntjs/grunt). + + +## License +Copyright (c) 2012, 2013, 2014 Rick Waldron +Licensed under the MIT license. +Copyright (c) 2014, 2015 The Johnny-Five Contributors +Licensed under the MIT license. diff --git a/JavaScript/node_modules/johnny-five/awesome.md b/JavaScript/node_modules/johnny-five/awesome.md new file mode 100644 index 0000000..098c53a --- /dev/null +++ b/JavaScript/node_modules/johnny-five/awesome.md @@ -0,0 +1,142 @@ +# Awesome Nodebots Built with Johnny-Five +---------------- +(Entries listed newest to oldest) + + +## Ricardo de Pena [@ricardodepena](https://twitter.com/ricardodepena) + +- Clawbot: bluetooth bot with a claw, controlled via a ps3 controller + [video](http://vimeo.com/86788094) + [code](https://github.com/rdepena/clawbot) + + +## Richard Key [@busyrich](http://twitter.com/busyrich) + +- Arduino Attack! + [video](http://www.youtube.com/watch?v=1NalU4d7a20) + [code](https://github.com/BusyRich/arduino-attack) + + +## Andrew Homeyer [@andrewhomeyer](https://twitter.com/andrewhomeyer), Matt Parrish [@mattparrish](https://twitter.com/mattparrish), Nicholas Boll [@nicholasboll](https://twitter.com/nicholasboll) + +- Missile Command: A rubber band launcher that took down a nodecopter + [video](http://youtu.be/0FAfu-Zowuo) + [code](https://github.com/homeyer/missile-command/) + + +## Sara Gorecki [@opheliasdaisies] (https://twitter.com/opheliasdaisies) + +- A tri-color LED that cycles according to pressure sensor input. + [video](http://youtu.be/ePiiaja1CuI) + [code](https://github.com/opheliasdaisies/tri-color-led) + + +## Rahul Ravikumar [@tikurahul](https://twitter.com/tikurahul), Bryan Hughes[@nebrius](https://twitter.com/nebrius) + +- Typing Bot (nodebots, jsconf) + [video](http://www.youtube.com/watch?v=kjTO2OkGnD8) + + +## Raquel Vélez [@rockbot](https://twitter.com/rockbot) + +- Manny the Manipulator: A 2-dimensional serial manipulator using forward/inverse kinematics (via [vektor](https://github.com/rockbot/vektor)) + [video](http://www.youtube.com/watch?v=JKumEFyOvuI) + [code](https://github.com/rockbot/vektor/tree/master/manipulator) + + +## Travis Thieman [@thieman](https://twitter.com/thieman) + +- Power Glove (OS X Volume Control): + [video](http://www.youtube.com/watch?v=j1BimT0hPSQ) + [code](https://github.com/tthieman/arduino-projects/blob/master/hackathon_20130217/power_glove.js) + + +## Francis Gulotta [@reconbot](https://twitter.com/reconbot) + +- Dorby the DoorBot + [video howto](http://www.youtube.com/watch?v=6VnSIbRAlFw) + [video servo operation](http://www.youtube.com/watch?v=gh7LtDA6EL0) + [code](https://github.com/reconbot/dorby) + + +## Tim Walker [@timwalker2k](https://twitter.com/timwalker2k) + +- An experimental Theremin using a proximity sensor and JavaScript. + [code](https://github.com/twalker/sine5) + +- A build status light for use within a continuous integration workflow + [code](https://github.com/twalker/cilite) + + +## Kelly Korevec [@korevec](http://twitter.com/korevec) + +- Medibot + [Picture](https://twitter.com/korevec/status/267848987711766528/photo/1) + [code](https://github.com/korevec/medibot) + +## Irene Ros [@ireneros](http://twitter.com/ireneros) + +- Wii Nunchuk Controller for AR Drone (nodecopter event) + [video](http://twitter.yfrog.com/n4u1nrxrakmkyopxxpjmxzmzz) + [code](https://github.com/iros/nodecoptering) + + +## Chris Williams [@voodootikigod](http://twitter.com/voodootikigod) + +- Wii Nunchuk Controller for AR Drone (nodecopter event) + [code](https://github.com/voodootikigod/wii-drone/) + + +## Andreas Haugstrup Pedersen [@hgstrp](http://twitter.com/hgstrp) + +- LCD Controller (First successful implementation!!) + [video](http://vimeo.com/46577266) + [code](https://gist.github.com/3200331) + (Became the basis for the LCD constructor!) + + +## Rebecca Murphey [@rmurphey](http://twitter.com/rmurphey) + +- Johnny-Five Projects + [On Github](https://github.com/rmurphey/johnny-five-projects) + +- Shift Register Implementation w/ Led Counter Display + [video](http://vimeo.com/46463390) + [code](http://gist.github.com/3185390) + +## Jonathan Blanchet [@jblanchefr](http://twitter.com/jblanchefr) + +- Arduino + Websockets + particles: + [video](http://www.youtube.com/watch?v=MXEGLGmpCfo) + [code](https://gist.github.com/3145395) + +- Arduino + Websockets + css change: + [video](http://www.youtube.com/watch?v=aYFOOr1amSg&feature=plcp) + [code](https://gist.github.com/3145461) + +- Arduino + potentiometer + particles: + [video](http://www.youtube.com/watch?v=d5r5r7pHUZI) + [code](https://gist.github.com/3147263) + + +## Cole Gillespie [@theCole](https://twitter.com/theCole) + +- Joystick Controlled Google Maps Streetview: + [video](https://air.mozilla.org/hack-jam-dundee/) + + +## Kelly Korevec [@korevec](https://twitter.com/korevec) + +- 6WD Rover + [image](http://twitpic.com/a9t3rg) + +## Sara Chipps [@sarajchipps](https://twitter.com/sarajchipps) + +- LEDs that change color based on Twitter sentiment + [video](http://www.youtube.com/watch?v=ws7svZuq29c) + [code](https://github.com/SaraJo/twitter-ring) + +## Yusuf Çakmak [@yukocan](https://twitter.com/yukocan) + Control Led's Color with Leap Motion + Arduino + [Code](https://github.com/yusufcakmak/leapmotion-arduino/blob/master/examples/ledcontrolhands.js) + [Vine](https://vine.co/v/MmhnAKO7aLx) diff --git a/JavaScript/node_modules/johnny-five/eg/.jshintrc b/JavaScript/node_modules/johnny-five/eg/.jshintrc new file mode 100644 index 0000000..d519a3c --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/.jshintrc @@ -0,0 +1,25 @@ +{ + "curly": true, + "eqeqeq": true, + "immed": true, + "latedef": false, + "newcap": false, + "noarg": true, + "sub": true, + "undef": true, + "boss": true, + "eqnull": true, + "node": true, + "strict": false, + "esnext": true, + "quotmark": "double", + "globals": { + "exports": true, + "document": true, + "$": true, + "Radar": true, + "WeakMap": true, + "window": true, + "copy": true + } +} diff --git a/JavaScript/node_modules/johnny-five/eg/=proximity-SRF10.js b/JavaScript/node_modules/johnny-five/eg/=proximity-SRF10.js new file mode 100644 index 0000000..724bc79 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/=proximity-SRF10.js @@ -0,0 +1,14 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + + var proximity = new five.Proximity({ + controller: "SRF10" + }); + + proximity.on("data", function() { + console.log(this.cm + "cm"); + }); + +}); diff --git a/JavaScript/node_modules/johnny-five/eg/accelerometer-adxl335.js b/JavaScript/node_modules/johnny-five/eg/accelerometer-adxl335.js new file mode 100644 index 0000000..68aa510 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/accelerometer-adxl335.js @@ -0,0 +1,22 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var accelerometer = new five.Accelerometer({ + controller: "ADXL335", + pins: ["A0", "A1", "A2"] + }); + + accelerometer.on("change", function() { + console.log("accelerometer"); + console.log(" x : ", this.x); + console.log(" y : ", this.y); + console.log(" z : ", this.z); + console.log(" pitch : ", this.pitch); + console.log(" roll : ", this.roll); + console.log(" acceleration : ", this.acceleration); + console.log(" inclination : ", this.inclination); + console.log(" orientation : ", this.orientation); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/accelerometer-adxl345.js b/JavaScript/node_modules/johnny-five/eg/accelerometer-adxl345.js new file mode 100644 index 0000000..0077625 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/accelerometer-adxl345.js @@ -0,0 +1,21 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var accelerometer = new five.Accelerometer({ + controller: "ADXL345" + }); + + accelerometer.on("change", function() { + console.log("accelerometer"); + console.log(" x : ", this.x); + console.log(" y : ", this.y); + console.log(" z : ", this.z); + console.log(" pitch : ", this.pitch); + console.log(" roll : ", this.roll); + console.log(" acceleration : ", this.acceleration); + console.log(" inclination : ", this.inclination); + console.log(" orientation : ", this.orientation); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/accelerometer-mma7361.js b/JavaScript/node_modules/johnny-five/eg/accelerometer-mma7361.js new file mode 100644 index 0000000..de9bc93 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/accelerometer-mma7361.js @@ -0,0 +1,36 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + // --- Sleep Pin + // The sleepPin is used to enable/disable the device and put it into sleep mode + // You can also tie the sleep pin to high with a 10k resistor and omit + // this option + + // --- Calibration of zero-G readings (zeroV) + // This device also benefits from a calibration step. You can autoCalibrate + // by placing the device level on startup. You can also read the calibrated + // centers by reading the accelerometer.zeroV array after calibration. Subsequent + // initializations, you can omit the autoCalibrate and set the zeroV array + // in the options instead + + var accelerometer = new five.Accelerometer({ + controller: "MMA7361", + pins: ["A0", "A1", "A2"], + sleepPin: 13, + autoCalibrate: true + }); + + accelerometer.on("change", function() { + console.log("accelerometer"); + console.log(" x : ", this.x); + console.log(" y : ", this.y); + console.log(" z : ", this.z); + console.log(" pitch : ", this.pitch); + console.log(" roll : ", this.roll); + console.log(" acceleration : ", this.acceleration); + console.log(" inclination : ", this.inclination); + console.log(" orientation : ", this.orientation); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/accelerometer-mpu6050.js b/JavaScript/node_modules/johnny-five/eg/accelerometer-mpu6050.js new file mode 100644 index 0000000..48fd3dc --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/accelerometer-mpu6050.js @@ -0,0 +1,21 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var accelerometer = new five.Accelerometer({ + controller: "MPU6050" + }); + + accelerometer.on("change", function() { + console.log("accelerometer"); + console.log(" x : ", this.x); + console.log(" y : ", this.y); + console.log(" z : ", this.z); + console.log(" pitch : ", this.pitch); + console.log(" roll : ", this.roll); + console.log(" acceleration : ", this.acceleration); + console.log(" inclination : ", this.inclination); + console.log(" orientation : ", this.orientation); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/accelerometer-pan-tilt.js b/JavaScript/node_modules/johnny-five/eg/accelerometer-pan-tilt.js new file mode 100644 index 0000000..40f0662 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/accelerometer-pan-tilt.js @@ -0,0 +1,41 @@ +var five = require("../lib/johnny-five.js"), + board; + +board = new five.Board(); + +board.on("ready", function() { + + var range, pan, tilt, accel; + + range = [0, 170]; + + // Servo to control panning + pan = new five.Servo({ + pin: 9, + range: range + }); + + // Servo to control tilt + tilt = new five.Servo({ + pin: 10, + range: range + }); + + // Accelerometer to control pan/tilt + accel = new five.Accelerometer({ + pins: ["A3", "A4", "A5"], + freq: 250 + }); + + // Center all servos + (five.Servos()).center(); + + accel.on("acceleration", function(err, timestamp) { + // console.log( "acceleration", this.axis ); + + tilt.to(Math.abs(Math.ceil(170 * this.pitch.toFixed(2)) - 180)); + pan.to(Math.ceil(170 * this.roll.toFixed(2))); + + // TODO: Math.abs(v - 180) as inversion function ? + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/accelerometer.js b/JavaScript/node_modules/johnny-five/eg/accelerometer.js new file mode 100644 index 0000000..f1cc3c0 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/accelerometer.js @@ -0,0 +1,88 @@ +var five = require("../lib/johnny-five.js"), + board, accel; + +board = new five.Board(); + +board.on("ready", function() { + + // Create a new analog `Accelerometer` hardware instance. + // + // five.Accelerometer([ x, y[, z] ]); + // + // five.Accelerometer({ + // pins: [ x, y[, z] ] + // freq: ms + // }); + // + + accel = new five.Accelerometer({ + pins: ["A3", "A4", "A5"], + + // Adjust the following for your device. + // These are the default values (LIS344AL) + // + sensitivity: 96, // mV/degree/seconds + zeroV: 478 // volts in ADC + }); + + // Accelerometer Event API + + + // "data" + // + // Fires when X, Y or Z has changed. + // + // The first argument is an object containing raw x, y, z + // values as read from the analog input. + // + accel.on("data", function(data) { + + console.log("raw: ", data); + }); + + // "acceleration" + // + // Fires once every N ms, equal to value of freg + // Defaults to 500ms + // + accel.on("acceleration", function(data) { + + console.log("acceleration", data); + }); + + // "orientation" + // + // Fires when orientation changes + // + accel.on("orientation", function(data) { + + console.log("orientation", data); + }); + + // "inclination" + // + // Fires when inclination changes + // + accel.on("inclination", function(data) { + + console.log("inclination", data); + }); + + // "change" + // + // Fires when X, Y or Z has changed + // + accel.on("change", function(data) { + + console.log("change", data); + }); +}); + +// @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/JavaScript/node_modules/johnny-five/eg/barometer-BMP180.js b/JavaScript/node_modules/johnny-five/eg/barometer-BMP180.js new file mode 100644 index 0000000..b805623 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/barometer-BMP180.js @@ -0,0 +1,14 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var barometer = new five.Barometer({ + controller: "BMP180" + }); + + barometer.on("change", function() { + console.log("barometer"); + console.log(" pressure : ", this.pressure); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/barometer-mpl115a2.js b/JavaScript/node_modules/johnny-five/eg/barometer-mpl115a2.js new file mode 100644 index 0000000..cbf7120 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/barometer-mpl115a2.js @@ -0,0 +1,14 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var barometer = new five.Barometer({ + controller: "MPL115A2" + }); + + barometer.on("data", function() { + console.log("barometer"); + console.log(" pressure : ", this.pressure); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/barometer-mpl3115a2.js b/JavaScript/node_modules/johnny-five/eg/barometer-mpl3115a2.js new file mode 100644 index 0000000..b70b63e --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/barometer-mpl3115a2.js @@ -0,0 +1,18 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var barometer = new five.Barometer({ + controller: "MPL3115A2" + }); + + barometer.on("data", function() { + console.log("barometer"); + console.log(" pressure : ", this.pressure); + console.log("--------------------------------------"); + }); +}); + +// @markdown +// - [MPL115A2 - I2C Barometric Pressure/Temperature Sensor](https://www.adafruit.com/product/992) +// @markdown diff --git a/JavaScript/node_modules/johnny-five/eg/board-multi.js b/JavaScript/node_modules/johnny-five/eg/board-multi.js new file mode 100644 index 0000000..9777ab6 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/board-multi.js @@ -0,0 +1,48 @@ +var five = require("../lib/johnny-five.js"); +var boards = new five.Boards(["A", "B"]); + +// Create 2 board instances with IDs "A" & "B" +boards.on("ready", function() { + + // Both "A" and "B" are initialized + // (connected and available for communication) + + // |this| is an array-like object containing references + // to each initialized board. + this.each(function(board) { + + // Initialize an Led instance on pin 13 of + // each initialized board and strobe it. + var led = new five.Led({ + pin: 13, + board: board + }); + + led.blink(); + }); +}); + +/** + * When initializing multiple boards with only an ID string, + * the order of initialization and connection is the order + * that your OS enumerates ports. + * + * Given the above program, "A" and "B" would be assigned as: + * + * A => /dev/cu.usbmodem411 + * B => /dev/cu.usbmodem621 + * + * + * You may override this by providing explicit port paths: + * + * var ports = [ + * { id: "A", port: "/dev/cu.usbmodem621" }, + * { id: "B", port: "/dev/cu.usbmodem411" } + * ]; + * + * new five.Boards(ports).on("ready", function() { + * + * // Boards are initialized! + * + * }); + */ diff --git a/JavaScript/node_modules/johnny-five/eg/board-with-port.js b/JavaScript/node_modules/johnny-five/eg/board-with-port.js new file mode 100644 index 0000000..795d44e --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/board-with-port.js @@ -0,0 +1,19 @@ +var five = require("../lib/johnny-five.js"); + +// Johnny-Five will try its hardest to detect the port for you, +// however you may also explicitly specify the port by passing +// it as an optional property to the Board constructor: +var board = new five.Board({ + port: "/dev/cu.usbmodem1411" +}); + +// The board's pins will not be accessible until +// the board has reported that it is ready +board.on("ready", function() { + this.pinMode(13, this.MODES.OUTPUT); + + this.loop(500, function() { + // Whatever the last value was, write the opposite + this.digitalWrite(13, this.pins[13].value ? 0 : 1); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/board.js b/JavaScript/node_modules/johnny-five/eg/board.js new file mode 100644 index 0000000..dcdcd61 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/board.js @@ -0,0 +1,11 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +// The board's pins will not be accessible until +// the board has reported that it is ready +board.on("ready", function() { + console.log("Ready!"); + + var led = new five.Led(13); + led.blink(500); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/boe-test-servos.js b/JavaScript/node_modules/johnny-five/eg/boe-test-servos.js new file mode 100644 index 0000000..cca7094 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/boe-test-servos.js @@ -0,0 +1,251 @@ +var five = require("../lib/johnny-five.js"), + board, Navigator, bot, left, right, sonar, scanner, servos, + expandWhich, reverseDirMap, scale; + +reverseDirMap = { + right: "left", + left: "right" +}; + +scale = function(speed, low, high) { + return Math.floor(five.Fn.map(speed, 0, 5, low, high)); +}; + + +/** + * Navigator + * @param {Object} opts Optional properties object + */ + +function Navigator(opts) { + + // Boe Navigator continuous are calibrated to stop at 90° + this.center = opts.center || 90; + + this.servos = { + right: new five.Servo({ + pin: opts.right, + type: "continuous" + }), + left: new five.Servo({ + pin: opts.left, + type: "continuous" + }) + }; + + this.direction = opts.direction || { + right: this.center, + left: this.center + }; + + this.speed = opts.speed == null ? 0 : opts.speed; + + this.history = []; + this.which = "forward"; + this.isTurning = false; + + setTimeout(function() { + this.fwd(1).fwd(0); + }.bind(this), 10); +} + +/** + * move + * @param {Number} right Speed/Direction of right servo + * @param {Number} left Speed/Direction of left servo + * @return {Object} this + */ +Navigator.prototype.move = function(right, left) { + + // Quietly ignore duplicate instructions + if (this.direction.right === right && + this.direction.left === left) { + return this; + } + + // Servos are mounted opposite of each other, + // the values for left and right will be in + // opposing directions. + this.servos.right.to(right); + this.servos.left.to(left); + + // Store a recallable history of movement + this.history.push({ + timestamp: Date.now(), + right: right, + left: left + }); + + // Update the stored direction state + this.direction.right = right; + this.direction.left = left; + + return this; +}; + + +// TODO: DRY OUT!!!!!!! + + +/** + * forward Move the bot forward + * fwd Move the bot forward + * + * @param {Number}0-5, 0 is stopped, 5 is fastest + * @return {Object} this + */ +Navigator.prototype.forward = Navigator.prototype.fwd = function(speed) { + speed = speed == null ? 1 : speed; + + var scaled = scale(speed, this.center, 110); + + this.speed = speed; + this.which = "forward"; + + return this.to(this.center - (scaled - this.center), scaled); +}; + +/** + * reverse Move the bot in reverse + * rev Move the bot in reverse + * + * @param {Number}0-5, 0 is stopped, 5 is fastest + * @return {Object} this + */ +Navigator.prototype.reverse = Navigator.prototype.rev = function(speed) { + speed = speed == null ? 1 : speed; + + var scaled = scale(speed, this.center, 110); + + this.speed = speed; + this.which = "reverse"; + + console.log(scaled, this.center - (scaled - this.center)); + + return this.to(scaled, this.center - (scaled - this.center)); +}; + +/** + * stop Stops the bot, regardless of current direction + * @return {Object} this + */ +Navigator.prototype.stop = function() { + this.speed = this.center; + this.which = "stop"; + + return this.to(this.center, this.center); +}; + +/** + * right Turn the bot right + * @return {Object} this + */ + +/** + * left Turn the bot lefts + * @return {Object} this + */ + + +["right", "left"].forEach(function(dir) { + Navigator.prototype[dir] = function() { + var actual = this.direction[reverseDirMap[dir]]; + + if (!this.isTurning) { + this.isTurning = true; + this.to(actual, actual); + + // Restore direction after turn + setTimeout(function() { + + this[this.which](this.speed); + this.isTurning = false; + + }.bind(this), 750); + } + + return this; + }; +}); + +expandWhich = function(which) { + var parts, translations; + + translations = [{ + f: "forward", + r: "reverse", + fwd: "forward", + rev: "reverse" + }, { + r: "right", + l: "left" + }]; + + if (which.length === 2) { + parts = [which[0], which[1]]; + } + + if (!parts.length && /\-/.test(which)) { + parts = which.split("-"); + } + + return parts.map(function(val, i) { + return translations[i][val]; + }).join("-"); +}; + +Navigator.prototype.pivot = function(which, time) { + var actual, directions, scaled; + + scaled = scale(this.speed, this.center, 110); + which = expandWhich(which); + + directions = { + "forward-right": function() { + this.to(this.center, scaled); + }, + "forward-left": function() { + this.to(this.center - (scaled - this.center), this.center); + }, + "reverse-right": function() { + this.to(scaled, this.center); + }, + "reverse-left": function() { + this.to(this.center, this.center - (scaled - this.center)); + } + }; + + directions[which].call(this, this.speed); + + setTimeout(function() { + + this[this.which](this.speed); + + }.bind(this), time || 1000); + + return this; +}; + + +board = new five.Board(); +board.on("ready", function() { + + sonar = new five.Sonar({ + pin: "A2", + freq: 100 + }); + sonar.on("change", function() { + console.log("Object is " + this.inches + "inches away"); + }); + + scanner = new five.Servo(12); + scanner.sweep(); + + this.repl.inject({ + // create a bot, right servo = pin 10, left servo = pin 11 + b: new Navigator({ + right: 10, + left: 11 + }) + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/brat.js b/JavaScript/node_modules/johnny-five/eg/brat.js new file mode 100644 index 0000000..3315194 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/brat.js @@ -0,0 +1,602 @@ +var five = require("../lib/johnny-five.js"), + compulsive = require("compulsive"); + +var ED, + priv = new WeakMap(); + + +/** + * ED + * + * Enforcement Droid Series + * (Lynxmotion Biped BRAT) + * + * http://www.lynxmotion.com/images/jpg/bratjr00.jpg + * http://www.lynxmotion.com/images/html/build112.htm + * Hardware: + - 1 x Alum. Channel - 3" Single Pack (ASB-503) + - 2 x Multi-Purpose Servo Bracket Two Pack (ASB-04) + - 1 x "L" Connector Bracket Two Pack (ASB-06) + - 1 x "C" Servo Bracket w/ Ball Bearings Two Pack (ASB-09) + - 1 x Robot Feet Pair (ARF-01) + - 1 x SES Electronics Carrier (EC-02) + - 1 x SSC-32 Servo Controller (SSC-32) + - 4 x HS-422 (57oz.in.) Standard Servo (S422) + * + * @param {Object} opts Optional properties object + */ + +function ED(opts) { + + opts = opts || {}; + + // Standard servos center at 90° + this.center = opts.center || 90; + + // Initiale movement is forward + this.direction = "fwd"; + + // Accessor for reading the current servo position will + // be defined and assigned to this.degrees object. + this.degrees = {}; + + // holds a reference to the current repeating/looping sequence + this.sequence = null; + + // Table of times (avg) to complete tasks + this.times = { + step: 0, + attn: 0 + }; + + // Minor normalization of incoming properties + opts.right = opts.right || {}; + opts.left = opts.left || {}; + + // Initialize the right and left cooperative servos + // TODO: Support pre-initialized servo instances + this.servos = { + right: { + hip: opts.right.hip && new five.Servo(opts.right.hip), + foot: opts.right.foot && new five.Servo(opts.right.foot) + }, + left: { + hip: opts.left.hip && new five.Servo(opts.left.hip), + foot: opts.left.foot && new five.Servo(opts.left.foot) + } + }; + + // Create shortcut properties + this.right = this.servos.right; + this.left = this.servos.left; + + // Create accessor descriptors: + // + // .left { .foot, .hip } + // .right { .foot, .hip } + // + ["right", "left"].forEach(function(key) { + + var descriptor = {}; + + ["foot", "hip"].forEach(function(part) { + descriptor[part] = { + get: function() { + var history = this.servos[key][part].history, + last = history[history.length - 1]; + + return last && last.degrees || 90; + }.bind(this) + }; + }, this); + + this.degrees[key] = {}; + + // And finally, create properties with the generated descriptor + Object.defineProperties(this.degrees[key], descriptor); + }, this); + + + Object.defineProperty(this, "isCentered", { + get: function() { + var right, left; + + right = this.degrees.right; + left = this.degrees.left; + + if ((right.foot === 90 && right.hip === 90) && + (left.foot === 90 && left.foot === 90)) { + return true; + } + return false; + } + }); + + // Store a recallable history of movement + // TODO: Include in savable history + this.history = [{ + timestamp: Date.now(), + side: "right", + right: { + hip: 0, + foot: 0 + }, + left: { + hip: 0, + foot: 0 + } + }]; + + // Create an entry in the private data store. + priv.set(this, { + // `isWalking` is used in: + // ED.prototype.(attn|stop) + // ED.prototype.(forward|fwd;reverse|rev) + isWalking: false, + + // Allowed to hit the dance floor. + canDance: true + }); +} + +/** + * attn Stop and stand still + * @return {Object} this + */ +//ED.prototype.attn = ED.prototype.stop = function() { +ED.prototype.attn = function(options) { + options = options || {}; + + if (!options.isWalking) { + + if (this.sequence) { + this.sequence.stop(); + this.sequence = null; + } + + priv.set(this, { + isWalking: false + }); + } + + this.move({ + type: "attn", + right: { + hip: 90, + foot: 90 + }, + left: { + hip: 90, + foot: 90 + } + }); +}; + +/** + * step Take a step + * + * @param {String} instruct Give the step function a specific instruction, + * one of: (fwd, rev, left, right) + * + */ +ED.prototype.step = function(direct) { + var isLeft, isFwd, opposing, direction, state; + + state = priv.get(this); + + if (/fwd|rev/.test(direct)) { + direction = direct; + direct = undefined; + } else { + direction = "fwd"; + } + + // Derive which side to step on; based on last step or explicit step + this.side = direct || (this.side !== "right" ? "right" : "left"); + + // Update the value of the current direction + this.direction = direction; + + // Determine if the bot is moving fwd + // Used in phase 3 to conditionally control the servo degrees + isFwd = this.direction === "fwd"; + + // Determine if this is the left foot + // Used in phase 3 to conditionally control the servo degrees + isLeft = this.side === "left"; + + // Opposing leg side, used in prestep and phase 2; + // opposing = isLeft ? "right" : "left"; + + // Begin stepping movements. + // + this.queue([ + + // Phase 1 + { + wait: 500, + task: function() { + var stepping, opposing, instruct; + + stepping = isLeft ? "left" : "right"; + opposing = isLeft ? "right" : "left"; + + instruct = {}; + + // Lift the currently stepping foot, while + // leaning on the currently opposing foot. + instruct[stepping] = { + foot: isLeft ? 40 : 140 + }; + instruct[opposing] = { + foot: isLeft ? 70 : 110 + }; + + // Swing currently stepping hips + this.move(instruct); + }.bind(this) + }, + + // Phase 2 + { + wait: 500, + task: function() { + var degrees = isLeft ? + (isFwd ? 120 : 60) : + (isFwd ? 60 : 120); + + // Swing currently stepping hips + this.move({ + type: "swing", + right: { + hip: degrees + }, + left: { + hip: degrees + } + }); + + }.bind(this) + }, + + // Phase 3 + { + wait: 500, + task: function() { + + // Flatten feet to surface + this.servos.right.foot.center(); + this.servos.left.foot.center(); + + + + }.bind(this) + } + ]); +}; + +[ + /** + * forward, fwd + * + * Move the bot forward + */ + { + name: "forward", + abbr: "fwd" + }, + + /** + * reverse, rev + * + * Move the bot in reverse + */ + { + name: "reverse", + abbr: "rev" + } + +].forEach(function(dir) { + + ED.prototype[dir.name] = ED.prototype[dir.abbr] = function() { + var startAt, stepper, state; + + startAt = 10; + state = priv.get(this); + + // If ED is already walking in this direction, return immediately; + // This prevents multiple movement loops from being scheduled. + if (this.direction === dir.abbr && state.isWalking) { + return; + } + + // If a sequence reference exists, kill it. This will + // clear all pending queue repeaters. + if (this.sequence) { + this.sequence.stop(); + this.sequence = null; + } + + + this.direction = dir.abbr; + + // Update the private state to indicate + // that the bot is currently walking. + // + // This is used by the behaviour loop to + // conditionally continue walking or to terminate. + // + // Walk termination occurs in the ED.prototype.attn method + // + priv.set(this, { + isWalking: true + }); + + stepper = function(loop) { + // Capture of sequence queue reference + if (this.sequence === null) { + this.sequence = loop; + } + + this.step(dir.abbr); + + if (!priv.get(this).isWalking) { + loop.stop(); + } + }.bind(this); + + // If the bot is not centered, ie. all servos at 90degrees, + // bring the bot to attention before proceeding. + if (!this.isCentered) { + this.attn({ + isWalking: true + }); + // Offset the amount ms required for attn() to complete + startAt = 750; + } + + this.queue([{ + wait: startAt, + task: function() { + this.step(dir.abbr); + }.bind(this) + }, { + loop: 1500, + task: stepper + }]); + }; +}); + +ED.prototype.dance = function() { + var isLeft, restore, state; + + // Derive which side to step on; based on last step or explicit step + this.side = this.side !== "right" ? "right" : "left"; + + // Determine if this is the left foot + // Used in phase 3 to conditionally control the servo degrees + isLeft = this.side === "left"; + + this.attn(); + + if (typeof this.moves === "undefined") { + this.moves = 0; + } + + this.queue([ + // Phase 1 + { + wait: 500, + task: function() { + var degrees = isLeft ? 120 : 60; + + if (this.moves % 2 === 0) { + this.move({ + type: "attn", + right: { + hip: 90, + foot: 60 + }, + left: { + hip: 90, + foot: 120 + } + }); + } else { + + this.move({ + type: "attn", + right: { + hip: 90, + foot: 120 + }, + left: { + hip: 90, + foot: 60 + } + }); + } + + // Swing currently stepping hips + this.move({ + type: "swing", + right: { + hip: degrees + }, + left: { + hip: degrees + } + }); + + // restore = this.servos[ this.side ].foot.last.degrees; + // this.servos[ this.side ].foot.move( restore === 140 ? 120 : 60 ); + + }.bind(this) + }, + + // Phase 2 + { + wait: 500, + task: function() { + var degrees = isLeft ? 60 : 120; + + // Swing currently stepping hips + this.move({ + type: "swing", + right: { + hip: degrees + }, + left: { + hip: degrees + } + }); + + // this.servos[ this.side ].foot.move( restore ); + + }.bind(this) + }, + + // Phase 3 + { + wait: 500, + task: function() { + + this.move({ + type: "attn", + right: { + hip: 90, + foot: 90 + }, + left: { + hip: 90, + foot: 90 + } + }); + + this.dance(); + + }.bind(this) + } + ]); + + this.moves++; +}; + + +/** + * move Move the bot in an arbitrary direction + * @param {Object} positions left/right hip/foot positions + * + */ +ED.prototype.move = function(positions) { + var start, type; + + if (this.history.length) { + start = this.history[this.history.length - 1]; + } + + type = positions.type || "step"; + + ["foot", "hip"].forEach(function(section) { + ["right", "left"].forEach(function(side) { + var interval, endAt, startAt, servo, step, s; + + if (typeof positions[side] === "undefined") { + return; + } + + endAt = positions[side][section]; + servo = this.servos[side][section]; + startAt = this.degrees[side][section]; + + // Degrees per step + step = 2; + + s = Date.now(); + + if (!endAt || endAt === startAt) { + return; + } + + if (start) { + // Determine degree step direction + if (endAt < startAt) { + step *= -1; + } + + // Repeat each step for required number of steps to move + // servo into new position. Each step is ~20ms duration + this.repeat(Math.abs(endAt - startAt) / 2, 10, function() { + // console.log( startAt ); + servo.move(startAt += step); + + if (startAt === endAt) { + this.times[type] = (this.times[type] + (Date.now() - s)) / 2; + } + }.bind(this)); + + } else { + // TODO: Stop doing this + servo.move(endAt); + five.Fn.sleep(500); + } + }, this); + }, this); + + // Push a record object into the stepping history + this.history.push({ + timestamp: Date.now(), + side: this.side, + right: five.Fn.extend({ + hip: 0, + foot: 0 + }, this.degrees.right, positions.right), + left: five.Fn.extend({ + hip: 0, + foot: 0 + }, this.degrees.left, positions.left) + }); +}; + +// Borrow API from Compulsive +["wait", "loop", "queue", "repeat"].forEach(function(api) { + ED.prototype[api] = compulsive[api]; +}); + +// Begin program when the board, serial and +// firmata are connected and ready +(new five.Board()).on("ready", function() { + var biped; + + // Create new Enforcement Droid + // assign servos + biped = new ED({ + right: { + hip: 9, + foot: 11 + }, + left: { + hip: 10, + foot: 12 + } + }); + + // Inject into REPL for manual controls + this.repl.inject({ + s: new five.Servo.Array(), + b: biped + }); + + biped.attn(); + + biped.wait(1000, function() { + biped.fwd(); + }); + + // Controlled via REPL: + // b.fwd(), b.rev(), b.attn() +}); + + + +// http://www.lynxmotion.com/images/html/build112.htm diff --git a/JavaScript/node_modules/johnny-five/eg/bug.js b/JavaScript/node_modules/johnny-five/eg/bug.js new file mode 100644 index 0000000..e3b1e87 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/bug.js @@ -0,0 +1,198 @@ +var five = require("../lib/johnny-five.js"); + +function Bug(servos) { + var part, k; + + this.isMoving = false; + + // Initialize list of body parts + this.parts = ["front", "left", "right", "rear"]; + + // Servo positions + this.history = []; + + // Interval id table + this.intervals = { + fwd: null, + rev: null + }; + + k = -1; + // Initialize Servo properties from "servos" argument + while (++k < this.parts.length) { + part = this.parts[k]; + + this[part] = servos[part] || null; + } + + // Unwind and wait ~10ms, center servos + setTimeout(function() { + this.idle(); + }.bind(this), 10); +} + +Bug.STEP_MAP = { + // steps + fwd: [ + [10, -30], + [-15, 30] + ], + rev: [ + [-15, 30], + [15, -30] + ] +}; + +/** + * idle Set the bug legs to center position and + * @return {Bug} + */ +Bug.prototype.idle = function() { + + // If the bug is actually in motion, + // stop the servo intervals + if (this.isMoving) { + this.stop(); + } + + // set to center position° + this.front.to(90); + this.rear.to(90); + + //return this; +}; + +/** + * step Take a full or half step + * + * @param {Dict} opts Properties: + * half {Boolean} + * dir {String} + * @return {Bug} + */ +Bug.prototype.step = function(opts) { + var dir, move, last, front, rear, step; + + opts = opts || {}; + + // Get last move from history if any history exists + // Provide a "fake" history if needed (first call) + last = this.history.length ? + this.history[this.history.length - 1] : { + step: 1 + }; + + // increment the last step + step = last.step + 1; + + // If step is too high, step back to 0 + if (step > 1) { + step = 0; + } + + // Derive direction if provided, + // defaults to fwd + dir = opts.dir || "fwd"; + + // Derive position° for next move + move = Bug.STEP_MAP[dir][step]; + + // Assign position° from center + front = 90 + move[0]; + rear = 90 + move[1]; + + // Write position° to servos + this.front.to(front); + this.rear.to(rear); + + // Allow half step or full if provided, + // defaults to full + // enum(false|null|undefined) + if (!opts.half) { + // Wait one second and move servos back to + // center idling position, 90° + setTimeout(function() { + this.idle(); + }.bind(this), 1000); + } + + // Push a step into history array; + // will be used as a reference for the subsequent step + this.history.push( + // NOTE: this is a great use case example for + // ES.next concise object initializers + { + dir: dir, + step: step, + front: front, + rear: rear + } + ); +}; + +/** + * stop Stop the bug by clearing the intervals + * @return {Bug} + */ +Bug.prototype.stop = function() { + Object.keys(this.intervals).forEach(function(key) { + if (this.intervals[key]) { + clearInterval(this.intervals[key]); + } + }, this); + //return this; +}; + +[ + /** + * fwd Move the bug forward continuously + * @return {Bug} + */ + "fwd", + + /** + * rev Move the bug backwards continuously + * @return {Bug} + */ + "rev" + +].forEach(function(dir, k) { + + Bug.prototype[dir] = function() { + + this.isMoving = true; + + this.intervals[dir] = setInterval(function() { + this.step({ + dir: dir, + half: true + }); + }.bind(this), 750); + + // //return this; + }; +}); + + + + +five.Board().on("ready", function() { + var bug, ranges, servos; + + bug = new Bug({ + front: new five.Servo(9), + rear: new five.Servo(10) + //, + //left: new five.Servo({ pin: 5, range: [ 70, 115 ] }), + //right: new five.Servo({ pin: 6, range: [ 70, 115 ] }) + }); + + // Inject the Servo Array into the REPL as "s" + this.repl.inject({ + bug: bug, + s: new five.Servos() + }); + + + // bug.step(); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/button-bumper.js b/JavaScript/node_modules/johnny-five/eg/button-bumper.js new file mode 100644 index 0000000..6fc74a4 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/button-bumper.js @@ -0,0 +1,18 @@ +var five = require("../lib/johnny-five.js"), + bumper, led; + +five.Board().on("ready", function() { + + bumper = new five.Button(7); + led = new five.Led(13); + + bumper.on("hit", function() { + + led.on(); + + }).on("release", function() { + + led.off(); + + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/button-hold-blink.js b/JavaScript/node_modules/johnny-five/eg/button-hold-blink.js new file mode 100644 index 0000000..5570d96 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/button-hold-blink.js @@ -0,0 +1,17 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + // Johnny-Five provides pre-packages shield configurations! + // http://johnny-five.io/api/motor/#pre-packaged-shield-configs + var motors = new five.Motors([ + five.Motor.SHIELD_CONFIGS.POLOLU_DRV8835_SHIELD.M1, + five.Motor.SHIELD_CONFIGS.POLOLU_DRV8835_SHIELD.M2, + ]); + + this.repl.inject({ + motors: motors + }); + + motors.speed(50); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/button-options.js b/JavaScript/node_modules/johnny-five/eg/button-options.js new file mode 100644 index 0000000..45ccc10 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/button-options.js @@ -0,0 +1,41 @@ +var five = require("../lib/johnny-five.js"), + board, button; + +board = new five.Board(); + +board.on("ready", function() { + + // Create a new `button` hardware instance + button = new five.Button({ + board: board, + pin: 7, + holdtime: 1000, + invert: false // Default: "false". Set to "true" if button is Active-Low + }); + + // Inject the `button` hardware into + // the Repl instance's context; + // allows direct command line access + board.repl.inject({ + button: button + }); + + // Button Event API + + // "down" the button is pressed + button.on("down", function() { + console.log("down"); + }); + + // "hold" the button is pressed for specified time. + // defaults to 500ms (1/2 second) + // set + button.on("hold", function() { + console.log("hold"); + }); + + // "up" the button is released + button.on("up", function() { + console.log("up"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/button-pullup.js b/JavaScript/node_modules/johnny-five/eg/button-pullup.js new file mode 100644 index 0000000..c4fe536 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/button-pullup.js @@ -0,0 +1,33 @@ +// The `isPullup` button option enables the pullup +// resistor on the pin and automatically sets the +// `invert` option to true + +// In this circuit configuration, the LED would always +// be on without the pullup resistor enabled + +// For more info on pullup resistors, see: +// http://arduino.cc/en/Tutorial/InputPullupSerial +// http://arduino.cc/en/Tutorial/DigitalPins +// https://learn.sparkfun.com/tutorials/pull-up-resistors + +var five = require("../lib/johnny-five"), + button, led; + +five.Board().on("ready", function() { + + button = new five.Button({ + pin: 2, + isPullup: true + }); + + led = new five.Led(13); + + button.on("down", function(value) { + led.on(); + }); + + button.on("up", function() { + led.off(); + }); + +}); diff --git a/JavaScript/node_modules/johnny-five/eg/button.js b/JavaScript/node_modules/johnny-five/eg/button.js new file mode 100644 index 0000000..83d3cb1 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/button.js @@ -0,0 +1,38 @@ +var five = require("../lib/johnny-five.js"), + board, button; + +board = new five.Board(); + +board.on("ready", function() { + + // Create a new `button` hardware instance. + // This example allows the button module to + // create a completely default instance + button = new five.Button(2); + + // Inject the `button` hardware into + // the Repl instance's context; + // allows direct command line access + board.repl.inject({ + button: button + }); + + // Button Event API + + // "down" the button is pressed + button.on("down", function() { + console.log("down"); + }); + + // "hold" the button is pressed for specified time. + // defaults to 500ms (1/2 second) + // set + button.on("hold", function() { + console.log("hold"); + }); + + // "up" the button is released + button.on("up", function() { + console.log("up"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/change.js b/JavaScript/node_modules/johnny-five/eg/change.js new file mode 100644 index 0000000..7378b9a --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/change.js @@ -0,0 +1,47 @@ +"use strict"; +/** + * Change + * + * Produces change "tracking" instances + * to determine if a given value has changed + * drastically enough + */ + +function Change(margin) { + if (!(this instanceof Change)) { + return new Change(margin); + } + this.last = 0; + this.margin = margin || 0; +} + +/** + * isNoticeable + * + * Determine if a given value has changed + * enough to be considered "noticeable". + * + * @param {Number} value [description] + * @param {Number} margin Optionally override the + * change instance's margin + * + * @return {Boolean} returns true if value is different + * enough from the last value + * to be considered "noticeable" + */ +Change.prototype.isNoticeable = function(value, margin) { + margin = margin || this.margin; + + if (!Number.isFinite(value)) { + return false; + } + + if ((value > this.last + margin) || (value < this.last - margin)) { + this.last = value; + return true; + } + return false; +}; + + +module.exports = Change; diff --git a/JavaScript/node_modules/johnny-five/eg/classic-controller.js b/JavaScript/node_modules/johnny-five/eg/classic-controller.js new file mode 100644 index 0000000..0db61ea --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/classic-controller.js @@ -0,0 +1,98 @@ +var five = require("../lib/johnny-five.js"), + board, nunchuk; + +board = new five.Board(); + + +// Setup for bread board +// Wire Color => Meaning => Arduino Pin Down +// Yellow => SCK => A04 +// White => GND => Ground +// Red => 5v => 5v +// Green => SDA => A05 + + +board.on("ready", function() { + + // Create a new `Wii.Classic` hardware instance, + // specifically the RVL-005 device (classic controller). + var classicController = five.Wii.Classic({ + freq: 100 + }); + + + // Nunchuk Event API + // + + // "read" (nunchuk) + // + // Fired when the joystick detects a change in + // axis position. + // + // nunchuk.on( "read", function( err ) { + + // }); + + // "change", "axischange" (joystick) + // + // Fired when the joystick detects a change in + // axis position. + // + nunchuk.joystick.left.on("change", function(err, event) { + console.log( + "Left joystick " + event.axis, + event.target[event.axis], + event.axis, event.direction + ); + }); + + nunchuk.joystick.right.on("change", function(err, event) { + console.log( + "Right joystick " + event.axis, + event.target[event.axis], + event.axis, event.direction + ); + }); + + // "down" + // aliases: "press", "tap", "impact", "hit" + // + // Fired when any nunchuk button is "down" + // + + // "up" + // alias: "release" + // + // Fired when any nunchuk button is "up" + // + + // "hold" + // + // Fired when any nunchuk button is in the "down" state for + // a specified amount of time. Defaults to 500ms + // + // To specify a custom hold time, use the "holdtime" + // option of the Nunchuk constructor. + // + + + ["down", "up", "hold"].forEach(function(type) { + + nunchuk.on(type, function(err, event) { + console.log( + event.target.which + " is " + type, + + { + isUp: event.target.isUp, + isDown: event.target.isDown + } + ); + }); + + }); + + + // Further reading + // http://media.pragprog.com/titles/msard/tinker.pdf + // http://lizarum.com/assignments/physical_computing/2008/wii_nunchuck.html +}); diff --git a/JavaScript/node_modules/johnny-five/eg/claw.js b/JavaScript/node_modules/johnny-five/eg/claw.js new file mode 100644 index 0000000..0bb87e7 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/claw.js @@ -0,0 +1,43 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + + var claw = new five.Servo(9); + var arm = five.Servo(10); + var degrees = 10; + var incrementer = 10; + var last; + + this.loop(25, function() { + + if (degrees >= 180 || degrees === 0) { + incrementer *= -1; + } + + degrees += incrementer; + + if (degrees === 180) { + if (!last || last === 90) { + last = 180; + } else { + last = 90; + } + arm.to(last); + } + + claw.to(degrees); + }); +}); + + +// @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/JavaScript/node_modules/johnny-five/eg/color-test.html b/JavaScript/node_modules/johnny-five/eg/color-test.html new file mode 100644 index 0000000..6f53a84 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/color-test.html @@ -0,0 +1,87 @@ + + + + + + + + + + +
+ Red 5 + Yellow 4 + Lime 3 + Blue 2 + + White 6 + Black 1 +
+ + + + + + + diff --git a/JavaScript/node_modules/johnny-five/eg/compass-hmc5883l.js b/JavaScript/node_modules/johnny-five/eg/compass-hmc5883l.js new file mode 100644 index 0000000..716ed48 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/compass-hmc5883l.js @@ -0,0 +1,22 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + + var compass = new five.Compass({ + controller: "HMC5883L" + }); + + compass.on("headingchange", function() { + console.log("headingchange"); + console.log(" heading : ", Math.floor(this.heading)); + console.log(" bearing : ", this.bearing.name); + console.log("--------------------------------------"); + }); + + compass.on("data", function() { + console.log(" heading : ", Math.floor(this.heading)); + console.log(" bearing : ", this.bearing.name); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/compass-hmc6352.js b/JavaScript/node_modules/johnny-five/eg/compass-hmc6352.js new file mode 100644 index 0000000..6f368d4 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/compass-hmc6352.js @@ -0,0 +1,22 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + + var compass = new five.Compass({ + controller: "HMC6352" + }); + + compass.on("headingchange", function() { + console.log("headingchange"); + console.log(" heading : ", Math.floor(this.heading)); + console.log(" bearing : ", this.bearing.name); + console.log("--------------------------------------"); + }); + + compass.on("data", function() { + console.log(" heading : ", Math.floor(this.heading)); + console.log(" bearing : ", this.bearing.name); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/compass.js b/JavaScript/node_modules/johnny-five/eg/compass.js new file mode 100644 index 0000000..5c2d8b7 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/compass.js @@ -0,0 +1,27 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + + var compass = new five.Compass({ + controller: "HMC6352" + }); + + // Or... + // var compass = new five.Compass({ + // controller: "HMC5883L" + // }); + + compass.on("headingchange", function() { + console.log("headingchange"); + console.log(" heading : ", Math.floor(this.heading)); + console.log(" bearing : ", this.bearing.name); + console.log("--------------------------------------"); + }); + + compass.on("data", function() { + console.log(" heading : ", Math.floor(this.heading)); + console.log(" bearing : ", this.bearing.name); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/current-monitor.js b/JavaScript/node_modules/johnny-five/eg/current-monitor.js new file mode 100644 index 0000000..eab81c0 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/current-monitor.js @@ -0,0 +1,114 @@ +var five = require("../lib/johnny-five.js"); +var scale = five.Fn.scale; +var board = new five.Board(); +// Measured with multimeter @ 4.440V +var VCC = 4440; + +function toMV(value) { + // Scale an ADC reading to milli-volts. + return scale(value, 0, 1023, 0, VCC) | 0; +} + +function render(mA) { + // mA means milli-amps + var mAF = mA.toFixed(2); + + mA = Number(mAF); + + // Limit bar rendering to values that are unique from the + // previous reading. This prevents an overwhelming number + // of duplicate bars from being displayed. + if (render.last !== mA) { + console.log( + mAF + ": " + "▇".repeat(scale(mA, 0.03, 2, 1, 50)) + ); + } + render.last = mA; +} + +board.on("ready", function() { + // Set up a 1kHz frequency sensor, with a name + // that's similar to the type of sensor we're using. + // This is a smart way to keep track of your physical + // devices throughout the program. + var acs = new five.Sensor({ + pin: "A0", + freq: 1 + }); + var time = Date.now(); + var samples = 100; + var accumulator = 0; + var count = 0; + var amps = 0; + var qV = 0; + + acs.on("data", function() { + // ADC stands for Analog-to-Digital Converter + // (https://en.wikipedia.org/wiki/Analog-to-digital_converter) + // which reads the voltage returning to an analog pin from + // a sensor circuit. The value is a 10-bit representation + // (0-1023) of a voltage quantity from 0V-5V. + var adc = 0; + var currentAmps = 0; + + // The "amps factor" or `aF` is calculated by dividing the + // the voltage by the max ADC value to produce the + // incremental value, which is ~0.0049V for each step + // from 0-1023. + // Use real VCC (from milli-volts) + var aF = (VCC / 100) / 1023; + + + // 1. Measure the the ACS712 reading with no load (0A); + // this is known as the quiescent output voltage, + // which is named `qV` in this program. + if (!qV) { + if (!count) { + console.log("Calibrating..."); + } + // Calibration phase takes measurements for ~5 seconds + if (count < (samples * 40)) { + count++; + accumulator += this.value; + } else { + qV = Math.max(512, (accumulator / (samples * 40)) | 0); + accumulator = count = 0; + + console.log("qV: %d (%d) ", toMV(qV), qV); + console.log("Elapsed: ", Date.now() - time); + } + } else { + + if (count < samples) { + // 2. Collect readings to calculate a current value + count++; + adc = this.value - qV; + accumulator += adc * adc; + } else { + // 3. Update the running root mean square value + currentAmps = Math.sqrt(accumulator / samples) * aF; + accumulator = count = 0; + + // ACS is fairly innaccurate below 0.03 + if (currentAmps < 0.03) { + currentAmps = 0; + } + } + + // If there is a currentAmps value: + // If there is an amps value: + // return average of currentAmps and amps + // Else: + // return currentAmps + // Else: + // return amps + amps = currentAmps ? + (amps ? (currentAmps + amps) / 2 : currentAmps) : + amps; + + if (qV && amps) { + render(amps); + } + } + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/edison-io-arduino.js b/JavaScript/node_modules/johnny-five/eg/edison-io-arduino.js new file mode 100644 index 0000000..d012114 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/edison-io-arduino.js @@ -0,0 +1,22 @@ +var five = require("../lib/johnny-five.js"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var led = new five.Led(13); + 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 diff --git a/JavaScript/node_modules/johnny-five/eg/edison-io-miniboard.js b/JavaScript/node_modules/johnny-five/eg/edison-io-miniboard.js new file mode 100644 index 0000000..16b38cc --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/edison-io-miniboard.js @@ -0,0 +1,22 @@ +var five = require("../lib/johnny-five.js"); +var Edison = require("edison-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + var led = new five.Led(1); + 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 diff --git a/JavaScript/node_modules/johnny-five/eg/edison.js b/JavaScript/node_modules/johnny-five/eg/edison.js new file mode 100644 index 0000000..6e90ec7 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/edison.js @@ -0,0 +1,15 @@ +var five = require("johnny-five"); +var Edison = require("galileo-io"); +var board = new five.Board({ + io: new Edison() +}); + +board.on("ready", function() { + console.log("ready"); + var led = new five.Led(11); + led.blink(); + + this.repl.inject({ + led: led + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/encoder-digital.js b/JavaScript/node_modules/johnny-five/eg/encoder-digital.js new file mode 100644 index 0000000..4519ca7 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/encoder-digital.js @@ -0,0 +1,14 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + var encoder = new five.Encoder({ + pins: [ 12, 11 ], + positions: 24, + }); + + + encoder.on("change", function() { + console.log(this.position); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/esc-PCA9685.js b/JavaScript/node_modules/johnny-five/eg/esc-PCA9685.js new file mode 100644 index 0000000..4937a11 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/esc-PCA9685.js @@ -0,0 +1,16 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + + var esc = new five.ESC({ + controller: "PCA9685", + pin: 1 + }); + + var pot = new five.Sensor("A0"); + + pot.scale(0, 100).on("change", function() { + esc.speed(this.value); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/esc-bidirectional-forward-reverse.js b/JavaScript/node_modules/johnny-five/eg/esc-bidirectional-forward-reverse.js new file mode 100644 index 0000000..a265a69 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/esc-bidirectional-forward-reverse.js @@ -0,0 +1,35 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var start = Date.now(); + var esc = new five.ESC({ + device: "FORWARD_REVERSE", + neutral: 50, + pin: 11 + }); + var throttle = new five.Sensor("A0"); + var brake = new five.Button(4); + + brake.on("press", function() { + esc.brake(); + }); + + throttle.scale(0, 100).on("change", function() { + // 2 Seconds for arming. + if (Date.now() - start < 2e3) { + return; + } + + var isForward = this.value > esc.neutral; + var value = isForward ? + // Scale 50-100 to 0-100 + five.Fn.scale(this.value, esc.neutral, esc.range[1], 0, 100) : + // Scale 0-50 to 100-0 + five.Fn.scale(this.value, esc.range[0], esc.neutral, 100, 0); + + if (esc.value !== value) { + esc[ isForward ? "forward" : "reverse" ](value); + } + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/esc-bidirectional.js b/JavaScript/node_modules/johnny-five/eg/esc-bidirectional.js new file mode 100644 index 0000000..87d5560 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/esc-bidirectional.js @@ -0,0 +1,28 @@ +var five = require("../"); +var board = new five.Board(); + +board.on("ready", function() { + var start = Date.now(); + var esc = new five.ESC({ + device: "FORWARD_REVERSE", + neutral: 50, + pin: 11 + }); + var throttle = new five.Sensor("A0"); + var brake = new five.Button(4); + + brake.on("press", function() { + esc.brake(); + }); + + throttle.scale(0, 100).on("change", function() { + // 2 Seconds for arming. + if (Date.now() - start < 2e3) { + return; + } + + if (esc.value !== this.value) { + esc.speed(this.value); + } + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/esc-dualshock.js b/JavaScript/node_modules/johnny-five/eg/esc-dualshock.js new file mode 100644 index 0000000..8671ffe --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/esc-dualshock.js @@ -0,0 +1,53 @@ +var five = require("../lib/johnny-five.js"); +var dualShock = require("dualshock-controller"); + +var board = new five.Board(); +var controller = dualShock({ + config: "dualShock3", + analogStickSmoothing: false +}); + +function scale(x, fromLow, fromHigh, toLow, toHigh) { + return (x - fromLow) * (toHigh - toLow) / + (fromHigh - fromLow) + toLow; +} + +board.on("ready", function() { + + var esc = new five.ESC(9); + + controller.on("connected", function() { + controller.isConnected = true; + }); + + controller.on("dpadUp:press", function() { + var speed = esc.last ? esc.speed : 0; + speed += 0.01; + esc.to(speed); + }); + + controller.on("dpadDown:press", function() { + var speed = esc.last ? esc.speed : 0; + speed -= 0.01; + esc.to(speed); + }); + + controller.on("circle:press", function() { + esc.stop(); + }); + + controller.on("right:move", function(position) { + var y = scale(position.y, 255, 0, 0, 180) | 0; + + if (y > 100) { + // from the deadzone and up + esc.to(scale(y, 100, 180, 0, 1)); + } + }); + + controller.connect(); +}); + + +// Brushless motor breadboard diagram originally published here: +// http://robotic-controls.com/learn/projects/dji-esc-and-brushless-motor diff --git a/JavaScript/node_modules/johnny-five/eg/esc-keypress.js b/JavaScript/node_modules/johnny-five/eg/esc-keypress.js new file mode 100644 index 0000000..7ff4b33 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/esc-keypress.js @@ -0,0 +1,38 @@ +var five = require("../lib/johnny-five.js"); +var keypress = require("keypress"); +var board = new five.Board(); + +board.on("ready", function() { + + var esc = new five.ESC(9); + + // Hold shift+arrow-up, shift+arrow-down to incrementally + // increase or decrease speed. + + function controller(ch, key) { + var isThrottle = false; + var speed = esc.last ? esc.speed : 0; + + if (key && key.shift) { + if (key.name === "up") { + speed += 0.01; + isThrottle = true; + } + + if (key.name === "down") { + speed -= 0.01; + isThrottle = true; + } + + if (isThrottle) { + esc.speed(speed); + } + } + } + + keypress(process.stdin); + + process.stdin.on("keypress", controller); + process.stdin.setRawMode(true); + process.stdin.resume(); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/esplora.js b/JavaScript/node_modules/johnny-five/eg/esplora.js new file mode 100644 index 0000000..c022b8e --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/esplora.js @@ -0,0 +1,271 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +// Select: Tools > Board > Arduino Leonardo +// (Ignore the "Arduino Esplora" option) +board.on("ready", function() { + + var estick = new five.Joystick({ + controller: "ESPLORA" + }); + + + estick.on("change", function() { + console.log("x", this.x); + }); +}); + +// -------------------------------------- + +// var Emitter = require("events").EventEmitter; +// var util = require("util"); +// var priv = new Map(); +// var axes = ["x", "y"]; + +// function Multiplexer(options) { +// this.pins = options.pins; +// this.io = options.io; + +// this.io.pinMode(this.pins[0], this.io.MODES.OUTPUT); +// this.io.pinMode(this.pins[1], this.io.MODES.OUTPUT); +// this.io.pinMode(this.pins[2], this.io.MODES.OUTPUT); +// this.io.pinMode(this.pins[3], this.io.MODES.OUTPUT); +// } + +// Multiplexer.prototype.select = function(channel) { +// this.io.digitalWrite(this.pins[0], channel & 1 ? this.io.HIGH : this.io.LOW); +// this.io.digitalWrite(this.pins[1], channel & 2 ? this.io.HIGH : this.io.LOW); +// this.io.digitalWrite(this.pins[2], channel & 4 ? this.io.HIGH : this.io.LOW); +// this.io.digitalWrite(this.pins[3], channel & 8 ? this.io.HIGH : this.io.LOW); +// }; + +// var Controllers = { +// ESPLORA: { +// initialize: { +// value: function(opts, dataHandler) { +// var multiplexer = new Multiplexer({ +// pins: [ 14, 15, 16, 17 ], +// io: this.io +// }); +// var channels = [ 11, 12 ]; +// var channel = 1; +// var dataPoints = { +// x: 0, +// y: 0 +// }; + +// this.io.analogRead(18, function(value) { +// dataPoints[axes[channel]] = value; + +// if (channel === 1) { +// dataHandler(dataPoints) +// } +// }); + +// setInterval(function() { +// multiplexer.select(channel ^= 1); +// }, 20); +// } +// }, +// toAxis: function(raw) { +// var state = priv.get(this); +// return raw - 512; +// } +// } +// } + +// function Joystick(opts) { +// if (!(this instanceof Joystick)) { +// return new Joystick(opts); +// } + +// var controller = null; + +// var state = { +// x: { +// value: 0, +// previous: 0, +// }, +// y: { +// value: 0, +// previous: 0, +// }, +// }; + +// Board.Component.call( +// this, opts = Board.Options(opts) +// ); + +// if (opts.controller && typeof opts.controller === "string") { +// controller = Controllers[opts.controller.toUpperCase()]; +// } else { +// controller = opts.controller; +// } + +// if (controller == null) { +// controller = Controllers["ANALOG"]; +// } + +// Object.defineProperties(this, controller); + +// if (!this.toAxis) { +// this.toAxis = opts.toAxis || function(raw) { return raw; }; +// } + +// priv.set(this, state); + +// if (typeof this.initialize === "function") { +// this.initialize(opts, function(data) { +// var isChange = false; + +// Object.keys(data).forEach(function(axis) { +// var value = data[axis]; +// var sensor = state[axis]; + +// sensor.value = value; + +// if (this.x !== sensor.x) { +// sensor.x = this.x; +// isChange = true; +// } + +// if (this.y !== sensor.y) { +// sensor.y = this.y; +// isChange = true; +// } +// }, this); + +// this.emit("data", { +// x: state.x.value, +// y: state.y.value +// }); + +// if (isChange) { +// this.emit("change", { +// x: this.x, +// y: this.y, +// z: this.z +// }); +// } +// }.bind(this)); +// } + +// Object.defineProperties(this, { +// hasAxis: { +// value: function(axis) { +// return state[axis] ? state[axis].stash.length > 0 : false; +// } +// }, +// x: { +// get: function() { +// return this.toAxis(state.x.value); +// } +// }, +// y: { +// get: function() { +// return this.toAxis(state.y.value); +// } +// } +// }); +// } + +// util.inherits(Joystick, Emitter); + + + + +// const HIGH = 1; +// const LOW = 0; +// const INPUT_PULLUP = 2; + +// const MUX_ADDR_PINS = [ 14, 15, 16, 17 ]; +// const MUX_COM_PIN = 18; + + +// const CH_SWITCH_1 = 0; +// const CH_SWITCH_2 = 1; +// const CH_SWITCH_3 = 2; +// const CH_SWITCH_4 = 3; +// const CH_SLIDER = 4; +// const CH_LIGHT = 5; +// const CH_TEMPERATURE = 6; +// const CH_MIC = 7; +// const CH_TINKERKIT_A = 8; +// const CH_TINKERKIT_B = 9; +// const CH_JOYSTICK_SW = 10; +// const CH_JOYSTICK_X = 11; +// const CH_JOYSTICK_Y = 12; + +// var channels = [ +// CH_SWITCH_1, +// CH_SWITCH_2, +// CH_SWITCH_3, +// CH_SWITCH_4, +// CH_SLIDER, +// CH_LIGHT, +// CH_TEMPERATURE, +// CH_MIC, +// CH_TINKERKIT_A, +// CH_TINKERKIT_B, +// CH_JOYSTICK_SW, +// CH_JOYSTICK_X, +// CH_JOYSTICK_Y, +// ]; + +// var channelNames = [ +// "CH_SWITCH_1", +// "CH_SWITCH_2", +// "CH_SWITCH_3", +// "CH_SWITCH_4", +// "CH_SLIDER", +// "CH_LIGHT", +// "CH_TEMPERATURE", +// "CH_MIC", +// "CH_TINKERKIT_A", +// "CH_TINKERKIT_B", +// "CH_JOYSTICK_SW", +// "CH_JOYSTICK_X", +// "CH_JOYSTICK_Y", +// ]; + + + +// function readChannel(channel) { +// digitalWrite(MUX_ADDR_PINS[0], (channel & 1) ? HIGH : LOW); +// digitalWrite(MUX_ADDR_PINS[1], (channel & 2) ? HIGH : LOW); +// digitalWrite(MUX_ADDR_PINS[2], (channel & 4) ? HIGH : LOW); +// digitalWrite(MUX_ADDR_PINS[3], (channel & 8) ? HIGH : LOW); + +// // workaround to cope with lack of pullup resistor on joystick switch +// if (channel == CH_JOYSTICK_SW) { +// pinMode(MUX_COM_PIN, INPUT_PULLUP); +// var joystickSwitchState = (digitalRead(MUX_COM_PIN) == HIGH) ? 1023 : 0; +// digitalWrite(MUX_COM_PIN, LOW); +// return joystickSwitchState; +// } else { +// return analogRead(MUX_COM_PIN); +// } +// } + +// function pinMode(pin, mode) { +// console.log("pinMode(%d, %d)", pin, mode); +// } + +// function digitalWrite(pin, value) { +// console.log("digitalWrite(%d, %d)", pin, value); +// } + +// function digitalRead(pin) { +// return Math.random() * 1 | 0; +// } + +// function analogRead(pin) { +// console.log("analogRead(%d)", pin); +// } + + +// for (var i = 0; i < channels.length; i++) { +// console.log(channelNames[i]); +// readChannel(i); +// console.log("-----------"); +// } diff --git a/JavaScript/node_modules/johnny-five/eg/expander-MCP23008.js b/JavaScript/node_modules/johnny-five/eg/expander-MCP23008.js new file mode 100644 index 0000000..783e873 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-MCP23008.js @@ -0,0 +1,20 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var virtual = new five.Board.Virtual( + new five.Expander("MCP23008") + ); + + var leds = new five.Leds( + Array.from({ length: 8 }, function(_, i) { + return new five.Led({ pin: i, board: virtual }); + }) + ); + + leds.on(); + + this.repl.inject({ + leds: leds + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/expander-MCP23017.js b/JavaScript/node_modules/johnny-five/eg/expander-MCP23017.js new file mode 100644 index 0000000..49437d8 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-MCP23017.js @@ -0,0 +1,20 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var virtual = new five.Board.Virtual( + new five.Expander("MCP23017") + ); + + var leds = new five.Leds( + Array.from({ length: 8 }, function(_, i) { + return new five.Led({ pin: i * 2, board: virtual }); + }) + ); + + leds.on(); + + this.repl.inject({ + leds: leds + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/expander-PCA9685.js b/JavaScript/node_modules/johnny-five/eg/expander-PCA9685.js new file mode 100644 index 0000000..1cefbb2 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-PCA9685.js @@ -0,0 +1,21 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var virtual = new five.Board.Virtual( + new five.Expander("PCA9685") + ); + + var leds = new five.Leds( + Array.from({ length: 8 }, function(_, i) { + return new five.Led({ pin: i * 2, board: virtual }); + }) + ); + + leds.pulse(); + + this.repl.inject({ + leds: leds + }); +}); + diff --git a/JavaScript/node_modules/johnny-five/eg/expander-PCF8574-input-output.js b/JavaScript/node_modules/johnny-five/eg/expander-PCF8574-input-output.js new file mode 100644 index 0000000..8b761d8 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-PCF8574-input-output.js @@ -0,0 +1,31 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board({ port: "/dev/cu.usbmodem1411" }); + +board.on("ready", function() { + var expander = new five.Expander("PCF8574"); + + var virtual = new five.Board.Virtual(expander); + + var led = new five.Led({ + board: virtual, + pin: 0, + }); + + // led.on(); + + var button = new five.Button({ + board: virtual, + pin: 7, + }); + + button.on("press", function() { + console.log("button press"); + led.on(); + }); + + button.on("release", function() { + console.log("button release"); + led.off(); + }); +}); + diff --git a/JavaScript/node_modules/johnny-five/eg/expander-PCF8574-sweep.js b/JavaScript/node_modules/johnny-five/eg/expander-PCF8574-sweep.js new file mode 100644 index 0000000..099f15a --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-PCF8574-sweep.js @@ -0,0 +1,21 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board({ port: "/dev/cu.usbmodem1411" }); + +board.on("ready", function() { + var expander = new five.Expander("PCF8574"); + var pin = 1; + + setInterval(function() { + if (pin > 0) { + expander.digitalWrite(pin - 1, 0); + } + expander.digitalWrite(pin++, 1); + + if (pin === 7) { + pin = 0; + } + }, 500); + + +}); + diff --git a/JavaScript/node_modules/johnny-five/eg/expander-PCF8574.js b/JavaScript/node_modules/johnny-five/eg/expander-PCF8574.js new file mode 100644 index 0000000..c128740 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-PCF8574.js @@ -0,0 +1,21 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var virtual = new five.Board.Virtual( + new five.Expander("PCF8574") + ); + + var leds = new five.Leds( + Array.from({ length: 8 }, function(_, i) { + return new five.Led({ pin: i, board: virtual }); + }) + ); + + leds.on(); + + this.repl.inject({ + leds: leds + }); +}); + diff --git a/JavaScript/node_modules/johnny-five/eg/expander-PCF8575.js b/JavaScript/node_modules/johnny-five/eg/expander-PCF8575.js new file mode 100644 index 0000000..cf7fd41 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-PCF8575.js @@ -0,0 +1,21 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var virtual = new five.Board.Virtual( + new five.Expander("PCF8575") + ); + + var leds = new five.Leds( + Array.from({ length: 8 }, function(_, i) { + return new five.Led({ pin: i * 2, board: virtual }); + }) + ); + + leds.on(); + + this.repl.inject({ + leds: leds + }); +}); + diff --git a/JavaScript/node_modules/johnny-five/eg/expander-PCF8591.js b/JavaScript/node_modules/johnny-five/eg/expander-PCF8591.js new file mode 100644 index 0000000..5c8f79a --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-PCF8591.js @@ -0,0 +1,17 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var virtual = new five.Board.Virtual( + new five.Expander("PCF8591") + ); + + var a = new five.Sensor({ + pin: "A0", + board: virtual + }); + + a.on("change", function() { + console.log(this.value); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/expander-bricktronics.js b/JavaScript/node_modules/johnny-five/eg/expander-bricktronics.js new file mode 100644 index 0000000..2788aec --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander-bricktronics.js @@ -0,0 +1,139 @@ +// var five = require("../lib/johnny-five.js"); +// var board = new five.Board(); + +// board.on("ready", function() { + +// // Bricktronics +// var en = 79; +// var pwm = 10; +// var dir = 78; + +// var expander = new five.Expander({ +// controller: "MCP23017" +// }); + +// var virtual = new five.Board.Virtual({ +// io: expander +// }); + +// var byte = 0; +// var index = 0; +// var leds = new five.Leds(); + +// for (var i = 0; i < 16; i++) { +// leds.push(new five.Led({ pin: i, board: virtual })); +// } + + + +// // leds.on(); + + +// // function next() { +// // byte |= (byte === 0 ? 1 : byte * 2); + + + +// // return byte; +// // } + + +// // var interval = setInterval(function() { + +// // leds[index++].on(); + +// // if (index === 16) { +// // clearInterval(interval); +// // } +// // }, 500); + +// function display(value) { +// if (value > 0xffff) { +// value -= 0xffff; +// } + +// for (var i = 0; i < 16; i++) { +// if ((value >> i) & 1) { +// leds[i].on(); +// } else { +// leds[i].off(); +// } +// } +// } + +// this.repl.inject({ + +// set bits(value) { +// display(value); +// } +// }); + + +// // var a = new five.Led({ +// // pin: 0, +// // board: virtual +// // }); + +// // console.log(expander.normalize); +// // var b = new five.Led({ +// // pin: 15, +// // board: virtual +// // }); + +// // a.blink(); +// // b.blink(); +// // led.blink(); + + +// // this.repl.inject({ +// // ex: expander +// // }); + + +// // // for (var i = 0; i < 16; i++) { +// // // expander.pinMode(i, 1); +// // // expander.digitalWrite(i, 1); +// // // } + + + +// // expander.pinMode(0, 1); +// // expander.pinMode(8, 1); + +// // expander.digitalWrite(0, 0); +// // expander.digitalWrite(8, 0); + +// // expander.pinMode(7, 0); + +// // expander.digitalRead(7, function(data) { +// // console.log(data); + +// // }); + + +// // expander.pinMode(en, this.MODES.OUTPUT); +// // expander.pinMode(pwm, this.MODES.OUTPUT); +// // expander.pinMode(dir, this.MODES.OUTPUT); + + +// // expander.digitalWrite(dir, this.MODES.LOW); +// // expander.analogWrite(pwm, 255); +// // expander.digitalWrite(en, this.MODES.HIGH); + + +// // setTimeout(function() { + +// // expander.digitalWrite(en, this.MODES.LOW); +// // expander.analogWrite(pwm, 0); +// // expander.digitalWrite(dir, this.MODES.LOW); + +// // setTimeout(function() { + +// // expander.digitalWrite(dir, this.MODES.LOW); +// // expander.analogWrite(pwm, 255); +// // expander.digitalWrite(en, this.MODES.HIGH); +// // }.bind(this), 2000); + +// // }.bind(this), 2000); + +// }); diff --git a/JavaScript/node_modules/johnny-five/eg/expander.js b/JavaScript/node_modules/johnny-five/eg/expander.js new file mode 100644 index 0000000..2788aec --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/expander.js @@ -0,0 +1,139 @@ +// var five = require("../lib/johnny-five.js"); +// var board = new five.Board(); + +// board.on("ready", function() { + +// // Bricktronics +// var en = 79; +// var pwm = 10; +// var dir = 78; + +// var expander = new five.Expander({ +// controller: "MCP23017" +// }); + +// var virtual = new five.Board.Virtual({ +// io: expander +// }); + +// var byte = 0; +// var index = 0; +// var leds = new five.Leds(); + +// for (var i = 0; i < 16; i++) { +// leds.push(new five.Led({ pin: i, board: virtual })); +// } + + + +// // leds.on(); + + +// // function next() { +// // byte |= (byte === 0 ? 1 : byte * 2); + + + +// // return byte; +// // } + + +// // var interval = setInterval(function() { + +// // leds[index++].on(); + +// // if (index === 16) { +// // clearInterval(interval); +// // } +// // }, 500); + +// function display(value) { +// if (value > 0xffff) { +// value -= 0xffff; +// } + +// for (var i = 0; i < 16; i++) { +// if ((value >> i) & 1) { +// leds[i].on(); +// } else { +// leds[i].off(); +// } +// } +// } + +// this.repl.inject({ + +// set bits(value) { +// display(value); +// } +// }); + + +// // var a = new five.Led({ +// // pin: 0, +// // board: virtual +// // }); + +// // console.log(expander.normalize); +// // var b = new five.Led({ +// // pin: 15, +// // board: virtual +// // }); + +// // a.blink(); +// // b.blink(); +// // led.blink(); + + +// // this.repl.inject({ +// // ex: expander +// // }); + + +// // // for (var i = 0; i < 16; i++) { +// // // expander.pinMode(i, 1); +// // // expander.digitalWrite(i, 1); +// // // } + + + +// // expander.pinMode(0, 1); +// // expander.pinMode(8, 1); + +// // expander.digitalWrite(0, 0); +// // expander.digitalWrite(8, 0); + +// // expander.pinMode(7, 0); + +// // expander.digitalRead(7, function(data) { +// // console.log(data); + +// // }); + + +// // expander.pinMode(en, this.MODES.OUTPUT); +// // expander.pinMode(pwm, this.MODES.OUTPUT); +// // expander.pinMode(dir, this.MODES.OUTPUT); + + +// // expander.digitalWrite(dir, this.MODES.LOW); +// // expander.analogWrite(pwm, 255); +// // expander.digitalWrite(en, this.MODES.HIGH); + + +// // setTimeout(function() { + +// // expander.digitalWrite(en, this.MODES.LOW); +// // expander.analogWrite(pwm, 0); +// // expander.digitalWrite(dir, this.MODES.LOW); + +// // setTimeout(function() { + +// // expander.digitalWrite(dir, this.MODES.LOW); +// // expander.analogWrite(pwm, 255); +// // expander.digitalWrite(en, this.MODES.HIGH); +// // }.bind(this), 2000); + +// // }.bind(this), 2000); + +// }); diff --git a/JavaScript/node_modules/johnny-five/eg/galileo-io.js b/JavaScript/node_modules/johnny-five/eg/galileo-io.js new file mode 100644 index 0000000..d0756b4 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/galileo-io.js @@ -0,0 +1,22 @@ +var five = require("../lib/johnny-five.js"); +var Galileo = require("galileo-io"); +var board = new five.Board({ + io: new Galileo() +}); + +board.on("ready", function() { + var led = new five.Led(13); + 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 diff --git a/JavaScript/node_modules/johnny-five/eg/game-of-life.js b/JavaScript/node_modules/johnny-five/eg/game-of-life.js new file mode 100644 index 0000000..3e24fde --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/game-of-life.js @@ -0,0 +1,294 @@ +// var fs = require("fs"); +// var five = require("../lib/johnny-five"); +// var board = new five.Board(); + +// board.on("ready", function() { + +// var game = new GameOfLife({ +// auto: true, +// interval: 500, +// maxCycles: Infinity, +// render: function(bytes, world) { +// console.log(String(world)); +// console.log("----------------"); + +// if (this.inPattern) { +// matrix.draw(bytes); +// } else { +// matrix.clear(); +// } +// } +// }); + +// var matrix = new five.Led.Matrix({ +// addresses: [0x70], +// controller: "HT16K33", +// rotation: 2, +// }); + +// var button = new five.Button({ +// isPullup: true, +// pin: 8 +// }); + +// button.on("hold", function() { +// game.reset().start(); +// }); + +// button.on("press", function() { +// fs.writeFile("gol-pattern-" + Date.now() + ".json", JSON.stringify(game.pattern, null, 2), "utf8"); +// }); + +// // this.repl.inject({ +// // GameOfLife: GameOfLife, +// // World: GameOfLife.World, +// // game: game +// // }); +// }); + + + + + + +// var priv = new Map(); + +// function random(howBig) { +// howBig >>>= 0; +// return Math.random() * howBig | 0; +// } + +// function toBytes(world) { +// var out = [0, 0, 0, 0, 0, 0, 0, 0]; +// for (var row = 0; row < 8; row++) { +// for (var col = 0; col < 8; col++) { +// out[row] |= world[row][col] << col; +// } +// } +// return out; +// } + +// function GameOfLife(options) { +// var layout; + +// if (Array.isArray(options)) { +// layout = options; +// options = { +// layout: layout +// }; +// } + +// var state = { +// auto: options.auto || false, +// dimensions: options.dimensions || [8, 8], +// interval: options.interval || 500, +// layout: options.layout || null, +// maxCycles: options.maxCycles || 255, +// render: options.render || console.log.bind(console), +// inPattern: false, +// isStill: false, +// cycle: 0, +// timer: null, +// history: [], +// pattern: [], +// mod: function(num) { +// num >>>= 0; +// return (num + this.dimensions[0]) % this.dimensions[0]; +// } +// }; + +// priv.set(this, state); + +// Object.defineProperties(this, { +// inPattern: { +// get: function() { +// return state.inPattern; +// } +// }, +// pattern: { +// get: function() { +// return state.pattern.slice(); +// } +// } +// }); + +// this.reset(); + +// if (options.auto) { +// this.start(); +// } +// } + +// GameOfLife.prototype.randomize = function() { +// var state = priv.get(this); + +// for (var row = 0; row < state.dimensions[0]; row++) { +// for (var col = 0; col < state.dimensions[1]; col++) { +// if (random(state.dimensions[1] - (state.dimensions[1] / 4)) > (state.dimensions[1] / 2)) { +// this.present[row][col] ^= 1; +// } +// } +// } +// }; + +// GameOfLife.prototype.reset = function() { +// var state = priv.get(this); + +// this.stop(); + +// this.present = new GameOfLife.World(state.layout || state.history.pop()); +// this.next = new GameOfLife.World(); + +// state.isStill = false; +// state.inPattern = false; + +// state.pattern.length = 0; +// state.cycle = state.maxCycles; + + +// if (!state.layout) { +// this.randomize(); +// this.randomize(); +// } + +// return this; +// }; + +// GameOfLife.prototype.start = function() { +// var state = priv.get(this); +// state.timer = setInterval(function() { +// this.generation(); + +// if (!--state.cycle || state.isStill) { +// this.reset(); + +// if (state.auto) { +// this.start(); +// } +// } +// }.bind(this), state.interval); +// return this; +// }; + +// GameOfLife.prototype.stop = function() { +// var state = priv.get(this); +// if (state.timer) { +// clearInterval(state.timer); +// } +// return this; +// }; + +// GameOfLife.prototype.generation = function() { +// var state = priv.get(this); + +// for (var row = 0; row < state.dimensions[0]; row++) { +// for (var col = 0; col < state.dimensions[1]; col++) { +// // Count living neighbors +// var alive = 0; + +// for (var cellX = -1; cellX <= 1; cellX++) { +// for (var cellY = -1; cellY <= 1; cellY++) { +// if (this.present[state.mod(row + cellX)][state.mod(col + cellY)] !== 0) { +// alive++; +// } +// } +// } + +// if (this.present[row][col]) { +// if (alive < 2 || alive > 3) { +// // Any cell with < 2 neighbors dies, due to under-population. +// // Any cell with > 3 neighbors dies, due to over-crowding. +// this.next[row][col] = 0; +// } else { +// // Any cell with 2 or 3 neighbors lives on to the next generation. +// this.next[row][col] = 1; +// } +// } else { +// if (alive === 3) { +// // Re-animate a dead cell if it has exactly 3 live neighbors. +// this.next[row][col] = 1; +// } +// } +// } +// } + +// // Copy next generation to present. +// var isStill = true; + +// for (var row = 0; row < state.dimensions[0]; row++) { +// for (var col = 0; col < state.dimensions[1]; col++) { +// isStill &= ((this.present[row][col] > 0) === (this.next[row][col] > 0)); +// // isStill &= this.present[row][col] === this.next[row][col]; +// this.present[row][col] = this.next[row][col]; +// } +// } + +// // The World is dead. +// if (toBytes(this.present).reduce(function(a, b) {return a + b; }) === 0) { +// this.reset().start(); +// return; +// } + + +// state.isStill = Boolean(isStill); +// state.history.push(new GameOfLife.World(this.present)); +// state.render.call(this, toBytes(this.present), state.history[state.history.length - 1]); + +// state.history = state.history.slice(-32); + +// var wasInPattern = state.inPattern; + +// for (var i = 0; i < 31; i++) { +// state.inPattern = false; +// if (this.present.equals(state.history[i])) { +// state.inPattern = true; +// state.pattern.push(this.present); +// break; +// } +// } + +// if (wasInPattern) { +// if (!state.inPattern) { +// state.pattern.length = 0; +// } else { +// // console.log("pattern: ", state.pattern); +// } +// } +// }; + +// GameOfLife.World = function(source, dimensions) { +// Array.call(this); + +// if (!dimensions) { +// dimensions = [8, 8]; +// } + +// for (var i = 0; i < dimensions[0]; i++) { +// this.push(source ? source[i].slice() : new Array(dimensions[1]).fill(0)); +// } +// }; + +// GameOfLife.World.prototype = Object.create(Array.prototype, { +// constructor: { +// value: GameOfLife.World +// } +// }); + +// GameOfLife.World.prototype.equals = function(other) { +// var a = toBytes(this); +// var b = toBytes(other); + +// for (var i = 0; i < (a.length / 2); i++) { +// if (a[i] !== b[i] || a[(a.length - 1) - i] !== b[(a.length - 1) - i]) { +// return false; +// } +// } +// return true; +// }; + +// GameOfLife.World.prototype.toString = function() { +// return this.reduce(function(accum, row) { +// accum += row.join("").replace(/0/g, " ").replace(/1/g, " ●") + "\n"; +// return accum; +// }, ""); +// }; diff --git a/JavaScript/node_modules/johnny-five/eg/gripper.js b/JavaScript/node_modules/johnny-five/eg/gripper.js new file mode 100644 index 0000000..21922e6 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/gripper.js @@ -0,0 +1,75 @@ +var five = require("../lib/johnny-five.js"), + compulsive = require("compulsive"), + wrist, gripper, motion, repeater; + +(new five.Board()).on("ready", function() { + + // Create a new `gripper` hardware instance. + // This example allows the gripper module to + // create a completely default instance + + wrist = new five.Servo(9); + gripper = new five.Gripper(10); + + + function slice() { + wrist.to(100); + + compulsive.wait(100, function() { + wrist.to(120); + }); + } + + function chop() { + compulsive.loop(200, function(loop) { + if (!repeater) { + repeater = loop; + } + slice(); + }); + } + + // Inject the `gripper` hardware into + // the Repl instance's context; + // allows direct command line access + this.repl.inject({ + w: wrist, + g: gripper, + chop: chop, + slice: slice + }); + + + motion = new five.IR.Motion(7); + + // gripper.open() + // + // gripper.close() + // + // gripper.set([0-10]) + // + // + // g.*() from REPL + // + // + motion.on("motionstart", function(err, ts) { + chop(); + }); + + // "motionstart" events are fired following a "motionstart event + // when no movement has occurred in X ms + motion.on("motionend", function(err, ts) { + if (repeater) { + repeater.stop(); + repeater = null; + } + }); + + + + }); + +// @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 diff --git a/JavaScript/node_modules/johnny-five/eg/grove-button.js b/JavaScript/node_modules/johnny-five/eg/grove-button.js new file mode 100644 index 0000000..15a946b --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/grove-button.js @@ -0,0 +1,35 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + + // Plug the Button module into the + // Grove Shield's D4 jack + var button = new five.Button(4); + + // Plug the LED module into the + // Grove Shield's D6 jack. See + // grove-led.js for more information. + var led = new five.Led(6); + + // The following will turn the Led + // on and off as the button is + // pressed and released. + button.on("press", function() { + led.on(); + }); + + button.on("release", 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 diff --git a/JavaScript/node_modules/johnny-five/eg/grove-lcd-i2c.js b/JavaScript/node_modules/johnny-five/eg/grove-lcd-i2c.js new file mode 100644 index 0000000..afdaf5c --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/grove-lcd-i2c.js @@ -0,0 +1,25 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + + // Plug the LCD module into any of the + // Grove Shield's I2C jacks. + var lcd = new five.LCD({ + controller: "JHD1313M1" + }); + + lcd.useChar("heart"); + + lcd.cursor(0, 0).print("hello :heart:"); + + lcd.blink().cursor(1, 0).print("Blinking? "); +}); +// @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 diff --git a/JavaScript/node_modules/johnny-five/eg/grove-lcd-rgb-temperature-display.js b/JavaScript/node_modules/johnny-five/eg/grove-lcd-rgb-temperature-display.js new file mode 100644 index 0000000..def9b56 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/grove-lcd-rgb-temperature-display.js @@ -0,0 +1,53 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + + // Plug the Temperature sensor module + // into the Grove Shield's A0 jack + var temperature = new five.Temperature({ + controller: "GROVE", + pin: "A0" + }); + + // Plug the LCD module into any of the + // Grove Shield's I2C jacks. + var lcd = new five.LCD({ + controller: "JHD1313M1" + }); + + temperature.on("data", function() { + + // The LCD's background will change + // color according to the temperature. + // + // Experiment with sources of hot and + // cold temperatures! + // + var f = temperature.fahrenheit; + var r = linear(0x00, 0xFF, f, 100); + var g = linear(0x00, 0x00, f, 100); + var b = linear(0xFF, 0x00, f, 100); + + console.log("temp: ", f); + + lcd.bgColor(r, g, b).cursor(0, 0).print(f.toFixed(2)); + }); +}); + +// [Linear Interpolation](https://en.wikipedia.org/wiki/Linear_interpolation) +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 diff --git a/JavaScript/node_modules/johnny-five/eg/grove-lcd-rgb.js b/JavaScript/node_modules/johnny-five/eg/grove-lcd-rgb.js new file mode 100644 index 0000000..4d4477a --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/grove-lcd-rgb.js @@ -0,0 +1,48 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + + // Plug the Rotary Angle sensor module + // into the Grove Shield's A0 jack + var rotary = new five.Sensor("A0"); + + // Plug the LCD module into any of the + // Grove Shield's I2C jacks. + var lcd = new five.LCD({ + controller: "JHD1313M1" + }); + + // Set scaling of the Rotary angle + // sensor's output to 0-255 (8-bit) + // range. Set the LCD's background + // color to a RGB value between + // Red and Violet based on the + // value of the rotary sensor. + rotary.scale(0, 255).on("change", function() { + var r = linear(0xFF, 0x4B, this.value, 0xFF); + var g = linear(0x00, 0x00, this.value, 0xFF); + var b = linear(0x00, 0x82, this.value, 0xFF); + + lcd.bgColor(r, g, b); + }); +}); + +// [Linear Interpolation](https://en.wikipedia.org/wiki/Linear_interpolation) +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 - Rotary Angle Sensor](http://www.seeedstudio.com/depot/images/product/GroveRotaryP.jpg) +// +// @markdown + + diff --git a/JavaScript/node_modules/johnny-five/eg/grove-led.js b/JavaScript/node_modules/johnny-five/eg/grove-led.js new file mode 100644 index 0000000..1815b3d --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/grove-led.js @@ -0,0 +1,28 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + + // Plug the LED module into the + // Grove Shield's D6 jack. + // + // Select an LED from the kit + // (red, green, blue) and insert + // it into the LED module, with + // the long pin in + and short + // pin in -. + var led = new five.Led(6); + + // This will blink the LED over + // 500ms periods. + 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 diff --git a/JavaScript/node_modules/johnny-five/eg/grove-sensor.js b/JavaScript/node_modules/johnny-five/eg/grove-sensor.js new file mode 100644 index 0000000..7f2d5e5 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/grove-sensor.js @@ -0,0 +1,33 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + + // Plug the Rotary Angle sensor module + // into the Grove Shield's A0 jack + var rotary = new five.Sensor("A0"); + + // Plug the LED module into the + // Grove Shield's D6 jack. See + // grove-led.js for more information. + var led = new five.Led(6); + + // Set scaling of the Rotary angle + // sensor's output to 0-255 (8-bit) + // range. Set the LED's brightness + // based on the value of the sensor. + rotary.scale(0, 255).on("change", function() { + led.brightness(this.value); + }); +}); + +// @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/JavaScript/node_modules/johnny-five/eg/grove-servo.js b/JavaScript/node_modules/johnny-five/eg/grove-servo.js new file mode 100644 index 0000000..952dacd --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/grove-servo.js @@ -0,0 +1,33 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + + // Plug the Rotary Angle sensor module + // into the Grove Shield's A0 jack + var rotary = new five.Sensor("A0"); + + // Plug the Servo module + // into the Grove Shield's D5 jack + var servo = new five.Servo(5); + + // Set scaling of the Rotary angle + // sensor's output to 0-180° (8-bit) + // range. Set the servo angle in + // degrees corresponding to the + // value of the sensor + rotary.scale(0, 180).on("change", function() { + servo.to(this.value); + }); +}); + +// @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/JavaScript/node_modules/johnny-five/eg/grove-touch.js b/JavaScript/node_modules/johnny-five/eg/grove-touch.js new file mode 100644 index 0000000..d0a86a0 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/grove-touch.js @@ -0,0 +1,37 @@ +var five = require("../lib/johnny-five"); +var board = new five.Board(); + +board.on("ready", function() { + + // Plug the Touch module into the + // Grove Shield's D4 jack. Use + // the Button class to control. + var touch = new five.Button(4); + + // Plug the LED module into the + // Grove Shield's D6 jack. See + // grove-led.js for more information. + var led = new five.Led(6); + + // The following will turn the Led + // on and off as the touch is + // pressed and released. + touch.on("press", function() { + led.on(); + }); + + touch.on("release", 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 - Touch Module](http://www.seeedstudio.com/wiki/images/0/01/Grove_-_touch_sensor_Photo.jpg) +// +// @markdown diff --git a/JavaScript/node_modules/johnny-five/eg/gyro-lpr5150l.js b/JavaScript/node_modules/johnny-five/eg/gyro-lpr5150l.js new file mode 100644 index 0000000..f58bf93 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/gyro-lpr5150l.js @@ -0,0 +1,20 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var gyro = new five.Gyro({ + pins: ["A0", "A1"] + }); + + gyro.on("change", function() { + console.log("gyro"); + console.log(" x : ", this.x); + console.log(" y : ", this.y); + console.log(" pitch : ", this.pitch); + console.log(" roll : ", this.roll); + console.log(" yaw : ", this.yaw); + console.log(" rate : ", this.rate); + console.log(" isCalibrated : ", this.isCalibrated); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/gyro-mpu6050.js b/JavaScript/node_modules/johnny-five/eg/gyro-mpu6050.js new file mode 100644 index 0000000..ceb8c8c --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/gyro-mpu6050.js @@ -0,0 +1,21 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var gyro = new five.Gyro({ + controller: "MPU6050" + }); + + gyro.on("change", function() { + console.log("gyro"); + console.log(" x : ", this.x); + console.log(" y : ", this.y); + console.log(" z : ", this.z); + console.log(" pitch : ", this.pitch); + console.log(" roll : ", this.roll); + console.log(" yaw : ", this.yaw); + console.log(" rate : ", this.rate); + console.log(" isCalibrated : ", this.isCalibrated); + console.log("--------------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/gyro.js b/JavaScript/node_modules/johnny-five/eg/gyro.js new file mode 100644 index 0000000..3d22fa7 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/gyro.js @@ -0,0 +1,78 @@ +var five = require("../lib/johnny-five.js"); +var board = new five.Board(); + +board.on("ready", function() { + var servo = new five.Servo("O2"); + var gyro = new five.Gyro({ + pins: ["I0", "I1"], + sensitivity: 0.67 // TK_4X + }); + + servo.center(); + + var threshold = 2; + var position = 0; + var lapse = 0; + + var sampleTime = 10; + var time = Date.now(); + + var pitch = { + value: 0, + last: 0, + angle: 0 + }; + + var roll = { + value: 0, + last: 0, + angle: 0 + }; + + gyro.on("change", function(err, data) { + var now = Date.now(); + + console.log("X raw: %d rate: %d", this.x, this.rate.x); + console.log("Y raw: %d rate: %d", this.y, this.rate.y); + + pitch.value = this.pitch.rate; + roll.value = this.roll.rate; + + // Ignore the gyro if our angular velocity does not meet our threshold + if (pitch.value >= threshold || pitch.value <= -threshold) { + pitch.angle += ((pitch.last + pitch.value) * 10) / 1000; + } + + if (roll.value >= threshold || roll.value <= -threshold) { + roll.angle += ((roll.last + roll.value) * 10) / 1000; + } + + pitch.last = pitch.value; + roll.last = roll.value; + + if (roll.angle < 0) { + roll.angle += 360; + } + + if (roll.angle > 359) { + roll.angle -= 360; + } + + // counterclockwise rotation of the gyro... + if (roll.angle >= 0 && roll.angle <= 90) { + // ...produces rotation from 90 to 180 deg on servo + position = (90 + roll) | 0; + } + + // clockwise rotation of the gyro... + if (roll.angle >= 270) { + // ...produces rotation from 90 to 0 deg on servo + position = (roll.angle - 270) | 0; + } + + // console.log( position ); + servo.to(position); + + console.log("-----------------------------------"); + }); +}); diff --git a/JavaScript/node_modules/johnny-five/eg/handclaw42-client.js b/JavaScript/node_modules/johnny-five/eg/handclaw42-client.js new file mode 100644 index 0000000..d715cf3 --- /dev/null +++ b/JavaScript/node_modules/johnny-five/eg/handclaw42-client.js @@ -0,0 +1,32 @@ +/* global io */ +$(document).ready(function() { + var $body = $("body"); + var socket = window.socket; + + socket = io.connect("http://192.168.1.186:8080"); + + socket.on("createServo", function(data) { + var div, span, input; + + div = $("
"); + // should probably just make this a