Wireless Arduino Programming with Electric Imp

Pages
Contributors: Nate
Favorited Favorite 9

Getting Started

Imp Arduino Bootloader Screen

Loading a new sketch via wireless

This tutorial will show you how to use an Electric Imp to repogram an Arduino from a webpage. Yep, you read that right. Now you can reprogram an Arduino (and an Imp) from anywhere in the world!

Picture of imp stack without yellow wire

The Electric Imp before modification for bootloading

The Electric Imp is a powerful device that allows you to connect to the internet relatively easily. For a lot of my Imp projects, I use an Arduino to handle the interface between the various bits of hardware. While reprogramming the Imp is extremely easy via their web-based IDE, reprogramming an Arduino is much more tedious and requires plugging in a computer and downloading new code. Why not use the Imp's wireless connection to push new Arduino sketches as well?

If you've ever installed an Arduino into a place that required a scissor lift, in a water tight enclosure, on the top of a building, or into a paper-mache piƱata, you understand how problematic it can be to fix that bug you never imagined. With a few bits of hardware you can have an Arduino attached firmly to the Internet of things as well as making the Imp+Arduino a heck of a lot easier to reprogram.

What in the world is Tomatoless Boots? Sorry. It's a joke first told by Rob Faludi:

Wireless is a pointless way to describe wireless. It only describes what wireless is not, not what it is. 
For example, it also has no tomatoes, so we might as well call it 'tomatoless'.

And since it's a bootloader of sorts, we decided (against good judgement) to call it Tomatoless Boots. Zomg thank you Aron Steg for writing the original Imp code. We took his code and made a few improvements to dramatically improve the bootload time and to get it to work with general Arduinos.

Required Materials

Parts you'll need:


Along with the above parts, you'll need the following tools.

This reprogramming-over-wifi trick only works with ATmega328 based Arduinos with a serial bootloader such as the Arduino Uno, Fio, LilyPad, Pro, Pro Mini, and RedBoard. This tutorial will not work with the Due, Leonardo, Micro, Galileo, or Teensy. There are probably some really good ways of getting these other boards to bootload over wifi but their bootloaders are different enough that this tutorial doesn't attempt to cover them.

Suggested Reading

Other tutorials you may want to brush up on before diving into this one:

Bootloading 101

Now for a bit of history and bootloader basics:

Optiboot logo

The Optiboot Logo

There have been lots of serial bootloaders written throughout the years for lots of different microcontrollers. I wrote one for the PIC ages ago and one to wirelessly bootload Arduinos over XBee as well. The Arduino originally used the STK500 bootloader written by Atmel(see app note AVR061) that was then updated by Peter Knight and Bill Westfield to become the shrunk down Optiboot. Optiboot and a handful of similar bootloaders are what are installed on every ATmega328 based Arduino today.

The serial bootloader is activated each time the ATmega328/Arduino is powered up or reset. For a brief period of time (about 500ms), the microcontroller will listen for a special set of characters. If it hears nothing from the computer, then the ATmega will exit the bootloader and begin to run the user's code that resides in flash memory. However, if the microcontroller hears those special characters, then it will know that a new program needs to be downloaded and begins to wait for a HEX file to be sent. Normally this communication is done while connected to a computer (via a USB to serial connection), but anything capable of attaching to the serial port on the Arduino has the option to reprogram it. The Imp can talk serial with ease, and the fact that it connects to the world wide web so easily makes it a good choice for wirelessly bootloading your board.

Hardware Connections

Bare Imp Shield

Imp Shield with no headers

The very first step is to solder the Arduino headers to the Imp shield. For more information about how to do this, checkout this tutorial.

Electric Imp Shield Schematic

Schematic for the Imp Shield

Next, we need to re-route the Imp's UART to the Arduino's serial pins (0 and 1). By default the Imp Shield connects the Imp's serial port (pins 5 and 7) to Arduino's pins 8 and 9.

Solder pads on Imp Shield

The TX and RX pads with default trace

Luckily, the genius behind the Imp shield design had the foresight to make it easy to switch pins (Jim is awesome). On the back of the shield, you'll find two jumpers labeled RX and TX. In the image above, you should see a small trace connecting the TX and RX pins of the Imp to the right pads labeled 8 and 9.

Cut solder pads

Default trace has been cut

Carefully use an exacto knife to cut the default trace. If you've never cut a trace before don't worry - it's easy! Just take your time. Cutting a trace is less like cutting through metal and more like scoring tile or scraping ice off your windshield; it takes a few passes. Once you've cut the traces, use a multimeter to do a continuity test to verify that you have indeed severed the connection between the center pad and the pad to the right.

Pads soldered together

New connections jumpered

Next, add some solder and jumper the center pads to their matching left pad. The Imp should now be wired directly to the Arduino's serial port.

Jumper wire from P1 to RST

Jumper wire added

The final hardware modification is a jumper from P1 of the Imp to RST on the shield. This will allow the Imp to reset the Arduino whenever it pulls the P1 pin low.

Full stack with jumper in place

Full stack with jumper in place

