【问题标题】:How do I make a button execute a function once?如何让按钮执行一次功能?
【发布时间】:2021-05-13 23:55:12
【问题描述】:

我目前正在开发一个连接到树莓派的键盘。按下每个按钮时,都需要将一个字符串附加到列表中一次,然后重新启动循环,以便可以放置下一个输入。代码如下所示:

message = [] #final list will be stored here
loop = 0 #determines the position of each number inputted
while True:
  if (GPIO.input(12) == GPIO.HIGH) and (GPIO.input(19) == GPIO.HIGH): #the character pad works in an array, when 2 "buttons" are pressed, they correspond do a location on the pad
    message.insert(loop, "1") #inserts the number into the list
    loop = loop + 1
  if (GPIO.input(12) == GPIO.HIGH) and (GPIO.input(15) == GPIO.HIGH):
    messege.insert(loop, "4")
    loop = loop + 1
  #this repeats for the other 14 buttons however the code is the same

如果按下“1”的按钮,然后按下“4”,则此代码的输出应该如下所示:

['1' '4']

但是,输出看起来像这样:

['1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1' '1...]

有没有办法让每个按钮每次按下激活一次?

这段代码中的按钮都是在pud_down中设置的

【问题讨论】:

  • 这里需要的叫做“边缘检测”。您需要保持输入的当前状态,当状态与您的理解发生变化时,您就需要采取行动。请记住,只要按下按钮,GPIO 线就会保持有效状态,并且它们将被按下很多次循环。

标签: python button arraylist raspberry-pi gpio


【解决方案1】:

考虑这样的事情。关键是不要评估状态,除非您知道某些情况发生了变化:

message = [] #final list will be stored here
loop = 0 
states = {
    12: GPIO.LOW,
    15: GPIO.LOW,
    19: GPIO.LOW
}
while True:
    change = False
    for line in (12,15,19):
        if GPIO.input(line) != states[line]:
            states[line] = GPIO.input(line)
            change = True

    if change:
        change = False
        if states[12]==GPIO.HIGH and states[19]==GPIO.HIGH:
            message.insert(loop, "1") #inserts the number into the list
            loop = loop + 1
        if states[12]==GPIO.HIGH and states[15]==GPIO.HIGH:
            messege.insert(loop, "4")
            loop = loop + 1

【讨论】:

    【解决方案2】:

    这是一种面向对象的方法。你可以创建一个Button 类。每个按钮都可以处于pressedreleased 状态。每当最初按下按钮时,它都会将消息附加到类变量Button.messages。在释放之前,相同的按钮不会附加另一条消息。在主轮询循环中,我们遍历所有按钮并按下或释放它们,具体取决于哪些引脚为高电平:

    class Button:
    
        messages = []
    
        def __init__(self, value):
            self.value = value
            self.is_pressed = False
    
        def hold(self):
            if not self.is_pressed:
                Button.messages.append(value)
                self.is_pressed = True
    
        def release(self):
            self.is_pressed = False
    
    
    buttons = {
        (12, 19): Button("1"),
        (12, 15): Button("4"),
        # ...
    }
    
    row_pins = (12, 13, 14) # You'll have to change these. I don't know what these values should be
    col_pins = (19, 15, 10) # You'll have to change these. I don't know what these values should be
    
    while True:
        for row in row_pins:
            for col in col_pins:
                button = buttons[(row, col)]
                (button.release, button.hold)[all((GPIO.input(pin) for pin in (row, col)))]()
    

    【讨论】:

      【解决方案3】:

      试试这个

      message = [] #final list will be stored here
      loop = 0 #determines the position of each number inputted
      val i = 0
      val k = 0
      bool canPressAgain =true
      while True:
        if (GPIO.input(i) == GPIO.LOW) and (GPIO.input(k) == GPIO.LOW):
          canPressAgain=true;
        if (GPIO.input(12) == GPIO.HIGH) and (GPIO.input(19) == GPIO.HIGH): 
          #the character pad works in an array, when 2 "buttons" are pressed, they correspond do a location on the pad
          i = 12
          k = 19
          message.insert(loop, "1") #inserts the number into the list
          loop = loop + 1
        if (GPIO.input(12) == GPIO.HIGH) and (GPIO.input(15) == GPIO.HIGH):
          i = 12
          k = 15
          messege.insert(loop, "4")
          loop = loop + 1
        canPressAgain = false; #Put this at the end of all 'if' statements
        #this repeats for the other 14 buttons however the code is the same
      

      【讨论】:

      • 那应该是什么语言?它看起来像是 C++、Python 和 Javascript 的组合。您可以选择一种语言并再次尝试您的答案吗?
      • @TimRoberts 已编辑。读者应该知道的主要内容是,默认情况下,“canPressAgain”布尔值是错误的; i & k 的值总是设置为最后按下按钮的输入变量。每个循环,如果带有 i&k 输入变量的按钮关闭(在处于打开状态后,需要设置 i 和 k),则可以按下另一个按钮并添加它的值。我希望这可以解决蒂姆:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      相关资源
      最近更新 更多