带按钮的Python GPIO触发LED

2024-09-29 22:25:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着控制和引导一个树莓派。在

我希望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()

按照“细化海克勒”建议的方式来实现它是完美的。 即使有多个输入和输出,它也能完美工作。 重要的是“elif”循环来保证快速变化的状态。 工作代码如下:

^{pr2}$

Tags: 代码importoutputgpioifisport状态
2条回答

你用文字写了这个计划:

  • 按下按钮,灯亮
  • 按下按钮,灯熄灭

但你写的代码更像:

  • 每秒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/错误,按下按钮时是1/真。在

^{pr2}$

因此,button和{}跟踪系统的状态。每次循环中,只有if块中的一个匹配,并且在获得使状态更改到下一个的按钮更改之前,它基本上什么也不做。在

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

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

现在,每次循环中,(button=='down' and light=='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()    

相关问题 更多 >

    热门问题