Experiment Guide for the Johnny-Five Inventor's Kit
Experiment 13: Controlling LEDs with a Shift Register
This experiment is the first time we'll use an Integrated Circuit (IC) all by itself with no breakout board or other support. We'll use a shift register to give you control over an additional eight outputs, while using up only three pins on the Tessel 2. Using the shift register in this experiment, you can control eight—count 'em, eight!—LEDs. That's a new record for us!
Preflight CheckWhoa there, Turbo! If this is your first experiment with the Johnny-Five Inventor's Kit (J5IK) and the Tessel 2, there are a few things you gotta do first:
The following tutorials provide in-depth background on some of the hardware concepts in this article:
You will need the following parts for this experiment:
- 1x Tessel 2
- 1x Breadboard
- 1x Shift Register
- 8x Standard LEDs
- 8x 100Ω Resistor
- 17x Jumper Wires
Introducing the Shift Register
The kind of shift register used in this experiment takes a byte of data (8 bits) and breaks it up, using each bit to determine the logic level of its eight output pins. For example, the message:
would result in the following states on the shift register's individual output pins:
Each bit in the sent byte, then, determines the state of its associated output pin. The shift register is able to give you extra outputs (eight, while using only three pins on the Tessel 2) because it takes serial data and converts it to parallel output.
You can think of the inside of a shift register as a big train-switching yard. A train (byte) arrives, and, like all of the other trains that come to this place, it is eight cars long. Each car in the train represents a single bit, and is either full (1) or empty (0). The train is disassembled; each car is switched onto its own track and waits. Once all of the cars are in place and the engine-master gives the all clear, the cars exit the yard on their assigned track (shift register output pin). Full cars (1s) will cause their output pins to go
HIGH while empty cars (0s) will cause their output pins to go
LOW. Bytes representing different orders of 1s and 0s cause different patterns of
HIGH states from the shift register's output pins.
If you have eight LEDs connected to the shift register's output pins, you could turn them all on by sending the message
11111111, or turn them all off by sending the message
There are 16 pins on the shift register included with this kit. If you orient the shift register chip with the semi-circular notch upward, the pins are numbered starting from the top-left pin. Pins 1 through 8 run top-to-bottom on the left side of the chip. Pins 9 to 16 run bottom-to-top on the right side. Read that again to avoid confusion: pins on the right are numbered bottom-to-top (pin 16 is the top-right pin).
The pins on the shift register do different things. Pin 15 and pins 1--7 are the output pins—those will get connected to the LEDs. A few pins need to be connected to power and ground. The three connections between the SR and the Tessel 2 are a data connection (to send those trains of bytes), a clock connection (to keep everyone in sync) and a latch (for, in part, controlling when data gets pushed out to output pins). You won't have to mess around with the clock and latch stuff—other than telling Johnny-Five which Tessel 2 pins are connected to those shift-register pins. You just have to decide what data to send to the shift register.
Does this circuit look a little shifty to you? Fear not! Let's build it and then master using the shift register.
|Polarized Components||Pay special attention to the component’s markings indicating how to place it on the breadboard. Polarized components can only be connected to a circuit in one direction.|
Build the Circuit
- Connect the shift register to the breadboard. Look for the semi-circular divot at one of the ends of the chip. That end of the chip should be oriented toward the top of the breadboard. Plug the shift register in so that it spans the center notch.
- Connect the eight LEDs. For each, plug the anode (longer leg) into a terminal row on the breadboard and the cathode (shorter leg) directly into the ground power rail.
- Connect the current-limiting resistors for the LEDs. Each 100Ω resistor should span the center notch.
- Some of the shift register's pins need to be connected to power or ground. Using jumper wires, connect shift register pins 16 and 10 to the supply power rail. Connect shift register pins 8 and 13 to the ground power rail.
- Connect each of the shift register's output pins to the LED it will control, using jumper wires. Start by connecting the shift register's Pin 15 to the first LED. Then connect the shift register's pins 1--7 to the rest of the LEDS, as shown in the wiring diagram.
- Connect the shift register to the Tessel 2. Shift register pins 14, 12 and 11 should be connected with jumper wires to Tessel 2's Port A, pins 3, 4 and 5, respectively (see wiring diagram).
- Use jumper wires to connect the Tessel 2's 3.3V and GND pins to the power rails of the breadboard.
Using a Shift Register to Display 8-Bit Values With Johnny-Five
Open your favorite code editor, create a file called
shift-register-bits.js and save it in the
Type—or copy and paste—the following into your terminal:
t2 run shift-register-bits.js
What You Should See
The program cycles through each LED, lighting one at a time, repeating the pattern forever.
Exploring the Code
In Experiment 9: Using an H-Bridge Motor Controller you learned about Johnny-Five's simplified argument forms, which can applied to every component class constructor; here, we can actually rewrite the above arguments as:
Therefore, the entire initialization could also be written as:
Much nicer! These argument forms are illustrated in the Johnny-Five
ShiftRegister component initialization API docs.
The next line sets an initial value of
128, represented as Binary Integer Literal:
We briefly looked at Binary Integer Literals in Experiment 3: Reading a Potentiometer, but this time we'll take a closer look. Open the Node.js REPL by typing
node and pressing ENTER in your terminal. Once open, type any of the following, each followed by pressing the ENTER key:
These are called Binary Integer Literals because they are literally the binary representation (1s and 0s) of an integer. Each 1 and/or 0 represents a single bit. The
The result of each, in order, must be:
As a nasty hack, you could figure out the minimum number of bits necessary to represent, in binary, a given number by writing:
All numbers have a
toString(radix) method, which converts a number to a String. The radix argument tells what base to use when translating the number.
2 is binary.
10 is decimal. It can accept any radix between
Since we can now literally see how many bits are in a number, we can move onto the next piece of code:
The first line in the looping callback function is assigning a new value to the variable
output based on whether the present value of
output is greater than zero.
If it is, then shift the actual bits of the present value of
output one place to the right (this shoves one of the 0s off of the right side). If it's not greater than zero, assign the value 128 (shown in binary integer literal form,
0b10000000), which will make the LED pattern start back at the beginning again. The last line of the function sends the
output to the shift register.
Here's the effect of every call to the loop callback, as it would appear over eight iterations:
B means "Bit", (i.e., Bit 7 = B7). B0 is the right-most bit.
Since we have eight LEDs, and we know it's helpful to think of our output in terms of range as 8-bit, let's visually count out the full range of 8-bit numbers (0--255) using the LEDs! Open your favorite code editor, create a file called
shift-register-count.js and save it in the
Instead of bit-shifting using the bitwise operator
output++ increments the value of
output by 1 on each iteration. If
output gets too big (greater than 255, or
0b11111111), reset it to 0 (
Type—or copy and paste—the following into your terminal:
t2 run shift-register-count.js
What You Should See
The LEDs will be lit to represent each number from 0--255 in its binary form, one number at a time.
- Try using Johnny-Five's
Expanderclass, with the
74HC595controller to treat each LED as a single
- Use an
Ledsinstance class with an
Expanderinstance to control all of the LEDs as you did in Experiment 2: Multiple LEDs.
- Use an