UNPKG

4.89 kBJavaScriptView Raw
1var Board = require("./board");
2var Collection = require("./mixins/collection");
3var util = require("util");
4var priv = new Map();
5
6function ShiftRegister(opts) {
7 if (!(this instanceof ShiftRegister)) {
8 return new ShiftRegister(opts);
9 }
10
11 if (Array.isArray(opts)) {
12 // [Data, Clock, Latch, Reset]
13 opts = {
14 pins: {
15 data: opts[0],
16 clock: opts[1],
17 latch: opts[2],
18 reset: opts.length === 4 ? opts[3] : null,
19 }
20 };
21 } else if (typeof opts.pins === "object" && Array.isArray(opts.pins)) {
22 opts.pins = {
23 data: opts.pins[0],
24 clock: opts.pins[1],
25 latch: opts.pins[2],
26 reset: opts.pins.length === 4 ? opts.pins[3] : null,
27 };
28 }
29
30 Board.Component.call(
31 this, opts = Board.Options(opts)
32 );
33
34 this.size = opts.size || 1;
35 this.pins.reset = typeof opts.pins.reset !== "undefined" ? opts.pins.reset : null;
36
37 var isAnode = typeof opts.isAnode !== "undefined" ? opts.isAnode : false;
38 var clear = isAnode ? 255 : 0;
39 var state = {
40 isAnode: isAnode,
41 value: new Array(this.size).fill(clear),
42 encoded: encoded[isAnode ? "anode" : "cathode"],
43 clear: clear,
44 };
45
46 priv.set(this, state);
47
48 Object.defineProperties(this, {
49 isAnode: {
50 get: function() {
51 return isAnode;
52 }
53 },
54 value: {
55 get: function() {
56 return state.value;
57 }
58 },
59 });
60}
61
62var encoded = {
63 cathode: [63, 6, 91, 79, 102, 109, 125, 7, 127, 103],
64 anode: [64, 121, 36, 48, 25, 18, 2, 120, 0, 24],
65};
66
67/**
68 * Print a digit on a seven segment display, or several
69 * digits across several displays.
70 */
71ShiftRegister.prototype.display = function(value) {
72 var state = priv.get(this);
73 var chars;
74
75 if (typeof value === "number") {
76 // 1, 20, etc.
77 return this.display(String(value));
78 }
79
80 if (typeof value === "string") {
81 var matches = value.match(/([0-9]{1}\.*)/g);
82
83 if (matches && matches.length) {
84 chars = matches.map(function(char) {
85 // "1"
86 if (char.length === 1) {
87 return state.encoded[char] | (1 << 7);
88 }
89 // "1.?.?"
90 return state.encoded[char[0]];
91 });
92 }
93 }
94
95 this.send(chars);
96
97 state.value = chars;
98
99 return this;
100};
101
102/**
103 * Send one or more values to the shift register.
104 * @param {...number} value Value to send
105 * @returns {ShiftRegister}
106 */
107ShiftRegister.prototype.send = function(value) {
108 var state = priv.get(this);
109 var args = Array.from(arguments);
110
111 if (args.length === 1) {
112 args = [value];
113 }
114
115 if (Array.isArray(value)) {
116 args = value;
117 }
118
119 // open latch to fill register with data
120 this.io.digitalWrite(this.pins.latch, this.io.LOW);
121
122 args.forEach(function(arg) {
123 if (typeof arg === "string") {
124 arg = arg.charCodeAt(0);
125 }
126 if (this.isAnode &&
127 (arg !== 255 && !state.encoded.includes(arg) && !state.encoded.includes(arg & ~(1 << 7)))) {
128
129 var index = encoded.anode.findIndex(function(value) {
130 return value === arg;
131 });
132
133 if (index !== -1) {
134 arg = encoded.cathode[index];
135 }
136 }
137 this.board.shiftOut(this.pins.data, this.pins.clock, true, arg);
138 }, this);
139
140 // close latch to commit bits into register.
141 this.io.digitalWrite(this.pins.latch, this.io.HIGH);
142
143 state.value = args;
144
145 return this;
146};
147
148/**
149 * Clear the shift register by replacing each value with a 0.
150 * @type {ShiftRegister}
151 */
152ShiftRegister.prototype.clear = function() {
153 var state = priv.get(this);
154 return this.send(Array(this.size).fill(state.clear));
155};
156
157ShiftRegister.prototype.reset = function() {
158 if (this.pins.reset === null) {
159 throw new Error("ShiftRegister was not initialized with a reset pin");
160 }
161 this.io.digitalWrite(this.pins.clock, this.io.LOW);
162 this.io.digitalWrite(this.pins.reset, this.io.LOW);
163 this.io.digitalWrite(this.pins.clock, this.io.HIGH);
164 this.io.digitalWrite(this.pins.reset, this.io.HIGH);
165
166 return this;
167};
168
169
170
171
172/**
173 * ShiftRegisters()
174 * new ShiftRegisters()
175 */
176function ShiftRegisters(numsOrObjects) {
177 if (!(this instanceof ShiftRegisters)) {
178 return new ShiftRegisters(numsOrObjects);
179 }
180
181 Object.defineProperty(this, "type", {
182 value: ShiftRegister
183 });
184
185 Collection.call(this, numsOrObjects);
186}
187
188util.inherits(ShiftRegisters, Collection);
189
190
191/*
192 * ShiftRegisters, display(...)
193 *
194 * eg. array.display(...);
195
196 * ShiftRegisters, send(...)
197 *
198 * eg. array.send(...);
199
200 * ShiftRegisters, clear()
201 *
202 * eg. array.clear();
203
204 * ShiftRegisters, reset()
205 *
206 * eg. array.reset();
207 */
208
209Collection.installMethodForwarding(
210 ShiftRegisters.prototype, ShiftRegister.prototype
211);
212
213// Assign ShiftRegisters Collection class as static "method" of ShiftRegister.
214ShiftRegister.Collection = ShiftRegisters;
215
216/* istanbul ignore else */
217if (!!process.env.IS_TEST_MODE) {
218 ShiftRegister.purge = function() {
219 priv.clear();
220 };
221}
222
223module.exports = ShiftRegister;