Wireless XBee/AVR Bootloading


Wireless Bootloading for ATmega168/ATmega328

Here you will read the story of my attempt to create a serial bootloader that is robust enough to be used over both wired and wireless connections to program HUGE programs (>30k code words). While not drop-in compatible with the Arduino IDE (please help out!), this wireless bootloader will work with Arduino Sketches (with an extra piece of Windows software).


How to setup and use this thing:

Things you need:

The Files:

The following tutorial was written for the ATmega168 but has been updated to work with the ATmega328 as well. This is perfect for the Arduino Mini Pros.



I need your help! I am a very bad Visual Basic scripter, not a Windows programmer. Screamer (the software that runs on the computer) currently only works under Windows. But the command structure should be portable to anything. I need help from someone to write a python script or other program that allows a command line interface to this bootloading system. Call it ScreamerCommand or some such. That way we can run Screamer from a command line, allowing implementation from Arduino IDE or from Programmer's Notepad. If you don't have VB, don't worry. The VB files listed above are readable with any test editor (search for cmdDownload_Click).

I have a printf debug style of programming. I'll program a small change, upload it to my target, then debug the program flow using printf statements. This requires two things : a good serial link, and a quick and easy way to upload new firmware.

When I decided to build a vehicle for the Autonomous Vehicle Competition, I realized it would be rather painful to be working on the rover during field testing. A laptop might get you outside, but when the rover gets more than a few feet away from you, I'm lazy and don't want to walk over to the bot just to plug in my 25' programming cable. A tethered robot is no fun. We've got these XBee units, and I keep reading about wirelessly bootloading an Arduino, so why not just use this wireless bootloader?

The problem arose when I started googling around. It seems like many people are having timeout issues with the stock stk500 serial bootloader. It simply wasn't designed to be used as a wireless bootloader. I tried. I really did! All I ever got was errors or partial loads that timed out:

avrdude.exe: stk500_getsync(): not in sync: resp=0x59
avrdude.exe: stk500_disable(): protocol error, expect=0x14, resp=0x59

