SparkFun Inventor's Kit for Edison Experiment Guide
Experiment 6: RGB LED Phone App
In the previous experiment, we used WebSockets to create a connection from a client (browser) to the server (Edison). With them, we can send data back and forth to control a simple LED.
In this experiment, we introduce the concept of Web Apps, which are applications designed to run in a browser. Specifically, we will create an HTML application intended for a smartphone. Because the application is written in HTML, it should be capable of running on most phone operating systems, including iOS, Android, and Windows Phone/Mobile.
In addition to the Edison and Block Stack, you will need the following parts:
- 1x Breadboard
- 1x RGB LED
- 3x NPN Transistor
- 3x 1kΩ Resistor
- 3x 100Ω Resistor
- 12x Jumper Wires
- Web App Using Intel® XDK -- Creating a simple Web App using the XDK
- Pulse-width Modulation -- How PWM works, and how to use to control the brightness of an LED
We will cover hybrid apps (with Cordova) in a future exercise.
Web App Libraries
In previous examples, we included libraries by adding the appropriate name and version (usually found from npmjs.com) into the package.json file. This told the XDK to download the Node library, build it (if needed), and transfer it to the Edison along with the other necessary program files.
When building a web app, it is often necessary to include other pieces of code as a library, much like we did with Node modules. However, the XDK does not have a good way of automatically knowing which libraries to find when it comes to web apps. As a result, we will need to manually download the library (often packaged as a .js file) and include it with the project files.
The brightness of an LED is controlled by the amount of current flowing through it. LEDs, generally, have a fixed voltage drop across their anode and cathode. In order to fix the amount of current, we usually need to choose the right resistor for the LED.
In our previous circuit, we used just the red channel of the RGB LED, which we will assume is 1 LED. We found that the red LED has a voltage drop of about 2.0V, and by using a 100Ω resistor and a 3.3V rail, we could get 11mA to pass through the resistor (well below its maximum current rating of 20mA.
Now, we want to add 2 more LEDs into the mix. The green and blue LEDs (all packaged within the same RGB LED housing) have a voltage drop of about 3.2V (according to the RGB LED datasheet). If we connect a 100Ω resistor to each of the green and blue LEDs and connect that to the 3.3V rail through a transistor (like we did for red), we would end up with almost no current flowing through them. They probably wouldn't turn on!
That can't happen! So, we need to increase the rail voltage that we are using for the green and blue LEDs (and not for the red channel). We will connect the collector of the transistors for green and blue to the VSYS rail, which is nominally 4.2V.
Now, we should have some current flowing through our green and blue LEDs. We can calculate that voltage drop across the 100Ω resistor:
With that, we can calculate the current flowing through the resistor (and, as a result, the LED):
8mA is not exaclty the same as the current flowing through the red LED (11mA), so the brightnesses will be different. For our purposes, it will be good enough to demonstrate how to mix red, green, and blue into different colors.
Pulse Width Modulation
In addition to controlling the current, we can also rapidly turn the LED off and on to give the appearance of a dimmer LED. This is known as "Pulse-Width Modulation" (PWM). Note that we are flipping the LED off and on so fast that generally our eyes cannot see the flickering.
We adjust the "duty cycle" of this flipping process in order to control the brightness. Duty cycle just refers to how long our LED stays on in relation to how long it stays off.
The higher the duty cycle (e.g. 75% in the image above), the brighter the LED will appear to be. At lower duty cycles (e.g. 25%) the LED will hardly appear to be on. For a full tutorial on PWM, see Pulse-width Modulation.
In our program, we will rely on the Edison's built-in PWM functionality (using MRAA's PWM class) to control the duty cycle of the individual red, green, and blue channels of the LED.
We build upon the previous, single LED example and add another set of transistors and resistors.
Part 1: Simple Web App
Create a Web App
In the XDK, create a new project, and under HTML5 Companion Hybrid or Web App select Templates and Blank. Select Standard HTML5, and click Continue.
Give your new app a name (e.g. "XDK_MyApp"), and click Create. You will notice that the files and folders in the web app template are different from the ones in IoT project templates.
Navigate to your Downloads directory, and copy the newly downloaded .js file. Then, navigate to your project directory. In the www directory (e.g. \
In that directory, create another directory named jquery.
The XDK should now show the jQuery file in the file browser pane (if not, switch to another project and then back to the web app project to reload the file browser).
Open the index.html file (found in the www directory in the project), and copy in the code below. Don't forget to save the file (File → Save) when you are done!
Open the app.js file (found in the www/js directory), and copy in the following code. Don't forget to save the file (File → Save) when you are done!
What You Should See
To test the program in the XDK's phone emulator, click on Run My App in the right-side pane. Click on the "Play" symbol (triangle) next to Run in Emulator. The XDK Emulator should boot up and give you a phone-like interface running our web app. Click the "Push Me!" button for a (very insignificant) surprise.
In the top-left pane, you can also select the model of phone you wish to test. It may not be as good as the real thing, but it's a start!
To test the program on a real phone, we will first need to download and install the Intel App Preview from the appropriate app store. App Preview can be found here for iOS, here for Android, or here for Windows.
In the XDK, go to the TEST tab, and click on the Push Files button. This will upload the project to Intel's servers, where you will be able to download it on your phone.
On your phone, open the Intel® App Preview app (don't think about the redundancy too hard). Press the Login button, and enter your Intel® Developer Zone username and password. Press the Server Apps tab on the bottom of the screen to view your uploaded projects (at this point, you should only see one).
Press on your project's name, and you will be presented with a launch screen.
Press the rather large Play button to start your app.
And that's it! Your web app is now running on your phone. To exit, tap the screen with three fingers simultaneously.
To build and deploy your app (i.e. run without the App Preview app), navigate to the BUILD tab in the XDK. There, you will see several options on building your app. To build your program as a Web App, click the WebApp button. To learn more about building XDK apps, read this article.
Code to Note
<button id="toggle_button"> that has the id "toggle_button". In app.js, we assign an event handler (the function
.on()) to the
$ is short for the class
jQuery. That means
$('#toggle_button') is really
jQuery('#toggle_button') (i.e. it's just a shortcut).
The piece of code
assigned the function
toggleText() to the on click action for the
toggle_button HTML element, which we created in index.html.
Part 2: RGB Color Picker
The Web App
In the previous part, we created a simple web app to demonstrate how web apps work. You might have noticed that we did not use the Edison at all. In this part, we will need to create 2 programs: one that runs on the Edison as a server and one that runs as a client on a smartphone.
Create a new Standard HTML5 app using the Blank Template (just like we did in part 1). Then, we need to add some libraries.
First, download the uncompressed, latest version of jQuery from http://jquery.com/download/. Copy that file (e.g. jquery-2.x.x.js) to \
Second, download the socket.io client library from https://github.com/socketio/socket.io-client (click Download ZIP). Unzip the .zip file, and copy socket.io.js to \
You might have to refresh the project in the XDK (i.e. right-click in the file explorer pane and select Refresh File Tree).
In www/index.html, paste in the following code:
Save the file, and in www/js/app.js, paste in the following code:
Don't forget to save!
Create a new project (Blank template under Internet of Things Embedded Application). This code will run on the Edison. Copy in the following code into main.js:
What You Should See
Upload the Edison code to the Edison and run it. You should see a note in the console, "Server listening on port 4242". Take note of the Edison's IP address.
Open the web app project back up and run it in an emulator or your smartphone. You will be presented with a couple of fields for IP address and port number. Enter the IP address of the Edison and 4242 for the port.
Click Connect and the web app should make a connection with the Edison (assuming your phone/emulator and Edison are on the same network). If it was successful, you should see an RGB color selector appear.
Try selecting different colors, and see how the LED connected to the Edison responds!
Code to Note
In the web app, we are using jQuery again to control elements, like in part 1. We rely on
fadeOut() to make the RGB selector appear and disappear. Additionally, we use the
alert() function to make a pop-up appear letting the user that the connection failed.
You might have noticed that we used
connectIP(). The window object is pre-defined as the open window in a browser. It contains all the displayed HTML. As it turns out, we need to access a
socket object in the function
connectIP() as well as the callback for the RGB color picker. However,
socket was never declared as a global variable, and as a result, the color picker callback (
convertCallback) does not know about the existence of
socket, as it was declared in
connectIP(). This is a problem of "scope."
To solve this issue (and without creating unnecessary global variables), we create a
socket object inside the
window object (we say that
window owns a
socket object) with
window is global, we can then access
window.socket anywhere in our code! To make sure that the window.socket object exists and has a connection before we use it to send data, we rely on the conditional
convertCallback. That way, we don't throw any
undefined errors when we try to use the
In the Edison code, we use the MRAA
Pwm object to control the brightness of the RGB LED, which is created with an MRAA pin number. To find the MRAA pin number, first find the pin number as it is listed on the GPIO Block, and find the associated MRAA pin number in Appendix E: MRAA Pin Table. For example, GP12 is MRAA pin 20.
- The web app does not start -- Try it in the XDK emulator first. In the emulator, click on the "debug" button (bug icon with an 'X' in the upper-left corner), and click on the Console tab to view error messages.
- The web app won't run on my phone -- Your phone might not be supported. If it is an older phone, read about legacy phone support for the XDK.
- The web app won't connect to the Edison -- Make sure the Edison and phone are on the same network (e.g. the phone must be connected to WiFi and on the same subnet as the Edison).
- Make a modified email notifier that changes the color of the LED depending on different parameters of your inbox. For example, you could have the LED be green for 1-10 new emails and red for 11+ emails.
- Add an image to the web app that turns the LED off and back on when you press it (hint).