Search
Wireless Bootloading for ATmega168/ATmega328Here 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:
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:![]() 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. ![]() On the Port Settings tab, click on Advanced. ![]() 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. ![]() 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! ![]() ![]() 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. ![]() Scroll down and set the serial interface rate to 19200. ![]() 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. ![]() ![]() 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. ![]() Click Read to pull in the contents of the new module's settings. ![]() Set the PAN ID to match the first unit's PAN ID. ![]() Scroll down and set the Serial Interface to 19200bps. ![]() 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! ![]() 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 BootloaderYou'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)![]() 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 JumperOne of the great features of this bootloader is the remote reset trick. This is based on Limor's Arduino wireless bootload tutorial.![]() Solder a jumper between the RTS pin and DIO3 on the XBee Explorer. Step 4: Wire up the Remote UnitNow we need to attach the various lines from the remote XBee to your target ATmega168. There are 5 lines that need to be wired:
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:
![]() The above image shows the 0.1uF cap wired inline with the Reset pin of the ATmega. Step 5: Screamer software![]() 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: PartyCongrats! 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).![]() 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:
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. ![]() 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. ![]() 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: ![]() 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:
Cheers! -Nathan |
||||||||
Feeds
Currency
Display prices in
Feedback
If you would like to tell us more, you can fill out our form if you need some psycho-suggestive questions. Go to the form.



























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.
xbee for arduino wireless programming (ladyada.net forums)
Programming Arduino wirelessly via XBee (arduino.cc forums)
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?
i rewrite Screamer-v2 on C#.
Works fine under Windows and Linux Mono.
http://akb77.com/g/net/screamer/
Hex file
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!
Why aren't we doing RTS on close anyway?
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?
I had somehow mixed up and swapped by base and remote xbee !!
Now everything works as it should!
Please erase all these embarrassing posts!!
http://www.vimeo.com/3293393
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.
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 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.
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.
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
Can someone tell me what should I change in the bootloader and Screamer in order to upload to atmega640?
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?