Getting ATMEGA328P to work below 2.7V

Hi

I am attempting to get my ATMEGA328P to work at low voltage (around 2.6V for 2x AA batteries). It works fine at 3.3V using the blink sketch, but at 2.6V it does not work.

I am using it together with a crystal and two capacitors for the clock, and programming the chip on my Duemilanove and extracting it when programmed and putting it on my breadboard.

I've read about fuses, and tried various settings using the fuse calculator AVR® Fuse Calculator – The Engbedded Blog. I did this by editing boards.txt and adding a new board definition, and changing the fuses settings. I attempted to set the brownout fuse to 1.8V, and the clock to a lower setting as I understand at 1.8V the maximum possible is 4Mhz(?).

I used these settings:

atmega328lowpower.name=Arduino Duemilanove Low Power

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

atmega328lowpower.bootloader.low_fuses=0x7F
atmega328lowpower.bootloader.high_fuses=0xD9
atmega328lowpower.bootloader.extended_fuses=0xFE
atmega328lowpower.bootloader.path=atmega
atmega328lowpower.bootloader.file=ATmegaBOOT_168_atmega328.hex
atmega328lowpower.bootloader.unlock_bits=0x3F
atmega328lowpower.bootloader.lock_bits=0x0F

atmega328lowpower.build.mcu=atmega328p
atmega328lowpower.build.f_cpu=1000000L
atmega328lowpower.build.core=arduino

However, I get this error when burning the bootloader via w/ Arduino as ISP;

****failed;
avrdude: verification error, first mismatch at byte 0x000
0xff != 0x07
avrdude: verification error; content mismatch

Any help is very much appreciated, I am desperate now :slight_smile:

P.S. Burning the normal settings as bootloader worked fine, so my programmer appears to be fine.

Looks like the data sheet says 2.7 Volts is the minimum to get 10 MHz operation. At 1.8 Volts you have to drop down to 4 MHz so I would recommend trying something more like 8 MHz at 2.6 Volts.

I have also read somewhere that the Arduino bootloader can only deal with clock frequencies in powers of 2 (2 MHz, 4 MHz, 8 MHz, 16 MHz) to keep the calculation of buad rates reasonable. Not sure how true that is and what the implications are.

Do you think I can use the 16MHz crystal to run the chip at 4MHz, should I be using the 128KHz internal clock source?

Try looking into the prescaler fuse bits. I'm not sure about the 328, but other chips have a prescaler on the fuses... that may allow you to keep the crystal.

Prescaler... like the 'divide clock by 8' flag?

Atmega328 as the single option to divide or not the input frequency by 8, it has no PLL or anything else to play with the clock source, you can either enable that fuse, replace the crystal, or use the internal RC oscilator but that one is a bit risky if you want to use serial coms.

Burning the bootloader with the default settings works fine, and the chip is programmable afterward.

However, changing just one setting, e.g. setting Extended to FF to disable brownout detection, causes that error message and the chip is unprogrammable.

Ideally I'd want the clock to be divided by 8 to get 2MHz, and brownout detection disabled, and use the external crystal.

If anyone knows how to do this, I would appreciate it very much as I am close to 'laming out' and doing something much less elegant to get a job done.

Do you think I can use the 16MHz crystal to run the chip at 4MHz

No.

jonny5alive:
However, changing just one setting, e.g. setting Extended to FF to disable brownout detection, causes that error message and the chip is unprogrammable.

Trying to set the Extended byte to 0xFF won't work because when avrdude reads back the value (to verify it) the "don't care" bits read as 0. You have to say 0x07 to set the bottom three bits to disable BOD.

Note: the CKDIV8 bit just pre-sets the Clock Pre-scale Register (CLKPR). You set that register at run time to set the system clock divider to any power of two between 1 (2^0) and 256 (2^8). Use the 16 MHz crystal and set the CKDIV8 fuse to start the CPU at 2MHz, then change the CLKPR register to run the processor up to 8MHz at run time.

Thank you so much. I see the problem, perhaps a bug in the Calculator web page. With that setting I was able to power the chip from 2.6V and it worked fine.

The next step is lowering the clock speed, ideally to about 4MHz to suit the rating graph:

