ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

带按钮的Python GPIO触发LED

2019-11-19 17:55:58  阅读:418  来源: 互联网

标签:gpio led raspberry-pi button python


我正在尝试在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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有