基于GPIO输入和时间控制的Python rpi GPIO输出控制

3

我正在尝试编写一个小脚本来控制两个树莓派GPIO输出引脚,基于两个因素:GPIO.input.17的状态和时间。

当GPIO.input.17为低电压时,我希望gpio.output.23和gpio.output.25也为低电压。
当GPIO.input.17为高电压且时间在0700-2159之间时,我希望gpio.output.23变为高电压。
当GPIO.input.17为高电压且时间在2200-0659之间时,我希望gpio.output.25变为高电压。

到目前为止,我编写的代码如下:

#!/usr/bin/python


import time
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)


# Setup GPIO pins
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)     # set GPIO 17 as input
GPIO.setup(23, GPIO.OUT)                                # set GPIO 23 as output
GPIO.setup(25, GPIO.OUT)                                # set GPIO 25 as output
GPIO.output(23, 0)                                      # set GPIO 23 as low
GPIO.output(25, 0)                                      # set GPIO 25 as low

while True: 
    dt = list(time.localtime())
    hour = dt[3]
    minute = dt[4]
    second = dt[5]
    time.sleep(1)
    print hour,minute,second;
    PIR_Active = GPIO.input(17)
    if not PIR_Active:
        GPIO.output(23, 0)
        GPIO.output(25, 0)
    elif (PIR_Active and (hour>=00 and hour<=6) and (minute >=00 and minute<=59) and (second >=0 and second<=59)):
        GPIO.output(25, 1)
    elif (PIR_Active and (hour>=7 and hour<=11) and (minute>=0 and minute<=36) and (second>=0 and second<=59)):
        GPIO.output(23, 1)
    else: (PIR_Active and (hour>=11 and hour<=23) and (minute >=37 and minute<=59) and (second >=0 and second<=59));
    GPIO.output(25, 1)
time.sleep(1)
GPIO.cleanup()


我将LED连接到23和25号引脚,脚本中显示的时间是我进行测试时记录的。使用此代码时,以下是我看到的结果:
当time变量为真时,Out.Pin 23会根据In.Pin.17的状态在高电位和低电位之间切换
当time变量不为真时,Out.Pin 23停止在高电位和低电位之间切换
我感觉Out.Pin.23可以工作了...

执行代码后,Out.Pin 25立即点亮并保持点亮,无论In.Pin.17的状态或时间如何。

请忽略脚本中的时间,它们来自我的测试,不会与上述要求匹配。

我是编码和编写脚本的初学者,非常感谢社区提供的任何帮助。

谢谢

3个回答

0

首先,我承认这不是你问题的完整答案,但对于评论来说太多了。

这个部分回答的目的是建议简化日期时间测试。

  • 设置一个现在时间
  • 设置一个白天时间
  • 设置一个晚上时间
  • 使用单个简单逻辑运算符测试是否为白天或晚上。

例如:

import datetime as dt

now = dt.datetime.now().time()
day = dt.time(7, 00)
night = dt.time(22, 00)

# Test if it's day time.
now
>>> datetime.time(14, 8, 6, 000000)
day < now < night
>>> True

# Test again at midnight.
now
>>> datetime.time(0, 0)
day < now < night
>>> False

将这个逻辑集成到您的代码中将有助于简化if/elifand语句。
例如,这样:
(PIR_Active and (hour>=00 and hour<=6) and (minute >=00 and minute<=59) and (second >=0 and second<=59))

...可以变成这样 - 显然使用您自己的时间定义。

all([PIR_Active, day < now < night])

0

我已经解决了这个问题...我的原始else语句是无效的,所以我添加了第三个elif与我的“夜间”条件,并用一个else语句完成了语句,将两个GPIO.out引脚都设置为1。

我还反转了输出的“休息”状态,因为我认为我得到的继电器单元是负应用的

这是带有注释的工作代码:

#!/usr/bin/python


import time
from time import sleep
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)


# Setup GPIO pins
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)     # set GPIO 17 as input
GPIO.setup(23, GPIO.OUT)                                # set GPIO 23 as output
GPIO.setup(24, GPIO.OUT)                                # set GPIO 25 as output
GPIO.output(23, 1)                                      # set GPIO 23 as high - relay boards are neg applied to activate, this keeps the relay powered off without a signal
GPIO.output(24, 1)                                      # set GPIO 25 as high - relay boards are neg applied to activate, this keeps the relay powered off without a signal

while True: 
    dt = list(time.localtime())
    hour = dt[3]
    minute = dt[4]
    second = dt[5]
    time.sleep(.01)                         #The first time.sleep command value impacts any similar statements made below it
    print hour,minute,second;
    PIR_Active = GPIO.input(17)             #Define a condition which is met in the statements below
    if not PIR_Active:                      #If the input is not active, reset both outputs to 'off'
        GPIO.output(23, 1)
        GPIO.output(24, 1)
    elif (PIR_Active and (hour>=00 and hour<=6) and (minute >=00 and minute<=59) and (second >=0 and second<=59)):
        GPIO.output(24, 0)                  #If all of the above is true, set this output to on
        time.sleep(30)                      #Hold this output 'on' for 30 seconds
    elif (PIR_Active and (hour>=7 and hour<=21) and (minute>=0 and minute<=59) and (second>=0 and second<=59)):
        GPIO.output(23, 0)                  #If all of the above is true, set this output to on
        time.sleep(30)                      #Hold this output 'on' for 30 seconds
    elif (PIR_Active and (hour>=22 and hour<=23) and (minute >=00 and minute<=59) and (second >=0 and second<=59)):
        GPIO.output(24, 0)                  #If all of the above is true, set this output to on
        time.sleep(30)                      #Hold this output 'on' for 30 seconds
    else:                                   #Cleanly exit out of the if/elif statements with an else that:
        GPIO.output(23, 1)                  #Resets this output to 'off'
        GPIO.output(24, 1)                  #Resets this output to 'off'
GPIO.cleanup()


0
感谢您的建议。虽然我可以在IDLE中运行它并按照您代码中的逻辑进行操作,但我无法将其集成到我的脚本中(它破坏了我一开始工作的GPIO.output.23跟随GPIO.input.17状态“在活动时间内”)。
鉴于我的新手水平,您能指导我在您的建议中出了什么问题吗?我喜欢整理if/elif语句的想法。
#!/usr/bin/python


import time
import datetime as dt
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)


# Define Time Variables
now = dt.datetime.now().time()
day = dt.time(16, 32, 59, 000000)
night = dt.time(16, 33, 00, 000000)

# Setup GPIO pins
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)     # set GPIO 17 as input
GPIO.setup(23, GPIO.OUT)                                # set GPIO 23 as output
GPIO.setup(25, GPIO.OUT)                                # set GPIO 25 as output
GPIO.output(23, 0)                                      # set GPIO 23 as low
GPIO.output(25, 1)                                      # set GPIO 25 as low

while True: 
    dt = list(time.localtime())
    hour = dt[3]
    minute = dt[4]
    second = dt[5]
    time.sleep(1)
    print hour,minute,second;
    PIR_Active = GPIO.input(17)
    if not PIR_Active:
        GPIO.output(23, 0)
        GPIO.output(25, 0)
    elif all([PIR_Active, day < now < night]):
        GPIO.output(23, 1)
    else: all([PIR_Active, day < now < night]);
    GPIO.output(25, 1)
time.sleep(1)
GPIO.cleanup()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接