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