On-off switch – improvements

My first version of an on-off switch for the Raspberry Pi showed some issues, and needed some improvement.

Here is a quick schematic of the improved version:

On-off switch v0.2

The first improvement from my previous version was the move from using a TTL Schmitt Inverter trigger to a CMOS part (SN74HC14N).  That resulted in a massive reduction in current draw.

The next major discovery I made was that I could not reboot anymore.  If I tried to reboot, the GPIO pin that was holding the power supply up went down on reboot, and caused the power to the Pi to be cut.

That led me to wondering which pins stayed up during a reboot. – The transmit pin of the serial console (TXD) is up most of the time, and stays in use during a reboot.  Connecting TXD to the base of a transistor did not stop the serial console working.  The only problem was the for some short periods of time, TXD went low, resulting in the base of my transistor getting pulled down to a level where it switched the input to my Schmitt trigger inverter low and stopped the power! – Putting a capacity across the input to the inverter (before a resistor) fixed that.  That also meant I could get rid of the capacitor on the input to the other transistor.

The second part to the on-off switch is the portion that is used to detect the off switch.  For this, I simply connect a switch to GPIO7.  Together with that, I have added an interrupt handler which sends systemd a signal to power down if I detect the switch being activated.

 
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
/*
 * Interrupt handler
 *********************************************************************************
 */
void myInterrupt7 (void)
{
  /* Tell init(1) to power the system off */
  kill (1, SIGRTMIN+4);
}

/*
 *********************************************************************************
 * main
 *********************************************************************************
 */

int main (void)
{
  wiringPiSetup () ;
  wiringPiISR (7, INT_EDGE_FALLING, &myInterrupt7) ;
  for (;;)
  {
    sleep(600);
  }

return 0 ;
}

This code (which is derived from one of the examples which is shipped with WiringPi) is set up as part of a service, which, on detecting a button press (on GPIO 7), shuts down and powers off the Pi.