Python 不要重复连续的行
Python Don't Repeat Consecutive Lines
我正在编写 python 脚本,它将在网络浏览器中显示 raspberry pi 的 gpio 输入引脚的状态。此脚本仅用于后端测试:
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
GPIO.setup(29, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(32, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(37, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
input_state = GPIO.input(37)
if input_state == False:
print('One')
time.sleep(0.2)
input_state = GPIO.input(32)
if input_state == False:
print('Two')
time.sleep(0.2)
input_state = GPIO.input(29)
if input_state == False:
print('Three')
time.sleep(.02)
我的输出疯狂地向屏幕发送数字,直到输入开关被关闭。如何防止相同的连续行立即重复?
谢谢!
您可以修改代码以使用 'on change' 类型逻辑:
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
# allows you to rename the io ports
io_names = [ 'One', 'Two', 'Three' ]
class IOMonitor():
def __init__( self, num , io, pud ):
self.num = num
GPIO.setup(self.num, io, pull_up_down=pud)
self.last_state = GPIO.input(self.num)
def poll( self ):
# detect current state
current_state = GPIO.input(self.num)
# compare with old state
if( current_state != self.last_state ):
# set new last state
self.last_state = current_state
# print name of io that changed
print( io_names[self.num] )
ioMonitors = [
IOMonitor(29, GPIO.IN, GPIO.PUD_UP),
IOMonitor(32, GPIO.IN, GPIO.PUD_UP),
IOMonitor(37, GPIO.IN, GPIO.PUD_UP)
]
def main():
while True:
for io in ioMonitors:
io.poll()
time.sleep(0.2)
main()
我无权访问您的库,因此此代码未经测试,但在逻辑上应该是正确的。
仅当输入状态实际改变时才打印怎么样?像这样的东西(未经测试):
# Your code to initialise everything:
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
GPIO.setup(29, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(32, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(37, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# New loop keeping track of the previous ("old") input states:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
if input_states != old_input_states:
for n, name in enumerate(['One', 'Two', 'Three']):
if input_states[n] == False:
print name
old_input_states = input_states
所以解释一下这个新的循环代码在做什么:
- 首先,创建一个包含三个
None
条目的列表 old_input_states
。这将用于记住三个 GPIO 的最后状态。
- 然后在循环开始时,调用
GPIO.input(n)
函数,因为n
三个GPIO分别为37、32和29。结果列表 input_states
现在包含三个 GPIO 状态。
- 然后将此列表与
old_input_states
列表进行比较,如果它们不同,它将执行以下操作:
- 对于
'One'
、'Two'
和'Three'
中的每个name
(由n
枚举,即对于'One'
它是0, 1 表示 'Two'
,2 表示 'Three'
),它检查 input_states[n]
的值,看它是否是 False
,如果是,它打印 name
应该匹配相应的 GPIO。
- 然后它更新
old_input_states
以匹配 input_states
因此在下一个循环中,它只会在 input_states
更改时再次检查(并可能打印)。
编辑
请注意,代码将输出 所有 个 GPIO,这些 GPIO 当前在检测到更改时 False
。要仅打印从 True
到 False
的那些,您应该能够对以 # New loop
注释开头的部分使用以下代码:
# New loop keeping track of the previous ("old") input states:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
for n, name in enumerate(['One', 'Two', 'Three']):
if input_states[n] != old_input_states[n] and input_states[n] == False:
print name
old_input_states = input_states
编辑 2
正如 OP 所指出的,首选输出无论如何都是列表形式的。此外,似乎在 GPIO 的开关输入上发生了一些弹跳,这可以通过使用 time.sleep
调用来改善。此外,输出应反转。 while
循环的最终代码如下所示:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
if input_states != old_input_states:
inverted_input_states = [1 - i for i in input_states]
print inverted_input_states
time.sleep(0.2)
old_input_states = input_states
免责声明:为了更好地消除开关的可靠性,我会使用不同的代码,但这超出了这个问题的范围
我正在编写 python 脚本,它将在网络浏览器中显示 raspberry pi 的 gpio 输入引脚的状态。此脚本仅用于后端测试:
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
GPIO.setup(29, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(32, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(37, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
input_state = GPIO.input(37)
if input_state == False:
print('One')
time.sleep(0.2)
input_state = GPIO.input(32)
if input_state == False:
print('Two')
time.sleep(0.2)
input_state = GPIO.input(29)
if input_state == False:
print('Three')
time.sleep(.02)
我的输出疯狂地向屏幕发送数字,直到输入开关被关闭。如何防止相同的连续行立即重复? 谢谢!
您可以修改代码以使用 'on change' 类型逻辑:
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
# allows you to rename the io ports
io_names = [ 'One', 'Two', 'Three' ]
class IOMonitor():
def __init__( self, num , io, pud ):
self.num = num
GPIO.setup(self.num, io, pull_up_down=pud)
self.last_state = GPIO.input(self.num)
def poll( self ):
# detect current state
current_state = GPIO.input(self.num)
# compare with old state
if( current_state != self.last_state ):
# set new last state
self.last_state = current_state
# print name of io that changed
print( io_names[self.num] )
ioMonitors = [
IOMonitor(29, GPIO.IN, GPIO.PUD_UP),
IOMonitor(32, GPIO.IN, GPIO.PUD_UP),
IOMonitor(37, GPIO.IN, GPIO.PUD_UP)
]
def main():
while True:
for io in ioMonitors:
io.poll()
time.sleep(0.2)
main()
我无权访问您的库,因此此代码未经测试,但在逻辑上应该是正确的。
仅当输入状态实际改变时才打印怎么样?像这样的东西(未经测试):
# Your code to initialise everything:
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
GPIO.setup(29, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(32, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(37, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# New loop keeping track of the previous ("old") input states:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
if input_states != old_input_states:
for n, name in enumerate(['One', 'Two', 'Three']):
if input_states[n] == False:
print name
old_input_states = input_states
所以解释一下这个新的循环代码在做什么:
- 首先,创建一个包含三个
None
条目的列表old_input_states
。这将用于记住三个 GPIO 的最后状态。 - 然后在循环开始时,调用
GPIO.input(n)
函数,因为n
三个GPIO分别为37、32和29。结果列表input_states
现在包含三个 GPIO 状态。 - 然后将此列表与
old_input_states
列表进行比较,如果它们不同,它将执行以下操作:- 对于
'One'
、'Two'
和'Three'
中的每个name
(由n
枚举,即对于'One'
它是0, 1 表示'Two'
,2 表示'Three'
),它检查input_states[n]
的值,看它是否是False
,如果是,它打印name
应该匹配相应的 GPIO。 - 然后它更新
old_input_states
以匹配input_states
因此在下一个循环中,它只会在input_states
更改时再次检查(并可能打印)。
- 对于
编辑
请注意,代码将输出 所有 个 GPIO,这些 GPIO 当前在检测到更改时 False
。要仅打印从 True
到 False
的那些,您应该能够对以 # New loop
注释开头的部分使用以下代码:
# New loop keeping track of the previous ("old") input states:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
for n, name in enumerate(['One', 'Two', 'Three']):
if input_states[n] != old_input_states[n] and input_states[n] == False:
print name
old_input_states = input_states
编辑 2
正如 OP 所指出的,首选输出无论如何都是列表形式的。此外,似乎在 GPIO 的开关输入上发生了一些弹跳,这可以通过使用 time.sleep
调用来改善。此外,输出应反转。 while
循环的最终代码如下所示:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
if input_states != old_input_states:
inverted_input_states = [1 - i for i in input_states]
print inverted_input_states
time.sleep(0.2)
old_input_states = input_states
免责声明:为了更好地消除开关的可靠性,我会使用不同的代码,但这超出了这个问题的范围