Experiment Guide for the Johnny-Five Inventor's Kit

Pages
Contributors: rwaldron, reconbot, D___Run___, lyzadanger, Shawn Hymel
Favorited Favorite 8

Experiment 1: Blink an LED

Introduction

Making an LED (Light-Emitting Diode) blink is the most basic "Hello, World!" exercise for hardware, and is a great way to familiarize yourself with a new platform. In this experiment, you'll learn how to build a basic LED circuit and use Johnny-Five with your Tessel 2 to make the LED blink and pulse. In doing so, you'll learn about digital output and Pulse Width Modulation (PWM).

Perhaps you've controlled LEDs before by writing Arduino sketches (programs). Using Johnny-Five + Node.js to control hardware is a little different, and this article will illustrate some of those differences. If you're totally new to all of this — not to worry! You don't need any prior experience.

Preflight Check

Whoa 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:
  1. Set up your computer
  2. Configure your Tessel 2
Note: These steps only have to be done once, but they are required. Internet connection may be necessary!

Parts Needed

You will need the following parts for this experiment:

  • 1x Tessel 2 and USB cable
  • 1x Breadboard
  • 1x Standard LED (Choose any color in the bag full of LEDs)
  • 1x 100Ω Resistor
  • 2x Jumper Wires
Using a Tessel 2 without the kit? No worries! You can still have fun and follow along with this experiment. We suggest using the parts below:
Breadboard - Self-Adhesive (White)

Breadboard - Self-Adhesive (White)

PRT-12002
$5.50
48
Jumper Wires - Connected 6" (M/M, 20 pack)

Jumper Wires - Connected 6" (M/M, 20 pack)

PRT-12795
$2.10
2
LED - Assorted (20 pack)

LED - Assorted (20 pack)

COM-12062
$3.95
8
Resistor 100 Ohm 1/4 Watt PTH - 20 pack (Thick Leads)

Resistor 100 Ohm 1/4 Watt PTH - 20 pack (Thick Leads)

PRT-14493
$1.25

Tessel 2

DEV-13841
4 Retired

Suggested Reading

The following tutorials provide in-depth background on some of the hardware concepts in this experiment:

  • What is a Circuit? — explains what circuits are and how they work
  • Voltage, Current, Resistance, and Ohm's Law — demonstrates the vital relationships between voltage, current and resistance as described by Ohm's Law
  • LEDs (Light-Emitting Diodes) — the details on how those ubiquitous little lights work
  • Resistors -- Why use resistors? Learn more about resistors and why they are important in circuits like the ones in this tutorial
  • Polarity -- Polarity is an important characteristic to pay attention to when building circuits

Introducing LEDs

Diodes are electronic components that only allow current to flow through them in a single direction, like a one-way street. Light-Emitting Diodes (LEDs) are a kind of diode that emit light when current flows through them.

Photo of a standard red LED

Grab an LED and take a look at it. The longer leg is called the anode. That's where current enters the LED. The anode is the positive pin and should always be connected to current source. The shorter leg, the cathode, is where current exits the LED. The cathode is the negative pin and should always be connected to a pathway to ground. Many LEDs also have a flat spot on the cathode (negative) side.

Drawing of LED parts: anode and cathode

If you apply too much current to an LED, it can burn out. We need to limit the amount of current that passes through the LED. To do that, we'll use a resistor. When you use a resistor in this way to limit current, it is called — surprise! — a current-limiting resistor. With the Tessel 2 board, you should use a 100 Ohm resistor. We have included a baggy of them in the kit just for this reason!

If you're curious to learn more about how voltage, current and resistance relate to one another, read this tutorial about Ohm's Law.

Hardware Hookup

Its now the fun part! It's time to start building your circuit. Let's take a look at what goes into building this circuit.

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.

Polarity

LEDs are polarized, meaning they need to be oriented in a specific direction when they are plugged in. You don't want to plug a polarized part in backward!

On the other hand, resistors are not polarized; they're symmetric, which means they don't have an opinion about which way current flows across them. You can plug a resistor in facing either direction in a circuit, and it will be just fine.

Plugging Things In

When working with components like resistors, you'll need to bend their legs at (about) 90° in order to correctly fit into the breadboard sockets. You can trim the legs shorter to make them easier to work with, if you like:

Bent resistor

All jumper wires work the same. They are used to connect two points together. All of the experiments in this guide will show the wires with different colored insulations for clarity, but using different combinations of colors is completely acceptable.

Image of jumper wires

