Skip to content

Instantly share code, notes, and snippets.

@cowboy
Created May 29, 2014 21:26
Show Gist options
  • Save cowboy/3183233bd6b67c508b2c to your computer and use it in GitHub Desktop.
Save cowboy/3183233bd6b67c508b2c to your computer and use it in GitHub Desktop.
node.js + johnny-five @ jsconf 2014
var j5 = require('johnny-five');
var Leds = require('./leds').Leds;
var board = new j5.Board();
var delay = 20;
var leds;
board.on('ready', function() {
leds = new Leds(4, 13);
var button = new j5.Button(2);
button.on('down', function() {
autoCycle.off();
nextMode();
});
button.on('hold', function() {
autoCycle.on();
});
autoCycle.eventually();
nextMode();
(function loopy() { mode.loop(); setTimeout(loopy, mode.delay || delay); }());
});
var mode, modeidx;
var modes = [];
function nextMode() {
var first = 0; //modes.length - 1;
modeidx = modeidx == null ? first : (modeidx + 1) % modes.length;
mode = modes[modeidx];
console.log('mode %s (%d)', mode.name, modeidx);
leds.off();
if (mode.init) { mode.init(); }
}
var autoCycle = {
id: null,
eventuallyId: null,
eventuallyDelay: 60000,
delay: 15000,
on: function() {
this.eventuallyReset();
if (!this.id) {
console.log('auto-cycle: enabled');
this.id = setInterval(nextMode, this.delay);
}
},
off: function() {
if (this.id) {
console.log('auto-cycle: disabled');
clearInterval(this.id);
this.id = null;
}
this.eventually();
},
toggle: function() {
this.eventuallyReset();
if (this.id) {
this.off();
} else {
this.on();
}
},
eventually: function() {
this.eventuallyReset();
this.eventuallyId = setTimeout(this.on.bind(this), this.eventuallyDelay);
},
eventuallyReset: function() {
clearTimeout(this.eventuallyId);
this.eventuallyId = null;
},
};
modes.push({
name: 'Blink',
init: function() {
this.delay = 300;
},
loop: function() {
leds.toggle();
},
});
modes.push({
name: 'Cycle',
init: function() {
this.delay = 50;
this.dir = 1;
this.current = -1;
},
loop: function() {
this.current = (leds.length + this.current + this.dir) % leds.length;
leds.on(this.current);
},
});
modes.push({
name: 'March',
init: function() {
this.delay = 300;
this.remainder = 1;
},
loop: function() {
this.remainder = 1 - this.remainder;
leds.forEach(function(led, i) {
led[i % 2 === this.remainder ? 'on' : 'off']();
}.bind(this));
},
});
modes.push({
name: 'Ping-pong',
init: function() {
this.delay = 50;
this.dir = 1;
this.current = -1;
},
loop: function() {
this.current += this.dir;
if (this.current < 0 || this.current === leds.length) {
this.dir = -this.dir;
this.current += 2 * this.dir;
}
leds.on(this.current);
},
});
modes.push({
name: 'Cylon',
init: function() {
this.delay = 50;
this.dir = 1;
this.pad = 1;
this.current = -1;
},
loop: function() {
this.current += this.dir;
if (this.current < 0 || this.current === leds.length) {
this.dir = -this.dir;
this.current += this.dir;
}
var arr = [];
for (var i = 0; i < leds.length; i++) {
if (i >= this.current - this.pad && i <= this.current + this.pad) {
arr.push(i);
}
}
leds.on(arr);
},
});
modes.push({
name: 'Starburst',
init: function() {
this.delay = 30;
this.frames = [
' ',
' XX ',
' XXXX ',
' XX XX ',
' XX XX XX ',
'XX XXXX XX',
'X XX XX X',
' XX XX XX ',
'XX XXXX XX',
'X XX XX X',
'XX XX',
'X X',
' ',
'XX XX',
'X X X X',
' X X X X ',
'X X XX X X',
' X X X X ',
' X XX X ',
' X X ',
' XX ',
' ',
' ',
];
this.current = -1;
},
loop: function() {
if (++this.current === this.frames.length) {
this.current = 2;
}
var arr = [];
this.frames[this.current].split('').forEach(function(n, i) {
if (n === 'X') { arr.push(i); }
});
leds.on(arr);
},
});
modes.push({
name: 'Skippy',
init: function() {
this.delay = 30;
this.frames = [
' ',
'X ',
' X ',
' X ',
' X ',
' X ',
' ',
' X',
' X ',
' X ',
' X ',
' X ',
' ',
'X ',
' X ',
' X ',
' X ',
' X ',
' ',
' X',
' X ',
' X ',
' X ',
' X ',
];
this.current = -1;
},
loop: function() {
this.current = (this.current + 1) % this.frames.length;
var arr = [];
this.frames[this.current].split('').forEach(function(n, i) {
if (n === 'X') { arr.push(i); }
});
leds.on(arr);
},
});
modes.push({
name: 'Binary Counter',
init: function() {
this.delay = 200;
this.num = 0;
},
loop: function() {
var arr = [];
(++this.num).toString(2).split('').forEach(function(n, i, a) {
if (n === '1') {
arr.push(leds.length - a.length + i + 1);
}
});
if (this.delay > 10) {
this.delay = Math.floor(this.delay * 0.99);
}
leds.on(arr);
},
});
var j5 = require('johnny-five');
function Leds(ledstartpin, ledendpin) {
for (var i = 0; i <= ledendpin - ledstartpin; i++) {
this[i] = new j5.Led(i + ledstartpin);
}
this.length = ledendpin - ledstartpin + 1;
}
exports.Leds = Leds;
Leds.prototype.forEach = function(fn) {
for (var i = 0; i < this.length; i++) {
if (typeof fn === 'function') {
fn.call(this, this[i], i);
} else if (typeof fn === 'string') {
this[i][fn].apply(this[i], [].slice.call(arguments, 1));
} else {
throw new TypeError('Invalid argument.');
}
}
};
Leds.prototype.on = function(idxs) {
if (arguments.length === 0) {
this.forEach('on');
} else {
idxs = typeof idxs === 'number' ? [idxs] : idxs;
this.forEach(function(led, i) {
led[idxs.indexOf(i) !== -1 ? 'on' : 'off']();
});
}
};
Leds.prototype.off = function() {
this.forEach('off');
};
Leds.prototype.toggle = function() {
this.forEach('toggle');
};
@cowboy
Copy link
Author

cowboy commented May 29, 2014

In a shell

$ npm install johnny-five
$ node leds-cycle.js

What it looked like

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment