Retired - Electric Imp Breakout Hookup Guide
This Tutorial is Retired!
An electric imp hug! Provides an overview of the imp card and breakout. Both hardware and firmware subjects are covered.
View the updated tutorial: Retired - Electric Imp Breakout Hookup Guide v2
impRoduction
The electric imp is a deviously awesome development platform. Disguised as an every day SD card, the imp is actually a unique combination of microprocessor and WiFi module. The imp makes connecting any device to the Internet a breeze. Looking to catch on with this "Internet of Things" fad? The imp is an excellent place to start.
In this tutorial, we'll be explaining how to use the imp with one of our Breakout Boards. This simple PCB assembly houses the bare minimum you might need to get an imp up-and-running. First, we'll cover how to hook up the hardware end of the imp/Breakout combo. Following that we'll head over into the firmware domain, programming the imp to blink LEDs and read analog and digital inputs. The last code example shows off the coolest part of the imp: controlling hardware over the Internet!
Requirements
Of course, you'll need an imp and a Breakout Board. Aside from those two parts, we'll use a few common electronics parts you may already have. Here's a wishlist of everything we'll be using. If you'd like to use some parts you may already have around the house
In addition to those items, you'll also need the following non-SparkFun materials:
- Wireless network with Internet access
- electric imp planner account (sign up is free/easy)
- electric imp planner website pulled up in your web browser
- SmartPhone w/ the electric imp app (Android or iOS)
Tools
There will be some soldering involved. The Breakout Board does not come with header pins soldered on, which you'll need in order to interface with the imp's I/O pins. You'll need a simple soldering iron and a bit of solder. (If you've never soldered before, this is a great place to start! The solder points are easy, through-hole jobs.)
Before We Begin
This tutorial builds upon some basic electronics concepts. If you aren't familiar with any of the topics below, consider reading through that tutorial first:
- How to Solder - Through-hole
- How to Power a Project
- Voltage Dividers
- Pulse Width Modulation
- Light-emitting Diodes
Let's start by overviewing the imp card itself. It's hard, at first, to wrap your head around the fact that this little, white SD-looking card is actually a powerful WiFi-enabled microcontroller platform.
About the imp
It may look like an everyday SD card, but the electric imp is much, much more. It's a WiFi-enabled microprocessor. It's programmable over the air. It's got GPIOs, UARTS, I2C and SPI interfaces, pulse-width-modulation, digital-to-analog and analog-to-digital converters. Basically, it's what you'd get if you smushed an ARM microprocessor and a WiFi module down into a tiny SD-card-sized package.
The imp provides an easy, integrated way to connect almost any hardware device to Internet services. It is well suited to be the backbone of your Internet-enabled project, whether you're remotely controlling your electric blanket or triggering an irrigation system via a web browser. Connecting your imp to a wireless network and programming it is a simple, streamlined process.
The Hardware: 6 Wondrous I/Os
The imp is basically made of pure awesome. But, if we lift the hood of awesomeness for a moment, we can talk a bit about the imp's hardware. The platform of the electric imp is a Cortex-M3 microprocessor. Just like any microprocessor, the imp has a collection of input and output pins, each with unique functions. There are six addressable I/O pins -- not as many as an Arduino, but it makes up for it in terms of functionality. The imp has three UARTs, two I2C and SPI interfaces, and two DAC outputs; plus each pin can act as an ADC input and PWM output.
Pin # | UART1289 | UART57 | UART12 | I2C89 | I2C12 | SPI257 | SPI189 | DAC | ADC | PWM |
---|---|---|---|---|---|---|---|---|---|---|
1 | CTS | TX | SCL | SCLK | Yes | Yes | Yes | |||
2 | RTS | RX | SDA | MISO | Yes | Yes | ||||
5 | TX | SCLK | Yes | Yes | Yes | |||||
7 | RX | MOSI | Yes | Yes | ||||||
8 | TX | SCL | MOSI | Yes | Yes | |||||
9 | RX | SDA | MISO | Yes | Yes |
Of course, each of those pins can also be used as a simple inputs (with or without pull-up resistors) or outputs, sinking/sourcing up to 4mA each.
Also in that tiny SD package is a WiFi module, an antenna, and a light sensor. We'll find out why the light sensor is critical in the coming pages.
The imp is a 1.8-3.3V device, supplying it any more voltage than that can be harmful. It can require up to 400mA (worst-case), but it'll usually pull about 80mA (even 5mA in a power-save mode).
The IDE: The imp Planner
All code written for the imp is done online, in a web browser. The integrated development environment (IDE) for the imps is called the planner. Everyone can (freely) create their own account on the planner, where both your programs and your imps are kept safe and secure.
There are certainly pros and cons to this "always online" approach (though you can write and save every program locally, and upload it when you're ready). Still, it seems like a good solution for this type of platform.
The Language: Squirrel
Firmware for the imp is written in a language called Squirrel. Squirrel is an object oriented language similar to Javascript, but unlike most embedded system programming languages we've encountered (namely Arduino). Entering imp development from the world of Arduino may be somewhat jarring. There are no loop()
or setup()
functions, instead most actions are event or timer-driven.
There are tons of great examples on electric imp's wiki page, and if you're truly interested in learning Squirrel, check out the Squirrel homepage. There's also the Electric Imp API to familiarize yourself with. These are functions and libraries used to perform actions with the imp's GPIO pins and other hardware functionality.
About the Breakout
In order to use an electric imp, two pieces of hardware are required: the imp card and the impee. An impee is the piece of hardware that houses the imp. Aside from having a standard SD socket for the imp to slide into, the impee also needs to provide power to the imp, and do something with the imp's I/O pins. Our impee for this tutorial is as simple as it gets...a breakout board.
The imp breakout provides the bare minimum you should need to add an electric imp to your project. There's an SD socket, a step-down voltage regulator, and every I/O pin of the imp is broken out to a 0.1"-spaced header.
Powering the Breakout
A big chunk of the circuitry on the Breakout board is a 3.3V TPS62172 step-down regulator (and the inductor/capacitors supporting it). This regulator allows for input voltages anywhere between 3.3V and 17V (voltages in the upper end of that range may produce some heat). It can support up to 500mA of continuous current.
There are three power inputs on the board, all of which, are fed into the on-board 3.3V regulator:
- "VIN" header - This standard 0.1" header feeds directly into the 3.3V regulator.
- Battery input - These are the pins and pads labeled "+" and "-". The footprint of the two through-hole pins matches up to a PTH 2-pin JST connector, which mates with our LiPo batteries (or AA batteries). This input needs to be selected using the jumper (see below).
- USB mini-B connector - This power input should feed a clean, 5V source into the breakout board's regulator. The USB voltage supply can come from either a mini-B cable connected to your computer or a USB wall adapter. This input needs to be selected using the jumper (see below).
Setting the Jumper
To use either the battery or USB power inputs, a jumper must be set on the board. To use the jumper, first solder a 3-pin male header to the jumper pins. Then use a 2-pin jumper to span from the middle pin, to whichever of the two inputs you'd like to use.
The Breakout's Schematic
There are three main components to the breakout board: a TPS62172 step-down regulator (U2), the electric imp socket (U1), and the ATSHA204 authentication chip (U3).
Pinout
All of the imp's GPIO pins are broken out to the 0.1"-spaced header, along with a few related power pins:
- GND - Common pin for input voltage.
- VIN - Input voltage supply fed into regulator.
- PIN1 - imp pin 1 (DAC, UART1289 CTS, UART12 TX, I2C12 SCL, SPI189 SCLK)
- PIN2 - imp pin 2 (UART1289 RTS, UART12 RX, I2C12 SDA, SPI257 MISO)
- PIN5 - imp pin 5 (DAC, UART57 TX, SPI257 SCLK)
- PIN7 - imp pin 7 (UART57 RX, SPI257 MOSI)
- PIN8 - imp pin 8 (UART1289 TX, I2C89 SCL, SPI189 MOSI)
- PIN9 - imp pin 9 (UART1289 RX, I2C89 SDA, SPI189 MISO)
- CD - Card detect. This signal will connect to GND whenever a card is inserted into the socket.
- 3V3 - 3.3V output from regulator.
- GND - Common ground.
ID Chip
There's actually one more piece of hardware required of the impee: an ID chip, which provides each impee with a unique identification code. This means that every impee you encounter should include an Atmel ATSHA204 authentication chip. The imp automatically interfaces with this chip every time it boots up, so it can identify which impee it's plugged into. This actually turns out to be pretty awesome, because the program that an imp runs depends on what impee it's plugged into. If you had two impees in your house -- say controlling an irrigation system and another controlling a coffee machine -- one, single imp would run two different programs depending on which machine it was plugged into.
You shouldn't ever have to fuss with the ID chip. In fact, you can forget we ever said anything about the ATSHA204!
Hardware Hookup
The hardware hookup approach in this guide is just one of many ways to use the board. The breakout is made to be a versatile extension of the imp. You can connect whatever you want to the imp pins, and power the board however your project requires.
Solder Headers
In order to do much with the input/output capability of the imp, you'll need to solder to the broken out pins. If you want to use the imp Breakout with a breadboard or perfboard, 0.1" male headers make for a good choice. Depending on your application, you could swap the headers with wire, female headers, screw terminals, or a variety of other connectors.
We're going to solder male headers into the board, so we can use it with a breadboard later on.
Apply Power
Depending on what you want to use for your power source there are a few options here. You could use the on-board USB connector. Or you could solder down a 2-pin JST connector, and plug battery (LiPo or AA) into the board to make it mobile. If you go with either of those options, you'll also need to set the jumper.
Alternatively, you can apply power straight to the headers labeled "VIN" and "GND". This pin bypasses the jumper and goes straight to the regulator.
Plug in the imp!
Nothing too complicated about this part. Plug the imp card in so the suspicious little imp logo is facing up.
If you've got power to the board, once plugged in, the imp should start blinking orange. If there's no blinking on the card, it's probably not getting any power. Double-check that the jumper is set correctly.
What's all that blinking signify? How do we get the imp connected to our wireless network? Read on!
BlinkUp
Blink Codes
The imp has an internal red/green LED, which is used to tell the world what state it's currently in. If you've just plugged the imp in, and haven't told it how to get on your WiFi network, it should be blinking orange (red/green simultaneously). Here are the rest of the codes to look out for:
Color | Speed | imp State |
---|---|---|
Orange | 1 Hz | No WiFi settings |
Green | Single Pulse | Successfully received configuration via Blinkup. |
Red | Triple-pulse | Failed to receive configuration via Blinkup. |
Red | 1 Hz | Attempting to connect to WiFi. |
Red, Orange, Off | 1 Hz | Getting IP address (via DHCP). |
Orange, Red, Off | 1 Hz | Got IP address, connecting to server. |
Green | 0.5 Hz | Connected to cloud (turns off after 60 seconds). |
Red | 2 Hz | Connection lost, attempting to reconnect. |
None | Normal operation |
Let's make that LED blink green! Time to send a BlinkUp.
BlinkUp
To get your imp connected to your WiFi network as well as the online imp servers, you need to go through the process electric imp calls commissioning. There's a great write-up on the commissioning process over on electric imp's wiki page. Here's the gist of it, as well as a few tips.
Before you begin, you'll need to make an Electric Imp account, by visiting the planner page.
Updating the imp with your WiFi credentials is a unique process. The imp card has a built-in light-sensor, looking out of the little window on the short, flat edge of the imp. The light-sensor can be used to process small amounts of precisely modulated data in the form of a blinking light.
To generate this blinking light, you need the electric imp app installed on your smartphone (iOS or android). Go download that app if you haven't already!
Follow the directions in the app, and prepare to update the imp with your WiFi network. Then, when your settings all look correct hit the Send BlinkUp button. Then quickly place the screen of the phone as close to the imp's light sensor as possible.
If all goes well, there should be a very short green blip of the LED, followed by a few blinks of red and orange. When the imp starts blinking green once a second, you know you've got your imp commissioned yay!
Troubleshooting
If you're imp isn't yet in the blinky green phase, use the LED blink codes to find out where it's failing. Here are some recommended steps, depending on the failure point:
- Connecting to the server (orange, red, off) - Make sure there's no firewall blocking the imp's way to the Internet (and make sure your WiFi network has an Internet connection in the first place).
- Getting IP address via DHCP (red, orange, off) - Double check your WiFi password.
- Attempting WiFI connection (red) - Double check your WiFi network name (SSID).
If all of the above are set correctly, try sending the BlinkUp one more time. We've found that it helps to close out all other app, or even try resetting your phone if it continues to fail.
You can also try turning off the room lights for a moment. Pinching the imp, just above and below the light-sensor window can help as well.
Example 1: I/O Control
The electric imp can do most anything an Arduino or similar microcontroller can. It's got analog-to-digital converters, PWM, SPI, I2C, UARTs, and it even has digital-to-analog converters. In this first snippet of example code, we'll show off the basics of I/O control -- digital and anlog input/output.
Using the Planner
After sending the BlinkUp and commissioning your imp, it should show up in your planner as a lone, blue rectangle. The word "Blank" will appear in the box. The box's name will reflect the code that the imp is running.
To upload code to the imp, you need to click the "slider" icon in the top-right of the blue box, and select the code you wish to stick on there. I guess that means we need some code then?!
Example Code
The setup for this example code requires three unique components: an LED, potentiometer, and a button (plus a current-limiting resistor for the LED). Here's a fritzing diagram and schematic (click to see it bigger) for our circuit:
Make sure the imp is getting power. USB is usually the quickest/easiest way to apply power to the breakout board, but you'll need to set the jumper accordingly.
The Code
To create a new piece of code, click over to the "Code" tab of the planner. Then click the "+" in the top left and give your new piece of code a name (we'll go with "LED-Trigger-Wiper").
This'll open up a blank piece of code. Copy and paste everything from the below box, into your code window and save.
language:Squirrel
/* Digital Input, Analog Input, PWM Output Example
by: Jim Lindblom
SparkFun Electronics
date: July 15, 2013
license: Beerware. Use, reuse, and modify this code however you see fit.
If you find it useful, buy me a beer some day!
This is a simple piece of code which uses an LED, potentiometer, and button.
The LED connects to pin 1 through a 47 ohm resistor. The cathode of the LED should connect to ground.
This means writing pin 1 will turn the LED on, and writing it to 0 turns the LED off.
The button connects on one side to pin 9, and the other pin of the button goes to ground.
We'll use the internal pull-up resistors on pin 9 to bias the button high.
When the button is pressed, pin 9 should read as low.
The wiper of the potentiometer is connected to pin 5. The other two pins of the pot should be
connected to +3.3V and GND. This'll make the voltage at pin 5 adjustable from 0-3.3V.
*/
////////////////////////////////////////
// Function definitions //
////////////////////////////////////////
local ledState = 1; // Says local, but think of this as a global var. Start with LED on
// function pin9Changed() will be called whenever pin 9 goes from high->low or low->high
function pin9changed()
{
local buttonState = hardware.pin9.read(); // Read from the button pin
if (buttonState == 0) // Button will read low if pressed
{
ledState = ledState ? 0 : 1; // Flip flop ledState
server.log("Button pressed!");
}
else // Otherwise button was released, no action
{
server.log("Button released");
}
}
// Loop constantly updates the LED. If ledState is 1, we'll read the pot, and set the LED brightness accordingly.
// If ledState is 0, we'll just turn the LED off. ledState is updated in the pin9Changed() function.
function loop()
{
if (ledState == 1)
{
local rawValue = hardware.pin5.read(); // Read from the potentiometer. Returns a value between 0 and 65535.
rawValue /= 65535.0; // Make rawValue a % (and a float). The pin write function requires a value between 0 and 1.
hardware.pin1.write(rawValue); // Pin 1 is already configured as PWM, write potentiometer value
}
else
{
hardware.pin1.write(0); // Write pin 1 low -- LED off
}
// This must be called at the end. This'll call loop() again in 10ms, that way it'll actually loop!
imp.wakeup(0.01, loop);
}
////////////////////////////////////////
// Setup Stuff: Runs first at startup //
////////////////////////////////////////
hardware.pin1.configure(PWM_OUT, 0.0005, 0.0); // Configure Pin 1 as PWM output, 5ms period, 0% high (off)
hardware.pin5.configure(ANALOG_IN); // Configure pin 5 as analog input
hardware.pin9.configure(DIGITAL_IN_PULLUP, pin9changed); // Configure pin 9 as digital input (with pull-up enabled). On change it'll call function pin9changed().
imp.configure("LED Trigger Wiper", [], []);
loop(); // Call loop, and let the program go!
This'll save a copy to your account on electric imp's server. You'll now always be able to open it up, view it, and modify it by clicking on the link in the "code" tab.
The code creates a simple adjustable-brightness LED controller. The brightness of the LED is adjusted by turning the potentiometer. Pressing the button will turn the LED on and off.
Explaining the Code
If you're only used to working with Arduino sketches, this code may make very little sense, electric imp programs have a very different "flow" to them. Begin by looking at the 5 lines of code at the bottom of the program (under the "Setup Stuff" header). This is actually where our imp starts when it begins to run it's code. Everything above is simply a function definition.
Most of this code makes heavy use of the imp's pin class, which handles a lot of the I/O control. If you're used to using Arduino GPIO's, the imp's API isn't too different. You have to set the pin up as either an input or output, analog or digital. Then write or read to the pin accordingly.
At the end of the setup, we make a call to the loop()
function, which is defined above. loop()
is simple, it checks a global variable named ledState
. If ledState
is 1, we read the potentiometer voltage, and adjust the brightness of our LED accordingly. The special sauce making loop actually loop is the last line of code in the function: imp.wakeup(0.01, loop)
. The imp.wakeup
function puts the imp to sleep, but sets a timer. When the timer goes off, the loop()
function is called from the beginning. In this case we set the timer to 0.01 seconds (10ms), so loop()
should run about 100 times a second. This is really the only way to make the electric imp "loop" like an Arduino might.
The ledState
variable is flip-flopped in the pin9changed()
function. This is like an interrupt. It's called whenever the state of pin 9 changes -- if it goes from high to low, or low to high. When setting up pin 9 as a digital input, we added this function as the one to be called when the state change occurred.
Check out the comments in the code for a more in-depth overview of each function call. Or, for more information, check out electric imp's API reference.
The next example will make use of the imp's greatest feature...it's web connectivity.
Example 2: Web Control
Some of the most fun you can have with the electric imp is connecting it to the Internet, and interfacing it with web pages. In this example, we'll use a simple HTML/Javascript web page to control some LEDs connected to the imp.
The Circuit
The circuit for this example is very simple. A common-cathode RGB LED is connected to the imp's pins 1, 2, and 5 (red, green, and blue anodes respectively). Then, another basic red LED is connected to pin 9 of the imp. Don't forget to add some current limiting resistors (in the range of 50-100Ω).
The imp Code
Create a new piece of code in the imp planner, and copy/paste the code below.
language:javascript
/* Electric Imp Web-controlled LEDs
by: Jim Lindblom
SparkFun Electronics
date: July 16, 2013
license: Beerware. Please use, reuse, and modify this code.
If you find it useful, buy me a beer some day!
This is a simple electric imp example, which shows how to interface
the imp with a web page. This example code goes hand-in-hand with an
HTML webpage. Check out this page for more information:
https://learn.sparkfun.com/tutorials/electric-imp-breakout-hookup-guide/example-2-web-control
This will show how you can use html range, text, and radio form inputs
to control turn LEDs on/off, PWM them, and set a timer to turn them off.
Circuit:
A common cathode RGB LED is connected to the imp's pins 1, 2, and 5.
The red anode connects to 1 through a 47 Ohm resistor, green 2, and blue 5.
The cathode of the LED connects to ground.
Another simple, red LED is connected to the imp to imp pin 9, through
another 47 Ohm resistor. The cathode of the LED is grounded.
*/
// This function just turns all LEDs off.
function ledsOff()
{
hardware.pin1.write(0);
hardware.pin2.write(0);
hardware.pin5.write(0);
hardware.pin9.write(0);
}
// This function is accessed every time an HTML POST is received. It will parse the post
// and turn the LEDs on/off accordingly.
// The InputPort class encapsulates incoming data from the server to the imp. In order to act on the data,
// imp programs should derive a new class from InputPort and override the set() method.
// In order to use this function, an HTTP IN vimp must be connected to this
// imp's input in the planner.
class LedInput extends InputPort
{
// Use received brightness in HTML to set the LED
// the name "set" is required for this function
function set(input)
{
// Get each of the form values and store them into a
// variable. The name of these values "pin1", "pin2", "suspect", etc.
// must be set exactly in the HTML page.
local pin1Value = input.pin1;
local pin2Value = input.pin2;
local pin5Value = input.pin5;
local pin9Value = input.pin9;
local suspect = input.suspect;
local duration = input.duration;
// Next we'll PWM the RGB LEDs
hardware.pin1.write(pin1Value);
hardware.pin2.write(pin2Value);
hardware.pin5.write(pin5Value);
// Then turn the lone LED on or off, depending on the radio input
if (pin9Value == "1")
hardware.pin9.write(1);
else
hardware.pin9.write(0);
// Print a message to the server log.
server.log(suspect + " set the LED to " + pin9Value + " for " + duration + " seconds");
// Finally, set a timer to eventually turn the LEDs off
imp.wakeup(duration, ledsOff); // Call ledsOff() in "duration" seconds
}
}
// Setup stuff -- Runs when the imp starts up.
hardware.pin1.configure(PWM_OUT, 0.01, 0.0); // PWM 0.01 period, 0% on
hardware.pin2.configure(PWM_OUT, 0.01, 0.0); // PWM 0.01 period, 0% on
hardware.pin5.configure(PWM_OUT, 0.01, 0.0); // PWM 0.01 period, 0% on
hardware.pin9.configure(DIGITAL_OUT); // Set as digital out
hardware.pin9.write(0); // Write low
// This sets up the info in the planner. This will name the imp
// "LED Web Controller", and give it an input. An HTTP IN vimp's output
// must be connected to the input of this imp.
imp.configure("LED Web Controller", [ LedInput() ], []);
Don't forget to upload the new code by clicking the "slider" icon of your imp in the planner and selecting the name of the saved code.
Again, check the comments for a line-by-line discussion of what the code is doing. This time, most of the action happens in the InputPort-extending LedInput class definition. Because we're using the InputPort class, we'll need to do a little extra setup in the imp planner (see the next section).
Setting Up the imp Planner
This imp code makes use of the imp's InputPort class. When using either that or the OutputPort class, a bit of extra setup is required in the imp planner. These classes take action on data coming in or out of the imp.
In this example, to get data into the imp, we need to add a virtual imp (vimp) block to the planner. To do so, first click the add node button, in the top left corner of the planner. And select the HTTP in block. This should add a green rectangle to your planner named "HTTP In". Click on the small tab on that block with a "+" on it. That will allow you to connect the output of the HTTP IN block to the input of our LED Web Controller block.
Making an HTML Page
Now, the last step is making a simple web page to control the imp. No servers are required for this bit of magic, just a computer with a web browser. Copy this HTML code and save it into a new file with an ".html" or ".htm" extension (or click here to download a copy of your own).
<html>
<head>
<script>
// This function is accessed when our form is submitted.
// It should read all values from the form, and construct a JSON string
// which our Electric Imp will later parse.
function sendForm(form)
{
// Get values from the form, store into variables
var redValue = form.redIn.value;
var greenValue = form.greenIn.value;
var blueValue = form.blueIn.value;
var pin9Value = form.pin9[0].checked? 0 : 1; // Equals 0 of Off checked, else 1 if On
var time = parseInt(form.timeIn.value); // Turn this value from string to integer
var suspect = form.suspect.value;
// Construct the JSON string in form.value
form.value.value = "{ \"pin1\": " + redValue +
", \"pin2\": " + greenValue +
", \"pin5\": " + blueValue +
", \"pin9\": \"" + pin9Value + "\"" + // Must add quotes (escaped with \) to make value a string
", \"suspect\": \"" + suspect + "\"" +
", \"duration\": " + time +
" }"
form.submit(); // Submit our JSON-constructed form
}
</script>
</head>
<body>
<form name="leds" action="https://api.electricimp.com/YOUR_URL_HERE" method="post">
<input type="hidden" name="value"> <!-- All imp inputs must have a form input named "value" -->
Red (0-1): <input type="range" name="redIn" min="0" max="1" step="0.01"><br>
Green (0-1): <input type="range" name="greenIn" min="0" max="1" step="0.01"><br>
Blue (0-1): <input type="range" name="blueIn" min="0" max="1" step="0.01"><br>
Lonely Red LED: <input type="radio" name="pin9" value="0" checked>Off
<input type="radio" name="pin9" value="1">On<br>
How long should the LEDs stay on? <input type="text" name="timeIn" value="10">seconds<br>
Your name? So we know who to blame! <input type="text" name="suspect" placeholder="Your name here"><br>
<br>
<input type="button" value="Update!" onClick="sendForm(this.form);">
</form>
</body>
</html>
Before opening your new HTML file in a web browser, you'll need to edit one piece of it, so open it up with a text editor (it could be as simple as Notepad or TextEdit). Towards the end of that file is this line:
<form name="leds" action="https://api.electricimp.com/YOUR_URL_HERE" method="post">
You need to replace the URL in the "action" option with the URL of your "HTTP In" vimp. To find that, click the "slider" of your "HTTP IN" vimp and look at the window that pops up.
In that, there should be a long, funky URL. Copy that into your HTML file and save.
Now you can open the HTML file in your favorite web browser. From there, you can adjust the top three sliders to change the color of the RGB LED. The On/Off radio buttons turn the lone red LED on or off. The duration text box will turn all LEDs off after a set number of seconds. And the name textbox will print your name in your imp's server log. Try it out!
This example provides a nice selection of some of the form inputs you can send to the imp. The code in the HTML file isn't as simplistic as we'd like (the form calls a javascript function, which assembles a JSON string for the electric imp to parse), but it works! And stuff should be pretty copy/paste-able if you want to try modifying it to make it your own.
Example 3: Web Response
In the previous example, we used a web page to send data to the imp. But what if you wanted to send data from the imp, back to a web page? This example shows how to use the imp to post a response to a web server.
The required materials for this example include everything from the last circuit, plus access to a web host with PHP installed. That part we'll leave up to you, our lovely reader. There are places around the world-wide-web which offer such services for free. You probably won't get a fancy domain, but you do get a private home on a shared web server.
Adding to the imp Code
There are actually only about three lines, on top of the code from the previous example, required to send data out to a server. Where before we used the InputPort class to bring data into the imp, this time we'll use the OutputPort class to send data out.
First, near the top of our code, we need to define an output port variable:
local output_suspect = OutputPort("Suspect", "string");
Then, to actually send something to the output, we need to call the set()
function:
output_suspect.set(suspect + " set the LED to " + pin9Value + " for " + duration + " seconds");
Lastly, we need to add our new output to the imp in the planner. This is done using the imp.configure()
function:
imp.configure("LED Web Controller/Reporter", [ LedInput() ], [output_suspect]);
See if you can spot those three lines of code in the full program below (copy/paste this as a new code in your imp planner):
language:javascript
/* Electric Imp Web-controlled LEDs with Response
by: Jim Lindblom
SparkFun Electronics
date: July 16, 2013
license: Beerware. Please use, reuse, and modify this code.
If you find it useful, buy me a beer some day!
This is a simple electric imp example, which shows how to interface
the imp with a web page. This example code goes hand-in-hand with an
HTML webpage. Check out this page for more information:
https://learn.sparkfun.com/tutorials/electric-imp-breakout-hookup-guide/example-2-web-control
This will show how you can use html range, text, and radio form inputs
to control turn LEDs on/off, PWM them, and set a timer to turn them off.
After receiving input from the html page, the imp will produce a response
on the OutputPort. This can be relayed to an HTTP Request vimp, which
can post the data to a php script on a web server.
Circuit:
A common cathode RGB LED is connected to the imp's pins 1, 2, and 5.
The red anode connects to 1 through a 47 Ohm resistor, green 2, and blue 5.
The cathode of the LED connects to ground.
Another simple, red LED is connected to the imp to imp pin 9, through
another 47 Ohm resistor. The cathode of the LED is grounded.
*/
// This function just turns all LEDs off.
function ledsOff()
{
hardware.pin1.write(0);
hardware.pin2.write(0);
hardware.pin5.write(0);
hardware.pin9.write(0);
}
// Output port to send something
local output_suspect = OutputPort("Suspect", "string");
// This function is accessed every time an HTML POST is received. It will parse the post
// and turn the LEDs on/off accordingly.
// The InputPort class encapsulates incoming data from the server to the imp. In order to act on the data,
// imp programs should derive a new class from InputPort and override the set() method.
// In order to use this function, an HTTP IN vimp must be connected to this
// imp's input in the planner.
class LedInput extends InputPort
{
// Use received brightness in HTML to set the LED
// the name "set" is required for this function
function set(input)
{
// Get each of the form values and store them into a
// variable. The name of these values "pin1", "pin2", "suspect", etc.
// must be set exactly in the HTML page.
local pin1Value = input.pin1;
local pin2Value = input.pin2;
local pin5Value = input.pin5;
local pin9Value = input.pin9;
local suspect = input.suspect;
local duration = input.duration;
// Next we'll PWM the RGB LEDs
hardware.pin1.write(pin1Value);
hardware.pin2.write(pin2Value);
hardware.pin5.write(pin5Value);
// Then turn the lone LED on or off, depending on the radio input
if (pin9Value == "1")
hardware.pin9.write(1);
else
hardware.pin9.write(0);
// Print a message to the server log.
server.log(suspect + " set the LED to " + pin9Value + " for " + duration + " seconds");
output_suspect.set(suspect + " set the LED to " + pin9Value + " for " + duration + " seconds");
// Finally, set a timer to eventually turn the LEDs off
imp.wakeup(duration, ledsOff); // Call ledsOff() in "duration" seconds
}
}
// Setup stuff -- Runs when the imp starts up.
hardware.pin1.configure(PWM_OUT, 0.01, 0.0); // PWM 0.01 period, 0% on
hardware.pin2.configure(PWM_OUT, 0.01, 0.0); // PWM 0.01 period, 0% on
hardware.pin5.configure(PWM_OUT, 0.01, 0.0); // PWM 0.01 period, 0% on
hardware.pin9.configure(DIGITAL_OUT); // Set as digital out
hardware.pin9.write(0); // Write low
// This sets up the info in the planner. This will name the imp
// "LED Web Controller", and give it an input. An HTTP IN vimp's output
// must be connected to the input of this imp.
imp.configure("LED Web Controller/Reporter", [ LedInput() ], [output_suspect]);
Servers and PHP Scripts
As embedded electronics engineers, this web "stuff" is the hard part for us. This is the part of the example where you need a web server with PHP installed. Somewhere on that server, make a new PHP file (we called ours "impIn.php"). Then copy/paste the below PHP script into it:
language:php
<?php
/* Electric Imp POST Example */
if(isset($_POST['value']))
{
$fd = fopen('impdata.txt', 'a');
if(flock($fd, LOCK_EX))
{
fwrite($fd, $_POST['value'] . " at " . gmdate('Y-m-d H:i:s') . "\n");
fflush($fd);
flock($fd, LOCK_UN);
}
fclose($fd);
}
?>
You'll probably also have to CHMOD that file (and any folder it might live in), to allow the proper users to execute it (all FTP clients should have a means for setting this property).
Setting Up the Planner
One, last step! We need to add another virtual imp (vimp) block to our planner. This time, in addition to the "HTTP IN" block from the last step, we need to add an "HTTP REQUEST" block.
Once it's added, attach the output of the imp to the input of the "HTTP REQUEST" block (click the "+" on the blue imp block, and connect the arrow to "HTTP REQUEST"). Then click the request block's "slider" and paste the URL (e.g. http://www.yourdomain.com/impIn.php) of your new php script into the blank URL box.
That's it! Now pull the HTML page from the previous example back up. It should still control the LEDs connected to your imp, however now it'll log some info to a text file on your web server. Point your browser to the same folder that your PHP file lives in, but instead go to a new file named "impdata.txt" (e.g.: http://www.yourdomain.com/impdata.txt). This file should have a line of text in it; something like: Jim set the LED to 1 for 100 seconds at 2013-07-19 18:40:19
. That was generated by our PHP script, and a new line will pop up every time you update the LEDs.
If the HTTP request is successful, the "HTTP REQUEST" block in your planner should show the number "200" inside it. If, instead, it's showing an error code, there are a few things you can check:
- If it's showing a 404 make sure you've entered the URL of your PHP script correctly.
- If you're getting an error 500, double, triple, quadruple-check that the permissions of the PHP file (and the folder it may be in) will allow you to execute it. (This was the biggest stumbling block for us.)
Going Further and Resources
Now that you know how to hook up the electric imp and its Breakout, what project will you be making with it? Will you be adding to the "Internet of Things"? Need some inspiration? Check out some of these products and projects:
- Using the OpenSegment - The OpenSegment displays are very easy-to-use 4-digit 7-segment displays. You could easily connect these to an imp via either serial, I2C, or SPI.
- The Uncertain 7-Cube - This project uses an Arduino to create a riff on the magic 8-ball. Swap out that Arduino with an imp, and make the Uncertain 7-Cube post to twitter or something!
- WiFly Shield Hookup Guide - The imp certainly isn't the only Internet-enabling development platform out there. You could combine an Arduino with the WiFly shield to connect your Arduino to the web.
If you're looking to interface an electric imp with an Arduino, check out the Electric Imp Shield. We've also written a tutorial on communicating via serial between the imp and Arduino.
Resources
The folks at electric imp have loads of great resources on their wiki. Among the many links on that page, these ones stand out for being extra helpful:
- electric imp API Reference - Here you'll find all of the imp-specific functions.
- electric imp Developer Forums - There's a wealth of knowledge in the imp community. If you've got a question, search for an answer here, or start a new topic.
- Imp Card Spec Sheet - A good datasheet for the imp. You'll find electrical characteristics here, along with other useful info.
If you're still left with imp-related questions, try consulting their forums.