Introduction: Arduino (or Microcontroller) Turns Itself Off
I wanted to make a device that turns off a fan after 10 minutes. The circuit sits idle almost all the time so I wanted it to take zero power from the battery.
I wanted to run it off of two AA cells instead of a 9V battery for the slightly lower profile.
I wanted the power to the servo motor to also shut off.
I also wanted to sense if the switch was pushed again so that I could increase the time (double for each press). Hence the optional diode.
For this circuit to work, the "on" button must be pressed long enough for the Arduino to boot up. This may not work for all users. It may require training your users like you do when you have to hold the toilet handle down till it fully flushes.
If you use 3 or 4 AA batteries (4.5 or 6V), this circuit should work without the little power supply board. You'd connect the mosfet to the "RAW" pin on the Arduino.
This circuit could work from a 9V or 12V battery or power supply too, but you'd have to choose a different MOSFET since this one can only handle 8V on its gate. Or if you're not comfortable picking mosfets, you could add another 10k resistor to voltage-divide (connect it in series with R1 and move only the mosfet gate to the midpoint between the two resistors).
This circuit also works with a single AA input! I verified it. But my servo can't be run off of 1.5V, nor off of the step-up board so it's not too helpful for me.
Prices are Feb 2020.
3.3V Spark Fun Pro Micro (Arduino), ~$18
Sparkfun NCP1402 3.3V step up (or equivalent, optional depending on battery voltage, see notes on final page), ~$7
On Semiconductor NDP602: Pchannel MOSFET, ~$1.80
2N3904 bipolar transistor, $0.22
Diode 1N4148 (optional), a few cents
two 10kohm resistors
a momentary switch
two AA batteries and a holder
Soldering iron, wire strippers, etc.
Step 1: Follow the Schematic and Wire It Up
I don't expect you to get much from the picture other than a sense for the sizes of things.
The circuit idea is as follows.
Initially, R2 keeps the mosfet off, so the little power supply board has no power.
When the momentary switch is pressed, the mosfet Gate-Source voltage is large so it turns on. This connects power to the little power supply which provides power to the Arduino. The Arduino boots up. The sketch then drives the analogout pin high. This provides current to the bipolar transistor which pulls down on the mosfet gate. The switch can then be released and the circuit will stay powered. When you want to shut off the power to the whole thing, have the sketch set the analogout pin to zero.
The ADC can be used to measure that gate voltage, but I had to add a diode so that the Arduino doesn't get powered through its ADC connection, which would be bad. The voltage that you measure at the ADC isn't very precise with this method but I just wanted a digital answer. The bipolar pulls the gate low (maybe 0.1V), but not as low as when the switch is on (pretty much zero). This may not be super reliable since the diode current is poorly defined. It might be better to add a pull up to 3.3V at the ADC pin.
Step 2: Some Notes on Components and the Sketch
I chose a Sparkfun Pro Micro for its small size and cheap price.
Unfortunately, to run a 3.3V Pro Micro from 3V, I needed a power supply boost chip. I chose the NCP1402 step-up breakout. This is not needed for 4.5V batteries or higher.
I ordered the other parts from Digikey or I picked them up from my local ma and pa electronics store, Anchor Electronics in Santa Clara, CA. You should go there to keep them in business and it's fun to poke around.
For the pass device I chose an NDP602. It has a low on-resistance, can easily handle the current and has a threshold voltage of 0.7V, so it can easily be turned on by 3V.
The bipolar transistor and diode I had kicking around.
The sketch attached has a lot of details for controlling my servo motor and sensing the state of the switch. If all you want to do is turn off the arduino, then you mostly just need the code that mentions "turnonpin" which is shown as "analogout" on the schematic. Basically all you need to do is define it and digitalWrite it high in the setup() and then digitalWrite it low when you want it to shut down.