Wireless Arduino Programming
My latest Arduino project (not pictured above) is not very accessible for programming. I have another project in my garage that requires holding my notebook with one hand and typing with the other to upload sketches. This is quite annoying and as a result I don’t update these projects much. A few years ago I looked for wireless programming solutions but did not find any good options. Now I'm revisiting this again. Here are some of the options I considered:
Raspberry Pi and Arduino. It’s easy to add wifi to a Pi and it’s powerful, but a bit overkill for my needs as the Pi would simply act as a wifi provider for the Arduino and programmer via USB (running avrdude). And, by the time you add sd card, wifi, power, case, etc. the price is approaching $60 or more. This would be a fine solution if I needed just one but it would get quite expensive to deploy this configuration for all the projects I currently have and intend to build. I use a Raspberry Pi for my device hub/server where I need just one.
I looked briefly at spark.io core. At first it seemed to be exactly what I was looking for; it is Arduino compatible and provides wireless programming. And, the new photon model very affordable at only $20. What I don’t like about spark.io is the device is fully dependent on their proprietary cloud service for programming and communication. If they ever go out of business then all your hardware may just cease to function.
The Electric Imp is another compelling offering with built-in wifi. The Imp is not an Arduino but Sparkfun provide a shield and has a tutorial on remote programming https://learn.sparkfun.com/tutorials/wireless-arduino-programming-with-electric-imp. The Imp has a cloud architecture similar to spark.io. The imp is priced at $30 and $20 for the Arduino shield.
The Moteino from http://lowpowerlab.com/ combines an atmega and HopeRF RFM12B for wireless. They came up with a very clever solution for remote programming, which uses an external EEPROM for storing Arduino programs. A Python app sends the hex program to the Moteino via the RFM12B, where it is written to the EEPROM. Upon reset, a custom bootloader looks for programs on the EEPROM and writes to flash. The Moteino is one of my favorite solutions but I'm not sold on the RFM12B. It seems to be a somewhat obscure and does not have a lot of traction in the Arduino community. Also it’s not available from Digikey, Mouser or any of the large distributors. RFM12B runs at lower frequencies: 400/900 band. Moteino comes in a compact form factor and is very reasonable priced at $23
Jeelabs is similar solution built on the RFM12B
Flutter https://www.kickstarter.com/projects/flutterwireless/flutter-20-wireless-arduino-with-half-mile-1km-ran is low cost and long range but details are scarce and it’s unclear if, or when this may be available.
It’s not wireless but I thought I'd mention Freetronics. They use a custom bootloader to support remote programming. It’s compatible with atmega328 and the wiznet ethernet (SPI). I don't have ethernet near my project so the Freetronics solution is not an option. http://www.freetronics.com.au/pages/how-to-upload-a-sketch-to-your-arduino-via-a-network#.VMbvKyc7SkU The bootloader must be configured with an ip address at build time so it knows what address to listen on for sketches. https://github.com/freetronics/arduino-tftpboot
Rfduino is Bluetooth LE arduino compatible. I don’t see any mention of remote programming capabilities http://www.rfduino.com/
One of the earliest remote Arduino programming solutions uses XBee. The idea is to use XBee in transparent mode (essentially as a wireless serial link) so that it looks to the Arduino IDE/avrdude as if it’s connected directly to the Arduino. There are some hacks required to enable the XBee to reset the Arduino, but is overall a relatively clean solution. I've read reports that this solution does not work with Arduino Uno or any Atmega168/328 that uses Optiboot (115200 baud rate). The problem with this solution is that it is not tolerant of tx errors or latency; if a packet arrives late or needs to be resent, the bootloader can timeout, in which case programming will fail. http://www.ladyada.net/make/xbee/arduino.html Nate, of sparkfun.com improved on this solution with a custom bootloader https://www.sparkfun.com/tutorials/122
A limitation with this approach is it requires XBees in transparent (AT) mode, while packet mode (API) is where you gain a lot more features of the radio (tx ack, i/o samples, rssi, remote at etc). You can switch between transparent mode and api with series 1, so that could be an option, but not with series 2 as they require a different firmware. XBees cost around $20 + ~$10 for the breakout for the odd socket footprint and logic shifting.
After not finding any good solutions, I’ve decided to build my own solution. My plan is to use two Arduinos, where one programs the other. There is a chicken-and-egg situation here such that an Arduino can't program itself (well actually it can with a custom bootloader + EEPROM as the Moteino uses), so an additional Arduino would be required to perform the programming task. In a nutshell, the programmer Arduino would receive the sketch via some wireless or wired means, then reset the Arduino and flash the sketch (hex) via serial to the bootloader over the STK500 protocol. This is the protocol that the Arduino IDE uses (actually avrdude), well a lite version anyways. The Arduino Pro/Mini clones are only about $3 shipped on ebay so adding another Arduino to the mix seems reasonable from an economics viewpoint.
A key component of this solution is program buffering. The Optiboot bootloader has a 500ms timeout, so flashing as data is received would never work well, as timeouts would cause to the bootloader to reset and would leave the target Arduino in an inoperable/semi-flashed state. And it’s not possible to buffer the program in memory, then flash because Arduino does not have anywhere near enough SRAM or EEPROM (2KB SRAM on 328) but programs can be up to 32KB.
To solve this problem I'll write the program to an external EEPROM and verify it before attempting to flash the Arduino.
- Buildable. It should be easy to build this solution — i.e no surface mount parts or proprietary software. This solution work with a variety of layouts from a breadboard with atmega328, Arduino mini/pro, Arduino UNO etc.
- Use a standard bootloader. Initially I plan to use Optiboot for programming convenience but this could be adapted to other bootloaders. Arduino UNO is supported by default since it uses Optiboot. Additionally, any atmega328/168 can run Optiboot. Optiboot only needs to be installed once for the life of the atmega and can be done with a programmer or with another Arduino (see ArduinoISP).
- Transport independent. The idea is to support any number of wireless or even wired transports. Some wireless options may come and go but the idea is this solution is not dependent on any single technology. Initially I’ll support XBee, then perhaps Nordic and Wifi.
- Low cost. It should be possible to build one for under $15 with Nordic or low cost wifi.
- Speed tolerant. Since we are writing the program hex to an EEPROM, this solution should be tolerant of any transfer speed (subject to user defined timeout). This is important because bootloaders are not tolerant of delays and timeout. The Optiboot default timeout is 500ms.
- Fault tolerant. With wireless, the one guarantee is you can expect to TX errors at times. This solution should be tolerant of transmission errors. It will retry failed TX attempts and to support this all packet transfers will be idempotent.
- Unbrickable. It should not be possible to render the Arduino in an unrecoverable state. For example if you upload a invalid or corrupt sketch, you can recover by sending a valid sketch, just as you would if you connected via USB. Another feature of this design is it will not Flash the Arduino until it receives the entire sketch, so it will never be left in a half programmed state, which can occur with some other solutions that don’t use an EEPROM.
- Staying power. The main component of this solution (Arduino/atmega168/328) should be available far into the future. It’s impossible to predict this exactly however it’s a fact that the atmega168/328 has been the defacto Arduino microcontroller for about 10 years now. There are millions of these out in the wild and safe to say that they will not lose support (either from Arduino IDE or atmega) anytime soon. EEPROMs come and go however it should be possible to swap out an EEPROM with another component with minimal effort should a chip become end-of-life.
- Transport availability for the application Arduino. A secondary goal of this project is make the transport (e.g. Nordic, XBee, wifi, ethernet etc.) available to the application Arduino. The transport must be connected to the programming Arduino so it cannot be simultaneously connected to the application Arduino. In the case of serial devices, it’s simple to solve by proxying the communication to and from the application Arduino. However, for SPI/I2C devices this becomes more complicated. One option that might work would be to add electronics to so that the signals could be switched to either Arduino
Here are some of the wireless options I'm considering:
- Not full duplex
- Limited range. can buy with external antenna for ~$6
- Low power
- Packets up to 32 bytes
- Cheap ~$1
- SPI interface
- 3.3V (5v tolerant)
- Arduino library
The Nordics have been around for a while and it seems the only major disadvantage is it’s only half duplex. I found a fair amount of activity in the Arduino community with the Nordics.
I wrote a guide to using nRF24L01+ with Arduino
- High power consumption — might work ok with arduino power, but ideally would require a separate power source
- Inconvenient pin out — need a breakout for breadboard
- Requires serial port with default baud rate (115K), although I found an example of someone who was able to change the baud rate to 9600 to use with softserial. To use with this solution it must be able to run on softserial, so max of 19200 baud rate.
- Seems to require the wifi password in the sketch, so that’s not exactly ideal from a security standpoint.
- Supports server or client configuration, but not at the same time
- Configured with AT commands
- Instructable for setting baud rate to 9600 http://www.instructables.com/id/ESP8266-Wifi-Temperature-Logger/
These are incredibly cheap at about $3 shipped, however the support documentation is very iffy. There appears to be several different firmware version available. The command set is simple enough that no library would be needed. An huge benefit of wifi over XBee and Nordic is it can be controlled directly by a phone app.
- Low power
- Mesh networking (scales out well to many nodes)
- Full duplex
- Excellent range
- 3.3V (not 5V tolerant)
- 84–100 bytes per packet depending on radio type/firmware
- Secure (supports encryption)
- Well supported
- Not low cost, about $20 per radio + breakout $7
- Arduino library — I wrote it!
I found lots of Bluetooth HC-05 radios on ebay. These go for about $6 with shipping. These may be a possibility but range concern with Bluetooth, typically advertised as 30 feet. Bluetooth LE (Low Energy) solutions are starting to appear in the marketplace. Adafruit is selling the Bluefruit, based on the Nordic nrf8001 http://www.adafruit.com/product/1697 for $20. Bluetooth LE is compelling since it can communitate directly with an Android/iphone, but doesn’t have much of an advantage for communicating with a host pc.
CC3000 is a TI wifi chip. I found several with Arduino shields from about $15 China to $30 USA http://www.adafruit.com/product/1469
The official Arduino wifi shield is built on the HDG204 chip, however the price tag of ~$90 is hard to understand.
Comments are welcome.
To be continued…