Request: bootloader options for brownout detection

I have been having problems with my ATMEGA8 program memory getting corrupted when I cycle the power on my experimental digital clock board:

http://cosinekitty.com/digitalclock

I am using a 9V wall adapter, and apparently what was happening was that when I unplug it, it has a capacitor that gradually loses its charge, so the voltage it supplies to the voltage regulator gradually (meaning many, many milliseconds!) falls to zero. I confirmed in the ATMEGA8 data sheet, and elsewhere, that this can cause the ATMEGA8 to execute instructions incorrectly, and thereby overwrite program memory.

I also found a fix: for the ATMEGA8 only, you can change the low fuse byte from 0xdf to 0x1f. This will NOT work on ATMEGA168; I have not yet read that microcontroller's data sheet to figure out the proper value. Quit out of Arduino if you are running it, then edit the file hardware/boards.txt in your Arduino install and add the following lines at the front of the file:

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

atmega8bod.name=ATMEGA8 with brownout detection

atmega8bod.upload.protocol=stk500
atmega8bod.upload.maximum_size=7168
atmega8bod.upload.speed=19200

atmega8bod.bootloader.low_fuses=0x1f
atmega8bod.bootloader.high_fuses=0xca
atmega8bod.bootloader.path=atmega8
atmega8bod.bootloader.file=ATmegaBOOT.hex
atmega8bod.bootloader.unlock_bits=0x3F
atmega8bod.bootloader.lock_bits=0x0F

atmega8bod.build.mcu=atmega8
atmega8bod.build.f_cpu=16000000L
atmega8bod.build.core=arduino

Note that I just copied the "Arduino NG or older w/ ATmega8" configuration, renamed all the "atmega8" prefixes to "atmega8bod" (bod = Brown Out Detection), changed low_fuses from 0xdf to 0x1f, and the "name" field.

After saving boards.txt, run Arduino, hook up your bootloader hardware (I use the do-it-yourself parallel port), and select Tools/Board. Choose the "Custom ATMEGA8 with brownout detection" option (the one we just added to boards.txt). Then choose Tools/Burn Bootloader, and then the appropriate hardware connection.

Afterward, you will need to hook up the serial port and reload whatever software you want to run on the chip, because the bootloader burn will have erased anything in there.

So far this seems to be working... my program memory is no longer corrupted, no matter how many times I unplug and replug my wall adapter.

My request to the Arduino developers is, can you provide options for all of these in the standard Arduino install? If it would help, I can try to research what all the fuse bits should be for the other microcontrollers. I will need somebody else to help me test in all the hardware configurations I do not own.

Thanks,

Don

So what would be the fuse settings to use this technique on the ATMega168?
(I know about the fuse calculator - but I want to be sure.)

I've had similar problems as cosine. Sometimes I even lost the bootloader.
Perhaps other's do too - it seems to be a common occurrence.
People power the Arduino with all kinds of wall worts and batteries.

I also wonder, out of curiosity, why the BOD was disabled in the first place.

same here. no more lost bootloaders or corrupt programs since enabling BOD on my 168's. i must say that i'm mostly running them from just 4 AA rechargables without a regulator. so lost bootloaders was a huge issue for me :slight_smile:

since this problem mostly appeared with my own creations, i believe BOD is disabled by default just because it's not needed in normal(PLUS) use, with a proper designed board. the only disadvantage of brownout detection i can imagine , would be unwanted resets in otherwise uncritical situations.

PS: i'm using avr studio on a friends PC to burn the bootloaders. so i can't tell about the correct fuse settings for the BOD levels on the AtMEGA128 now.

When reading the ATMEGA8 data sheet, the disadvantage they mention about brownout detection is that it consumes slightly more current from the power source. However, this is a small price to pay for most applications. I would think brownout detection should be the default, since most of us experimentalists have enough problems trying to get stuff to work! However, disabling brownout detection should be an option for projects that are trying to be as power efficient as possible, and that have well-regulated power with auto-shutdown of the power supply when the voltage gets too low.

This might give some help with the ATMEGA168 fuse bits:

http://wolfpaulus.com/journal/embedded/arduino3.prn

Also... we always have the multi-hundred-page confusingly written data sheets!!! :slight_smile:

  • Don

Did some poking around, and if I'm right, I found the following with respect to the 168:

The BOD fuses are already set for a 2.7V BO.
This is true in both rel. 0010 and 0011.
Boards.txt for the 168 has the Fuse High Byte set to 0xDD which gives b101 for BODLEVEL:2-0.
(per the datasheet p. 288 & 308)

This surprises me since I have read several times here that BOD is not set at all on the 168.

Now it could be that 2.7V is on the low side (the 168 chip runs between 2.7V - 5.5V and the 168V chip runs between 1.8V - 5.5V).

It appears that if you want to set the BOD to 4.3V, you need to change the Fuse High Byte to 0xDC.

Someone please correct me if I'm wrong. If not I'll try it and report back.

I'm also not sure what the diff is between the ATMega168 and ATMega168V, but I assume the "V" is the surface mount Lilypad type.

Here is what I will try in boards.txt . . .

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

diecimilabod.name=Diecimila w/ 4.3V Brownout 

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

diecimilabod.bootloader.low_fuses=0xff
diecimilabod.bootloader.high_fuses=0xdc
diecimilabod.bootloader.extended_fuses=0x00
diecimilabod.bootloader.path=atmega168
diecimilabod.bootloader.file=ATmegaBOOT_168_diecimila.hex
diecimilabod.bootloader.unlock_bits=0x3F
diecimilabod.bootloader.lock_bits=0x0F

diecimilabod.build.mcu=atmega168
diecimilabod.build.f_cpu=16000000L
diecimilabod.build.core=arduino

[edit]Well, it looks like the "V" is the low voltage version. :-?[/edit]

I hooked a variable power supply to the Arduino and did some tests on BOD.

The "standard" (Rel. 0010 & 0011) fuse settings do indeed trigger BOD at 2.7V.

Using the fuse settings above (high fuse = 0xdc) BOD is triggered at 4.3V.

I think some of the confusion as to whether or not the Arduino uses any BOD at all, comes from this tutorial, which is probably dated.

FWIMBW John

BroHogan, thanks for confirming that! I need to get one of those variable power supply thingies! :slight_smile:

The problem with the 2.7V default is that the processor is already mis-executing instructions at this point, leading to unpredictable results, including corrupting program memory. I was aware of this lower setting when I read the data sheet, but I probably did not make this clear. It's pretty scary when your chip can do random stuff and corrupt memory before getting reset! I was having to re-flash my ATMEGA8 every now and then before I made this fuse bit change on it.

  • Don

I agree, 2.7V seems to be too close to the edge.
I will be using a 4.3V bootloader on all my battery driven projects.

Since we're already paying the price in "increased current consumption in sleep mode" for the 2.7V BOD, why not? (Not that I really cared anyway.)

Glad if this helped some of you.
John