【问题标题】:Python script with many elif for GPIO in and out带有许多用于 GPIO 输入和输出的 elif 的 Python 脚本
【发布时间】:2015-02-04 00:26:47
【问题描述】:

我编写了一个 python 脚本来检测瞬时按钮按下并将每个按钮记录到一个文件中。每次按下时,一个 LED 也会通过 GPIO.OUT 亮起。 原始文件可以创造奇迹,但是我目前需要在混合中添加两个按钮(现在总共 4 个),每个按钮还将写入一个文件并点亮一个 LED。当我执行我认为应该工作的脚本时,只有按钮 1 工作。任何有关如何调试非工作代码的帮助表示赞赏。

非工作代码(4 个按钮):

#!/usr/bin/env python

import RPi.GPIO as GPIO
import time
import serial
import syslog
import MySQLdb as mdb
import subprocess

poursdir = '/var/www/RPints'
path = '/var/www/RPints/includes/pours.php'

outpin1 = 26
inpin1 = 18
outpin2 = 16
inpin2 = 23
outpin3 = 6
inpin3 = 17
outpin4 = 5
inpin4 = 22

GPIO.setmode(GPIO.BCM)
GPIO.setup(outpin1, GPIO.OUT)
GPIO.setup(inpin1, GPIO.IN)
GPIO.setup(outpin2, GPIO.OUT)
GPIO.setup(inpin2, GPIO.IN)
GPIO.setup(outpin3, GPIO.OUT)
GPIO.setup(inpin3, GPIO.IN)
GPIO.setup(outpin4, GPIO.OUT)
GPIO.setup(inpin4, GPIO.IN)

while True:
    value1 = GPIO.input(inpin1) 
    value2 = GPIO.input(inpin2)
    value3 = GPIO.input(inpin3)
    value4 = GPIO.input(inpin4)
    if not value1 or value2 or value3 or value4:     
        GPIO.output(outpin1, 0)
        GPIO.output(outpin2, 0)
        GPIO.output(outpin3, 0)
        GPIO.output(outpin4, 0)
    else:
        if value1:
            GPIO.output(outpin1, 1)
            subprocess.call(["php", path, "1", "1"])
        elif value2:
            GPIO.output(outpin2, 1)
            subprocess.call(["php", path, "2", "1"])
        elif value3:
            GPIO.output(outpin3, 1)
            subprocess.call(["php", path, "3", "1"])
        elif value4:
            GPIO.output(outpin4, 1)
            subprocess.call(["php", path, "4", "1"])
    time.sleep(.3)
GPIO.cleanup()

工作代码(2 按钮):

 #!/usr/bin/env python
import RPi.GPIO as GPIO
import time
import serial
import syslog
import MySQLdb as mdb
import subprocess

poursdir = '/var/www/RPints'
path = '/var/www/RPints/includes/pours.php'

outpin1 = 26
inpin1 = 18
outpin2 = 16
inpin2 = 23

GPIO.setmode(GPIO.BCM)
GPIO.setup(outpin1, GPIO.OUT)
GPIO.setup(inpin1, GPIO.IN)
GPIO.setup(outpin2, GPIO.OUT)
GPIO.setup(inpin2, GPIO.IN)

while True:
    value1 = GPIO.input(inpin1) 
    value2 = GPIO.input(inpin2)
    if not value1 and not value2:    
        GPIO.output(outpin1, 0)
        GPIO.output(outpin2, 0)
    else:
        if value1 and not value2:
            GPIO.output(outpin1, 1)
            subprocess.call(["php", path, "1", "1"])
        elif value2 and not value1:
            GPIO.output(outpin2, 1)
            subprocess.call(["php", path, "2", "1"])
    time.sleep(.3)
    time.sleep(.05) 
GPIO.cleanup()

【问题讨论】:

  • 你为什么改变'if not value1 or value2 or value3 or value4'的逻辑?工作代码不同。

标签: python gpio


【解决方案1】:

您是否应该检查完整的 一组值?即

if not value1 and not value2 and not value3 and not value4:
       # reset
elif value1 and not value2 and not value3 and not value4:
      #light up led 1
elif not value1 and value2 and not value3 and not value4:
      #light up led 2
elif not value1 and not value2 and value3 and value4:
     #light up 3
elif not value1 and not value2 and not value3 and value4
      #light up 4

