Is Brown-out the end of the line?

Go To Last Post
43 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm working on a project that uses an OLED display. The display is working very well but it has an odd power down requirement that I'm having trouble getting my mind around.
The manual recommends that before powering down you send a power down sequence of characters to the display. The interface is serial.
I'm using an ATmega164P and assume that a brownout interrupt could be used to send the power down characters.
I've never used the brownout function to perform a task before, does this work or make sense?
One more question, I can't find the name of the reset interrupt routine for the 164P. Any suggestions?
Thanks,
Tom

[threads now merged]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The brownout detector doesn't fire any interrupt but it resets your AVR. If your application is directly battery powered without any regulator, then you can poll VCC via the ADC by using VCC as reference (REFS1...0 = 0b01 in ADMUX register) and internal 1.1V reference as ADC input (MUX4...0 = 0b11110 in ADMUX register). This method uses only internal resources no pin is wasted for this feature) VCC can be calculated by the formula:

VCC = 1.1V * 1024 / ADC

If you have a voltage regulator then you can connect the regulator input voltage to an AC, ADC or digital input pin via an adequate voltage divider.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using an ATmega164P and I need to detect loss of power to shut down a peripheral gently.

When the brown-out interrupt/reset event occurs, can I execute any more code at the reset vector? I need to send three characters using the UART.

Thanks,

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No you need an external BOD or you need to use the internal bandgap and ADC to predict the falling power rail before it reaches BOD.

When the AVRs BOD occurs it immediately pulls the CPU into reset - there's no time left to do "mopping up"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can execute code...

The problem is that it's a race. You need to benchmark and find out how much you can execute before your power levels drop too low.

You also need to see which portions of the chip/board will still operate correctly for the remaining amount of power you have.

It's a tricky situation. Most people provide some buffered power source to assist in brown-out situations...(I am not an electrical engineer so I don't have any advice for that)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

You can execute code...

The problem is that it's a race. You need to benchmark and find out how much you can execute before your power levels drop too low.


No that is without the internal BOD enabled. If it is then as soon as Vcc reaches the BOD trigger level the CPU core is pulled into _RESET

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tom, if you didn't understand the answer I gave you this morning here then it would be much better to mention it there instead of starting a new thread. Noone gets upset just because you have problems to understand an answer (Not every answer is perfect). But ignoring people who try to help, could discourage even others to invest any time for you.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sebastian,

Thank you for your answer, I did understand it. My thought was that this was really a hardware question, not a gcc issue.

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As noted above I moved this to the AVR forum titled:

Is Brown-out the end of the line?

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson,

Thanks for the clarification. I've always been confused by the documentation because brown-out is listed in the interrupt table. So, anything that jumps to RESET is a special case?

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A good way is to have a ADC that monitor your power source (as close to the power AC or what ever it is) when that drops you will have some time to send SOS on the RS232 and go into a wait for BOD or power be good again mode.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I’m using an ATmega164P and assume that a brownout interrupt

Quote:

I've always been confused by the documentation because brown-out is listed in the interrupt table.

OK, I'll bite: Which vector is that specifically? (Are you thinking of WDT?)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Shouldn't political threads be in the off-topic section?

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Shouldn't political threads be in the off-topic section?

???

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

Shouldn't political threads be in the off-topic section?

???
"Brown-out" -> recent political development in England

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank God someone explained it!

Quite ironic really about 1 minute ago I just watched Gordon Brown leave No.10 for the last time and get in a car to Buckingham Palace to tender his resignation as PM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Someone outed Mr. Brown, and forced him to resign? Aren't y'all tolerant of differing sexual orientations on that side of the pond? [which Forum now, John, since I've used the s-e-x word?]

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch,

The ATmega164P manual, section 9.2 on interrupt vectors says that brown-out, non-political, is vector one.

The section title is "Interrupt Vectors in ATmega164P/324P/644P"

But, the table (9-1) is titled "Reset and Interrupt Vectors".

So, I guess the correct way to look at that is that Reset is unique and everything else in the table is an interrupt?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure you have the right datasheet? I'm looking at 164P/324P/644P document 8011E-AVR-04/07. The vectors are listed in table 10-1 in section 10.2 on page 61. There is no mention of any kind of "BOD vector" there at all? (or, AFAIK, in any AVR datasheet - there couldn't be BOD *STOPS* AVR execution immediately it occurs)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The current doc is 8272A–AVR–01/10. Mine was a few months out of date. The interrupt stuff moved to 11.2

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The ATmega164P manual, section 9.2 on interrupt vectors says that brown-out, non-political, is vector one.

