带按钮的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