【讨论】:

  • 我没有检查全套,因为我一次只会按一个按钮。我确实尝试为每个添加“而不是 valueX”,但这对我的结果没有帮助,所以为了简单起见,我把它省略了。最后,也许包含以防万一是个好主意。
  • 我回来做生意了,基本上按照你的逻辑。但是,它在第​​ 4 个 elif 语句之后挂断。我已经为每个 elif 添加了打印语句,直到第 4 次才打印任何内容,并且它不断循环。我需要添加什么来停止它?之后添加一个 else 没有做任何事情,因为它无法到达 else。输入此内容后,可能是电线短路。以防万一,告诉我你是否认为可以添加代码来修复。
  • 正如我所料,在全部切换到之后不需要额外的代码,除非每个条件都为 elif 语句保留为 True。问题是我选择的 GPIO 引脚 22,它默认为 out,因此脚本认为在每 0.3 秒休息后总是按下按钮。感谢大家的想法!
【解决方案2】:

啊啊!我花了一分钟,但我意识到当你说 if not value1 or value2 or value3 or value4: 时,python 读取它的方式,如果 value1 为 false(如果你按下任何其他按钮),if 看起来像这样:

if True or False or False or False:
    print "write zero"

Python 读取 if not value1 和各种 ors(无关紧要)。因为 value1 为 false(当您按下除它以外的任何按钮时),而 not value1 为 True,所以它执行 if 块中的操作。你以为它会写成“如果不是这些,就做这个”,但实际上它正在做的是“如果与这个或其中任何一个相反”。要修复它,请返回使用 and not value2 等作为您的 4 按钮脚本。

编辑:是的@compie 是对的,逻辑是问题

【讨论】:

    【解决方案3】:

    您可以尝试使用 switch 样式的语句。例如:

    定义新闻(事件): 返回 { “价值1”:1, “价值2”:2, “价值3”:3, 'value4': 4, }.get(事件,无) 而真: v1 = GPIO.输入(inp1) v2 = GPIO.输入(inp2) v3 = GPIO.输入(inp3) v4 = GPIO.输入(inp4) 值 = [v1,v2,v3,v4] 对于值中的事件: 新闻(事件) #仅用于调试.. 如果不是事件 == '无': 打印(按(事件))

    这将创建一个函数,该函数将接受任何值,并确定它是哪个值,并根据收到的内容返回一个代码。

    while 循环显然只是不断检查每个 GPIO 输入中的非“无”值。

    我没有机会在 Pi 上对此进行测试,所以我可能遗漏了一些东西,但我认为这可能是一个解决方案。

    【讨论】:

      【解决方案4】:

      工作代码:

      #!/usr/bin/env python
      
      import RPi.GPIO as GPIO
      import time
      import serial
      import syslog
      import MySQLdb as mdb
      import subprocess
      
      poursdir = '/var/www/RPints'
      path = '/var/www/RPints/includes/pours.php'
      
      outpin1 = 26
      inpin1 = 18
      outpin2 = 16
      inpin2 = 23
      outpin3 = 6
      inpin3 = 17
      outpin4 = 5
      inpin4 = 4
      
      GPIO.setmode(GPIO.BCM)
      GPIO.setup(outpin1, GPIO.OUT)
      GPIO.setup(inpin1, GPIO.IN)
      GPIO.setup(outpin2, GPIO.OUT)
      GPIO.setup(inpin2, GPIO.IN)
      GPIO.setup(outpin3, GPIO.OUT)
      GPIO.setup(inpin3, GPIO.IN)
      GPIO.setup(outpin4, GPIO.OUT)
      GPIO.setup(inpin4, GPIO.IN)
      
      while True:
          value1 = GPIO.input(inpin1) 
          value2 = GPIO.input(inpin2)
          value3 = GPIO.input(inpin3)
          value4 = GPIO.input(inpin4)
          if not value1 and not value2 and not value3 and not value4:  
              GPIO.output(outpin1, 0)
              GPIO.output(outpin2, 0)
              GPIO.output(outpin3, 0)
              GPIO.output(outpin4, 0)
          else:
              if value1 and not value2 and not value3 and not value4:
                  GPIO.output(outpin1, 1)
                  subprocess.call(["php", path, "1", "1"])
              elif not value1 and value2 and not value3 and not value4:
                  GPIO.output(outpin2, 1)
                  subprocess.call(["php", path, "2", "1"])
              elif not value1 and not value2 and value3 and not value4:
                  GPIO.output(outpin3, 1)
                  subprocess.call(["php", path, "3", "1"])
              elif not value1  and not value2 and not value3 and value4:
                  GPIO.output(outpin4, 1)
                  subprocess.call(["php", path, "4", "1"])
      
          time.sleep(.3)
          time.sleep(.05)
      GPIO.cleanup()
      

      正如 cmets 所说,我为每个条件添加了“而不是”,除非我想评估每个按钮是否为“真”。此外,第 4 个按钮的 pin 设置由 out 为 22 更改为 4,以解决持续打开的情况。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-16
        相关资源
        最近更新 更多