Arduino using external clock and 1mhz

I want to adjust the default operation of my atmega328s so that they will run down to 2.1v or so from 2xaa batteries.

I know i need therefore to get them running at a lower speed, and i have 4MHZ, 8MHZ and 16MHZ crystals to hand. I need to maintain good accuracy so think i need to stick with the external crystal based clock and not the +/- 10% internal one, and i need to do serial comms so i need the BAUD rates to still work as they should.

What i cant figure out despite days to trawling many many posts is how to adjust the fuse settings and burn the new bootloader.

I think i need to adjust the clock speed in the boards.txt file, and also use the Prescaler to divide the clock down. So i can use my 8mhz external crystal and then divide by 8 with the prescaler, but cant see how to do this.

Any help really appreciated - i am 6 months into a project and now need to get it running at low voltage.

Many thanks all...
R55Boy

Start with the correct fuse settings...
http://www.engbedded.com/fusecalc

Low = CC, high = D7, extended = FE should give you...

Ext. Crystal Osc.; Frequency 3.0-8.0 MHz; Start-up time PWRDWN/RESET: 258 CK/14 CK + 4.1 ms; [CKSEL=1100 SUT=00]
Boot Flash section size=256 words Boot start address=$3F00; [BOOTSZ=11]
Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0]
Serial program downloading (SPI) enabled; [SPIEN=0]
Brown-out detection level at VCC=1.8 V; [BODLEVEL=110]

The 4 MHz crystal or 8 MHz crystal should work. The startup time is fast. The bootloader size is appropriate for Optiboot. The BOD ensures the processor stops running when the batteries get close to empty.

For the bootloader I suggest using a pre-built Optiboot configured for 16 MHz or 8 MHz. For 4 MHz, the baud rate is simply halved (or quartered).

To install the bootloader I suggest using OptiLoader.

Unless someone else does it first, I'll get back to you later today regarding boards.txt.

8MHz on 2xAA cells works well, whether on the internal oscillator or a crystal/resonator. Here is a thread with a boards.txt entry I use, and an 8MHz version of Optiboot:

Thanks guys...some things to try over the weekend here.

But I have one outstanding question ... How to set the prescaler to divide the clock frequency from say 8mhz down to 1mhz, which is what I want to run at.

And codling badly...you are absolutely right...I need to change the brownout setting as that's what's stopping my app now at approx 2.7 volts.

will get to work on this at home over the weekend...work as usual gets in the way!

r55boy:
How to set the prescaler to divide the clock frequency from say 8mhz down to 1mhz, which is what I want to run at.

Everything you need to make that adjustment: Reply #1, Reply #4, the stuff between your ears. :wink:

I'd probably start with setting CKDIV8 in the fuses, then at the very beginning set CLKPR. If you intend to use the Arduino bootloader and serial I/O to reprogram it you'd probably have to custom-build the bootloader with the speed of crystal_MHz/8, although I'd probably forego the bootloader and do direct ISP programming of the sketches.

Then very early on, in setup(), set the CLKPR register. I think there's a way you can set things even earlier than that (one of the .initX code sections?) but I've never done it.

Looks like this is the procedure for setting it:

CLKPR = 0x80; // Set Clock-Prescalar Change Enable
CLKPR = ; // Set Clock-Prescalar

Clock division of 2 = 0x01, 4 = 0x02, 8 = 0x03, 16=0x04, 32=0x05, 64=0x06, 128=0x07, 256=0x08
So when CKDIV8 fuse is active, CLKPR is preinitialized as 0x03, with CKDIV8 fuse disabled it's 0x00.

I have set the fuses now to 0x4c (not 0xcc as i am running an 8mhz processor but want to divide by 8 to give me 1mhz runspeed), and 0xd7 and 0xfe suggested. All burned well using optiloader burned into a 328 on my UNO board.

I then disconnect the optiloader lines D10-D13 and connect TX and RX instead to load a sketch onto my target device but get the not in sync error and cannot upload.

My boards.txt is below...any idea what i am missing? I ahve the freq set to 1000000, but its pointing at an 8mhz hex file which i dont really understand.

I should be possible to upload a sketch normally even though my target 328 is running 1mhz right?

Thanks so much in advance for any help guys...

