RPiKids | Raspberry Pi Shutdown via Arduino
Gracefully shutting down a Raspberry Pi has been covered in many posts. There are many solutions but none seemed to meet my requirements.
- Full power off – Low power consumption when not being used
- Switch Multiple Sources – Simultaneous power switching for Pi a small amplifier running at different operation voltages
- Parental Controls implemented at the hardware level
My basic approach was sparked a post found here. I will be using a Raspberry Pi2 and an Arduino Uno.
Adding no additional hardware you can create a USB serial link between the Pi and the Uno. This is possible because the Uno implements a serial port firmware uploading. Using the serial link the Pi2 can listen for the Arduino’s shut down command and issue a safe shut down.
GOTCHA – The Arduino Uno’s serial port wants to “auto reset” during serial port initialization so I needed to put a 10uF capacitor between the GND and RESET pin to disable reset.
The Arduino sketch can be found here
Here is my Hardware schematic. The two relay coils are shown on the left, but the relay contacts are not. I simply used the normally open contacts to switch the power supply for the Pi and the audio amplifier.
Powering ON
- Everything is powered OFF, the Arduino is polling for the encoder button to be depressed
- Power button is pressed, the Arduino will wake up and assert the appropriate GPIO lines to close the relay and power up the Pi and audio amplifier
Powering OFF
- Everything is powered ON, the Pi has a Python daemon program running in the background, awaiting input from the Arduino.
- Power Button is pressed, the Arduino issues a serial command to the Pi, notifying it to shut down.
- The Pi issues the shut down command
- NOW the Arduino can wait for a safe amount of time before opening the relay and disconnecting power
- The Arduino waits for some more user input
The Arduino sketch (available at the top of this page) basically has one line when the encoder button is pressed:
Serial.println("shutdown");
A simple python daemon /home/pi/pwrd/pwrd.py
import serial
import os
ser = serial.Serial('/dev/ttyACM0', 9600)
while 1 :
line = ser.readline()
if line == 'shutdownrn':
os.system("sudo shutdown -h now")
Create a /etc/init.d/pwrd to launch on start up
case "$1" in
start)
echo "Starting pwrd.py"
# run application you want to start
python /home/pi/pwrd/pwrd.py &
;;
stop)
# kill application you want to stop
;;
*)
echo "Usage: /home/pi/pwrd/pwrd.py {start|stop}"
exit 1
;;
esac
exit 0
Make /etc/init.d/pwrd executable:
sudo chmod 755 /etc/init.d/pwrd
Register script to be run at start-up:
sudo update-rc.d /etc/init.d/pwrd defaults
Thanks for this post. I searched a lot for this. Could you please alse post the arduino skript?
Thanks in advance
Hi Jeroen, Thanks for the input. I posted the Arduino sketch here
I’m doing something similar with my Pi and I have a few questions.
In addition to Power Up and Shutdown, which your setup seems to handle nicely, I want to add a Sleep Timer. So maybe something like 1 button press turns it all on, a second button press shuts it all down, and pressing and holding for a few seconds starts a Shutdown Timer which will send the Shutdown command after say 30 minutes.
The idea is I’m building a internet radio for my elderly mother, it tunes in only one station, her favorite one. It needs to be simple because she’s old and will be turning it on and off in very low light.
Thanks!
A sleep timer sounds pretty simple Patrick. You just need to edit my sketch and remove the combination lock portions and leave the timer functionality. My sketch implements a shutdown timer in 10 minute increments, yours will always be the same time (30 minutes) The wiring will be very too.
You could additionally add a photo cell so she just has to turn off her lights and her radio shuts done!
Your code and wiring helped me immensely in making my project work exactly as I wanted, thanks!
I wound up using a Arduino to power up two relays (5V for the Pi and 12V for the audio amp) for 60 seconds, to give the Pi time to boot.
In a python script on the Pi I set GPIO25 to go HIGH and I have that connected to one of the Arduino Analog Pins.
The Arduino code activates the relays when either of two things happen. 1) The Green button is pressed and the relays are Enabled for 60 seconds OR the Analog pin connected to the Pi has a value greater than 500. (The 3.3V from the Pi registers at around 620 on the Analog Pin. I could have used a logic converter and a Digital pin but the Analog solution is simpler.)
That way the Pi takes over the task of keeping the relays enabled after the button times out after 60 seconds.
When the Pi shuts down, GPIO25 goes low, and that disables the relays, cutting power to the Pi and the audio amp.
In the same python script I have GPIO23 set as an input and so when the Red shutdown button is pressed, the command “sudo shutdown -h now” is sent and the Pi shuts down.
I also have GPIO24 set as an input and so when the Yellow shutdown button is pressed, the command “sudo shutdown -h +60” is sent and the Pi shuts down after 60 minutes.
Everything is working perfectly!
Many thanks exactly what i was looking for
Hello adrian and thank you kindly for this great post.
I am in dire need of a shutdown method with my digistump for a PI, as i am building something for christmas as a gift.
But as the Pi is constantly running Emulation Station, simple keypresses do not suffice, i think.
May I ask if those serial commands do work even if the PI is running another program?
And if so, would you mind helping me to cut down on your sketch to just send the shutdown command to the daemon when a button is pressed?
This would be an immense help for me and my deadline and i would gladly offer you my help if you ever need a logo or something like that.
Thank you very much!
Best regards
Hi Fleder,
I’m not sure I fully understand your question, I’m not familiar with Digistump products.
The RPIKids project is always running Emulationstation on the Pi and the Python daemon script is always listening for input for the Arduino as to when the shutdown command should be issued. After a safe amount of time has elapsed, the Arduino cuts power to the Pi 🙂