NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » Making the MCU shut off its own power supply

March 02, 2010
by bretm
bretm's Avatar

I have a battery-powered circuit that I want to automatically shut off after a few minutes of inactivity. Putting the MCU into power-save mode isn't enough because there is external circuitry that I want to shut off.

I came up with this circuit, but I've never used a JFET so I'm not sure how they work. What's supposed to happen is that SCR1 acts as a switch that is turned on by SW1 and then kept on by the current through SCR1. When the Q1 gate gets a signal from the MCU (or another pushbutton) the JFET chokes off the supply current and the SCR stops conducting.

Self shut-off circuit

Is this a feasible way to do this? Is there a better way?

March 04, 2010
by bretm
bretm's Avatar

OK, this wasn't going to work well. It would have needed a negative-voltage signal to the JFET gate, and carefully selected components.

I found a better circuit to do this at the bottom of this page. I simplified it to the circuit below and it works great for turning the circuit on and allowing the MCU to turn it off. The original circuit and another MCU pin would be needed to allow using the same button for both on and off.

Soft power on, MCU-controlled off

March 07, 2010
by mrobbins
(NerdKits Staff)

mrobbins's Avatar

Hi bretm,

That second circuit looks OK. You may need to adjust the resistor values somewhat depending on what you're trying to drive. The 33K resistor will allow roughly (9-0.7)/33K = 272uA of base current from Q1, so even if we're generous and assume a current gain of 100, that's at most 27.2mA into the voltage regulator before you start getting saturation. It could easily be the case that your microcontroller+LCD+misc parts draw that much, and then the transistor will start to have a substantial voltage drop across it. If that happens, make the 33K value a smaller resistance (maybe 10K).

On the other hand, the one that is currently 10K at the base of Q2 is "generous" -- i.e. it allows for more base current then you really need. It could easily be in the 100K or higher range. But this will just save you a bit of power, and given the first paragraph, it's probably not enough to worry about.

If you build it, let us know how it performs!

Mike

March 07, 2010
by bretm
bretm's Avatar

You were right about needing to reduce the 33k, but it turns out I mostly only need to do that for programming mode which doesn't use any of the power-saving modes of the MCU.

I have my app down to a diet of 20ma for now, which I may increase if I add features. I'm doing this by using idle mode as much as possible, reducing the display brightness, and of course, shutting the power off after 5 minutes of no activity (drum pad hits or keypad entries in my case). It's nice to know I'm not going to drain the battery if I forget to turn the device off. The circuit above works great.

I might also replace the 7805 with LM317 or something like that, which seems, from the datasheet, like it would be more efficient.

The power-saving features of the Atmega are really easy to use, if anyone is curious. To play with it, I modified led_blink to use Timer 2 instead of delay_ms because Timer 2 can wake the chip out of power-saving mode. It only uses 6ma when the LED is off:

// led_blink.c
// for NerdKits with ATmega168
// hevans@nerdkits.edu

#define F_CPU 14745600

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"

// PIN DEFINITIONS:
//
// PC4 -- LED anode

int main() {

  DDRC |= _BV(PC4);             // configure the LED pin for output

  // set up timer 2
  TCCR2A |= _BV(WGM21);         // clear timer on compare match
  TCCR2B |= _BV(CS22) 
          | _BV(CS21) 
          | _BV(CS20);          // clk/1024 = 14400 Hz
  OCR2A = 143;                  // divide by 144 more = 100 Hz
  TIMSK2 |= _BV(OCIE2A);        // enable timer interrupt

  sei();                        // enable interrupts in general
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);  // choose sleep mode

  // keep going into power-save mode after interrupt knocks us out of it
  while(1) {
    sleep_mode();
  }

  return 0;
}

uint8_t counter = 0;

ISR(TIMER2_COMPA_vect)
{
    counter++;                  // Count 1/100ths of a second.

    if (counter == 50)          // After a half-second,
    {
        counter = 0;            // reset the counter
        PORTC ^= _BV(PC4);      // and toggle the LED.
    }
}

By the way, I noticed that led_blink, because it doesn't use a current-limiting resistor, does bad things (63ma through pin PC4) if you use a lab power-supply instead of the battery. The blink rate and duty cycle go up, indicating a sick little MCU.

Post a Reply

Please log in to post a reply.

Did you know that you need to think about wires differently when you're transmitting signals more than a few inches? Learn more...