I ticked the CKDIV8, resulting in:

7F DA 07

And changed CPU speed to 8MHz:

atmega328.build.f_cpu=8000000L

The bootloader burnt OK, but when I replaced the chip back into my Duemilanove, I get stk500 sync errors.

Any ideas?

If there are any insights on how to use the internal clock too, that would be useful. I already have the crystal so I don't need it this time, but it might be useful for other people to see.
Thanks.

But your duemilanove board as an 16Mhz crystal in it...

Senso:
But your duemilanove board as an 16Mhz crystal in it...

Should I use 2000000 instead? (16000000 / 8)

Maybe you should look at using a charge pump setup to get the voltage up.

atmega328lowpower.upload.speed=57600
:
atmega328lowpower.build.f_cpu=1000000L

I don't think you can run 57600bps at 1MHz clock rate. In fact, 1MHz seems to be a particularly LOUSY speed for serial comm purposes. See WormFood's AVR Baud Rate Calculator Ver. 2.1.1

Assuming you want a crystal, you probably need an actual slower crystal rather than using the internal divider to generate the lower clock rate from a high-speed crystal. I don't recall seeing anything in the datasheet that says that the crystal oscillator is capable of operating at high frequencies even when the voltage is low; you shouldn't assume anything other than the oscillator following the same section 23.8 graph...

If you use a 16 MHz crystal and turn on CKDIV8 to get an initial 2 MHz clock, that is what the bootloader will run at. If you later change the CLKPR register in your sketch to bring the speed up to 4 or 8 MHz then your sketch will be running at a different rate.

I think you should put the final clock rate in the boards.txt entry so millis() and such will work in your sketch. That will mean the baud rate used by the bootloader will be much lower. For example if you start at 2 MHz, boost up to 8 MHz later, and the bootloader normally runs at 9600, put:

atmega328lowpower.upload.speed=2400
:
atmega328lowpower.build.f_cpu=8000000L

The last successful programming I did was setting the CLK divider by 8. Since then, it hasn't accepted any bootloader uploads :confused: In fact, it gives the same results if I just disconnect the ISP:

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
0xff != 0x0c
avrdude: verification error; content mismatch

I used:

avrdude -v -v -v -v -C ../etc/avrdude.conf -b 57600 -p atmega328p -c stk500v1 -P COM3 -e -U flash:w:../../../arduino/bootloaders/atmega/ATmegaBOOT_168_atmega328.hex:i

Any ideas? I tried every combination of clock speeds and baud rates I could in desperation :slight_smile:

jonny5alive:
The last successful programming I did was setting the CLK divider by 8. Since then, it hasn't accepted any bootloader uploads :confused: In fact, it gives the same results if I just disconnect the ISP

Are you programming with an ISP, through the 6-pin ICSP header? In that case you must use the baud rate of the ISP (the SPI interface used for ICSP includes a separate bit clock).

If you are programming through the serial bootloader running on the target chip you will need to set the baud rate to bootloader-baud-rate * (actual-clock-rate / expected clock rate). If the bootloader expects to be running on a 16 MHz processor and you are running it at 2 MHz you will need to use a baud rate 1/8th as fast (1200 instead of 9600). I'm not sure where the bootloader gets the clock rate. If it gets set from boards.txt and your entry says 8MHz you may only need to divide the baud rate by 4.

I'm programming via a Duemilanove which has ArduinoISP sketch installed, then writing up Reset/11/12/13 to an ATMega328P with a crystal. I just managed to get it working again, by using 38400 baud manually via avrdude. I think the problem is the Arduino IDE was not respecting the upload rate defined in boards.txt which I saw when turning on verbose mode. Doing it manually has enabled me to turn off the divide by 8 clock again, which is great as I did not know if the chip was broken etc.

Hopefully this will let me do a few trial and error tests as I can see some probable combinations that will work but noone seems sure :slight_smile:

Thank you for your help.

So far, experimenting has proved:

  • Default 16MHz setup needs to be uploaded with 57600 rate
  • Turning on divide by 8 requires 38400 upload rate

Getting there!

*EDIT: Jinx, now have no clue.