带按钮的Python GPIO触发LED
我正试图控制和引导一个覆盆子圆周率 当我按下按钮时,我希望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
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倍,
- 如果按钮打开了,什么也不要做
- 如果按下按钮,则切换灯
(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()