编程语言
首页 > 编程语言> > 带按钮的Python GPIO触发LED

带按钮的Python GPIO触发LED

作者:互联网

我正在尝试在Raspberry Pi上控制LED并使其发光.

我希望按下按钮时LED点亮,并保持该状态直到再次按下按钮.

我已经实现了以下代码,并且效果很好.但是,当我按下按钮或按住按钮的速度不够快时,我会遇到问题.

import RPi.GPIO as GPIO
from time import sleep

inpin = 16
outpin = 20

GPIO.setmode(GPIO.BCM)
counter = 0
GPIO.setup(outpin, GPIO.OUT)
GPIO.setup(inpin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

try:
        while True:

                if GPIO.input(inpin):
                        if counter == 0:
                                print "port is low"
                                GPIO.output(outpin, 0)
                                counter = 0

                        else:
                                print "port is high"
                                GPIO.output(outpin, 1)
                                counter = 1
                else:
                        if counter == 1:
                                print "port is low"
                                GPIO.output(outpin, 0)
                                counter = 0
                        else:
                                print "port is high"
                                GPIO.output(outpin, 1)
                                counter = 1
                sleep(0.1)

finally:
        GPIO.cleanup()

以“ TessellatingHeckler”建议的方式完美实施.
即使有多个输入和输出,它也可以完美工作.
重要的是“ elif”循环,以确保状态快速变化.
这是工作代码:

import RPi.GPIO as GPIO
from time import sleep



GPIO.setmode(GPIO.BCM)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(20, GPIO.OUT)
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(27, GPIO.OUT)


btn1_button = 'up'
btn1_light = 'off'

btn2_button = 'up'
btn2_button = 'off'



def LED1(output):
    GPIO.output(20, output)

def LED2(output):
    GPIO.output(27, output)

while True:


######################## BUTTON 1 ########################
    if (btn1_button == 'up' and btn1_light == 'off'):
            if not  GPIO.input(16):
            print "LED1 ON"
            LED1(1)         
            btn1_button = 'down'
            btn1_light = 'on'


    elif (btn1_button == 'down' and btn1_light == 'on'):
            if GPIO.input(16):
            btn1_button = 'up'


    elif (btn1_button == 'up' and btn1_light == 'on'):
            if not GPIO.input(16):
            print "LED1 OFF"
            LED1(0)
            btn1_button = 'down'
            btn1_light = 'off'


    elif (btn1_button == 'down' and btn1_light == 'off'):
            if GPIO.input(16):
            btn1_button = 'up'

###########################################################

####################### BUTTON 2 ##########################
    if (btn2_button == 'up' and btn2_light == 'off'):
                if not  GPIO.input(17):
                        print "LED2 ON"
                        LED2(1)
                        btn2_button = 'down'
                        btn2_light = 'on'

    elif (btn2_button == 'down' and btn2_light == 'on'):
                if GPIO.input(17):
                        btn2_button = 'up'


    elif (btn2_button == 'up' and btn2_light == 'on'):
                if not GPIO.input(17):
                        print "LED2 OFF"
                        LED2(0)
                        btn2_button = 'down'
                        btn2_light = 'off'


    elif (btn2_button == 'down' and btn2_light == 'off'):
                if GPIO.input(17):
                        btn2_button = 'up'
    sleep(0.1)
###########################################################

GPIO.cleanup()

解决方法:

您用语言写了这个计划:

>按下按钮,指示灯点亮
>按下按钮,指示灯熄灭

但是您用代码编写的内容更像是:

>每秒10倍,

>如果按钮向上,则什么也不做
>如果按下按钮,请切换指示灯

这是完全不同的.按住按钮1/10秒以上,它开始变得怪异.我的意思是说您的代码会遍历整个循环,并且每次尝试更新所有内容时都将遍历.您正在跟踪整个循环中最后一次发生的情况,这意味着您最多只能保持一个循环持续时间.相反,您需要将循环与状态跟踪分开,以便状态可以一遍又一遍保持不变,并且仅当按钮更改时才让狗吃饼干.

是驱动系统状态的按钮,而不是时间流逝的按钮.系统可以处于4种可能的状态,如下所示:

(Button=Up, Light=Off) <----------------
        |                               |
        | Button pushed down            |
        \/                              |
(Button=Down, Light=/On/)               |
        |                               |
        | Button released               |
        \/                              |
(Button=Up, Light=On)                   |
        |                               |
        | Button pushed down            |
        \/                              |
(Button=Down, Light=/Off/)              |
        |                              / \
        | Button released               |
        |                               |
         -------------------------------

如果您明确编码这些状态并按照顺序进行操作,则让按钮成为唯一允许您从一个状态转到另一个状态的方法…按住按钮的时间过长,您将无法获得任何奇怪的行为.我希望.您当前的代码从(Button = Down,Light = On)跳转到(Button = Down,Light = Off)并再次返回.

我的代码未经测试,因此无法完全确定按下和释放按钮时GPIO.input()的运行方式.我假设大多数情况下是0 / False,按下按钮时是1 / True.

import RPi.GPIO as GPIO
from time import sleep

inpin = 16
outpin = 20

GPIO.setmode(GPIO.BCM)
GPIO.setup(outpin, GPIO.OUT)
GPIO.setup(inpin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

button='up'
light='off'

while True:

    if (button=='up'   and   light=='off'):
        # wait for button press before changing anything
        if not GPIO.input(inpin):
            GPIO.output(outpin, 1)
            button='down'; 
            light='on'

    elif (button=='down' and   light=='on'):
        # stay in this state until button released
        if GPIO.input(inpin):
            button='up'

    elif (button=='up'   and   light=='on'):
        if not GPIO.input(inpin):
            GPIO.output(outpin, 0)
            button='down'
            light='off'

    elif (button=='down' and   light=='off'):
        if GPIO.input(inpin):
            button='up'
    sleep(0.1)

因此,按钮和指示灯会跟踪系统的状态.每次循环时,只有一个if块会匹配,并且在获得将状态更改为下一个的按钮更改之前,它几乎什么都不做.

第一次,第一个块匹配,它检查是否有按钮按下.它一直在这样做.

按下按钮,现在第一个模块点亮LED并更新状态.

现在,每次循环时,(button ==’down’和light ==’on’)匹配.它处于状态2,只要您按下按钮,它就会一直保持该状态.每次循环时,它都会寻找按钮的释放,这是唯一可以触发任何状态更改的东西.

等等

标签:gpio,led,raspberry-pi,button,python
来源: https://codeday.me/bug/20191119/2038010.html