In the end, I scrapped the avrdude+stk500 serial bootloader in place of my own. The resulting bootloader is lightning fast over a wired connecting (the terminal window is extremely handy!), pretty fast over a wireless connection (can't get around the XBee overhead), and able to program any size program (tested using a 14,000 code word program - around the max size of the code space including the bootloader on an ATmega168).




That's great and all, but how do I use this thing?

How to setup and use this thing:

Step 1: Configure the XBee Modules

You will need to configure the remote XBee module (connected to the AVR) and the base XBee module (connected to the computer) slightly differently. The Digi X-CTU software is a handy windows application to configure the large amount of settings on the XBee. To download, try this link or search for "x-ctu download". If you really can't find it, we have version 5.1.4.1 (25MB!) here.


Setting up the remote unit:

Plug the first XBee unit into the XBee-Explorer and attach it to the computer. You may have to install FTDI Serial drivers. Now you need to figure out what COM port it got assigned to:

http://www.sparkfun.com/tutorial/WirelessBootloader/DeviceManager-1.jpg


Device Manager


Right click on My Computer, then Properties. Click on the Hardware tab, and finally on the Device Manager button. You can also get to this by running "devmgmt.msc" from the Run command or a command line prompt. Once the device manager is open, expand 'Ports'. You will see the USB Serial Port that is the XBee Explorer. COM 109?! Wow. That is a bit high. For Screamer to work, you need to have a COM port that is 1 through 4. To force XBee Explorer from 109 to 3, right click on the USB Serial Port (COM109), and click on Properties.

http://www.sparkfun.com/tutorial/WirelessBootloader/DeviceManager-2.jpg




On the Port Settings tab, click on Advanced.
http://www.sparkfun.com/tutorial/WirelessBootloader/DeviceManager-3.jpg




Now you can change the COM port number to anything you'd like. For this example, I used COM3. COM1 is probably where your real serial port is located, so don't use that one. Note: 'Set RTS on Close' is not checked. Click on OK until you are out of all these windows. Now, every time you connect the XBee Explorer, it will use COM3.


Once complete, open the X-CTU software.

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-1.jpg

If you've got fresh XBee units, by default, they are set to communicate at 9600bps. Be sure to select your correct USB COM port!
 

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-2.jpg
 

Now click on Modem Configuration tab and click 'Read'. If you're firmware version is not up to date, I recommend choosing the latest version and upgrading both modules.

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-9.jpg


I chose a new PAN ID so that my XBees would not interface with any other default XBees in the area. Pick any ID that you like and can remember. You'll have to set the same PAN ID on the second module.
 

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-10.jpg


Scroll down and set the serial interface rate to 19200.
 

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-11.jpg


Scroll down and set DIO3 Configuration to '5 - DO HIGH'. This will cause the DIO3 pin to act as an output and toggle whenever the base unit sees a change in its DIO3 pin.

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-12.jpg
 

Set the I/O Output Enable to '0 - Disabled'. This setting will suppress the XBee module from outputting serial bytes every time the DIO3 pin changes.
 

http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-14.jpg

 

Finally, you will need to set the I/O line passing 'Input Address' to FFFF. Click on write and make sure the settings are written successfully.

Now remove this XBee unit (from now on, it's the remote unit) from XBee Explorer and set it near your XBee breakout board and sockets.


Setting up the base unit:


Attach a second XBee unit to the XBee Explorer. I hot swap (I don't unplug the Explorer from USB) because I am a bad, lazy engineer.

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-8.jpg


 Click Read to pull in the contents of the new module's settings.

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-9.jpg


Set the PAN ID to match the first unit's PAN ID.

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-4.jpg


Scroll down and set the Serial Interface to 19200bps.

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-5.jpg


Scroll to I/O settings and set DIO3 to '3 - DI'. If these images look a bit different then your X-CTU, you've probably got a different firmware version loaded onto the XBee. Probably won't make a difference so don't worry!

  http://www.sparkfun.com/tutorial/WirelessBootloader/XCTU-6.jpg


Set the DIO Change Detect to 8. This will monitor 0x08 or pin 3 (in binary: 0000.1000) for any changes. Now click write and be sure the parameters are written successfully.

Leave this XBee unit in the Explorer - this is your base unit. Now whenever you power up these XBee units, they will search each other out and automatically form a direct point-to-point serial link!


Step 2: Program Bootloader

You'll need to download and program this hex file onto an ATmega168. Connect your programmer to the AVR. If you're unsure how to attach a programmer to an AVR, we've got the tutorial for you over here. From a command line, navigate to the directory that contains Wireless_Bootloader_ATmega168.c and the Makefile and type:


make all

(This will compile the bootloader so that you have a current HEX file)


make program

(This will use attempt to use the parallel stk200 programmer over the LPT port)

  http://www.sparkfun.com/tutorial/WirelessBootloader/make-commandline-M.jpg


Be sure that everything completes without errors (as shown above). This version of the bootloader currently only works with the internal 8MHz oscillator but you can tweak the make file to your heart's content. I know programming it can be tricky, but once you have successfully loaded the bootloader onto the AVR, you'll never have to do it again!


Step 3: Solder the RTS Jumper

One of the great features of this bootloader is the remote reset trick. This is based on Limor's Arduino wireless bootload tutorial.


  http://www.sparkfun.com/tutorial/WirelessBootloader/RTSJumper-M.jpg


Solder a jumper between the RTS pin and DIO3 on the XBee Explorer.



Step 4: Wire up the Remote Unit


Now we need to attach the various lines from the remote XBee to your target ATmega168. There are 5 lines that need to be wired:

  1. Power
  2. Ground
  3. Data In (DIN)
  4. Data Out (DOUT)
  5. Reset (DIO3)
http://www.sparkfun.com/tutorial/WirelessBootloader/Remote-Wired-2-M.jpg


Here you can see the five wires soldered into an old prototype I had sitting around. You should really use a XBee Breakout Board and XBee sockets. Solder in the XBee sockets so that the XBee can live happily in the breakout board. Solder five wires from the five pins on the breakout board (DIN, DOUT, 3.3V, GND, DIO3). Remeber, XBees run at 3.3V not 5V so you will need to regulate down if your system runs at 5V.

Pin on XBee / Pin on ATMega:

  1. XBee DIN goes to ATmega TX
  2. XBee DOUT goes to ATmega RX
  3. XBee DIO3 goes to ATmega Reset (through 0.1uF cap)

The DIO3 will toggle every time the RTS pin is wiggled on the base XBee. This is used to reset the ATmega and kick off the bootloader. In order to make this work, you need to put a 0.1uF in between the DIO3 pin and the reset pin on the ATmega168. This will prevent the XBee from holding the ATmega in the constant reset state.

http://www.sparkfun.com/tutorial/WirelessBootloader/DIO3-Cap-M.jpg
 

The above image shows the 0.1uF cap wired inline with the Reset pin of the ATmega.


Step 5: Screamer software

  http://www.sparkfun.com/tutorial/WirelessBootloader/Screamer.jpg


Download Screamer
and unzip to one directory. Run Screamer-v2.exe. If windows yells at you about missing MSCOMM32.OCX or comdlg32.ocx, these extra VB files are included in the zip.

Now power your remote unit. Make sure the XBee Explorer is hooked up and happy. From Screamer, open blink-v10.hex. This is a demo program that demonstrates blink and printf commands. Select the correct COM port in Screamer (whatever your USB port may be). Then hit download! Screamer should reset the remote unit setting off the bootloader and the unit should start downloading blink-v10.hex.

Step 6: Party

Congrats! You've made it through. If you're now bootloading wirelessly, enjoy! If you'd like to learn more about how we cobbled this thing together, keep reading.


How It Works:

I'm not entirely sure how avrdude works. It might use checksums, and it might use timeout control, but I could not make a solid download work no matter how I modified the original STK500/Arduino bootloader. And since I'd rather not dig into the avrdude source, I wrote my own wireless bootloader to work with my own Windows program (complete cheating).

  http://www.sparkfun.com/tutorial/WirelessBootloader/Breadboard-Testing-M.jpg


That's a breadboard with ATmega168, a parallel port connection to program the bootloader onto the AVR, a serial connection for testing a wired serial download, and two XBees for wireless downloading. Madness.

The SparkFun Wireless bootloader does a couple of things:

  • Transmits only binary data
  • Uses checksum
  • Uses control characters with timeout checking
  • Jumps directly into a terminal window for easy debugging and control

Binary only data:

Why transmit more than we need to? I rip out all the extraneous parts of the intel hex file on the computer side and transmit only firmware codewords.

http://www.sparkfun.com/tutorial/WirelessBootloader/HEX-File.jpg

Open any HEX file. You'll see it is visible ASCII characters.

Historically, bootloaders will transmit the line length, memory address, whether or not it is the last line of the file, ~16 bytes of firmware, and a checksum. For each line. Old bootloaders would transmit 43 bytes to convey 16 bytes of firmware! This is wasteful.


  http://www.sparkfun.com/tutorial/WirelessBootloader/Screamer-VB-M.jpg


The AVR needs 128 bytes to program a page. Screamer strips out all the extra information and transmits a total of 133 bytes to convey 128 bytes of firmware.

Checksum:

Checksums protect the wireless link from corruption. If the remote unit receives a payload where the checksum is not 0, it will reject those 128 bytes and request the payload to be sent again. The SparkFun wireless bootloader uses a standard 8-bit checksum for each payload of 133 bytes. This might be a bit on the low side (16-bit would be more protection) but I haven't experienced a false positive yet.

Control characters and timeout:

The problem with many bootloaders is they are too inflexible to deal with the latency often associated with wireless links. RF is not perfect and packets can be lost. A good wireless module will buffer bytes on either end with a protocol that attempts to assure delivery. What this means is the XBee modules might have to transmit a few bytes, a couple times before they are successfully delivered to the opposite end of the link. All the while, you are throwing tons of data at their serial pins expecting data to arrive in a timely fashion. The humble XBee units are buffering all sorts of stuff, making sure the data gets where it needs to be but the protocol overhead causes time delays between delivery of data. Any RF link will make a fast data connection stream seem irregular in throughput.


Someone want to draw me a timing diagram that shows this better?


So our bootloader doesn't expect data to arrive in a regular manner. The remote unit will happily sit and wait for data. In the current version, Wireless_Bootloader_ATmega168.c waits for enough time for 15 characters to come through before it starts calling the transmission a timeout. If the XBee units (try hard! but) fail to deliver the payload that Screamer sent out, the remote AVR will ask for the last line to be resent. It's sort of a check-in/check-out system. Even if two XBee units are in a harsh RF environment, if they have thick walls between them, or if they are very far from each other, this bootloader will do its best to get the firmware there, correctly, every time.

Jumps directly to terminal window:

http://www.sparkfun.com/tutorial/WirelessBootloader/Screamer-Terminal.jpg

This is one of the great features of this bootloader. If you've used Arduino and you've been annoyed with the serial port view window (Bad java script! Bad!), you'll be pleasantly surprised by the Screamer terminal window.

No need to worry about closing hyperterminal every time you want to re-program, Screamer automatically closes the port before starting a new download, then re-ports the port in the terminal window. Seamless debugging!

Current limitations:

  • Only works at 19200 - this is easily fixable but I've found there is no speed advantage, the XBees are the bottleneck
  • 8MHz internal osc - if you need something different, tweak the makefile for Wireless_Bootloader_ATmega168 It now works with the ATmega328 at 16MHz external!
  • Base software is in VB (only for windows) - The principles of transmitting only 133 bytes per 128 can be translated to any programming language, VB was just quick and easy to whip up the GUI
  • ATmega168/ATmega328 - This bootloader can be ported to other AVRs, even other families (LPC21xx) with a little work. Mostly it is changes in the bootloader firmware and not Screamer. Only the pagesize variable needs changing for Screamer to work with any type of microcontroller.


Cheers!
-Nathan

Comments 78 comments

  • Great tutorial Nathan. Thanks!
    I couldn’t get the remote reset function working, and did some digging. I looked at the DIO3 pin on the remote xbee and discovered it was not doing anything. I had to add the following configuration change to the remote xbee:
    ATIA0
    This binds the outputs of the remote xbee to mirror the inputs of the base xbee.
    I also added the following change to the remote xbee:
    ATT35
    This causes the remote DIO3 line to return back to its default state (high) after 500ms.
    Now you don’t need the .1uF cap between DIO3 and RESET. When RTS goes low on the base unit, the remote RESET is held low 500ms and then goes back high, allowing the atmega to run.

  • I ported Screamer V2.0 to work in Linux, and added support for the ATMEGA1280, with the bootloader included. Hope this helps all the Linux user’s out there, with LScreamer, I can develop and download it all in Linux.
    Here’s a link to my simple blog
    http://mecharobotics.wordpress.com/2010/12/16/27/

  • I use 3 OS’s OS X, Ubuntu and win2k, none of which will run visual basic 2008. So I created a new version of avrdude. I’ve posted the source at http://alan.backlund.googlepages.com/sfxb_avrdude-5.6.tgz .
    Use the usual unix ./configure and make to build it (under cygwin in windows). It adds a new programmer type “sfxb” that works with Wireless_Bootloader_ATmega168.c. It requires the avrdude.conf generated by make so put avrdude (or avrdude.exe) and avrdude.conf in your working directory and run like this “avrdude -c sfxb -C avrdude.conf -p m168 -P com8 -U flash:w:Blink.hex”.
    It does not toggle rts to reset the avr, avrdude never did. So reseting can still be a problem. I plan to continue working on improving Wireless_Bootloader_ATmega168.c and avrdude.

    • I plan to continue working on improving Wireless_Bootloader_ATmega168.c and avrdude.
      Hi Alan, did you make any further progress with this project? I’m looking at integrating your changes into a more recent version of avrdude and would like to talk with you about it. Thanks.

      • I’ve been using abacklund’s patch to avrdude to bootload my remote arduino for the past 2 years and it’s been working pretty well. I recently switched to series 2 Xbees and wrote a variation of the sfxb programmer called sfxb_api that uploads to remote AVR’s over an XBee mesh network using API mode. Using API mode is required for S2 XBees since they don’t do line passing so the only way to toggle the pin to reset the Arduino was to use API mode to send explicit commands to toggle the pin. (In getting that to work, I also found a buffer overrun in the sfxb programmer that might have been why avrdude sometimes would segfault for me.)

        • Would you be willing to share some code and more information about that please? I’m trying to do exactly that with Series 2 XBees in API mode. Any help would be greatly appreciated!

          • I had a similar problem of wireless Arduino bootloading over XBee Series 2 (ZigBee) mesh network. Solved it.

            I’ve started with a patch to avrdude to support AVR code upload over XBee ZigBee mesh using API mode. I’ve put the corresponding patch to avrdude to github here https://github.com/elizarov/haworks/blob/master/avrdude-xbee.diff but I’m not using it anymore.

            Instead, I’ve written Arduino programmer that works over XBee mesh network in Java from scratch. It also has a number of utilities to manage my XBee home automation network (scan, manage, and reprogram remote devices). It has a console interface where you can do things like “discover”, “link” console to messages on your network to type text to your devices and “@name avr f:w:your-hex-file”. It is available on github at https://github.com/elizarov/xtools but unfortunately I did not find time yet to write a decent documentation (there is built in help for console commands, though, when you type ‘?’ and <ENTER>), while I’m the only one who uses it. You’ll need to have your device attached to XBee with AT firmware running at the same baud rate as your arduino bootloader, while for the programming computer I use XBee usb dongle (thank you sparkfun) and an XBee with API firmware (any fast enough baud will work - it does not have to match and I have a mix of 57600 and 115200 bootloaders in my home).

            If anybody is interested, I can spend some time writing a better documentation.

          • Sorry, I didn’t check this page for a while. I’ve put my avrdude on bitbucket, see link below.

  • I’m here to report that this worked uploading my full robot hex of 32KB with absolutely no problems!!!

    • Yay! Thank you very much for testing out the tutorial. Indeed, size of the program should not matter - the bootloader will try hard to load any size file.

  • I had some trouble understanding how the AVR chip actually handles the internals of the boot loader vs. appliction memory - why didnt the bootloader overwrite itself ?
    By reading the document “AVR109: Self Programming” available at http://atmel.com/dyn/resources/prod_documents/doc1644.pdf I gained some better understanding.
    I highly recomend reading this document!

  • Thanks, excellent project. If not completely abandoned, has anybody else tried this on Arduino Nano 3.0 and Uno (both 328)? I have tried on both with no sucess. The reset signal is obviously passing to the board, but the avrdude replies:

    avrdude: stk500_getsync(): not in sync: resp=0x00

    Serial ports tested and working fine for 57600 bod, and all the settings are correct as above.

    Perhaps, the new boards firmware cannot handle the wireless uploads? Any advise would be much appreciated.

  • I got a request for my modified version of avrdude that can program an sfxb arduino through an Xbee talking API instead of straight serial, so I put it up at https://bitbucket.org/lutorm/avrdude_sfxb in case anyone else is interested. (It also includes abacklund’s serial sfxb programmer that he posted here.)

  • Hi, I’m using the RN42-XV Bluetooth module to wireless program an Fio board but I can’t have the DTR or RTS signals working to drive the Reset pin. The Bluetooth DUN profiles don’t seem to drive the pins and the MDM SPP profile makes it impossible to use serial monitor or Arduino IDE because the device is automatically recognized as a keyboard. Does anybody have a clue ?

  • Is it possible to wireless program in API mode?

  • Hi there!

    I have maybe have a quiet stupid question. I’m new to all this fascinating programming topic. I’m a musician from Germany working on a new Show - all Techno, all fun. I’m using the EL Sequencer from Sparkfun, and 2 Xbees for wireless control. Now I want to program a wireless bootloader.

    HOW DO I PROGRAM MY EL SEQUENCER?

    I already tried a lot of different things - but I always get stuch at Step 2: Programmuung the wireless bootloader. I’m still new, but really want to get into the topic. I think I need someone who could walk me through. Can someone please help me and explain some of the basic issues to me?

  • I tried to program my Arduino Fio wirless using Xbee Pro S1. But every time I tried to upload the sketch wireless to my Arduino Fio, I always encounter this message:
    avedude: stk500_getsync(): not in sync: resp=0x00
    avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51
    I checked my config a few time and all were correct.
    Anyone have any ideas to solves this problem?
    Thank you.

    • That’s a generic “Arduino could not be contacted” message- it means the IDE failed to make timely contact with the bootloader.

      Check your serial link between the two devices- something is most likely wrong between the two points.

  • I just wanted to point out something, after setting the config for the remote unit, I wanted to change some of the things to test. I still don’t know why, but the jumper from RTS to DIO3 made some issues with X-CTU, making it look bricked.
    The funny thing (and lucky for me) is that this doesn’t happen with the base one (using the same USB explorer), since it has DIO3 as input.

  • Hi Nathan,
    looks great.
    Im using the RN-XV WiFly module, and wondering if i can do the wireless bootloading also.
    What would i need to have on the client side (i only have a Mac book).
    cheers,
    David

    • I would think you would have to modify screamer to include a port for your computers tcp/ip stack, and also be able to send the pure binary stream as a data packets. ?? Not real sure about this, Anything is possible though. I think i read some threads out there somewhere, talking about using tftp protocol with some ethernet shields, could start a path for you.

  • Hey Nate,
    If your out there, Was wondering if you might be able to chime in on a couple of questions regarding your screamer util?
    All is working well, But with v2_Screamer I’m limited to 16K of code? It gives me an error.I’m not a VB guy at all, Does Screamer source need to be updated for the 328 and 32K of code space? Can I just change the Main.Frm file on this line…
    Dim intel_hex_array(16384) As Byte,
    To
    Dim intel_hex_array(30720) As Byte,
    Save it, and be able to utilize the full space?
    Thanks in Advance.
    J

  • Hello, and thanks for the well-written tutorial!
    I am, however, unable to load code. When Screamer starts to load, the retry counter endlessly goes up, with no code words loaded. I can see that data is going in, and out of both Xbees.
    Any suggestions as to what the problem is?
    EDIT: It does load about 1024 code words, but after about 3000 retrys.
    EDIT2: When finished, it did not program flash!

  • Would this method work for uploading a program compiled in AVR Studio as a .hex file or would it need to be compiled with the Arduino libraries?

  • Ok, so I just got the new Explorer Regulated, some Series 1 XBees, and after much toiling, I finally got wireless programming of an Arduino Pro 5v/16MHz.
    I used the following 2 tuts:
    http://www.sparkfun.com/tutorials/122 (this one) (still using stk500 through Arduino IDE)
    http://www.ladyada.net/make/xbee/arduino.html (did not do RTS on COM port)
    My problem is that my Arduino will now randomly reset while the XBee is connected. It seems to be related to specific actions, but I can’t figure why.
    1. Bring Pin 3 High….Reset
    2. Use Ethernet Client (w/ Shield)…Reset
    3. A few others have caused it, but harder to replicate.
    Someone help!!! I am happy to share my experience with wireless programming.

    • Could you be sending something through the Serial link that represents the bootloader reset command for the xbee (oxo8)?

  • I just wanted to confirm that SPM_PAGESIZE is in bytes. Also what does the incoming_page_data variable represent.

    • incomingpage_data represents how much page data is sent to the bootloader at a time, which is the same size as the page size. This VB6 program, or my Python program, will send one page at a time, and won’t send the next page until the current page has successfully been written.

  • Can you have the Xbee transmit data from the micro-controller wirelessly through the USB into the computer? Or can these only be used to program the micro-controller remotely?
    For example, if the output should be a temperature can this be sent through the Xbee to the computer and have it be read that way and perhaps graphed in MATlab while it is measuring?
    I have the Xbee dongle which I believe should give me serial data, which MATLAB would be able to read.
    How can this be completed? Is there any forums/lessons/manuals that you can turn me too?
    Sorry if these are dumb questions but I am brand new at this and desperate to learn…

    • Yes you can use the Xbee to transmit any form of serial data from a micro-controller wirelessly. They have USB to Xbee dongles that you can purchase, which would fit your hardware requirements nicely.
      I’m not sure if MATLAB can read directly from a com port or not, but in either case you will have to format the serial packet coming from the microcontroller in such a way that it is easy to decipher by MATLAB.

  • Great tutorial! I was able to get this to work for the Arduino Pro board (not the mini, 5V) with the series 1 XBees.
    I wanted to mention that it’s possible to program the bootloader using only the 5V USB to FTDI cable.
    Follow this site’s instructions except the physical connections: http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
    You’re gonna want to modify the config file it has you download to include this paragraph:
    #arduino pro
    programmer
    id = “ardpro”;
    desc = “Arduino Pro BitBang”;
    type = ft245r;
    miso = 3; # CTS Brown -> D12
    sck = 0; # TXD Orange -> D13
    mosi = 1; # RXD Yellow -> D11
    reset = 2; # RTS Green -> RESET
    ;
    Note you may want to copy and paste the diecilima section because the GUI program is sensitive to correct whitespaces. Sorry for double spacing the above this comment section would have combined it to 1 line otherwise. It should be single spaced in the config, again just look at the diecilima programmer section as an example.
    After that connect with some wire the pins from the cable to the ports on the board as shown in the config. Don’t forget to connect black to GND and red to VCC.
    Finally, finish following the instructions to burn the wireless bootloader .hex file from this tutorial.
    Note: Make sure you select the right programmer: “Arduino Pro BitBang”, CPU: “ATMega328”, and fuse settings: “DA”, “FF”, “00”.
    I hope this helps those new who don’t have the ISP programmers.

  • Got this working last night, and managed to download a hex file successfully through my very bad Xbee connection. Thanks a lot for the writeup!<br />
    <br />
    A few things: I was confused first about the need for an AVR programmer to get the bootloader onto the Arduino. If you’re used to just uploading through the existing bootloader the fact that you need a special piece of equipment might escape you.<br />
    <br />
    Second, I had the same 64-bit problem with the drivers here, but looking at that USBTiny page at adafruit I found that the “1.12 drivers” there are 64-bit signed and work fine with Win7 x64 without any hassle.<br />
    <br />
    Third, Screamer wouldn’t run for me, but it complained about another .ocx file (not one of the two mentioned above). After a bit of googling I found it on the web, then it worked perfectly.<br />

    • After playing with it for a while (using the sfxb-avrdude posted above), I found that to get it to start syncing, I had to increase the initial wait in the bootloader code, and also add a little delay before sending the 0x05, otherwise the programmer never synced up. I assume this was because of the delay introduced by the Xbees over a longish, bad link. Once the programming has started, it always seems to work fine.

  • I second Rainman. I am working on a project with a ATMega328p. Just reached the 16k code limit and up came the ‘subscript out of range’ error in Screamer. Really need some help with this. Can anyone help?

  • Hi
    Over at http://funnel.cc/Hardware/FIO it’s claimed that over the air (OTA) loading doesn’t work with Digi 2.X modules but here it says they should so I hope to find out soon… since I just got an FIO and some 2.5 Zigbee Pro Digi XB24-BWIT-004 modules from DigiKey. In my case I want them to interoperate with other ZBP modules and to have the features of ZBP such as mesh networking. Has anyone else had success with FIO (purchased here) and XBee Series 2?

  • How hard would it be to get this ported to the MEGA (1280 chipset)?

  • If I want to do this, but still be able to upload thru Arduino IDE, will I have any problems if I just use 2 xbee modules programmed to pass the dio lines from one to the other, one hooked up to the DTR, RX, and TX lines on the FTDI basic breakout, and the other hooked up respectively on the arduino pro mini?
    This way, it’s a virtual connection such that its as if the ftdi basic was directly connected to an arduino.
    Amongst the many reasons I ask this, the important one is that arduino IDE 0018 no longer outputs hex files.
    So, are there any problems with this idea?

  • Has anyone gotten this to work with an XBee 900 Pro and a Fio? Many of the setting listed aren’t available and I suspect I’m out of luck.
    I see that Mark got it to work with some tweaks to the bootloader on the version 2.5 boards:
    http://homewireless.org/wp/2010/04/wireless-bootloader-for-the-funnel-io/
    But I dont have an AVR programmer to experiment with loading a new bootloader, and don’t want to buy one if someone hasn’t already gotten it to work with a 900 Pro.
    Thanks

  • I’ve been using screamer for my arduino project, very useful. however my program has become too large for Screamer’s 16k limit. I’m trying to program an ATMega328p (which as you know has 32k of flash).
    could you release a new version that allows for larger programs?

  • Great tutorial, but a quick question regarding the level shifting. I’m using a Serial Controlled Dual Motor Driver board (runs a ATMega328 at 5V) along with a XBee Explorer Regulated. So my DI/DO pins are regulated nicely, but do we need to level shift on DIO3 as well? It seems the cap generally protects it, except on toggling when it acts as a sink to allow RST to be pulled low. Is a full transistor or other level shifter needed or could we get away with a voltage divider in that case? Thanks!

  • This looks great, thanks for doing it. I hope to make use of it in a few projects. Here’s a few comments/questions:
    The executable doesn’t appear to work with the 328’s and a 16Mhz external crystal, nor do I see references to that chip in the source. Does the link go to the updated version of Screamer?
    Also I’d love to use this with Sanguino/Atmega644’s. I’ll poke around the source to see if I can realistically do this. I’ll look for the comments, but any advice on what/where to add to the code?
    Lastly, what are the chances of using this for batch programming a bunch of zigbee connected Atmegas at once. Does the checksum make it a one at a time process?
    thanks

  • Hi Nate -
    Question regarding the statement:
    “For Screamer to work, you need to have a COM port that is 1 through 4”.
    While I agree COM109 seems high, is COM 1-4 simply what you programmed, or it some limitation of the MSCOMM32.ocx?
    Since COM’s 1-4 are already in regular use on my machine, I was thinking about trying to tweek screamer to use some higher COM numbers. I don’t currently have VB loaded (but could load it if necessary). I do have C# Express, and was going to try tweeking the C# code posted by X893, but thought it might be a good idea to find out about why the COM 1-4 limitation is there in the first place…..
    Thanks
    Paul G.

  • So after doing some research this is impossible or nearly impossible to do with the series 2 Xbee modules. Stick with series 1 Xbee modules. 40 dollar mistake.

    • Just to reiterate this - yep, I tore my hair out for a couple hours with Series 2 modules. If you just need a serial cable replacement/connection, series 1 is the way to go.

  • Good morning.
    I have a comment.
    On the XBee the RTS pin is an input.
    It would not CTS (which is an output) that must connect to the DIO3?

  • If people are having trouble with programming the linux format programming issue shows open source GUI interface C# programming that can work with serial ports & could run and compile on multiple os.

  • Hi!!!
    We’re a group of reserchers workin with the 6dof athomic and Xbee module.
    the pirncipal problem that we have it’s the wireless comunication in the series xb24-b s2.
    we wonder if you could send the parameters to configurate the xb24-b with the x-ctu software.

  • great tutorial, I could follow all the steps easily but didn’t succeed in loading the blink-example with screamer. I uploaded the the wireless atmega168-bootloader to an arduinoProMini 5V following this link:
    http://www.arduino.cc/en/Hacking/MiniBootloader
    using the avr mkII which worked fine.
    Before I digg deeper: is it normal that the the LED on pin 13 starts blinking rapidly as soon as the bootloader is uploaded?

  • Hi,
    Can someone tell me what should I change in the bootloader and Screamer in order to upload to atmega640?

  • Hey Nate, excellent tuorial. In order to get my setup to work with a ‘328, I needed to 'disable’ the CTS on DIO7 for both Xbee’s. Works great !!
    Can this wireless programming being adapted to work with PICs ?? I have done it with PICs and Basic Stamps, but that required a set of Ewave full duplex radio modems which are verry expensive and big. I way prefer the Xbee’s, but they are half duplex. Can it be done using your setup and tweaking the bootloader. I was thinkin' something like a 16F873..since I have a buch of them and Screamer v2 seems to support that chip.
    Thanks

  • Does anyone know if this would be hard to use a bluesmirf module instead of the Xbee?

  • Great Work Nathan,
    I was trying to wirelessly bootload atmega32L. I burnt bootloader code into micro controller and it is giving 0x05 as it is supposed but i am unable to configure screamer software for the same. New compiled screamer with hex_size of 32k gives error 380, while your compiled screamer transmits code and displays that it did so successfully but micro controller is not getting programmed. can someone tell me how to correct this error.

  • Hi guys, you may want to re-check the tutorial I wrote that this is based off of: http://www.ladyada.net/make/xbee/arduino.html
    I’ve just update it & it seems to have fixed the flakiness problem, and kept it all Arduino/AVRdude compatible (no bootloader changes).
    You may also want to update this page with the transistor buffer I’ve added because not all XBees have the current capacity to pull the reset pin low.

  • As hinted at by CowboyBob in another post this should work for series 2 modules. You need to use the destination address in the addressing section of X-CTU to point each module at the address of the other. The reason the coordinator “dies” sending to the broadcast address is a timeout to ensure all nodes receive the data. In tests of my attempt at a commandline version of this protocol I’ve transferred a 15360 byte sketch in 25 seconds (between 2 series 2 XBees attatched to PCs directly, hopefully soon I’ll get time to test with an Arduino).

  • Oh man you gotta be kidding me….
    I had somehow mixed up and swapped by base and remote xbee !!
    Now everything works as it should!
    Please erase all these embarrassing posts!!

  • When you mention this “Screamer should reset the remote unit setting off the bootloader and the unit should start downloading blink-v10.hex. "
    Its not doing that for me. I get the message "Waiting for target IC to boot broadcast"
    So when I reach over and reset the target manually it then uploads.
    So why isn’t it sending a reset?

  • Sorry…it works only if i manually reach over and hit the reset button

  • Yeah I can’t run it twice in a row without the status saying “Waiting for target IC to boot broadcast' What am I missing here?
    Why aren’t we doing RTS on close anyway?

  • So I went to try doing this a second time and it didn’t work. I am thinking that it is because I didn’t set the lock bits properly to protect the bootloader from being overwritten. I’ll let everyone know when I get a chance in the next day or two to look at this closer.

  • I believe I have compiled this for 16 mhz. Are the only changes at the top of the c file and the top of the make file? Do I need to modify anything with the baud rate?
    Hex file

    • At 16MHz you will need to use an external oscillator. You will need to change the fuse bits within the make file. Please see our beginning embedded electronics tutorial to see how to change fuse bits.

      • Well, the fuse bits on my 168 are already set for the default arduino bootloader, and I’m just using the makefile to build the hex, and not to program.

  • great tut. screen shots correspond to reality and there is a logical sequence of the events that need to take place. Thanks much! ~B

  • i publish initial version of Screamer (Windows .NET 2.0, Linux Mono later). Protocol from VB6 version but i havn’t XBee device. I use standard bootloader protocol to arduino.
    http://akb77.com/g/net/screamer/

  • I am very interested in this, could you post the code?

  • Excellent
    i rewrite Screamer-v2 on C#.
    Works fine under Windows and Linux Mono.

  • I’ve been working on something like this for about a year now. My first pass was with a BlueSMiRF and the fast, tiny, & mega bootloader from avrfreaks.com…That got me nowhere :(
    My second pass was following the tutorial on ladyada.com using a Roboduino/Freeduino and her no wait/hang bootloader, and I got it to work, but only with very small sketches (led blinking ones)
    I am wondering if the same limitations apply here? Can you do sketches any bigger than making an LED blink?

  • Nathan it would be real easy to add in command line support to your existing vb application… in your form_load just check if commmand is not “”. Then parse the command string to set the filename and process it. If you would like help with this let me know.

  • By the way, I’ve had discussions about this topic on a couple of forums; hopefully we can connect the interested parties.
    xbee for arduino wireless programming (ladyada.net forums)
    Programming Arduino wirelessly via XBee (arduino.cc forums)

  • This is excellent, Nathan! I was stymied by the inability to make Rob or Limor’s tutorials work and eventually gave up. Hopefully someone can incorporate your work so that the existing avrdude infrastructure can be maintained.

  • Nevermind, I watched the video. Thanks!!

  • Hey, I really like this tut, and I was wondering if this would work on the FunnelIO, or any other arduino board with a change to 16mhz ext. osc.? I’m also working on a project where wireless programming would be very helpful, and I am leaning towards a FIO. I also have a pretty good amount of experience in Arduino programming.

    • Awesome question. Out of the box, this will work with FIO, but the *.c assumes internal 8MHz. So you will sacrifice some processor speed. You can easily modify the bootloader to work at 16MHz/19200bps.
      Use Funnel IO - I like it a lot! In this tutorial I use a production-failed Ardupilot (free for me!) because I need servo connections for my autonomous vehicle.