我从这里得到了一段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事件,当实际函数是重启或关闭时(它应该调用reboot还是shutdown)?
2 回答
因为回调函数在单独的线程中运行 . 这意味着,例如,当您在主循环中调用任何回调函数时它仍然有效(主循环),因此当您从回调函数(线程#1)和主循环调用函数gpio.add_event_detect时会发生这种情况(线程#2)同时 . 这是典型的比赛条件 . 您可以通过运行此代码来检查它:
所以,在Anton Glukhov向我解释了要注意什么之后,我发现了如何解决每一个问题,现在它正在完美地运作 .
这是更好地解释我做了什么的链接:http://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
不幸的是,除了在main函数中使用while循环之外,我无法做任何其他方式 . 但由于没有任何重要的事情发生,每个循环都添加了1秒的睡眠,确保最小的CPU使用率 .
我在这里分享最终的代码,希望它可以帮助其他人: