UNPKG

johnny-five

Version:

The JavaScript Robotics and Hardware Programming Framework. Use with: Arduino (all models), Electric Imp, Beagle Bone, Intel Galileo & Edison, Linino One, Pinoccio, pcDuino3, Raspberry Pi, Particle/Spark Core & Photon, Tessel 2, TI Launchpad and more!

229 lines (183 loc) 4.97 kB
var IS_TEST_MODE = !!process.env.IS_TEST_MODE; var Board = require("./board"); var Collection = require("./mixins/collection"); var priv = new Map(); function ShiftRegister(opts) { if (!(this instanceof ShiftRegister)) { return new ShiftRegister(opts); } if (Array.isArray(opts)) { // [Data, Clock, Latch, Reset] opts = { pins: { data: opts[0], clock: opts[1], latch: opts[2], reset: opts.length === 4 ? opts[3] : null, } }; } else if (typeof opts.pins === "object" && Array.isArray(opts.pins)) { opts.pins = { data: opts.pins[0], clock: opts.pins[1], latch: opts.pins[2], reset: opts.pins.length === 4 ? opts.pins[3] : null, }; } Board.Component.call( this, opts = Board.Options(opts) ); this.size = opts.size || 1; this.pins.reset = typeof opts.pins.reset !== "undefined" ? opts.pins.reset : null; var isAnode = typeof opts.isAnode !== "undefined" ? opts.isAnode : false; var clear = isAnode ? 255 : 0; var state = { isAnode: isAnode, value: new Array(this.size).fill(clear), encoded: encoded[isAnode ? "anode" : "cathode"], clear: clear, }; priv.set(this, state); Object.defineProperties(this, { isAnode: { get: function() { return isAnode; } }, value: { get: function() { return state.value; } }, }); } var encoded = { cathode: [63, 6, 91, 79, 102, 109, 125, 7, 127, 103], anode: [64, 121, 36, 48, 25, 18, 2, 120, 0, 24], }; /** * Print a digit on a seven segment display, or several * digits across several displays. */ ShiftRegister.prototype.display = function(value) { var state = priv.get(this); var chars; if (typeof value === "number") { // 1, 20, etc. return this.display(String(value)); } if (typeof value === "string") { var matches = value.match(/([0-9]{1}\.*)/g); if (matches && matches.length) { chars = matches.map(function(char) { // "1" if (char.length === 1) { return state.encoded[char] | (1 << 7); } // "1.?.?" return state.encoded[char[0]]; }); } } this.send(chars); state.value = chars; return this; }; /** * Send one or more values to the shift register. * @param {...number} value Value to send * @returns {ShiftRegister} */ ShiftRegister.prototype.send = function(value) { var state = priv.get(this); var args = Array.from(arguments); if (args.length === 1) { args = [value]; } if (Array.isArray(value)) { args = value; } // open latch to fill register with data this.io.digitalWrite(this.pins.latch, this.io.LOW); args.forEach(function(arg) { if (typeof arg === "string") { arg = arg.charCodeAt(0); } if (this.isAnode && (arg !== 255 && !state.encoded.includes(arg) && !state.encoded.includes(arg & ~(1 << 7)))) { var index = encoded.anode.findIndex(function(value) { return value === arg; }); if (index !== -1) { arg = encoded.cathode[index]; } } this.board.shiftOut(this.pins.data, this.pins.clock, true, arg); }, this); // close latch to commit bits into register. this.io.digitalWrite(this.pins.latch, this.io.HIGH); state.value = args; return this; }; /** * Clear the shift register by replacing each value with a 0. * @type {ShiftRegister} */ ShiftRegister.prototype.clear = function() { var state = priv.get(this); return this.send(Array(this.size).fill(state.clear)); }; ShiftRegister.prototype.reset = function() { if (this.pins.reset === null) { throw new Error("ShiftRegister was not initialized with a reset pin"); } this.io.digitalWrite(this.pins.clock, this.io.LOW); this.io.digitalWrite(this.pins.reset, this.io.LOW); this.io.digitalWrite(this.pins.clock, this.io.HIGH); this.io.digitalWrite(this.pins.reset, this.io.HIGH); return this; }; /** * ShiftRegisters() * new ShiftRegisters() */ function ShiftRegisters(numsOrObjects) { if (!(this instanceof ShiftRegisters)) { return new ShiftRegisters(numsOrObjects); } Object.defineProperty(this, "type", { value: ShiftRegister }); Collection.call(this, numsOrObjects); } ShiftRegisters.prototype = Object.create(Collection.prototype, { constructor: { value: ShiftRegisters } }); /* * ShiftRegisters, display(...) * * eg. array.display(...); * ShiftRegisters, send(...) * * eg. array.send(...); * ShiftRegisters, clear() * * eg. array.clear(); * ShiftRegisters, reset() * * eg. array.reset(); */ Collection.installMethodForwarding( ShiftRegisters.prototype, ShiftRegister.prototype ); // Assign ShiftRegisters Collection class as static "method" of ShiftRegister. ShiftRegister.Collection = ShiftRegisters; /* istanbul ignore else */ if (IS_TEST_MODE) { ShiftRegister.purge = function() { priv.clear(); }; } module.exports = ShiftRegister;