Breadboards are vital tools for prototyping circuits. Inside the breadboard there are electrical connections between certain sockets. Power rails — columns on the left and the right of the breadboard — are electrically connected vertically, while terminal rows — rows in the middle of the breadboard — are connected horizontally (note that connections do not continue across the center notch in the breadboard).

image of breadboard

You can read a tutorial about breadboards to learn more.

Build the LED Circuit

Each of the experiments in this guide will have a wiring diagram. They'll show you where to plug in components and how to connect them to your Tessel 2.

alt text

Having a hard time seeing the circuit? Click on the wiring diagram for a closer look.

  1. Plug the LED into the breadboard, taking care to plug the cathode into row 1 and the anode into row 2. Make sure not to plug it in backward!
  2. Connect a 100Ω resistor between the LED's cathode and ground as shown, spanning the notch in the middle of the breadboard.
  3. Use jumper wires to connect the breadboard's components to the Tessel 2: connect ground (row 1) to the Tessel 2's Port A GND pin and source (row 2) to the Tessel 2's Port A, Pin 5.

Using Johnny-Five to Make an LED Blink

Open your favorite code editor, create a file called led.js and save it in the j5ik/ directory. Type — or copy and paste — the following JavaScript code into your led.js file:

language:javascript
var Tessel = require("tessel-io");
var five = require("johnny-five");

var board = new five.Board({
  io: new Tessel()
});

board.on("ready", () => {
  var led = new five.Led("a5");
  led.blink(500);
});

Now for the big reveal! Type — or copy and paste — the following into your terminal:

t2 run led.js

You terminal will display something like this:

alt text

And when the program starts up:

alt text

What You Should See

Your LED should be blinking:

State Time
On 500ms
Off 500ms

Exploring the Code

Let's take a deeper look at what's going on in the led.js Johnny-Five code.

Requiring Modules

In Node.js, a program can use any number of code modules. Modules are independent chunks of functionality. The software functionality for Tessel and Johnny-Five is contained within modules. We need to tell Node.js to require those modules so that they are available to the program:

language:javascript
var Tessel = require("tessel-io");
var five = require("johnny-five");

Note: For Node.js to be able to find and use the modules, you need to use npm to install for the project. That happened when you set up your working environment—you used npm install to install both the tessel-io and johnny-five modules.

Instantiating Objects

Next, the code needs to instantiate (create) a new object that represents the Tessel 2 board, and assign it to a variable (board) so we can access it later:

language:javascript
var board = new five.Board({
  io: new Tessel()
});

This creates a new instance of a Johnny-Five Board.

Johnny-Five supports many kinds of development boards. The support for some boards is built right in to Johnny-Five, but others — including Tessels — rely on external plugins encapsulated in modules. That's why the code requires the tessel-io npm module. Here, we tell Johnny-Five to use a Tessel object for IO when communicating with the board.

Learn more: Working with JavaScript Objects

Listening for Events

JavaScript code statements are typically executed top to bottom, in order, until they're "done" (the program runs to completion) and nothing is left to do. One of Node.js' great powers is to allow programmers to "schedule" things to happen outside of this simple sequential-then-done flow. A program will terminate if there's nothing left to do, but there are a number of ways to give the program something to do so that it keeps running.

Because the Tessel 2 board initialization involves hardware and I/O, it takes a few moments—considerably longer than the rest of the led.js script would take to execute. The initialization of the board won't get in our program's way—it happens asynchronously, allowing our script to keep executing statements without blocking—but we need to schedule something to happen when the board is ultimately ready.

language:javascript
board.on("ready", function() {
  // ...this will execute when the board emits the `ready` event
});

The code snippet defines a function that will get executed when ('on') the board emits the ready event.

Next we need to fill in what that function should do when the board is ready to go.

Learn more: In-depth: JavaScript's Concurrency Model and Event Loop

Blinking the LED

Once the board is ready, it's time to configure an LED on Port A, Pin 5 and then tell that LED to blink. In Johnny-Five, that looks like this:

language:javascript
board.on("ready", function() {
  var led = new five.Led("a5");
  led.blink(500);
});

Instances of Johnny-Five's Led class have some handy tools (attributes and methods) for doing LED things—for example, blink..

This code creates a new Led object and tells it what pin to use (in this case "a5"). Then it tells the LED to blink every 500 milliseconds (half a second). That means the LED will cycle 500ms off, then 500ms on.

Comparing Node.js + Johnny-Five With Arduino Sketches

