Python "shutdown / reboot raspberry pi" 脚本,使用单个按钮
Python "shutdown / reboot raspberry pi" script, using a single button
我从这里得到了 Python 中的一段代码:
http://www.raspberry-pi-geek.com/Archive/2013/01/Adding-an-On-Off-switch-to-your-Raspberry-Pi
我想改进它。
因为这是我第一次使用 Python,所以我一直在理解实际发生的事情。
代码如下:
# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
from time import sleep
gpio.setmode(gpio.BCM) # Set pin numbering to board numbering
gpio.setup(22, gpio.IN) # Set up pin 22 as an input
rebootBool = 0
# Define a function to keep script running
def main(pin):
while True:
#gpio.remove_event_detect(pin)
gpio.add_event_detect(22, gpio.RISING, callback=confirmation, bouncetime=200) # Set up an interrupt to look for button presses
sleep(5000000)
def confirmation(pin):
gpio.remove_event_detect(pin)
gpio.add_event_detect(22, gpio.RISING, callback=shutdown, bouncetime=200)
sleep(3) # if button has been pressed again within 3 seconds, shut down will happen
main(22)
def reboot(pin):
rebootBool = 1
call('reboot', shell=False)
exit(0)
# Define a function to run when an interrupt is called
def shutdown(pin):
gpio.remove_event_detect(pin)
gpio.add_event_detect(22, gpio.RISING, callback=reboot, bouncetime=200)
sleep(3) # if the button has been pressed for a third time, within 3 seconds, Pi will reboot
if rebootBool == 0: # Just to make sure a halt is not called after the 3 seconds have passed, if reboot is called
call('halt', shell=False)
exit(0)
main(22) # Run the loop function to keep script running
我想做的是:
- 如果按钮被按下一次,则执行确认功能,如果在 3 秒内被按下,它会重置按钮以调用关机功能。
- 否则,继续主循环
- 在关机函数中,如果再次按下(3秒以内),则复位调用重启函数。
- 否则继续,关闭
这是怎么回事:
如果我按按钮两次或三次,它会告诉我 gpio.add_event_detect 已经定义,当它试图在 main() 中定义它时。
所以它不会改变它,如果我再按一次,它会调用关机功能。
我不明白的是:
为什么要在 main 中定义 gpio 事件,而实际功能是重启或关机(并且它应该调用重启或关机)?
因为回调函数运行在一个单独的线程中。这意味着,例如,当您在主循环中调用任何回调函数时它仍然有效(主循环),因此当您从回调函数(线程#1)和从主循环(线程#2)同时。这是典型的比赛条件。
您可以通过运行此代码进行检查:
#!/usr/bin/python
# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
from time import sleep
gpio.setmode(gpio.BCM) # Set pin numbering to board numbering
gpio.setup(22, gpio.IN, pull_up_down=gpio.PUD_DOWN) # Set up pin 22 as an input
rebootBool = 0
# Define a function to keep script running
def main(pin):
while True:
print "main loop"
gpio.remove_event_detect(22)
gpio.add_event_detect(22, gpio.RISING, callback=confirmation, bouncetime=200) # Set up an interrupt to look for button presses
sleep(1)
#raw_input()
def confirmation(pin):
print "confirmation1"
sleep(5)
print "confirmation2"
gpio.remove_event_detect(22)
gpio.add_event_detect(22, gpio.RISING, callback=shutdown, bouncetime=200)
sleep(5) # if button has been pressed again within 3 seconds, shut down will happen
gpio.remove_event_detect(22)
main(22)
def reboot(pin):
rebootBool = 1
print "reboot"
#call('reboot', shell=False)
exit(0)
# Define a function to run when an interrupt is called
def shutdown(pin):
print "shutdown"
gpio.remove_event_detect(pin)
gpio.add_event_detect(22, gpio.RISING, callback=reboot, bouncetime=200)
sleep(3) # if the button has been pressed for a third time, within 3 seconds, Pi will reboot
if rebootBool == 0: # Just to make sure a halt is not called after the 3 seconds have passed, if reboot is called
#call('halt', shell=False)
print "halt"
exit(0)
main(22) # Run the loop function to keep script running
因此,在 Anton Glukhov 向我解释了要注意的事项之后,我找到了解决每个问题的方法,现在它运行得非常完美。
这是 link 更好地解释了我所做的事情:
http://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
不幸的是,除了在 main 函数中使用 while 循环之外,我无法以任何其他方式做到这一点。
但是由于没有任何重要的事情发生,每个循环都增加了 1 秒的休眠时间,以确保使用最少的 CPU。
我在这里分享最终代码,希望对其他人有所帮助:
# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
from time import sleep
from os import system
gpio.setmode(gpio.BCM) # Set pin numbering to BCM numbering
gpio.setup(22, gpio.IN) # Set up pin 22 as an input
def confirmation(pin):
#print "Confirmation Function on pin %d" % pin
system('echo Press again to confirm Shut down menu! | wall -n') # let all logged in users know
gpio.remove_event_detect(pin)
gpio.add_event_detect(pin, gpio.RISING, bouncetime=200)
sleep(2) # if button has been pressed again within 2 seconds, shut down function is called
if gpio.event_detected(pin):
shutdown(pin)
else:
#print "canceled"
system('echo Shut down canceled! | wall -n') # let all logged in users know
main()
def resetPin(pin):
#print "Pin %d has been reset" % pin
gpio.remove_event_detect(pin)
gpio.add_event_detect(pin, gpio.RISING, bouncetime=200)
def reboot(pin):
#print "Reboot Function on pin %d" % pin
call('reboot', shell=False)
exit(0)
# Define a function to run when an interrupt is called
def shutdown(pin):
#print "ShutDown function on pin %d" % pin
system('echo Press again if you want to reboot instead of shut down! | wall -n') # let all logged in users know
gpio.remove_event_detect(pin)
gpio.add_event_detect(pin, gpio.RISING, bouncetime=200)
sleep(2) # if the button has been pressed for a third time, within 2 seconds, Pi will reboot
if gpio.event_detected(pin):
reboot(pin)
else:
call('halt', shell=False)
exit(0)
# Define a function to keep script running
def main():
#print "Main Function"
resetPin(22)
while True:
sleep(1)
if gpio.event_detected(22):
confirmation(22)
main() # Run the main function to keep script running
我从这里得到了 Python 中的一段代码: http://www.raspberry-pi-geek.com/Archive/2013/01/Adding-an-On-Off-switch-to-your-Raspberry-Pi
我想改进它。
因为这是我第一次使用 Python,所以我一直在理解实际发生的事情。
代码如下:
# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
from time import sleep
gpio.setmode(gpio.BCM) # Set pin numbering to board numbering
gpio.setup(22, gpio.IN) # Set up pin 22 as an input
rebootBool = 0
# Define a function to keep script running
def main(pin):
while True:
#gpio.remove_event_detect(pin)
gpio.add_event_detect(22, gpio.RISING, callback=confirmation, bouncetime=200) # Set up an interrupt to look for button presses
sleep(5000000)
def confirmation(pin):
gpio.remove_event_detect(pin)
gpio.add_event_detect(22, gpio.RISING, callback=shutdown, bouncetime=200)
sleep(3) # if button has been pressed again within 3 seconds, shut down will happen
main(22)
def reboot(pin):
rebootBool = 1
call('reboot', shell=False)
exit(0)
# Define a function to run when an interrupt is called
def shutdown(pin):
gpio.remove_event_detect(pin)
gpio.add_event_detect(22, gpio.RISING, callback=reboot, bouncetime=200)
sleep(3) # if the button has been pressed for a third time, within 3 seconds, Pi will reboot
if rebootBool == 0: # Just to make sure a halt is not called after the 3 seconds have passed, if reboot is called
call('halt', shell=False)
exit(0)
main(22) # Run the loop function to keep script running
我想做的是:
- 如果按钮被按下一次,则执行确认功能,如果在 3 秒内被按下,它会重置按钮以调用关机功能。
- 否则,继续主循环
- 在关机函数中,如果再次按下(3秒以内),则复位调用重启函数。
- 否则继续,关闭
这是怎么回事:
如果我按按钮两次或三次,它会告诉我 gpio.add_event_detect 已经定义,当它试图在 main() 中定义它时。 所以它不会改变它,如果我再按一次,它会调用关机功能。
我不明白的是:
为什么要在 main 中定义 gpio 事件,而实际功能是重启或关机(并且它应该调用重启或关机)?
因为回调函数运行在一个单独的线程中。这意味着,例如,当您在主循环中调用任何回调函数时它仍然有效(主循环),因此当您从回调函数(线程#1)和从主循环(线程#2)同时。这是典型的比赛条件。 您可以通过运行此代码进行检查:
#!/usr/bin/python
# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
from time import sleep
gpio.setmode(gpio.BCM) # Set pin numbering to board numbering
gpio.setup(22, gpio.IN, pull_up_down=gpio.PUD_DOWN) # Set up pin 22 as an input
rebootBool = 0
# Define a function to keep script running
def main(pin):
while True:
print "main loop"
gpio.remove_event_detect(22)
gpio.add_event_detect(22, gpio.RISING, callback=confirmation, bouncetime=200) # Set up an interrupt to look for button presses
sleep(1)
#raw_input()
def confirmation(pin):
print "confirmation1"
sleep(5)
print "confirmation2"
gpio.remove_event_detect(22)
gpio.add_event_detect(22, gpio.RISING, callback=shutdown, bouncetime=200)
sleep(5) # if button has been pressed again within 3 seconds, shut down will happen
gpio.remove_event_detect(22)
main(22)
def reboot(pin):
rebootBool = 1
print "reboot"
#call('reboot', shell=False)
exit(0)
# Define a function to run when an interrupt is called
def shutdown(pin):
print "shutdown"
gpio.remove_event_detect(pin)
gpio.add_event_detect(22, gpio.RISING, callback=reboot, bouncetime=200)
sleep(3) # if the button has been pressed for a third time, within 3 seconds, Pi will reboot
if rebootBool == 0: # Just to make sure a halt is not called after the 3 seconds have passed, if reboot is called
#call('halt', shell=False)
print "halt"
exit(0)
main(22) # Run the loop function to keep script running
因此,在 Anton Glukhov 向我解释了要注意的事项之后,我找到了解决每个问题的方法,现在它运行得非常完美。
这是 link 更好地解释了我所做的事情: http://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
不幸的是,除了在 main 函数中使用 while 循环之外,我无法以任何其他方式做到这一点。 但是由于没有任何重要的事情发生,每个循环都增加了 1 秒的休眠时间,以确保使用最少的 CPU。
我在这里分享最终代码,希望对其他人有所帮助:
# Import the modules to send commands to the system and access GPIO pins
from subprocess import call
import RPi.GPIO as gpio
from time import sleep
from os import system
gpio.setmode(gpio.BCM) # Set pin numbering to BCM numbering
gpio.setup(22, gpio.IN) # Set up pin 22 as an input
def confirmation(pin):
#print "Confirmation Function on pin %d" % pin
system('echo Press again to confirm Shut down menu! | wall -n') # let all logged in users know
gpio.remove_event_detect(pin)
gpio.add_event_detect(pin, gpio.RISING, bouncetime=200)
sleep(2) # if button has been pressed again within 2 seconds, shut down function is called
if gpio.event_detected(pin):
shutdown(pin)
else:
#print "canceled"
system('echo Shut down canceled! | wall -n') # let all logged in users know
main()
def resetPin(pin):
#print "Pin %d has been reset" % pin
gpio.remove_event_detect(pin)
gpio.add_event_detect(pin, gpio.RISING, bouncetime=200)
def reboot(pin):
#print "Reboot Function on pin %d" % pin
call('reboot', shell=False)
exit(0)
# Define a function to run when an interrupt is called
def shutdown(pin):
#print "ShutDown function on pin %d" % pin
system('echo Press again if you want to reboot instead of shut down! | wall -n') # let all logged in users know
gpio.remove_event_detect(pin)
gpio.add_event_detect(pin, gpio.RISING, bouncetime=200)
sleep(2) # if the button has been pressed for a third time, within 2 seconds, Pi will reboot
if gpio.event_detected(pin):
reboot(pin)
else:
call('halt', shell=False)
exit(0)
# Define a function to keep script running
def main():
#print "Main Function"
resetPin(22)
while True:
sleep(1)
if gpio.event_detected(22):
confirmation(22)
main() # Run the main function to keep script running