AAaahhh--that is the RESET vector--for various types of RESETS. It is the place the AVR goes to when it restarts.

You will indeed get there when a BOD event happens. But it has already happened--in the past. And it resets "right now".

1 $0000(1)  RESET External Pin, Power-on Reset, Brown-out Reset, 
            Watchdog Reset, and JTAG AVR Reset

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK I've now downloaded the later document. So remind me again where it says anything about a BOD vector?

EDIT: Ah I see Lee has spotted your confusion already

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, since the brown-out can’t be used and I’ve thought about the suggestions that have been offered, here is what I’m thinking.
Use the analog comparator with one input on a Vcc voltage divider and another on the input to the voltage regulator, again with a divider. The comparator will give me an interrupt and then I can service the peripheral. That service routine would just end in an infinite loop.
Once power fell off, the BOD would reset the device.
That seems reasonable to me, so please let me know where I’ve gone wrong.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

...That service routine would just end in an infinite loop.

Close, IME.

The short answer is the standard "it depends". It depends on your power source, how far up the line you can sense, other power suckers, the effects of lost power on your app (getting to a "safe state"), space, size, ...

1) Sense impending power loss as far up the food chain as you can. For AC mains, you can detect missing zero crossings, for example. Raw DC can indeed be done much as you described.

1a) If you do indeed use the analog comparator, you will be getting false trips on every little glitch. I'll bet on it. I normally set a trip point at about 50% to 75% of nominal depending on other factors. But I used the ADC, and make a rolling average that won't trip on a short glitch. (The raw can drop momentarily, for example, when a big backlight is turned on.)

2) The actions depend on your app. My race is usually to put the app into a safe state, and save any needed info to EEPROM. Then wait to die.

3) The expected action is a power loss, and the BOD kicking in. You don't want to reset prematurely and try to start up again. So you kick the watchdog in the wait-to-die state.

4) Notice I said "wait-to-die state", and not "loop". You probably want to continue to monitor power levels to see if it is restored. If you don't and it was a momentary drop you will be in your wait-to-die forever...

5) Now, when you see power is restored in 4), what do you do? I then do indeed go into a hard loop >>without<< kicking the dog, and force a reset. Thus the action is >>as if<< the power went away.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Lee,

I believe you have covered all the possible problem areas.

Tom

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S-Sohn wrote:
then you can poll VCC via the ADC by using VCC as reference (REFS1...0 = 0b01 in ADMUX register) and internal 1.1V reference as ADC input
That's probably a good way, but be aware that VCC measured this way has a large and variable error that can be as much as 100mv.

That's what I found on a Mega329 and a Mega644. Some people agree with me and some don't. Has anyone seen an example where there is no such error?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

san_juan_dad wrote:
Any suggestions?
Some voltage regulators have a power good comparator.

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:
S-Sohn wrote:
then you can poll VCC via the ADC by using VCC as reference (REFS1...0 = 0b01 in ADMUX register) and internal 1.1V reference as ADC input
That's probably a good way, but be aware that VCC measured this way has a large and variable error that can be as much as 100mv.

That's what I found on a Mega329 and a Mega644. Some people agree with me and some don't. Has anyone seen an example where there is no such error?


According to the datasheet the 1.1V reference can vary from device to device in the range of +/-10%. However, the reference is very stable across the complete temperature range (approx. 1%). So you might need to store a calibration value in the EEPROM or flash. Doing this once should be sufficient for most applications

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's a chart which shows the variation of the internal 2.56V reference of an ATtiny861 (Automotive) across the temperature.

The second chart displays the ADC output of the internal temperature sensor.

When looking at the datasheet you might get the impression, that the internal reference and the temperature sensor can't be used for any real application. But when doing adequate calibration you can expect good results.
And by combing the internal reference with the internal temperature sensor in a lookup table you can even expect very accurate results.

Regards
Sebastian

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Has anyone seen an example where there is no such error?

Lessee--100mV on a 5V Vcc is 2%. Is that a "raw" 2%? Very understandable as the BG has like [depending on model] +/- 8% spec.

But if one-time calibrated that initial error "goes away".

There is a thread that indicated that a number of conversions of the BG channel need to be done before getting good results. Is that what you are referring to?

Quote:

Here's a chart which shows the variation of the internal 2.56V reference of an ATtiny861 (Automotive) across the temperature.

That's interesting. There was a thread on this fairly recently IIRC. I cannot find a chart like this for the BG in the Mega48/family datasheet, but the BOD threshold chart is fairly flat across temperature. (I guess I'm assuming that the BOD is based on BG.) That hump is about +/- 1%.

Anyway, a bit more on topic, measuring the AVR's Vcc level to race a BOD trip isn't going to be of much use in most apps, IME/IMO.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
That hump is about +/- 1%.
Lee, a similar error shows my chart, too. Note that the Y-Axis starts with 2.39V and ends at 2.49V.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have lost me. I >>was<< referring to your chart. And the range in What you posted goes from a "starting" of 2.41 to less than 2.43 to a bit more than 2.39--less than +/- 1%. No 2.49 to be seen.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
You have lost me.
Oops, I have misunderstood you. Anyway, the 2.49V was a typo.
Did you mean that the BOD charts in the datasheets look more flat than the chart I had posted? (It's still a bit unclear to me :? )

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Did you mean that the BOD charts in the datasheets look more flat than the chart I had posted?
Yes. At least for Mega48P/PA and friends.

Now, is the BG used for BOD? If so, I thought that turning off AC and ADC turned off the internal reference for power saving. Then how could it be used for BOD? But there is also the sleeping-BOD in picopower.

Look at your '861 datasheet; "Figure 24-29. BOD Threshold vs. Temperature (BOD Level is 4.3V)" is quite flat.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Look at your '861 datasheet; "Figure 24-29. BOD Threshold vs. Temperature (BOD Level is 4.3V)" is quite flat.
Hmm, the BOD charts in the ATtiny861 Automotive datasheet is quite rough. But by looking at other datasheets I understand now what you mean.

Quote:
Now, is the BG used for BOD? If so, I thought that turning off AC and ADC turned off the internal reference for power saving. Then how could it be used for BOD? But there is also the sleeping-BOD in picopower.
The AVR datasheets seem to imply that. ATtiny861 datasheet chapter "8.7.4 Internal Voltage Reference":
Quote:
The Internal Voltage Reference will be enabled when needed by the Brown-out Detection, the
Analog Comparator or the ADC. If these modules are disabled as described in the sections
above, the internal voltage reference will be disabled and it will not be consuming power.
It is a little confusing that the datasheet mentions a BG and a "Internal Reference" but I'll say the BG and the internal reference are just two names for one thing.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S-Sohn wrote:
steve17 wrote:
S-Sohn wrote:
then you can poll VCC via the ADC by using VCC as reference (REFS1...0 = 0b01 in ADMUX register) and internal 1.1V reference as ADC input
That's probably a good way, but be aware that VCC measured this way has a large and variable error that can be as much as 100mv.

That's what I found on a Mega329 and a Mega644. Some people agree with me and some don't. Has anyone seen an example where there is no such error?


According to the datasheet the 1.1V reference can vary from device to device in the range of +/-10%. However, the reference is very stable across the complete temperature range (approx. 1%). So you might need to store a calibration value in the EEPROM or flash. Doing this once should be sufficient for most applications

Regards
Sebastian

Your reply is irrelevant. I'll bet you never tried measuring VCC this way. If you did, then you didn't check the results.

The results are way off and vary greatly with VCC. My guess is the ADC doesn't work right when the reference voltage is close to or equal to VCC.

I always measure the bandgap, but that's not the problem. When I measure VCC the normal way, with an external voltage divider, the results are accurate. The plain fact is, there is a large error when AVCC is connected to AREF.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

steve17 wrote:
I'll bet you never tried measuring VCC this way. If you did, then you didn't check the results.
And how have you exactly tried it?
The BG reference has a quite high impedance. After selecting it as ADC input you have to wait a quite long time or have to do multiple dummy conversions before you get a stable result.

Here is an example measurement:
http://wap.taur.dk/bandgap.png

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can't believe nobody has tried it but me, but you are all experts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Your reply is irrelevant. I'll bet you never tried measuring VCC this way. If you did, then you didn't check the results.
Quote:
I can't believe nobody has tried it but me, but you are all experts.
Didn't you get enough coffe today or why are you so aggressive?

OK, here we go. I'm having a ATtiny25 laying around. I set up the fuses for the internal oscillator with CKDIV8 fuse programmed (F_CPU = 1MHz). And wrote the following program into the chip:

int main (void)
{
    uint16_t result;
    
    // VREF = VCC
    // ADC Input = 1.1V Bandgap
    ADMUX = (1 << MUX3) | (1 << MUX2);
    
    // Enable ADC
    // Set ADC Clock = F_CPU / 8 = 1MHz / 8 = 125kHz
    ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0);
    
    while (1)
    {
        // Start ADC
        ADCSRA |= (1 << ADSC);
        
        // Loop Until ADC Has Finished Operation
        while (ADCSRA & (1 << ADSC));
        
        // Get ADC Result
        result = ADC;
    }
    
    return 0;
}