The structure of Node.js scripts written with Johnny-Five differs from how Arduino sketches are written in the Arduino Programming Language. The following is an example sketch in the Arduino Programming Language that would make an LED blink on and off (assuming that LED was connected to pin 13 of a theoretical board):

language:cpp
void setup() {
  pinMode(13, OUTPUT); // Set up pin 13 as an OUTPUT pin
}

void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH puts voltage on the pin)
  delay(500);               // wait for a half second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(500);               // wait for a half second
}

Arduino sketches have two sections:

  1. setup: runs once and is a place for configuring pins and initializing stuff
  2. loop: runs over and over and over and over

Another thing you'll notice is that Arduino code is lower-level, meaning that there are fewer abstractions of specific hardware details. Instead of having an LED object that can do LED-like things (blink, pulse, fade, etc.), you interact directly with the digital pin and write LOW and HIGH states to it.

Between those digital writes, you tell everything to stop and wait for 500 milliseconds (delay). And the thing about delay is: it stops everything. It's a process-blocking operation. Nothing else can happen while delay, well, delays.

In terms of code complexity, the difference between Johnny-Five and the Arduino Programming Language isn't too significant when you're just blinking an LED, but when it comes to pulsing an LED, Arduino sketch code starts getting more complicated.

Pulsing an LED

Now that we've covered the basics and some of the lower level technical aspects of Johnny-Five, let's write a program that pulses the LED. Instead of blinking the LED on and off, pulsing fades the LED smoothly from off to on, and then from on to off again.

Pulse Width Modulation (PWM)

The state of a digital output pin can only be one of two things: LOW or HIGH. That means, at any given exact moment, an LED connected to the pin can only be off or on. We fool the eye into thinking an LED is dimmed to, say, half brightness by using a technique called Pulse Width Modulation (PWM)

With PWM, the pin can be switched between HIGH and LOW very quickly, causing the LED turn on and off, too. This cycle between on and off happens too fast for the human eye to discern. The percentage of time that the pin (with the LED attached) is HIGH (on) over a given period is its duty cycle. A 30 percent duty cycle (on — or HIGH — 30% of the time) will make an LED look like it's partially lit — dimmer than bright but definitely on. By adjusting the duty cycle over time, we can fake (very convincingly!) an LED fading on and off.

Only certain pins on development boards support PWM. On the Tessel 2, pins 5 and 6 on both ports (A and B) support PWM.

Pulsing an LED With Arduino

Pulsing an LED in an Arduino sketch (Arduino Programming Language) requires more effort than blinking. Much has changed here from the blinking sketch, but certain things remain the same. There is still a process-blocking operation (delay), this time for 30ms on each loop cycle. We can no longer use the digitalWrite() function (it can only write binary LOW or HIGH); instead we'll need the analogWrite() function for writing PWM values from 0 (0% duty cycle) to 255 (100% duty cycle). There are also now three variables to keep track of: led for the pin number, brightness to track the present brightness state, and lastly fadeAmount which holds the increase or decrease value to be applied to the value of brightness. Whew!

Here's what that looks like all together:

language:cpp
int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

void setup() {
  pinMode(led, OUTPUT);
}

void loop() {
  analogWrite(led, brightness);

  brightness = brightness + fadeAmount;

  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ;
  }

  delay(30);
}

It may be hard to get your head around the logic in that program. It's not that easy to read. It doesn't scream "pulse an LED" in the way that it expresses itself, does it?

Pulsing an LED With Johnny-Five

Let's see what pulsing an LED looks like in Johnny-Five. Open your led.js script again. You'll need to edit one line. Change the line that currently reads:

led.blink(500);

to

led.pulse(500);

No kidding—that's it! No need to keep track of things, handle scheduling and timing or do arithmetic—instances of Johnny-Five's Led do it all for you. Like blink, the pulse method takes an argument that is the pulse period in milliseconds. Here is the complete script for your copying-and-pasting convenience:

language:javascript
var Tessel = require("tessel-io");
var five = require("johnny-five");

  var board = new five.Board({
    io: new Tessel()
  });

  board.on("ready", function() {
    var led = new five.Led("a5");
    led.pulse(500);
  });

Remember, to run the script and see your LED pulse, type — or copy and paste — the following command in a terminal:

t2 run led.js

What You Should See

Your LED should be pulsing in 500ms period cycles.

Building Further

Try adjusting the speed passed to the led.blink() and led.pulse() calls. For example: led.blink(1000) or led.pulse(1000) would change the cycles to 1000ms periods.

Reading Further