Python "shutdown/reboot raspberry pi"脚本,使用单个按钮

标签 python linux raspberry-pi interrupt

我从这里得到一段 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)和主循环中调用函数 gpio.add_event_detect 时会发生这种情况(线程#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

关于Python "shutdown/reboot raspberry pi"脚本,使用单个按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30334424/

相关文章:

linux - Docker - 从 docker 容器中重启树莓派主机

python - tensorflow - 线性回归 : Not proper able to do proper plotting

python - 有没有一种有效的方法可以从数组索引计算两个 3D 向量的点积?

Python 使用 Seaborn Relplot 绘制带有列表单元格的数据框

python - 在 Python 2.6 中打印 float 的 str.format() 错误

php - 如何读取名称中包含空格和特殊字符的文件?

regex - 在终端中替换包含正则表达式的文本

node.js - pm2 在 Raspberry Pi 上失败

tcp - Pymodbus 无法连接 PLC Slave 和 Raspberry Pi Master

python - RaspberryPi 3 上的 Google Assistant SDK - sounddevice.PortAudioError