I debugged the chip with my JTAGICE MKII to read the ADC results. After reset the first ADC result was incorrect and thus ignored.

With VCC = 4.989V the ADC result on my chip was 229. By knowing VCC and the ADC result I can calculate the bandgap voltage:
Vbg = ADC * VCC / 1024 = 229 * 4.989V / 1024 = 1.116V

The next step was to change VCC to 3.311V. The bandgap voltage was calculated to be 1.116V. So I could expect an ADC result of:
ADC = Vbg * 1024 / VCC = 1.116V * 1024 / 3.311V = 345

However, the true ADC result was 346. That's an error of 1 LSB.

Now I have set VCC to 2.226V. I'd expected an ADC result of 513 and got 516. That's an error of 3 LSB.

My opinion is that this is usable.

Regards
Sebastian

EDIT:

Quote:
The plain fact is, there is a large error when AVCC is connected to AREF.
Maybe you shouldn't connect AVCC to AREF but use proper settings of the REFSx bits in the ADMUX register instead.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The plain fact is, there is a large error when AVCC is connected to AREF.

Do you mean physically connected between the two pins? Or "logically" using the setting of "Vref is AVcc"?

1) Yes, I have measured Vcc levels using conversions on the BG channel, in several production battery-powered apps.
2) IIRC, some of the apps are "logically" connected and some are "physically" connected.
3) Yes, the nominal BG value is +/- some per cent.
4) Yes, other threads have outlined how multiple conversions on the BG channel are needed to get good results.
5) With the above in mind, I do NOT get any "large error" when testing with the above in mind.

For lithium batteries with a sharp knee in the curve, I take the middle of the +/- range for my trip point. E.g., for a 3.6V lithium it doesn't matter if my nominal trip point for Low Battery warning is 3.2V or 2.8V.

For alkaline apps, I one-time cal on the bench against a known Vcc level.

It all seems to work fine in practice.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sebastion,

Thanks for testing. I don't have an ATTinys. I will try porting your code to a mega324.

When I said I connected AVCC to AREF, I meant the internal connection.

Don't worry about my coffee consumption. My doctor said 10 cups per day was plenty. Actually she said I should cut down to 2 cups. I'm thinking about it. :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S-Sohn wrote:
Quote:
By knowing VCC and the ADC result I can calculate the bandgap voltage:
Vbg = ADC * VCC / 1024 = 229 * 4.989V / 1024 = 1.116V
You are calculating the bandgap voltage to give the right answer. That seems like cheating to me.

You should measure the bandgap voltage. You can put it on the AREF pin, unless you have something else there.

If you calculate the bandgap to give the right answer, then you should use that bandgap voltage as the reference and measure a known voltage connected to the mux. Then see if there is an error.

On my Megas I've never seen a bandgap voltage greater than 1.102 volts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sebastian,

If I use the bandgap voltage I measure at AREF, and use your code, I get roughly the same errors I saw last year when I ran some tests on a Mega324. They are a little different, and I haven't figured out why.

When VCC = 2.084v, error = -47mv
When VCC = 3.084v, error = -68mv
When VCC = 3.780v, error = -76mv