In this chapter, you are going to build a colored mood light, but instead of expressing the emotion of a single person or object, your CheerfulJ5 project is going to hook into the global CheerLights service: a social experiment that uses Twitter to synchronize the color of lights all around the world (see Figure 9-1). You’ll learn to control an RGB LED using Johnny-Five and how to connect to services like ThingSpeak and the Twitter Streaming API to incorporate real-time data from the cloud into your project.
You’ll first build and program the circuit using a standard Arduino, then explore how to take it wireless using a Johnny-Five IO Plugin to substitute a Spark WiFi Development Kit in place of the Arduino. However, the use of a Spark is optional and not required to complete the project. You could also substitute alternative hardware platforms using other available Johnny-Five IO plug-ins. To finish up, we’ll discuss options for creating an enclosure for your final CheerfulJ5 project to make it suitable for decorative use in the home or office.
The electronics for CheerfulJ5 are very simple. The components listed in Table 9-1 can be purchased individually from sites like Adafruit, Sparkfun, Maker Shed, or Amazon. But if you don’t already have some of these basics, most retailers carry their own version of a “Getting Started with Arduino” kit that typically contains everything you need. In particular, if you plan to use the Spark WiFi Development Kit to build the wireless version of CheerfulJ5, the Spark Maker Kit contains all the components needed to complete the project.
Count | Part | Estimated Price | Part Numbers |
---|---|---|---|
1 |
Arduino Uno R3 |
$25 |
MS MKSP99; AF 50; SF DEV-11021 |
1 |
Spark Photon or Core |
$20-$40 |
|
1 |
RGB LED (common cathode or anode) |
$2 |
SF COM-09264; AF 159; AZ B005VMDROS |
3 |
200–300 Ohm resistors |
$0.25 |
SF COM-08377; AZ B00E9Z0OCG |
1 |
Mini breadboard |
$4 |
MS MKKN1-B; AF 65; SF PRT-12043 through PRT-12047 |
1 |
Jumper wire kit |
$7 |
SF PRT-00124 |
1 |
A-Male to B-Male USB |
$3 |
AZ B000FW60E8; SF CAB-00512 |
1 |
3.7V LiPo battery |
$9 |
AF 1578; SF PRT-0034 |
1 |
LiPo battery charger |
$8 |
AF 1904; SF PRT-10217 |
We’ll demonstrate a sample enclosure for our CheerfulJ5 project, but this is completely optional. Feel free to make your own creative enclosure or even leave your project exposed and show off the underlying electronics. In our example, you’ll create a simple tabletop mood lamp made out of a frosted cylindrical vase that both conceals the electronics and helps to diffuse the light from the LED. Any appropriately sized glass container will work or you can even use a simple piece of tracing or diffusion paper to make your own.
Part | Estimated Price | Source |
---|---|---|
Glass vase, globe, or jar |
$3–10 |
Hobby or craft store |
Tracing paper or tissue or wax paper (alternative diffusion option) |
$3 |
Hobby or craft store |
#216 white diffusion filter (optional, for even better diffusion) |
$6 |
Sold in sheets at theatrical or photography suppliers |
An RGB LED behaves much like a standard LED, except it actually has three LEDs together inside its body: one red, one green, and one blue. You can control the brightness of each of these colored LEDs to mix the colors that you want to produce. There are two types of RGB LEDs: common cathode and common anode. Either type will work for your CheerfulJ5 project; you just have to wire it up appropriately. In our examples, we’ll be showing a common cathode LED, but it’s easy to modify the circuit to support common anode. The code is essentially the same for either type because Johnny-Five takes care of the translation for you!
The four leads on an RGB LED correspond to red (lead 1), green (lead 3), blue (lead 4), and a common connection (lead 2). Note that the common lead is the second from the flat side of the LED and is the longest of the four. A common cathode RGB LED should have its common lead connected to the ground pin on your Arduino. If using a common anode RGB LED instead, its longest lead should be connected to the 5V pin.
Let’s wire up your RGB LED and get ready for a simple test, as shown in Figure 9-2. We show the circuit wired on a mini breadboard so it will be easier to fit inside your enclosure later.
Connect leads 1, 3, and 4 of the LED to the Arduino.
Regardless of which type of RGB LED you are using, each individual LED requires its own resistor between it and the Arduino IO pins. You have some flexibility on which value resistor to use, but 200–330 Ohm resistors should be fine. The wiring diagram shown here uses 270 Ohm resistors (red/purple/brown). The RGB LED requires pulse-width modulation (PWM) to control the brightness of each individual LED so be sure to wire it up to supported pins on the Arduino (see Table 9-3).
Hardware | PWM pins |
---|---|
Arduino UNO |
3, 5, 6, 9, 10, and 11 |
Spark |
D0, D1, A0, A1, A4, A5, A6 and A7 |
Connect lead 2, the LED’s common connection, to the Arduino.
If using a common cathode RGB LED, connect lead 2 to the Arduino ground pin. If using a common anode RGB LED, connect it to the 5V pin.
Now it’s time to write some code to control your RGB and connect it to the CheerLights service.
Let’s get started by creating a bare-bones Johnny-Five application that you can build off of. If you need help installing StandardFirmata, setting up Node.js, or installing Johnny-Five, refer to the appendix.
Install Node.js, Johnny-Five, and other dependencies.
If you haven’t already done so, install Node.js, followed by the latest version of Johnny-Five from npm
. You’ll also need to install request
, which you’ll use later to query the CheerLights service:
npm install johnny-five npm install request
Be sure you have the latest version of StandardFirmata running on your Arduino.
Johnny-Five communicates with the Arduino using the Firmata protocol. StandardFirmata is generally installed by default on most Arduino boards, but can be reinstalled if necessary using the Arduino IDE.
Create a new file named cheerful.js.
We’ll start with a “Hello World” program that loads the Johnny-Five library, connects to the Arduino via USB, and then prints “Hello World” once the connection is established. Create a new file named cheerful.js and enter the code shown in Example 9-1.
var
five
=
require
(
"johnny-five"
),
var
board
=
new
five
.
Board
();
board
.
on
(
"ready"
,
function
()
{
console
.
log
(
"Hello World"
);
});
That’s not a lot of code to talk to the Arduino, so what’s going on here behind the scenes? When the five.Board
object is created, Johnny-Five automatically looks for an Arduino connected via USB. Once it’s successfully established communication with the Arduino, the ready
event is triggered. You use the on("ready")
function to listen for this event and then start executing the main portion of your application. The callback function here is where you will include the bulk of your CheerfulJ5 code later.
Let’s run a quick test to be sure everything is configured properly.
Plug the Arduino into the computer using the USB cable and run the following command:
node cheerful
The program should print “Hello World” then display a prompt awaiting input from the console. You can just press Ctrl-C a couple times to exit.
You’ve successfully established a connection to your Arduino. Now on to the fun stuff!
Johnny-Five includes an Led.RGB
class for controlling an RGB LED. The Led.RGB
class has many of the same functions as the standard Led
class, but adds additional functionality for controlling the color. Let’s add to your bare-bones application by defining an RGB LED object and setting its color:
Initialize an Led.RGB
object to represent your LED (Example 9-2).
var
five
=
require
(
"johnny-five"
);
var
board
=
new
five
.
Board
();
board
.
on
(
"ready"
,
function
()
{
var
led
=
new
five
.
Led
.
RGB
({
pins
:
{
red
:
3
,
green
:
5
,
blue
:
6
}
});
});
This code is the same as the “Hello World” program before, but once the Aruino is connected, we define an RGB LED and tell Johnny-Five that it is connected on pins 3, 5, and 6 for the red, green, and blue leads, respectively.
Alternatively, the Led.RGB
class specifies a shorthand constructor:
var
led
=
new
five
.
Led
.
RGB
([
3
,
5
,
6
]);
This version will normalize an array of pins in [r, g, b]
order to an object that is shaped like:
{
red
:
r
,
green
:
g
,
blue
:
b
}
If you’re using a common anode RGB, you’ll need to let Johnny-Five know.
Using the full constructor, set the isAnode
property to true
. After that, all other commands are the same as a common cathode RGB. Johnny-Five translates everything for you automatically!
// Initialize a Common Anode RGB LED
var
led
=
new
five
.
Led
.
RGB
({
pins
:
{
red
:
3
,
green
:
5
,
blue
:
6
},
isAnode
:
true
});
Set the color of the LED.
To set the color of the RGB LED, you make a call to Led.RGB.color()
and pass either a hexadecimal color string or an array of the form [r, g, b]
. For example, if you want the RGB to be red, you can pass the string "#ff0000"
:
led
.
color
(
"#ff0000"
);
console
.
log
(
led
.
color
()
);
Calling Led.RGB.color()
without a color value causes it to return the current red, green, and blue values. In this case, you simply log the returned object to verify that red is set to its maximum value (255) and the green and blue values are both zero.
Run the application again (node
cheerful
) and the RGB should turn red.
At this point, it might be helpful to experiment with the available Led.RGB
functions. The Node.js read-eval-print loop (REPL) provides a way to interactively run JavaScript from the Node.js command prompt.
To take advantage of this functionality, you need to inject the led
variable into the REPL so you can interactively enter Johnny-Five commands to control your LED. Add the following code inside the board.on("ready")
function:
this
.
repl
.
inject
({
led
:
led
});
Now you can execute the application again (node cheerful
) and enter commands at the prompt. For example, to make the LED blink once per second, enter led.blink(1000)
. Feel free to experiment with other Led.RGB
functions to better understand what each one does.
For convenience sake, let’s define a map of color names to hexadecimal values that can be passed to Led.RGB.color()
. To make your code more modular, put it in its own file that you can require
in your main application:
Create a new file and name it cheerlights-colors.js.
In this file, let’s define the color names supported by CheerLights, as shown in Example 9-3.
var
colorMap
=
{
red
:
"#ff0000"
,
green
:
"#00ff00"
,
blue
:
"#0000ff"
,
cyan
:
"#00ffff"
,
white
:
"#ffffff"
,
warmwhite
:
"#fdf5e6"
,
purple
:
"#a020f0"
,
magenta
:
"#ff00ff"
,
pink
:
"#ff69b4"
,
yellow
:
"#ffff00"
,
orange
:
"#ff8c00"
};
module
.
exports
=
colorMap
;
You might have to tweak the color definitions to more accurately represent each color for your RGB LED and enclosure.
Update cheerful.js to use the CheerLights color definitions.
Now, instead of setting the color directly by passing in a hexadecimal value, update your previous code to reference one of the standard color names from the color map object. The only changes are to require
the new cheerlights-colors.js at the beginning of your application and to update the call to Led.RGB.color()
:
var
colorMap
=
require
(
"./cheerlights-colors"
);
// ...
led
.
color
(
colorMap
[
"red"
]);
Now that you have your RGB LED set up and are able to control its color, it’s time to hook up your application to CheerLights!
The CheerLights service synchronizes color via Twitter messages sent to @cheerlights or using the hashtag #cheerlights. CheerLights clients around the world can listen for updated color commands and update their own color accordingly. We are going to explore two methods for listening for new color commands. First, we’ll look at how to query the CheerLights ThingSpeak API. Then, we’ll see how you can tap into the Twitter Stream directly.
ThingSpeak is an open source platform for the Internet of Things with a RESTful API for querying historical and real-time data. To simplify access to the CheerLights service, the creators of the project created a CheerLights ThingSpeak “channel” that captures and stores all incoming color messages. The CheerLights project utilizes the TweetControl App from ThingSpeak to listen to Twitter for the keyword “cheerlights” and update the CheerLights ThingSpeak channel to store the latest requested color. The ThingSpeak Channel API can be used to query for the current color so you can set your RGB LED’s color appropriately.
For CheerfulJ5, we only care about the current CheerLights color, so you need to query ThingSpeak for the last requested color value. ThingSpeak provides a last
endpoint as part of their Channel API that returns the most recent value for a ThingSpeak channel. The response is availabe as XML, JSON, and plain text.
A call to the last
endpoint is of the following format: https://api.thingspeak.com/channels/1417/feed/last.json.
You can test the Channel API by entering the RESTful API URL directly in your browser. In this case, 1417
is the ThingSpeak Channel ID for the CheerLights stream, so you can request the latest CheerLights color in JSON format. The only value you care about in the returned JSON object is field1
, which contains the last color string requested.
Let’s update your cheerful.js code to call the ThingSpeak API, parse out the returned value, and update the color of your RGB LED accordingly:
Add a function to cheerful.js that calls the ThingSpeak API.
You’ll need to define a new function called getLatestColor()
, shown in Example 9-4, that asynchronously calls the ThingSpeak API and passes the returned color to a callback function. You will use request
, a simplified Node HTTP request client, to make your calls to ThingSpeak. You first pass request
the URL to the last
endpoint of the ThingSpeak Channel API and tell it that you are expecting a JSON response. The second argument to request
is a function that is called when your API call finishes successfully. Here you extract the latest color string from field1
and return it to the getLastColor()
callback function.
function
getLatestColor
(
callback
)
{
request
({
url
:
"https://api.thingspeak.com/channels/1417/feed/last.json"
,
json
:
true
},
function
(
error
,
response
,
body
)
{
if
(
!
error
&&
response
.
statusCode
===
200
)
{
var
color
=
body
.
field1
;
callback
(
null
,
color
);
}
else
{
callback
(
error
,
null
);
}
});
}
Update LED color based on returned ThingSpeak value.
To update your CheerfulJ5 RGB LED, you just need to poll ThingSpeak at a given interval and call led.color()
with the returned result. Note that you’re only asking for the latest CheerLights color, so it’s possible that you will miss colors between calls to the API—but that’s OK for these purposes. You’ll use a standard JavaScript setInterval()
call to check the color every 3 seconds. You’ll also save a reference to the current color so you can output to the console when it changes.
Putting everything together, Example 9-5 shows the complete cheerful.js code.
var
request
=
require
(
"request"
);
var
five
=
require
(
"johnny-five"
);
var
colorMap
=
require
(
"./cheerlights-colors"
);
var
board
=
new
five
.
Board
();
board
.
on
(
"ready"
,
function
()
{
console
.
log
(
"Connected"
);
var
lastColor
=
"white"
;
var
led
=
new
five
.
Led
.
RGB
([
3
,
5
,
6
]);
this
.
repl
.
inject
({
led
:
led
});
led
.
color
(
colorMap
[
lastColor
]);
setInterval
(
function
()
{
getLatestColor
(
function
(
err
,
color
)
{
if
(
!
err
&&
colorMap
[
color
])
{
if
(
color
!=
lastColor
)
{
lastColor
=
color
;
console
.
log
(
"Changing to "
+
color
);
led
.
color
(
colorMap
[
color
]);
}
}
});
},
3000
);
});
function
getLatestColor
(
callback
)
{
request
({
url
:
"https://api.thingspeak.com/channels/1417/feed/last.json"
,
json
:
true
},
function
(
error
,
response
,
body
)
{
if
(
!
error
&&
response
.
statusCode
===
200
)
{
var
color
=
body
.
field1
;
callback
(
null
,
color
);
}
else
{
callback
(
error
,
null
);
}
});
}
Try running the application (node cheerful
) and sending color commands to @cheerlights using Twitter to watch your RGB update in sync with your Twitter messages! For example, you might tweet:
@cheerlights Let’s celebrate JavaScript by turning our @CheerfulJ5 yellow!
The CheerLights server listens for Twitter mentions and parses the color name from the message. CheerfulJ5 picks up the change and turns the LED yellow the next time it checks in with the CheerLights server (assuming another user doesn’t change the color again before your application polls the API). See Figure 9-3.
Our previous approach to getting the current CheerLights color was to poll the preprocessed ThingSpeak channel. This provides a nice, simple solution, but has a few drawbacks. The constant polling of the ThingSpeak channel is inefficient if there are no updates coming in. You could reduce the polling frequency, but that leads to longer response times once a new color command is sent. For some applications, you may also want to avoid missed colors.
As an alternative, you could instead monitor the Twitter stream directly using the Twitter Streaming API. This requires a little more work to essentially duplicate the functionality of the ThingSpeak CheerLights API, but it means you can get the updates immediately and not miss any colors.
To use the Twitter Streaming API, you need to set up a Twitter Developer account (free) and configure a CheerfulJ5 application:
Create a Twitter Developer account (free).
Go to https://dev.twitter.com and log in with your Twitter username and password. If you do not yet have a Twitter account, click the “Sign up now” link under the login form.
If you have not yet used the Twitter developer site, you’ll be prompted to authorize the site to use your account. Click “Authorize App” to continue.
Create a new Twitter Application.
Visit the Twitter Application Manager and click the “Create New App” button to get started. When defining a new application, you are requested to enter a name (e.g., “CheerfulJ5”), description, and a website. (You can enter a placeholder URL if you don’t have a public website for your project.)
Generate Twitter access credentials for your application.
You need two key pairs to access the Twitter Streaming API: the “Consumer Key/Consumer Secret” and “Access Token/Access Token Secret” for your account. These are found under the “Keys and Access Tokens” tab in the Twitter Application Manager. The Consumer Key (API key) and Consumer Secret (API secret) are automatically generated for us and are listed under “Application Settings.” To generate the Access Token, you need to click the “Create my access token” button at the bottom of the page. After doing so, the newly generated Access Token and Access Token Secret are displayed.
Save access credentials as environment variables.
It’s best not to keep your access credentials for Twitter in your source code, so let’s store them as environment variables that you can access via Node.js.
Create a file in your home directory called .twitterrc that contains your Twitter API credentials:
export
TWITTER_API_KEY
=
"your API key"
export
TWITTER_API_SECRET
=
"your API secret"
export
TWITTER_TOKEN
=
"your access token"
export
TWITTER_TOKEN_SECRET
=
"your access token secret"
To load your credentials automatically, you can add the following to your dot-rc file of choice:
source
~/.twitterrc
Install node-tweet-stream
module.
There are a number of npm
modules that allow you to easily use the Twitter APIs. There’s no need to reinvent the wheel, so let’s take advantage of one of the existing solutions. Because you are only interested in the Twitter Streaming API for this project, the node-tweet-stream
module will suffice for making your queries. You’ll just need to install it via npm
:
npm install node-tweet-stream
Replace the ThingSpeak API call with node-tweet-stream
.
The node-tweet-stream
module is very straightforward to use. You create a new twit
object and pass in the keys you generated previously. You then tell twit
what phrase(s) you want to monitor using the track()
function. Any time a matching tweet is found, an event is fired and you can capture the message using the on("tweet")
function.
To use the Twitter Streaming API in place of the ThingSpeak API call, you remove the getLatestColor()
function and associated setInterval
call. Instead, you define your twit
object, tell it to track both “@cheerlights” and “#cheerlights”, and update the RGB color when the on("tweet")
function is triggered.
Because you’re not using the preprocessed data from ThingSpeak, you have to parse through the tweet text and extract the color string manually. Inside the on("tweet")
function, you’ll need to look for an instance of a supported color string in the body of the Twitter message. To do this, extract the keys from your colorMap
object (representing valid CheerLights colors) as a JavaScript Array. Then use the Array.prototype.some()
function to iterate through each color string and check to see if it is found in the Twitter message using tweet.text.indexOf(color)
. Once a match is found, you set the RGB color with a call to led.color( colorMap[color] )
as before.
Example 9-6 shows the full modified version.
var
request
=
require
(
"request"
);
var
five
=
require
(
"johnny-five"
);
var
twit
=
require
(
"node-tweet-stream"
);
var
colorMap
=
require
(
"./cheerlights-colors"
);
var
board
=
new
five
.
Board
();
board
.
on
(
"ready"
,
function
()
{
var
lastColor
=
"white"
;
var
led
=
new
five
.
Led
.
RGB
([
3
,
5
,
6
]);
led
.
color
(
colorMap
[
lastColor
]);
t
=
new
twit
({
consumer_key
:
process
.
env
.
TWITTER_API_KEY
,
consumer_secret
:
process
.
env
.
TWITTER_API_SECRET
,
token
:
process
.
env
.
TWITTER_TOKEN
,
token_secret
:
process
.
env
.
TWITTER_TOKEN_SECRET
});
t
.
track
(
"@cheerlights"
);
t
.
track
(
"#cheerlights"
);
t
.
on
(
"tweet"
,
function
(
tweet
)
{
// grab a matching supported color in the tweet
Object
.
keys
(
colorMap
).
some
(
function
(
color
)
{
if
(
tweet
.
text
.
indexOf
(
color
)
>=
0
)
{
if
(
color
!=
lastColor
)
{
lastColor
=
color
;
console
.
log
(
"Changing to "
+
color
);
led
.
color
(
colorMap
[
color
]);
}
return
true
;
}
else
{
return
false
;
}
});
});
t
.
on
(
"error"
,
function
(
err
)
{
console
.
log
(
"Error with Twitter stream: %o"
,
err
);
});
});
Now your CheerfulJ5 updates its color in real time without a delay for polling! At this point, the CheerfulJ5 project is complete if you don’t plan to make use of a Spark WiFi device. If that’s the case, you can skip straight to the end of this chapter for suggestions on packaging the final product.
Let’s remove the need to tether your CheerfulJ5 project to your computer by replacing the Arduino with either a Spark Core or Spark Photon WiFi Development Kit.
If you haven’t already done so, you’ll need to claim your Spark device and configure it for use with Johnny-Five. Full instructions for setting up your Spark device are available in Appendix A. Our code examples here will assume that you have installed the custom VoodooSpark firmware and that Spark credentials have been saved as environment variables as suggested in the appendix.
The wiring for the Spark version of CheerfulJ5 is very similar to what you used before with the standard Arduino. But with the Spark, you can take advantage of the small form factor and fit the entire circuit on a single mini breadboard. This is very convenient when you look at putting it in an enclosure. For simplicity, you can just power the Spark from your computer (via USB) during testing and then switch to an appropriate battery later depending on which enclosure you use. But if you want to go ahead and hook up your battery, the wiring diagram here also demonstrates how you can optionally power the Spark via the vin
pin (see Figure 9-4).
Now your Spark is ready to go. Next up is to communicate with it in Johnny-Five using the Spark-io IO Plugin.
The Spark-io plug-in is a Firmata-compatible interface that allows Johnny-Five to communicate with a Spark device in the same way it would a standard Arduino. Spark-io takes care of the interface with both the Spark Cloud and VoodooSpark for us. It queries the Spark Cloud to get your device’s IP address and port. Then it uses those to connect to VoodooSpark and issue commands to the device. Spark-io can be used standalone or with Johnny-Five. When used alone, the device’s pins can be accessed directly via commands like this.digitalWrite()
. But when paired with Johnny-Five, you get the full power and functionality of Johnny-Five on the Spark!
Using the Spark-io IO Plugin is simple. Instead of using the default five.Board()
constructor, you use an expanded constructor and pass a reference to a Spark object (along with your Spark credentials) using the io
property. Once you’ve created the board using Spark-io, the rest of the code is the same as your previous example using a standard Arduino!
If you don’t have a Spark device but would like to use an alternative IO Plugin to connect another Firmata compatible device, the process is essentially the same. You just need to require the necessary plug-in and create the five.Board
with the io
property configured as required for your hardware platform. Ensure that you are using I/O pins that support PWM and the rest of the code should work without modification.
For more information on using and creating IO Plugins, visit the Johnny-Five wiki.
Let’s update your previous cheerful.js application:
Start by copying your existing cheerful.js code into a new file named cheerful-spark.js.
Require spark-io
to include the IO Plugin in your application:
var
Spark
=
require
(
"spark-io"
);
Replace the call to new five.Board()
with an expanded Spark-io constructor:
var
board
=
new
five
.
Board
({
io
:
new
Spark
({
token
:
process
.
env
.
SPARK_TOKEN
,
deviceId
:
process
.
env
.
SPARK_DEVICE_ID
})
});
Change the pin assignments for your RGB LED to use PWM pins on the Spark and specify the pins with an A
prefix:
var
led
=
new
five
.
Led
.
RGB
([
"A5"
,
"A6"
,
"A7"
]);
And you are done! Everything else is the same as before.
At this point, you have a choice to make. You’ll need to switch to battery power if you want to go completely wireless. You have several options. You can power the Spark using a mini-USB backup battery and the included USB port. This is an easy solution, but may be a bit bulky for your intended enclosure later. Alternatively, you can supply power via the Spark’s vin
pin. The Spark datasheet lists an input voltage range of 3.6V to 6.0V. Ideal sources of power can be a 3.7V LiPo battery or 4AA battery pack. Simply connect the positive wire from the battery to the Spark vin
pin and the negative wire to the Spark ground
pin (see Figure 9-5).
Now that you have a working CheerLights client, let’s finish the project by packaging it up in an attractive way. The CheerfulJ5 circuit is pretty simple and lends itself well to a variety of fun applications. This is your opportunity to be creative! Don’t feel like you have to do it exactly as suggested here. We’ll discuss a few options that will hopefully inspire your own ideas to make CheerfulJ5 unique to you. The examples here all assume you are working with the Spark implementation of CheerfulJ5 because it has a smaller form factor. But if you don’t have a Spark, don’t let that stop you! You can simply find a similar, but larger, enclosure to use. Or alternatively, you could embed just the RGB LED circuit in your enclosure and run a set of extension wires to an externally placed Arduino. Here are the steps you should follow:
First, select a container for CheerfulJ5. One option is to use a very simple enclosure to create a small tabletop mood lamp out of your project by placing your CheerfulJ5 electronics inside a frosted cylindrical vase, as shown back in Figure 9-1. The vase shown here was purchased at a local craft store. It is approximately 5” in diameter by 7” tall and works nicely to conceal the electronics, but also allows for the RGB LED to fully light the lamp.
If possible, take your CheerfulJ5 project with you to the store so you can make sure you buy a container that is large enough to completely hold the Spark, mini breadboard, and battery. For the best results, power up your RGB LED while you’re there to see how it looks inside the container. Experiment with several options, such as frosted or patterned glass, to see how your project will look.
Optionally, you may choose to add diffusing material. If you use a clear glass container or would prefer more uniform lighting, you may want to add an insert made from tracing paper, wax paper, tissue paper, or a diffusion filter. Cut the paper or filter to size, depending on the dimensions of the container, and roll it into a tube. After placing it inside the glass, it should naturally unroll to fill the container. If needed, a small piece of tape can be added to help it maintain its form. If a circle of paper is cut to cover the bottom of your container, it will help reflect light back up as well.
Finally, cover the Spark’s built-in RGB. The main onboard RGB on the Spark (the board’s status light) is a bit bright and may overpower the RGB you’re synchronizing with CheerLights. If that’s the case for your enclosure, you can fold a small piece of paper over the RGB to block it.
Don’t be afraid to think outside the box when packaging your project. You will often find inspiration in unexpected departments within your local craft store. For example, you may try CheerfulJ5 using the following alternative enclosures:
Small plastic craft container
Candle holder and wall sconce
Touch light (disassembled with CheerfulJ5 in place of the standard bulb, using the light’s existing batteries and switch)
Mounted behind a glass Christmas tree ornament
Small luminary bag
Now it’s time to place your CheerfulJ5 in a prominent place and enjoy watching the color change in sync with other CheerLights clients around the world. Because this project allows for a lot of creativity in the final packaging, we’d love to see your final project. Post your photos to Twitter and tag @CheerfulJ5.
So where do we go from here? Hopefully you’ll find the ability to integrate RGB LEDs very useful for future NodeBots projects. LEDs are a great way to provide feedback to users, communicate emotion in robotics, or just add flair to your creation. Connecting to real-time data sources in the cloud like ThingSpeak and Twitter also opens up lots of opportunities for smart and interactive robotics applications. My hope is that CheerfulJ5 has inspired you to build something amazing!