uno1.name=Arduino Uno 1mhz
uno1.upload.protocol=stk500
uno1.upload.maximum_size=32256
uno1.upload.speed=115200
uno1.bootloader.low_fuses=0x4c
uno1.bootloader.high_fuses=0xd7
uno1.bootloader.extended_fuses=0xfe
uno1.bootloader.path=optiboot
uno1.bootloader.file=optiboot_atmega328_pro_8MHz.hex
uno1.bootloader.unlock_bits=0x3F
uno1.bootloader.lock_bits=0x0F
uno1.build.mcu=atmega328p
uno1.build.f_cpu=1000000L
uno1.build.core=arduino
##############################################################

I believe you need to rebuild the bootloader with a different F_CPU value. That's outside the scope of the arduino IDE I think, so you'll have to find the directory where the bootloader code is stored, edit the Makefile and run "make" to compile it. Search around for other threads on rebuilding the bootloader.

r55boy:
uno1.upload.speed=115200

Probably too fast for a 1MHz system clock. I'd try 19200.

Imagine James Earl Jones, Barry White, and Isaac Hayes. Now imagine them saying, "lower". :wink:

115200 * 1000000 / 8000000 = 14400 Ouch! I think @r55boy is going to need a new bootloader.

On a more serious note, @r55boy if you are going for low power consumption you need to get rid of the bootloader. The alternative is ISP programming...

Actually I haven't tried a bootloader with a system clock < 8MHz, I just use ICSP.

So - i have tried the no bootloader route suggested by Codling Badly. Here is what i did:-

I burned the ArduinoISP onto a new 328P in an UNO board successfully.

I then edited the boards.txt to add the line ".upload.using=arduinoisp" to tell it to use the ArduinoISP instead of the bootloader. See below for boards.txt. The "arduinoisp" matches the values in preferences.txt file which is also in the /hardware/arduino directory.

The i hook up the UNO board to my target chip on a breadboard (with 8mhz crystal and fuses set as per before to 0x4c, 0xd7 and 0xfe) with the D11-D13 connected and reset, Vcc and GND.

When i hit upload i get
avrdude: stk500_getsync(): not in sync: resp=0xff
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0xff

Still no further forward - any more suggestions?

It sounds so simple - "run at 1mhz" - but soooo isnt! Thanks so much in advance for more suggestions guys...

BTW - all i really want to do is get the thing running down to 2v or so and minimise power, so if i am overcomplicating please suggest alternative...maybe Arduino is not designed to do this?

BOARDS.TXT for ArduinoISP programming instead of Bootloader:

uno1.name=Arduino Uno 1mhz
uno1.upload.protocol=stk500
uno1.upload.maximum_size=32256
uno1.upload.speed=9600
uno1.upload.using=arduinoisp
uno1.bootloader.low_fuses=0x4c
uno1.bootloader.high_fuses=0xd7
uno1.bootloader.extended_fuses=0xfe
uno1.bootloader.path=optiboot
uno1.bootloader.file=optiboot_atmega328_pro_8MHz.hex
uno1.bootloader.unlock_bits=0x3F
uno1.bootloader.lock_bits=0x0F
uno1.build.mcu=atmega328p
uno1.build.f_cpu=1000000L
uno1.build.core=arduino
##############################################################

BTW - all i really want to do is get the thing running down to 2v or so and minimise power, so if i am overcomplicating please suggest alternative...maybe Arduino is not designed to do this?

For months, I've been using an Arduino (or Teensy) as a programmer. The path you are on is a good choice that will get you to your goal.

Attached is the "breadboard core" I use. The fuse settings may not be exactly what you want but this "core" is known to work so it eliminates one variable from the troubleshooting. Simply extract the contents to your SketchRoot/hardware folder. The final tree should be something like this...

\Arduino\Sketch\hardware\breadboard\boards.txt
\Arduino\Sketch\hardware\breadboard\bootloaders
\Arduino\Sketch\hardware\breadboard\cores
\Arduino\Sketch\hardware\breadboard\bootloaders\empty
\Arduino\Sketch\hardware\breadboard\bootloaders\empty\empty328Pat1.hex
\Arduino\Sketch\hardware\breadboard\bootloaders\empty\empty328Pat16.hex
\Arduino\Sketch\hardware\breadboard\bootloaders\empty\empty328Pat8.hex
\Arduino\Sketch\hardware\breadboard\cores\empty
\Arduino\Sketch\hardware\breadboard\cores\empty\Arduino.h
\Arduino\Sketch\hardware\breadboard\cores\empty\main.cpp
\Arduino\Sketch\hardware\breadboard\cores\empty\WProgram.h

