Thursday, 7 July 2016

Arduino, AVR and internal/external oscillators

One of the nice things about working with PICs is that you know straight away if you've done something wrong. Things work. Or - if you've got them wrong - they don't.

And when things go wrong, the first thing that most people do is revert to a simple "blinky"  example - check that the microcontroller is actually running, and at the correct speed. It's a time-honoured thing that we all do.

So things got a bit weird today, using the same idea with Arduino.
We wanted our breadboard AVR chip to run from it's own internal oscillator at 8Mhz. We managed to get a blinky sketch running, after poking about with the fuses, but it was at about 1/8th of the required speed; our chip was running off it's internal oscillator, but at 1Mhz.

Of course, simply changing the firmware would fix this - shortening a 1sec delay to 125ms for examply - but this isn't the answer we wanted to implement. So we tried running the board off an external 8Mhz crystal, to see where the problem lay.

Here's the boards.txt we used, complete with fuse settings

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

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

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

atmega328bb.bootloader.low_fuses=0x62
atmega328bb.bootloader.high_fuses=0xD9
atmega328bb.bootloader.extended_fuses=0x07

atmega328bb.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F

atmega328bb.build.board=avr_atmega328bb
atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=1000000L
atmega328bb.build.core=arduino:arduino
atmega328bb.build.variant=arduino:standard


atmega328bb.bootloader.tool=arduino:avrdude
atmega328bb.upload.tool=arduino:avrdude

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

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

atmega328bb2.upload.protocol=arduino
atmega328bb2.upload.maximum_size=30720
atmega328bb2.upload.speed=57600

atmega328bb2.bootloader.low_fuses=0xE2
atmega328bb2.bootloader.high_fuses=0xD9
atmega328bb2.bootloader.extended_fuses=0x07

atmega328bb2.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bb2.bootloader.unlock_bits=0x3F
atmega328bb2.bootloader.lock_bits=0x0F

atmega328bb2.build.board=avr_atmega328bb
atmega328bb2.build.mcu=atmega328p
atmega328bb2.build.f_cpu=8000000L
atmega328bb2.build.core=arduino:arduino
atmega328bb2.build.variant=arduino:standard


atmega328bb2.bootloader.tool=arduino:avrdude
atmega328bb2.upload.tool=arduino:avrdude


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

atmega328bb3.name=ATmega328 on a breadboard (8 MHz external clock)

atmega328bb3.upload.protocol=arduino
atmega328bb3.upload.maximum_size=30720
atmega328bb3.upload.speed=57600

atmega328bb3.bootloader.low_fuses=0xCF
atmega328bb3.bootloader.high_fuses=0xD9
atmega328bb3.bootloader.extended_fuses=0x07

atmega328bb3.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
atmega328bb3.bootloader.unlock_bits=0x3F
atmega328bb3.bootloader.lock_bits=0x0F

atmega328bb3.build.board=avr_atmega328bb
atmega328bb3.build.mcu=atmega328p
atmega328bb3.build.f_cpu=8000000L
atmega328bb3.build.core=arduino:arduino
atmega328bb3.build.variant=arduino:standard


atmega328bb3.bootloader.tool=arduino:avrdude
atmega328bb3.upload.tool=arduino:avrdude


And the result...


See that little silver thing on the desk?
That's our 8mhz crystal. We took it off the breadboard and yet the sketch still runs. So the mcu is obviously still running off it's internal oscillator. And still only running at 1Mhz.

So it looks like it's working.
Except it's not.

It's on days like this that I really hate Arduino.




EDIT: a few people have suggested that there's no reason why we can't treat our AVR chips just like PICs - i.e. create a hex file (albeit using the Arduino IDE to code it up) and then burn it to the chip using a separate program, just as we do with PICKit2.

AVRDudess is just such a program.
And when we used that to burn our hex files instead of the Arduino IDE, everything worked as expected!


It's on days like this that I really hate Arduino.