Birds Like Wires

Feed the Birds

Arduino Bootloader on ATmega168

I’ve recently had cause to build a very simple microcontroller-based project. I like the Arduino platform, so I wanted to burn the Arduino bootloader onto an ATmega168. To keep the circuit as simple as possible, I also wanted to have the ATmega168 use it’s own internal 8MHz oscillator, instead of having to provide a 16MHz one externally. One chip, some power, flashy LEDs; dead simple. Except, how to get that bootloader onto the chip?

The easiest way with the equipment I had around was to pop the Arduino ISP sketch onto a working Arduino and connect everything up as shown in the documentation. The image bottom-left shows the setup I was after. I then moved on to the Arduino to Breadboard documentation, which is lovely and clear, but does seem to have an important little thing missing.

The illustrations all clearly show an ATmega168 on the breadboard, but the archive that it links to only provides the settings for burning to an ATmega328. This doesn’t work with the ’168. It is possible to use the LilyPad Arduino w/ ATmega168 board configuration to burn the bootloader, but I found that this introduced a delay of about 10 seconds before anything happened when the chip was powered up or reset.

Hardware Configurations for 8MHz

To fix it properly, I had a dig inside Arduino.app and found that there’s a proper ATmegaBOOT_168_pro_8MHz.hex bootloader hiding in there. If you’re looking for it, it’s here (on Mac OS X):

/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/bootloaders/atmega/

Great stuff. Now, using a combination of the settings for the LilyPad Arduino and the correct bootloader, I created a boards.txt file in ~/Documents/Arduino/hardware/breadboard/ which contains this:

##############################################################

atmega168bb.name=ATmega168 on a breadboard (8 MHz internal clock)

atmega168bb.upload.protocol=stk500
atmega168bb.upload.maximum_size=14336
atmega168bb.upload.speed=19200

atmega168bb.bootloader.low_fuses=0xe2
atmega168bb.bootloader.high_fuses=0xdd
atmega168bb.bootloader.extended_fuses=0x00
atmega168bb.bootloader.path=arduino:atmega
atmega168bb.bootloader.file=ATmegaBOOT_168_pro_8MHz.hex
atmega168bb.bootloader.unlock_bits=0x3F
atmega168bb.bootloader.lock_bits=0x0F

atmega168bb.build.mcu=atmega168
atmega168bb.build.f_cpu=8000000L
atmega168bb.build.core=arduino:arduino

##############################################################

atmega328bb.name=ATmega328 on a breadboard (8 MHz internal clock)

atmega328bb.upload.protocol=stk500
atmega328bb.upload.maximum_size=30720
atmega328bb.upload.speed=57600

atmega328bb.bootloader.low_fuses=0xE2
atmega328bb.bootloader.high_fuses=0xDA
atmega328bb.bootloader.extended_fuses=0x05
atmega328bb.bootloader.path=arduino:atmega
atmega328bb.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F

atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=8000000L
atmega328bb.build.core=arduino:arduino

Give Arduino.app a restart and you should see the ‘ATmega168 on a breadboard (8 MHz internal clock)’ option under the Tools > Board menu. Set up the Arduino and the ATmega168 on the board as shown, set your board and serial port from the Tools menu, then go to Tools > Burn Bootloader > w/ Arduino as ISP.

Hooray! That should have worked, and this is what you should have seen.

Exiting, no? ;)

If you now connect the chip up as shown in the ‘Uploading sketches to an ATmega on a breadboard’ illustration (remembering to remove the microcontroller from your Arduino) you can upload sketches directly to the microcontroller on the breadboard. The chip can then be dropped straight into your project using as few components as possible. If you’ve tried the LilyPad flashing method before, you’ll also notice that your sketch starts running almost immediately – much better!

Gotcha!

The first error that haunted me was this one:

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

This is because of the auto-reset function of the Arduino being triggered, causing the whole thing to restart. Ignore everything on the Arduino site about resistors and removing components from your board; just pop a 10µF capacitor between the reset pin and ground. That will ‘soak up’ the pulse telling the chip to reset.

The second error that haunted me was this:

avrdude: Device signature = 0x000000 
avrdude: Yikes!  Invalid device signature. 
         Double check connections and try again, or use -F to override 
         this check. 

The reason I was seeing it was that I had been impatient and swiped the ATmega168 from my Diecimila to test with. These ATmegas have had their fuses set to expect an external timing source, so you must provide one for anything to happen. You can change the fuse settings using the method above (it is done automatically when you choose the 8MHz board option), but you need to provide it with a 16MHz signal first for it to run at all. And no, so far as I am aware you can’t burn the 8MHz bootloader in situ on an Arduino – not without using an external ISP like a USBtinyISP.

From the factory the microcontrollers default to using their own oscillator, so when my blanks arrived they worked perfectly first time.

← Recent Articles