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。要仅打印从 TrueFalse 的那些,您应该能够对以 # 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

免责声明:为了更好地消除开关的可靠性,我会使用不同的代码,但这超出了这个问题的范围