This post is being written after a pretty nasty foul-up on my part w.r.t. sending out badly-flashed ATmega chips. It’s probably too late to be of use to anyone involved in that little débâcle, but I thought I’d describe a DIY fix here in full detail anyway. I’ve simplified the code to make it even easier to use than what was described here.
So what is this about, eh?
The ATmega328 chip used in JeeNodes (and Arduino’s, and various other similar board) comes with a serial boot loader pre-loaded into the high end of its flash memory. This is arguably one the most important features that made the Arduino popular: it lets you upload a new “sketch” into the ATmega over the serial or USB port.
Lots of little details, but the point here is that the boot loader itself can’t easily be damaged, even if you load a non-functional sketch into the ATmega. Just resetting it will let the boot loader overwrite the flash memory with a new version – hopefully a better one. Basically, no matter what goes wrong, there’s always the boot loader in the ATmega to upload a new sketch to it.
There’s a chicken-and-egg problem, though: how do you get that boot loader into the ATmega in the first place? Well … you don’t. It’s normally placed there by the supplier of your ATmegas.
Since Jee Labs is one of the suppliers of JeeNodes (for Europe, and Modern Device for the US), I do need to do a little more. I use an “ISP” programmer to place that boot loader there, along with the RF12demo sketch.
But there’s really not much to all this, and this whole boot loader / ISP stuff can easily be performed by anyone. Keep in mind that’s it’s just about getting that first step right: proper fuses and the boot loader stored in flash memory. Nothing more.
All you need is a working unit and a second target unit with the ATmega that needs to be repaired (or initialized for the first time – same thing). For Arduino’s, it’s all explained at http://arduino.cc/en/Tutorial/ArduinoISP.
As it so happens, there’s now even simpler software to do this, so I’m going to describe the process in terms of using one (working) JeeNode to repair another JeeNode (note that this still should work for Arduino’s as well).
The basic idea is still the same: we need to connect 6 wires. There are 2 wires for +3V and GND and 4 wires connected to ports 1 and 4. On the target JeeNode, the wires will be connected to the ISP connector:
The target JeeNode will receive its power from the working JeeNode, so don’t plug it into anything. Note that this can also be done with JeeNode USBs. All we need, is to make a few connections for power and I/O.
The working JeeNode should be plugged into a USB-BUB, or something similar. Do that now, because the following wiring step can be a bit sensitive to movement.
The following six connections need to be made:
On the working unit, the wires or wire jumpers can be inserted into the 6-pin port headers.
On the target side, you’ll probably just have gold-plated holes for the ISP connector. The nice thing about gold plating is that it easily makes contact. So one way to hook up the wires is to insert all six as shown above, and position the whole thing in such a way that there is a slight tension on the wires – just enough to make contact.
Ok, you should now have the working unit powered up, and the target unit receiving power and signals through these 6 wires. Good, leave them alone now.
To do the actual reflashing, I’ve added an isp_repair.pde sketch to the Ports library, which does everything. Upload that sketch to the working JeeNode, and open up the console. Here’s what you should see:
That’s it. The target ATmega has been set up with the proper fuse settings and a boot loader. You can remove all the wires, and hook up the JeeNode to a USB-BUB. It’ll now accept sketches like any other JeeNode. Fixed!
Can you cross-program a bootloader- e.g. use a Lilypad Arduino to program a JeeNode, or a JeeNode to program a Lilypad?
Does the isp_repair sketch let you choose which bootloader to load into the target, presumably there are differences for at least some hardware combinations or clock rates?
You could. The current isp_repair.pde sketch has the standard Arduino bootloader, same as used for JeeNodes. So this should work as is to program a JeeNode from a Lilypad. Would need to change the code to program the other way around – the boot loader is included in the source as an array of bytes. I could add the Lilypad loader if you like, selectable via a compile-time #define. Are there any other boot loaders that would be useful to include in here?
Nice!
Yea. This is awsome. I have a few arduino duemilanove hanging arround with some bad firmware onto them. i assume there are some bad fuses setup on the uP (the speed at which it works is wierd) can i use it to repair my duemilanove also ?
For the people going to really low levels, the USB HUB ISP http://www.pjrc.com/hub_isp/
@mike – Should work…
Thanks for that note, have now come across http://arduino.cc/en/Tutorial/ArduinoISP and that works nicely between *duino types (just tested successfully with a Duemilanove reflashing a dead Lilypad). That was using the File … Examples … Arduino ISP sketch provided with Arduino 0018, very nice feature, glad you can do it with jeenodes too.
Do you know if you could also upload a sketch with this method ? Don’t know if you remember, but I have a JeeNode USB, and a simple one, and no USB-BUB ! I’d like to program the simple through the USB… I assume it must be a matter of tweaking the isp_repair sketch. Regards
Yes. Easiest way is probably to upload the “isp_flash” sketch to your JN USB, see http://jeelabs.org/2010/04/24/isp-plug/ – that turns the JN USB into an AVRISP compatible ISP programmer, which can then be used as uploader for the IDE. You probably need to add an extra programmer definition to the IDE. Or use avrdude directly, then it’s just a matter of programming the proper hex file through the JN USB running isp_flash.
Thanks for this tool JC! I had a JeeNode that mysteriously bricked, and reflashing the bootloader it came back to life.