Once you've soldered the jumpers and single wire, add the Imp shield to your Arduino and connect a USB cable. Assuming you have commissioned your Imp to your local wifi, the Imp should power up, blink red, then blink green as it attaches to the Internet.


Now why did I tell you to take your time cutting the default traces? Because I made a big mistake when cutting the default TX trace. Have a second look:

Cut trace

Don't see the problem? How about now:

A bad cut trace

Uh oh...

I was going too fast, the cut I made was too long, and I ended up cutting the TX trace to the Imp. When I attached everything to my Imp bootloading failed to work; everything was timing out because the Imp never heard a response from the Arduino (because the TX trace was cut). Luckily, I had a second functioning setup, so I tested my code on that. Everything worked, so I knew it must be a hardware problem with the board I was using for this tutorial. After a few minutes of scratching my head I used a multimeter to start probing for continuity. Once I discovered TX was not connected I tracked down this bad cut.

Green wire fix

Green wire fix

With some 30AWG wire wrap wire and some hemostats, the trace was quickly repaired, and the board started working as expected.

Take extra time when cutting traces so as to not cut beyond or knick nearby traces.

Software Connections

We are going to assume that you have already commissioned your Imp and gotten it onto your local wifi. Log in to your Electric Imp account and open the Imp IDE. Here is the code you'll need to load code into the Agent:

Above is the code for the Imp Agent

And here is the code you'll need to load into the Imp Device:

Above is the code for the Imp Device

Once you've successfully loaded both bits of code, find the agent link at the top of the page. Open another browser tab, and navigate to the agent link. You should be presented with a simple HTML page:

Imp Bootloading Page

Get ready... Go!

From here you can select the hex file you would like to send to your Arduino. The HEX file is found after compiling your sketch in the Arduino IDE. We'll tell you how to get these HEX files in the next section. For now, use these two:

Download these HEX files to your local computer. Select the Blink-1Hz.hex from the 'Choose File' button, then 'Send' the file to the Arduino. After a few seconds, your Arduino should be bootloaded with the new program! The LED should be blinking once per second. Now select the Blink-Fast hex file, and upload it. The LED should now be blinking four times per second.

Output log in Imp IDE

Watch the output in the IDE

The Imp will provide various bits debug information as well during booloading. If you run into issues, be sure to check the output from the Imp IDE.

Getting HEX

By default, Arduino outputs the HEX file of your sketch to a rather hard to find, hidden, temporary folder such as C:\Users\Cylon\AppData\Local\Temp\build7734646579940080062.tmp\Blink.cpp.hex. Here's a trick to make change the output folder of Arduino to an easier to find C:\HEXFiles\Blink.cpp.hex.

Arduino Preferences Menu

Open Arduino, and click on File->Preferences. This will show you where the preferences.txt file is stored. If you move your cursor to this area of the window, the directory will turn blue, and if you click on it, you will open the directory that contains the preferences.txt file. You must close Arduino before editing this file. Every time Arduino closes, it will overwrite the preferences file with the current settings. If you edit the preferences file while Arduino is open all your changes will be lost.

Arduino properties file

With Arduino closed, open the preferences.txt. Add a line:

build.path=C:\Arduino-Output\

Or the equivalent path for your OS. Any path without spaces is valid. I enjoy pointing both my Arduino sketch folder and output folder to a dropbox folder so that I can share libraries and HEX files between computers. You will need to avoid spaces in your build.path otherwise you may see this error:

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-ar: unable to rename 'core.a'; reason: File exists

For example: build.path=C:\Arduino HEX Files\ does not work because of the spaces.

Once you have a path in place, save the changes, and close the file. Reopen Arduino, and open a sketch of your choice (use the Examples->Digital->Blink if you have no other sketches). Hit the Verify button to compile the sketch.

HEX File in list

There's the HEX file!

Now, navigate to the build.path folder. You should see a bunch of files including one with a .hex extension. This is the file that needs to be selected and sent via the Electric Imp bootloader.

Resources and Going Further

The Tomatoless Boots project is a work in progress. If you found this tutorial helpful, or if you know Squirrel and would like to help, we would love it! Please let us know. There is also a place over on Github to file issues and help make improvements. A few features that would make Tomatoless Boots even better:

  • Create a send again button: As you develop a project it's common to send the same sketch over and over again with small tweaks so it would be really handy to avoid having to navigate to the same HEX file location. If the previous HEX file location can be remembered it should be relatively easy to create a button that allows a user to send the file that resides in the same spot. For example the contents of Blink.cpp.hex may change, but I'll want to send it multiple times as I work out bugs and features. It would be nice to just hit a 'Send Again' button.

  • Pull from and poll a dropbox folder: If we can direct the Imp to monitor a page or folder location out on the Internet it would remove the need to even select the HEX file. I love dropbox, and it's possible to have Arduino export directly to a given folder (see previous section). Why not have Arduino compile to a shared dropbox folder, and when the Imp detects a status change (aka /delta), automatically bootload that HEX file to the target Arduino?

For more wireless goodness, check out these other SparkFun tutorials: