我正在尝试控制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()
答案 0 :(得分:3)
你用文字写了这个计划:
但你在代码中写的更像是:
这是完全不同的。按住按钮超过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)
因此,button
和light
会跟踪系统的状态。每次循环时,只有if
块中的一个匹配,并且在获得按钮更改之前它几乎不会执行任何操作,从而使状态更改为下一个。
第一次通过,第一个块匹配,它检查按下按钮。它一直这样做。
按下按钮,现在第一个模块点亮LED并更新状态。
现在,每次循环,(button=='down' and light=='on')
都匹配。它处于状态2,并且只要按下按钮就会保持该状态。每次循环都会查找按钮释放,这是唯一可以触发任何状态更改的东西。
等
答案 1 :(得分:0)
请尝试以下操作,这可以消除启动时的“启动指示灯”问题:
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()