Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带按钮的Python GPIO触发LED_Python_Button_Raspberry Pi_Gpio_Led - Fatal编程技术网

带按钮的Python GPIO触发LED

带按钮的Python GPIO触发LED,python,button,raspberry-pi,gpio,led,Python,Button,Raspberry Pi,Gpio,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(in

我正试图控制和引导一个覆盆子圆周率

当我按下按钮时,我希望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()
按照“Tessellingheckler”建议的方式实现它是完美的。 即使有多个输入和输出,它也能完美工作。 重要的是“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倍,
    • 如果按钮打开了,什么也不要做
    • 如果按下按钮,则切换灯
这是完全不同的。按住按钮超过十分之一秒,它开始变得奇怪。我的评论的意思是,你的代码经过循环,每次它试图更新一切;您正在跟踪上一次循环中发生的情况,这意味着您不能持有超过一个循环持续时间的任何内容。相反,您需要将循环与状态跟踪分开,这样状态可以一次又一次地保持不变,并且只在按钮更改时让狗吃饼干

它是驱动系统状态的按钮,而不是时间的传递。系统可能处于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               |
        |                               |
         -------------------------------
因此,
按钮
跟踪系统的状态。每次通过循环时,只有一个
if
块匹配,并且在按钮更改使状态更改为下一个之前,它几乎什么也不做

第一次通过时,第一个块匹配,它检查是否按下按钮。它一直这样做

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

现在,每次通过循环时,
(按钮=='down'和灯=='on')
匹配。它处于状态2,只要你按下按钮,它就会一直处于该状态。每次通过循环,它都会寻找按钮释放,这是唯一能触发任何状态变化的东西


等等。

尝试以下操作,这样可以消除启动时的“led开启”问题:

import RPi.GPIO as GPIO
from time import sleep

inpin = 11
outpin = 7

GPIO.setmode(GPIO.BOARD)
GPIO.setup(outpin, GPIO.OUT)
GPIO.setup(inpin, GPIO.IN)

x=0
y=0

try:

   while True:

     if (x==0   and   y==0):
           # wait for button press before changing anything
          if GPIO.input(inpin) == 0:
                 GPIO.output(outpin, 0)
                 x=0 
                 y=1
                 print("led off")

     elif (x==0  and   y==1):
           # stay in this state until button released
          if GPIO.input(inpin) == 1:
             x = 1

     elif (x==1   and   y==1):
          if GPIO.input(inpin) == 0:
                 GPIO.output(outpin, 1)
                 x=1
                 y=0
                 print("led on")

     elif (x==1 and   y==0):
          if GPIO.input(inpin) == 1:
             x=0
     sleep(0.1)


except KeyboardInterrupt:
          GPIO.output(outpin, 0)
          GPIO.cleanup()    

你的描述只提到按下按钮。你忘记了释放按钮。在松开并重新按下按钮之前,不要再进行任何LED更改。您是在说类似的事情吗将RPi.GPIO作为GPIO GPIO.setmode(GPIO.BCM)GPIO.setup(4,GPIO.IN,pull_up_down=GPIO.PUD_down)GPIO.setup(25,GPIO.OUT,initial=GPIO.LOW)GPIO.add_event_detect(4,GPIO.BOTH)def my_callback():GPIO.output(25,GPIO.input(4))GPIO.add_event_callback(4,my_callback)如果您的编辑是文件的准确副本,btn2的压痕混合;btn2的最后三个“如果”测试缩进太远,它们都在第一个测试的内部。这不是因为缩进。我编辑的帖子只是一个巨大的打字错误,一切正常。再次感谢您的帮助谢谢您的完美输入!我现在正在实施这个想法,并将在我实施并反复测试后发布结果。有两个问题:第一个问题是,在程序启动后,LED灯就亮了,我当时没有按任何键。第二个问题是,LED无法保持其状态。当我按下按钮时,LED灯熄灭,松开后,它又亮了。我想这意味着我读错了按钮-与实际相反。尝试更改这两个
if-GPIO.input(inpin):
以便他们说
if-not-GPIO.input(inpin):
并从另外两个中删除
not
。(我也用这个变化更新了我的帖子)。是的,我也这么认为,所以后来我改变了它,但它仍然不能完美地工作。这比以前好多了。我现在唯一的问题是,状态并非总是正确地改变。我将再次测试它并显示结果经过一些测试后,我得出结论,它工作得很好。它适合我的需要,唯一没有用处的情况是当你想经常使用按钮时,因为在状态之间快速切换会导致意外的结果!但是谢谢你的解决方案。这对于meThis来说是完美的,它消除了startHello的“led on”问题,而不是将解释放在对答案的评论中,并在答案旁边向提问者提供信息。
import RPi.GPIO as GPIO
from time import sleep

inpin = 11
outpin = 7

GPIO.setmode(GPIO.BOARD)
GPIO.setup(outpin, GPIO.OUT)
GPIO.setup(inpin, GPIO.IN)

x=0
y=0

try:

   while True:

     if (x==0   and   y==0):
           # wait for button press before changing anything
          if GPIO.input(inpin) == 0:
                 GPIO.output(outpin, 0)
                 x=0 
                 y=1
                 print("led off")

     elif (x==0  and   y==1):
           # stay in this state until button released
          if GPIO.input(inpin) == 1:
             x = 1

     elif (x==1   and   y==1):
          if GPIO.input(inpin) == 0:
                 GPIO.output(outpin, 1)
                 x=1
                 y=0
                 print("led on")

     elif (x==1 and   y==0):
          if GPIO.input(inpin) == 1:
             x=0
     sleep(0.1)


except KeyboardInterrupt:
          GPIO.output(outpin, 0)
          GPIO.cleanup()