With this "core" you can use Burn Bootloader to change the fuse settings and erase the processor (no bootloader is actually installed).

On the "programmer" (your Uno running ArduinoISP) connect an LED to pin 9. At all times it should display a "heartbeat". Does it?

How did you disable auto-reset on your Uno? Capacitor?

breadboard.7z (1.14 KB)

Codling Badly

Thanks for the info mate - much appreciated. No luck so far.

Capacitor working as required - heartbeat led is constant and no reset occurs when i try to burn the bootloader which is what we want.

I have set the fuses in the new boards.txt. I have uploaded ArduinoISP to the UNO board.

But when i then hit "Tools->Burn bootloader with Arduino as ISP" i get the same message:

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

So the only thing i have made work is to burn a bootloader using optiloader, but then i cant load a sketch!

More info - i just put a brand new 328p in as the target, which flashes an led on pin13, and the flashing is not interrupted at all during the attempted programming...

Am i correct linking both reset pins together and using the cap to suppress the forced reset by the UNO on upload?

r55boy:
More info - i just put a brand new 328p in as the target, which flashes an led on pin13, and the flashing is not interrupted at all during the attempted programming...

Excellent.

Am i correct linking both reset pins together

No. Pin 10 on the "programmer" to RESET on the "target". MISO to MISO. MOSI to MOSI. SCK to SCK. GND to GND. Ensure the target is powered.

and using the cap to suppress the forced reset by the UNO on upload?

Yes. A capacitor is connected between RESET and GND on the programmer to disable auto-reset.

CodingBadly - Made the changes and still no different.

whatever i try i get the same sync error.

Capacitor and reset now correct - cap on programmer is suppressing reset, reset on target to D10, D11-D13 from prog to target, target has external crystal. Optiloader works fine, but then i cant upload a sketch due to sync error. ArduinoISP using my boards and your new suggestion sync error (in fact this happens even without a target chip on the breadboard).

I am wondering about uninstalling arduino (0022) and then reinstalling the latest? Any baud rate settings anywhere - how come optiloader can do this but the arduino env cant?

I just tried using another UNO as the target board instead of my breadboard but same problem.

I note that you advised choosing "Burn bootloader" to upload a sketch using your new boards.txt, whereas if i use my one then i should be hitting upload as usual? Is this correct? In both cases the boards.txt says upload using arduinoisp. i have the 4 lines connected D10-D13, and the TX/RX lines not coinnected - which must be right as this is using the ArduinoISP.

I have tried with 16 and 8mhz crystals on the target board.

ERROR:
avrdude: stk500_getsync(): not in sync: resp=0xff
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0xff

MY relevant BOARDS.TXT entry:
##############################################################

uno1.name=Arduino Uno 1mhz
uno1.upload.protocol=stk500
uno1.upload.maximum_size=32256
uno1.upload.speed=9600
uno1.upload.using=arduinoisp
uno1.build.mcu=atmega328p
uno1.build.f_cpu=1000000L
uno1.build.core=arduino

YOUR modified BOARDS.TXT relevant entry:
###########################################################################

atmega328Pbb0.name=ATmega328P @ 1 MHz (external oscillator; BOD level1)
atmega328Pbb0.upload.using=arduino:arduinoisp
atmega328Pbb0.upload.maximum_size=32768
atmega328Pbb0.bootloader.low_fuses=0x4c
atmega328Pbb0.bootloader.high_fuses=0xD7
atmega328Pbb0.bootloader.extended_fuses=0xfe
atmega328Pbb0.bootloader.path=empty
atmega328Pbb0.bootloader.file=empty328Pat1.hex
atmega328Pbb0.build.mcu=atmega328p
atmega328Pbb0.build.f_cpu=1000000L
atmega328Pbb0.build.core=arduino:arduino
atmega328Pbb0.build.variant=arduino:standard

Possibly related - the bootloader burned by optiloader - if i put that chip then in a Duemilanove i get sync errors. some of my 328p's work only in UNO, some work only in Duemilanove.

Sorry if this is just confusing things... ;-(