act on loss of 5vdc

can the arduino monitor its own +5vdc power with an analog input pin and take an action on loss of power?

i'm in need of a device that can monitor its own +5vdc source and send a serial command string on power up (should be easy) and a different string on power off. i'm attempting to automate some home entertainment gear that doesn't support discrete power controls by referencing a different device in the system that does.

i could provide a secondary voltage source to run the device, but was hoping there was a sneaky way to get the arduino to take action before it dies from lack of incoming power.

any ideas would be appreciated. thx!

-thom

can the arduino monitor its own +5vdc power with an analog input pin and take an action on loss of power?

Not all by itself, it needs some supporting circuitry. For example, you can do continuous conversions on the voltage drop across a diode (around 0.7V) and when the A/D readings "start to go up" (meaning the source voltage is coming down) that tells you you're losing power. But this assumes that the power is coming down slowly enough that you can a) take an A/D reading and act on it, and b) send a serial string out. I doubt the Arduino will be "alive" long enough to do those things once power goes.

Here is a circuit that will hold up the power to the Arduino for a couple of seconds once power goes out:

http://ruggedcircuits.com/html/circuit__13.html

I don't think there are any "sneaky ways" to get around the fact that it takes time to send out serial command strings and you need power during that time.

--
The Aussie Shield: breakout all 28 pins to quick-connect terminals

that's pretty cool. thx Rugged for the response.

would you measure the voltage drop on the output of the holdup circuit's zenier diode or do you need a different diode tied to the +5vdc source? i'm a s/w developer by trade and not well versed in ee. thanks again for your help!

-thom

This is what I was thinking....innovative suggestions with fewer parts are welcome:

The idea is that with 5V power the 0.7V across the diode will be measured by the analog converter as a code of about 0.7/5*1023 = 143.

Now as soon as power goes out, the 5V supply will go down to about 4.7V due to diode D1, so the analog converter will return a code of 0.7/4.7*1023 = 152. That should be a big enough difference (esp. after filtering a couple of samples) to let the code know that the power went out.

--
The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, speaker, microphone, light sensor, potentiometer, pushbuttons

Well there is a way for a sketch to measure it's own Vcc voltage. However that leaves unanswered if your specific sketch would have time to do what you need done before the lights all go out. This example sketch measures it's own Vcc and also corrects the A/D calibration on the run to compensate for a decreasing Vcc such as when using direct battery power for the Vcc.

// Function created to obtain chip's actual Vcc voltage value, using internal bandgap reference
// This demonstrates ability to read processors Vcc voltage and the ability to maintain A/D calibration with changing Vcc
// Now works for 168/328 and mega boards.
// Thanks to "Coding Badly" for direct register control for A/D mux
// 1/9/10 "retrolefty"

int battVolts;   // made global for wider avaliblity throughout a sketch if needed, example a low voltage alarm, etc

void setup(void)
    {
     Serial.begin(38400);
     Serial.print("volts X 100");
     Serial.println( "\r\n\r\n" );
     delay(100);
    }
    
void loop(void)
    {
     battVolts=getBandgap();  //Determins what actual Vcc is, (X 100), based on known bandgap voltage
     Serial.print("Battery Vcc volts =  ");
     Serial.println(battVolts);
     Serial.print("Analog pin 0 voltage = ");
     Serial.println(map(analogRead(0), 0, 1023, 0, battVolts));
     Serial.println();    
     delay(1000);
    }

int getBandgap(void) // Returns actual value of Vcc (x 100)
    {
        
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
     // For mega boards
     const long InternalReferenceVoltage = 1115L;  // Adjust this value to your boards specific internal BG voltage x1000
        // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc reference
        // MUX4 MUX3 MUX2 MUX1 MUX0  --> 11110 1.1V (VBG)         -Selects channel 30, bandgap voltage, to measure
     ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR)| (0<<MUX5) | (1<<MUX4) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
  
#else
     // For 168/328 boards
     const long InternalReferenceVoltage = 1056L;  // Adjust this value to your boards specific internal BG voltage x1000
        // REFS1 REFS0          --> 0 1, AVcc internal ref. -Selects AVcc external reference
        // MUX3 MUX2 MUX1 MUX0  --> 1110 1.1V (VBG)         -Selects channel 14, bandgap voltage, to measure
     ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0);
       
#endif
     delay(50);  // Let mux settle a little to get a more stable A/D conversion
        // Start a conversion  
     ADCSRA |= _BV( ADSC );
        // Wait for it to complete
     while( ( (ADCSRA & (1<<ADSC)) != 0 ) );
        // Scale the value
     int results = (((InternalReferenceVoltage * 1023L) / ADC) + 5L) / 10L; // calculates for straight line value 
     return results;
 
    }

Oooo...I like it. I'll have to file that one away. I forgot the '328's let you measure the bandgap.

--
The Rugged Motor Driver: two H-bridges, more power than an L298, fully protected

you guys are awesome... thanks for all your insight and assistance!

-thom

I know this is a really, really old thread, but...

What if I wanted to know very quickly if the power went away? The code above requires that it be periodically called to sample the voltage. That both takes time away from other processing, and requires that the board be up long enough for us to get to sampling. Suppose I wanted to trigger a pin to use an an interrupt?

Thanks...

I suspect that you could put a diode and a big fat capacitor on VCC and then connect the power before the diode to one of the interrupt pins.