Below is the start to my arduino nano based power circuit for Famicom based retro pie build.
The goal of this Arduino sketch is to detect when the Super Famicom power switch state has changed and either power on the Rpi3 or tell the Rpi3 to shutdown and then remove power from the Rpi3 circuit. To accomplish these goals I would like it to do the following:
- Graceful shutdown of Rpi after power switch is turned off.
- Serial Communication between Rpi and Arduino over I2C to initiate and confirm shutdown.
- Power on of Rpi without touching the power cable.
- Illumination of the Power LED.
Arduino Sketch:
const int switchPin = 2; // pin the SNES power switch is connected to const int powerLedPin = 13; // pin the SNES power LED is connected to const int mainPowerRelayPin = 6; // pin for the 5V relay that provides power to the Rpi const int piStatusPin = 7; // pin for telling the pi when it is time to shutdown (shutdown = 0, run = 1) int switchState = 0; // SNES power switch state int switchStatePrevious = 0; // Previous state of power switch void setup() { pinMode(switchPin, INPUT); // initialize the SNES power switch pin pinMode(powerLedPin, OUTPUT); // initialize the SNES power LED pin pinMode(mainPowerRelayPin, OUTPUT); //initialize Relay pin digitalWrite(mainPowerRelayPin, HIGH); //Set relay to High as it triggers low pinMode(piStatusPin, OUTPUT); //initialize Pi status pin Serial.begin(9600); // initialize serial } void loop() { switchState = digitalRead(switchPin); // check the state of the SNES power switch //Check to see if the state of the power switch has changed if (switchState == switchStatePrevious) { Serial.print("-"); } //If the Power switch state has changed and the new state is HIGH, start the power on procedure else if ( switchState != switchStatePrevious && switchState == HIGH){ powerOn(); } //If the Power switch state has change and the new state is LOW, start the power off procedure else if ( switchState != switchStatePrevious && switchState == LOW){ powerOff(); } switchStatePrevious = switchState; delay(1000); } //Power On //Turn on power LED //Switch on power relay to provide power to Rpi and logic converter void powerOn(){ pinHigh(powerLedPin); pinHigh(piStatusPin); pinLow(mainPowerRelayPin); } //Shutdown function //Turn off power LED //Wait 30 seconds for Rpi to shutdown and then switch of Relay //TODO: replace delay with confirmation of shutdown from Rpi using Serial void powerOff(){ pinLow(powerLedPin); pinLow(piStatusPin); delay(10000); //TODO: change from test time of 3sec to 30 pinHigh(mainPowerRelayPin); } //Move a pin to high and output that change to serial void pinHigh( int pin){ digitalWrite(pin, HIGH); Serial.print(pin); Serial.println(" switched to HIGH"); } //Move a pin to low and output that change to serial void pinLow( int pin){ digitalWrite(pin, LOW); Serial.print(pin); Serial.println(" switched to LOW"); }
The following python script will need to be placed on the Raspberry Pi. I recommend placing it in /home/pi/Scripts/, you may have to create the Scripts folder if you have not already done so.
This script will detect when a GPIO pin which is pulled low, is instead high. Once this state is detected the shutdown command will be run.
#!/bin/python # Configure Rpi to check if the GPIO pin for shutdown is high, if so, shutdown the Rpi. import RPi.GPIO as GPIO import time import os int shutdownPin = 23 # Setup shutdownPin with pull DOWN enabled. GPIO.setmode(GPIO.BCM) GPIO.setup(shutdownPin, GPIO.IN, pull_up_down = GPIO.PUD_DOWN) # Gracefully shutdown when shutdownPin is HIGH def Shutdown(channel): os.system("sudo shutdown -h now") # Detect when shutdownPin goes high, and run the shutdown function GPIO.add_event_detect(23, GPIO.RISING, callback = Shutdown, bouncetime = 2000) # Sleep thread so that shutdownPin is only checked once a second while 1: time.sleep(1)
With the script tested and working on the Rpi, we need to make sure it runs at startup. To do this we will need to add a line to /etc/rc.local.
The easiest way to do this is with nano using the command
sudo nano/etc/rc.local
The following line will needed to be added before “fi”
sudo python /home/pi/Scripts/shutdown_pi.py &
Be sure to include the ampersand at the end. This forks the process which is important as this script will be running continuously until shutdown.
In Part 2 we will test the code above on the hardware side.