1 目标效果

想要实现用外接在树莓派上的开关来对其进行关机操作的效果,对于一个简单的两档开关,按下“关”将使树莓派在几分钟后关机,如果再按下“开”的话则可以取消关机。

2 接线和编程

实现的原理其实很简单,在自己的程序中判断开关的状态,如果是按下了开关,就调用shutdown的系统命令来关机。

准备一个两档的开关,一头接在树莓派的GND脚,一头接在任意的GPIO口(我接在了BCM.4),将BCM.4脚设置为输入模式,并拉高电阻,这样开关断开的时候输入为高电平,闭合的时候为低电平。

然后编写程序。为了及时检测GPIO口的电平状态,可以使用add_event_detect方法为GPIO口添加回调函数,在遇到上升沿或下降沿的时候及时进行处理。当开关闭合时,产生一个下降沿,我们在此时通知系统关机;当开关断开时,产生一个上升沿,我们通知系统取消关机。程序如下:

import time
import RPi.GPIO as GPIO
import os,sys

#回调函数,检测GPIO口的电平高低进行相应的操作
def onSwitch(channel):
    if GPIO.input(channel)==GPIO.LOW:
        command='sudo shutdown -h +'+str(timeBeforeShutdown) #使用shutdown指令,表示在timeBeforeShutdown分钟后关机   
        os.system(command) #使用os.system函数执行指令
    else:
        command='sudo shutdown -c' #取消关机的指令
        os.system(command)

timeBeforeShutdown=1 #几分钟后关机

pin_switch=4
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(pin_switch,GPIO.IN,pull_up_down=GPIO.PUD_UP)

#设置为GPIO.BOTH,表示对上升沿和下降沿都进行捕获
GPIO.add_event_detect(pin_switch,GPIO.BOTH,callback=onSwitch)

try:
    while True:
        time.sleep(0.01)    
except:
    print('Close...')
finally:
    GPIO.cleanup()

3 结果

执行上面的程序,按下开关,shell中显示出shutdown的执行结果信息,表示已经启动关机操作。

再断开开关,此时关机已取消。