Управление выводом GPIO rpi Python на основе ввода GPIO и времени суток

#python #datetime #raspberry-pi #gpio

#python #datetime #raspberry-pi #gpio

Вопрос:

Я пытаюсь написать небольшой скрипт для управления двумя выводами gpio Raspberry pi на основе двух факторов: состояния GPIO.input.17 и времени суток.

Я бы хотел, чтобы gpio.output.23 и gpio.output.25 были низкими, когда gpio.input.17 был низким.
Я бы хотел, чтобы gpio.output.23 был высоким, когда gpio.input.17 высок, а время находится между 0700-2159.
Я бы хотел, чтобы gpio.output.25 был высоким, когда gpio.input.17 высок, а время находится между 2200-0659.

пока что код, который я собрал, выглядит следующим образом:

 #!/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()

  

У меня светодиоды подключены к выводам 23 и 25, время, указанное в скрипте, взято из моего тестирования, и результаты, которые я вижу с помощью этого кода:
Out.Pin 23 переключается между high и low, следуя статусу In.Pin.17, пока переменная времени имеет значение true
Out.Pin 23 прекращает переключениемежду высоким и низким значением, пока переменная time не является true
Я чувствую, что у меня работает Out.Pin.23…

Out.Pin 25 сразу загорается при выполнении кода и остается включенным независимо от состояния In.Pin.17 или времени.

Пожалуйста, не обращайте внимания на время в скрипте, они взяты из моего тестирования и не будут соответствовать приведенным выше требованиям.

Я новичок в программировании и написании сценариев и был бы признателен за любую помощь со стороны сообщества.

Спасибо

Ответ №1:

Прежде всего, я признаю, что это не полный ответ на ваш вопрос, но слишком много для комментария.

Цель этого частичного ответа — предложить упрощение тестов datetime.

  • Установите now время
  • Установите day время
  • Установите night время
  • Пользователь использует один простой логический оператор для проверки, день сейчас или ночь.

Пример:

 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/elif and операторы , .

Например, это:

 (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])
  

Ответ №2:

спасибо за ваше предложение. Хотя я мог запустить это в режиме ожидания и следовать логике вашего кода, я не смог интегрировать его в свой скрипт (это нарушило то, что я работал в первую очередь: 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()
  

Ответ №3:

Мне удалось решить эту проблему … мое исходное утверждение 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()