The Johnny-Five Tutorial Series is geared towards Arduino programming on Node.js, using the Johnny-Five framework. Get caught up here.
LED Matrix signs are everywhere: roadways (even cars themselves!), store awnings, offices, the grocery store deli, airports, train stations, taxi stands, libraries, alarm clocks, and so on. The use cases are so broad because the technology is very old and well-proven. LED Matrix displays are controlled by one or more shift registers. The shift register, which first appeared in the Colossus Mark II in 1943-44, is a sequential logic circuit comprised of flip-flops connected in a chain. Output from one flip-flop is the input to the next flip-flop. Readers won’t specifically need to understand shift registers for this tutorial, but I recommend All About Circuits: Shift Registers for further reading. Today, we’ll be wiring up a simple LED matrix display and using it to display symbols and messages. Let’s get started!
Parts:
Connect the following:
- LED Matrix: J1
- VCC to 5V
- GND to GND
- DIN to Digital 2
- CS to Digital 4
- CLK to Digital 3
Before we continue, let’s clarify some labelling terminology:
- DIN: “Data IN“, corresponds to the
data
pin - CS: “Chip Select”, corresponds to the
cs
pin - CLK: “CLocK“, corresponds to the
clock
pin
First, let’s get comfortable with the Led.Matrix
API, save the following as led-matrix-basics.js
:
var five = require("johnny-five");
var board = new five.Board();
board.on("ready", function() {
var matrix = new five.Led.Matrix({
pins: {
data: 2,
clock: 3,
cs: 4
}
});
matrix.on();
/*
A single Led.Matrix object can control one
or more led matrix devices. All methods of
Led.Matrix objects expect the target device's
index as their first argument. Since this
might seem cumbersome when there is only
one matrix device, use the `device()` method
to create a display device bound to an index.
*/
this.repl.inject({
display: matrix.device(0)
});
});
Run node led-matrix-basics.js
and wait for the program to connect to the board. Once connected, try the following commands one-at-a-time:
// Control one led at a time
// display.led(row 0-7, column 0-7, 0|1)
// Turn on the top-left led:
display.led(0, 0, 1);
// Turn on the top-right led:
display.led(0, 7, 1);
// Turn on the bottom-left led:
display.led(7, 0, 1);
// Turn on the bottom-right led:
display.led(7, 7, 1);
// Clear the device at index 0
display.clear(0);
Controlling an entire row or column also requires only a single value: an 8-bit (0-255) binary value can be used to tell the register which leds in a given row are “on” and which are “off”. To help understand the row
and column
APIs, use the following interactive 8-bit value generator:
8×8 Matrix: 8-Bit Value Generator
// Control one row or column at a time by
// providing a single 8-bit value that
// represents which leds to "fill".
//
// row(0-7, 0-255);
// column(0-7, 0-255);
// HINT: Paste or type one loop at a time!
// Turn on all leds in each row
for (var x = 0; x < 8; x++) {
display.row(x, 255);
}
// Turn off all leds in each row
for (var x = 0; x < 8; x++) {
display.row(x, 0);
}
// Turn on all leds in each column
for (var y = 0; y < 8; y++) {
display.column(y, 255);
}
// Turn off all leds in each column
for (var y = 0; y < 8; y++) {
display.column(y, 0);
}
Now that we’re familiar with controlling row and column display, the next logical step is to display entire 8×8 “drawings” with the draw()
method. The draw()
method will accept a string value containing the “name” of a single character or icon that corresponds to a predefined character or an array of eight 8-bit values (one value for each row) for custom characters.
// Predefined Characters
0 1 2 3 4 5 6 7 8 9
! " # $ % & ' ( ) * + , - . / : ; < = > ? @
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ `
a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~
Back in the program, try the following calls to the draw
method:
// Draw "0"
display.draw("0");
// Draw "A"
display.draw("A");
// This one is a surprise:
display.draw([0x00, 0x00, 0x24, 0x00, 0x81, 0x42, 0x3c, 0x00]);
Now that we’re familiar with the basics of controlling an Led.Matrix
instance, save the following as led-matrix-controller.js
:
/*
NOTE: In the video, there is a "winking smiley face" shown.
This version of the program omits the "winking smiley
face" for the sake of simplicity. Readers are encouraged
to implement a solution to reproduce the "animation".
*/
var readline = require("readline");
var five = require("johnny-five");
var board = new five.Board({
repl: false
});
board.on("ready", function() {
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var display = new five.Led.Matrix({
pins: {
data: 2,
clock: 3,
cs: 4
}
});
var message = [];
function update() {
if (message.length) {
// When a message is ready to be written,
// write one character at a time to device 0.
display.draw(0, message.shift());
// When the end of the message has been reached,
// show the readline prompt.
if (!message.length) {
rl.prompt();
return;
}
setTimeout(update, 500);
}
}
rl.prompt();
rl.on("line", function(text) {
message = (text + " ").split("");
update();
});
display.on();
});
Run node led-matrix-controller.js
to see the program in action! Type a message into the console and hit the <ENTER>
key to display it!
Homework
Based on the program above, use the LED Matrix to display data readings from a sensor.