Is there Brown-out detection for Arduino Uno?

I have implemented a watchdog timer to restart my Arduino Uno when the code hangs. But I also want to avoid to run code when the voltage drops too much. Is there Brown-out Detection (BOD) for Arduino Uno? :astonished:
I read http://arduino.cc/forum/index.php/topic,49044.0.html
And also found this fuse calculator AVR® Fuse Calculator – The Engbedded Blog.
But still I'm not sure how to set the BOD in a sketch.

1 Like

See page 48 of the datasheet. When enabled, the processor resets if the voltage drops below the brown-out level.

I have implemented a watchdog timer to restart my Arduino Uno when the code hangs.

It is much better to write proper code in the first place.

But yes a brownout detector is available. However you can only run this on an arduino powered by 5V as 3V3 is below the brownout threshold.

The brown-out detector can be set for 1.8, 2.7 or 4.3V via the extended fuse byte. Arduino Unos are set for the 2.7V level. I'm currently working on a project where it was beneficial to change it to 4.3V.

Yes I've read p48 of the datasheet and I'm using 5V through USB.
I found boards.txt in the IDE? It says:

##############################################################
uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=stand
###########################################################

According to AVR® Fuse Calculator – The Engbedded Blog I should change the extended fuses from 0x05 to 0xFC to get 4.3V level.
Let's try that.... but now what? Is that it? Do I need to burn a bootloader?

@jrsikken, either change the boards.txt file then burn the bootloader (which also burns the fuse bytes) or just change the one fuse byte with AVRDUDE.

BTW, the top five bits of the efuse sort of "aren't there", so setting the efuse to 0x04 turns out to be the same as 0xFC.

@Jack, thanks for your reply! I will try tomorrow. Now it's bedtime!

jrsikken:
According to AVR® Fuse Calculator – The Engbedded Blog I should change the extended fuses from 0x05 to 0xFC to get 4.3V level.
Let's try that.... but now what? Is that it? Do I need to burn a bootloader?

That's one way, although you can change the fuses on their own. You need an ICSP programmer to do either. You can use another Uno for that.

Example:

Isn't 2.7V a bit low? At 16 MHz the processor requires 3.78V. So it would become unreliable before the brown-out reset kicked in.

Agree completely, but it is what it is!

Page 54 of the datasheet shows that I can read a brown-out reset flag. And also the watchdog reset flag. That's nice to monitor.

jrsikken:
Page 54 of the datasheet shows that I can read a brown-out reset flag. And also the watchdog reset flag. That's nice to monitor.

I hope someone else can confirm, but I think the bootloader may get in the way of that.

Better read this:

Welcome back all, I tried changing the extended fuses from 0x05 to 0xFC in boards.txt to get 4.3V level, but it did not work. It showed error : ***failed; avrdude: verification error, first mismatch at byte 0x0000 0xfc != 0x04 avrdude: verification error; content mismatch. Then I tried to change extended fuses to 0x04, then it worked! Thanks to the comment of Jack Christensen : "BTW, the top five bits of the efuse sort of "aren't there", so setting the efuse to 0x04 turns out to be the same as 0xFC."

I don't know about the watchdog issue, but I just went through the brownout business a couple of days
ago. This info is VERY difficult to track down, no matter what anyone says, and the bits and pieces are
scattered all over the darn place. See Post #16 on the following thread,

I have it as 2.7V, assuming I actually did find the correct source [jeesh], but this explains why I am able
to run my Duemilanove and UNO chips at both 5V and 3.3V.

Hey, if the extended fuse is standard 0x05 then the Uno already has BOD enabled.
0x04=4,3V
0x05=2.7V
0x06=1.8V
0x07=disabled BOD
And then I actually changed from default 2,7V to 4,3V. I'm not sure if that is an improvement.

I presume it's an improvement because the processor won't run at 2.7V at 16 MHz. In fact you can't run above 10 MHz at that voltage.

Now all is clear to me, I wrote this summary to have all the information in one place and to share with you.

I wanted to have low voltage (brown-out) detection on my Arduino Uno R3 to prevent it from unexpected behaviour or even destroying my sketch when the 5V power supply drops below a certain level. I want to show how to correctly set the brown out detection. To set the brown-out detection a new bootloader with the setting must be burned to the Uno. I have used 1 Arduino Uno to burn a bootloader to another Arduino Uno. The other Uno is used as an in-system programmer(ISP). Here's a description how to do that http://arduino.cc/en/Tutorial/ArduinoISP.

In the Arduino IDE (mine is 1.0.1) boards.txt contains bootloader settings of many different Arduino boards. On my computer the file is located here D:\programs\arduino-1.0.1\hardware\arduino\boards.txt. In that file you need to find the Uno.

##############################################################
uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard
##############################################################

A change must be made to one of these lines to set the fuses of the Uno.

To find the fuse settings this fuse calculator is useful. AVR® Fuse Calculator – The Engbedded Blog. For Uno select ATmega328P. The second table shows that the brown-out detection (BOD) level is set with the extended fuse. Bits 0 to 2 are used to set the voltage level. Bits 3 to 7 are not used. Playing around with the calculator shows that 0x04 is 4.3V, 0x05 is 2.7V, 0x06 is 1.8V and 0x07 is disabled BOD. The datasheet of the ATmega328P shows the same BOD level coding.

This means that the default setting of 0x05 for the Uno that came with the IDE is 2.7V. So the Uno already has brown-out detection enabled. That's interesting, because the Arduino Uno runs on a 16MHz external crystal. The datasheet of the ATmega328P shows that at 2.7V the maximum frequency for safe operation is 10MHz. So at 16MHz the minimum voltage for safe operation must be set to 4.3V. So extended fuse must be set to 0x04.

You now learned that it useful to change the brown-out detection level for your Uno. Don't forget to save the boards.txt file, restart the IDE, burn the bootloader and then burn your sketch. Happy brown-out detecting!

I presume it's an improvement because the processor won't run at 2.7V at 16 MHz. In fact you can't run above 10 MHz at that voltage.

On one of my homebrew pcbs, I can select Vcc=5V or 3.3V, and both Duemilanove and UNO chips run
fine at either voltage using a 16-Mhz xtal. I know the d/s curves indicate you can only run up to about
13.3-Mhz at 3.3V, but it seems to work fine at 16-Mhz [even though most people were recommending
against it on other recent threads - I'll just use it till it stops working, :-)].

Also, I just bought a couple of JeeNode modules this past week, and they interestingly include a 16-Mhz
resonator and the v.reg is a 3.3V part. And they've been selling commerically for a few years, so .... ???

I think when I was testing power savings I cranked the voltage down and it kept working, and eventually stopped. No doubt under the recommended voltage.

But, operating out of spec, what can I say? You can't complain if it goes wrong.