Включение реле на 15 минут каждые 2 часа через кнопку в приложении Blynk!

nehetos
Offline
Зарегистрирован: 11.04.2020

Добрый вечер,товарищи!Цель такая при включении в приложении Blynk кнопки с виртуальным пином V5,пока кнопка нажата(включена),реле замыкалось каждые 2 часа на 15 минут.Прикрепляю код ниже...Сейчас при нажатии этой кнопки вообще ничего не происходит.Если что,за 2 реле отвечает одна кнопка,потому что разрабатывается управление вентиляцией и нужно подавать напряжение на 2 вентилятора.Друзья,помогите пожалуйста!

#define RELE1 D1
#define RELE2 D2
#define RELE3 D3
#define RELE4 D4
#define RELE5 D5
#define RELE6 D6
#define RELE7 D7
#define RELE8 D8
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
bool para_rele1;
bool para_rele2;
bool para_rele3;
bool para_rele4;
bool rele_off;
bool rele_cycle;
unsigned long timer = 0;
unsigned long ON = 900000;
unsigned long OFF = 7200000;

char auth[] = "*******";
char ssid[] = "*****";
char pass[] = "********";

void setup()
{
  Serial.begin(115200);
  Blynk.begin(auth,ssid,pass);
  pinMode(RELE1,OUTPUT);
  pinMode(RELE2,OUTPUT);
  pinMode(RELE3,OUTPUT);
  pinMode(RELE4,OUTPUT);
  pinMode(RELE5,OUTPUT);
  pinMode(RELE6,OUTPUT);
  pinMode(RELE7,OUTPUT);
  pinMode(RELE8,OUTPUT);
  
  digitalWrite(RELE1,HIGH);
  digitalWrite(RELE2,HIGH);
  digitalWrite(RELE3,HIGH);
  digitalWrite(RELE4,HIGH);
  digitalWrite(RELE5,HIGH);
  digitalWrite(RELE6,HIGH);
  digitalWrite(RELE7,HIGH);
  digitalWrite(RELE8,HIGH);

  Blynk.virtualWrite(1,HIGH);
  Blynk.virtualWrite(2,HIGH);
  Blynk.virtualWrite(3,HIGH);
  Blynk.virtualWrite(4,HIGH);
  Blynk.virtualWrite(5,HIGH);
  Blynk.virtualWrite(6,HIGH);
  Blynk.virtualWrite(7,HIGH);
  Blynk.virtualWrite(8,HIGH);

  }
  
  void relefunc0()
  {
     digitalWrite(RELE1,HIGH);
     digitalWrite(RELE2,HIGH);
     digitalWrite(RELE3,HIGH); 
     digitalWrite(RELE4,HIGH);
     digitalWrite(RELE5,HIGH);
     digitalWrite(RELE6,HIGH);
     digitalWrite(RELE7,HIGH);
     digitalWrite(RELE8,HIGH);
     
     Blynk.virtualWrite(V1,0);
     Blynk.virtualWrite(V2,0);
     Blynk.virtualWrite(V3,0);
     Blynk.virtualWrite(V4,0);
     Blynk.virtualWrite(V5,0);
  }

  void relefunc1()
  {
     digitalWrite(RELE1,LOW);
     digitalWrite(RELE2,LOW);
     digitalWrite(RELE3,HIGH); 
     digitalWrite(RELE4,HIGH);
     digitalWrite(RELE5,HIGH);
     digitalWrite(RELE6,HIGH);
     digitalWrite(RELE7,HIGH);
     digitalWrite(RELE8,HIGH);
     
     Blynk.virtualWrite(V0,0);
     Blynk.virtualWrite(V2,0);
     Blynk.virtualWrite(V3,0);
     Blynk.virtualWrite(V4,0);
     Blynk.virtualWrite(V5,0);
  }

  void relefunc2()
  {
     digitalWrite(RELE3,LOW);
     digitalWrite(RELE4,LOW);
     digitalWrite(RELE1,HIGH);
     digitalWrite(RELE2,HIGH);
     digitalWrite(RELE5,HIGH);
     digitalWrite(RELE6,HIGH);
     digitalWrite(RELE7,HIGH);
     digitalWrite(RELE8,HIGH);
     
     Blynk.virtualWrite(V0,0);
     Blynk.virtualWrite(V1,0);
     Blynk.virtualWrite(V3,0);
     Blynk.virtualWrite(V4,0);
     Blynk.virtualWrite(V5,0);
  }

  void relefunc3()
  {
     digitalWrite(RELE5,LOW);
     digitalWrite(RELE6,LOW);
     digitalWrite(RELE2,HIGH);
     digitalWrite(RELE4,HIGH);
     digitalWrite(RELE1,HIGH);
     digitalWrite(RELE3,HIGH);
     digitalWrite(RELE7,HIGH);
     digitalWrite(RELE8,HIGH);
     
     Blynk.virtualWrite(V0,0);
     Blynk.virtualWrite(V1,0);
     Blynk.virtualWrite(V2,0);
     Blynk.virtualWrite(V4,0);
     Blynk.virtualWrite(V5,0);
  }

  void relefunc4()
  {
     digitalWrite(RELE7,LOW);
     digitalWrite(RELE8,LOW);
     digitalWrite(RELE1,HIGH);
     digitalWrite(RELE2,HIGH);
     digitalWrite(RELE3,HIGH);
     digitalWrite(RELE4,HIGH);
     digitalWrite(RELE5,HIGH);
     digitalWrite(RELE6,HIGH);
     
     Blynk.virtualWrite(V0,0);
     Blynk.virtualWrite(V1,0);
     Blynk.virtualWrite(V2,0);
     Blynk.virtualWrite(V3,0);
     Blynk.virtualWrite(V5,0);
  }

  BLYNK_WRITE(V0)
  {
  rele_off = param.asInt();
  if (rele_off ==1)
    {
     relefunc0();
    }
  }
  
  BLYNK_WRITE(V1)
  {
  para_rele1 = param.asInt();
  if (para_rele1 ==1)
    {
     relefunc1();
    }
  }
  BLYNK_WRITE(V2)
  {
  para_rele2 = param.asInt();
  if (para_rele2 ==1)
    {
     relefunc2();
    }
  }
  BLYNK_WRITE(V3)
  {
  para_rele3 = param.asInt();
  if (para_rele3 ==1)
    {
     relefunc3();
    }
  }
  BLYNK_WRITE(V4)
  {
  para_rele4 = param.asInt();
  if (para_rele4 ==1)
    {
      relefunc4();
    }
  }  
  BLYNK_WRITE(V5){
    rele_cycle = param.asInt();
    if (rele_cycle ==1)
      {
        if(millis() - timer > OFF)
        {
        timer = millis();
        digitalWrite(RELE1,LOW);
        digitalWrite(RELE2,LOW);
        digitalWrite(RELE3,HIGH);
        digitalWrite(RELE4,HIGH);
        digitalWrite(RELE5,HIGH);
        digitalWrite(RELE6,HIGH);
        digitalWrite(RELE7,HIGH);
        digitalWrite(RELE8,HIGH);
        Blynk.virtualWrite(V0,0);
        Blynk.virtualWrite(V1,0);
        Blynk.virtualWrite(V2,0);
        Blynk.virtualWrite(V3,0);
        Blynk.virtualWrite(V4,0);
       }
      if(millis() - timer > ON)
      {
        timer = millis();
        digitalWrite(RELE1,HIGH);
        digitalWrite(RELE2,HIGH);
        digitalWrite(RELE3,HIGH);
        digitalWrite(RELE4,HIGH);
        digitalWrite(RELE5,HIGH);
        digitalWrite(RELE6,HIGH);
        digitalWrite(RELE7,HIGH);
        digitalWrite(RELE8,HIGH);
        Blynk.virtualWrite(V0,0);
        Blynk.virtualWrite(V1,0);
        Blynk.virtualWrite(V2,0);
        Blynk.virtualWrite(V3,0);
        Blynk.virtualWrite(V4,0);
      }
    }
  }
void loop(){
  Blynk.run();
}

 

b707
Offline
Зарегистрирован: 26.05.2017

Не уверен, как работает Блинк - но по-моему, ваша функция BLYNK_WRITE(V5)  будет запускаться один раз лишь в момент нажатия кнопки - а сл-но никакие таймеры на 2 часа и на 15 работать не будут.

Кроме того, даже если бы таймеры запускались - включение "каждые 2 часа на 15 минут"написано неверно, ваш код будет каждые 15 минут включать реле, а выключать не будет никогда. Нужно делать отдельный таймер на включение, и отдельный на выключение.

nehetos
Offline
Зарегистрирован: 11.04.2020

Спасибо,можете пожалуйста подробнее обьяснить:"Кроме того, даже если бы таймеры запускались - таймеры на замыкание "каждые 2 часа на 15 минут"написаны неверно, ваш код будет каждые 15 минут включать реле, а выключать не будет никогда. Нужно делать отдельный таймер на включение, и отдельный на выключение.".Как это будет выглядеть в виде кода?Я понимаю что 15 минут должны начаться,потом закончиться и запуститься уже другой таймер на начало 2 часов и на окончание 2х часов и опять запуск 15 минут.Извиняюсь за глупость,новичок в этом деле)Пытался что то сделать ,но как вижу не получилось(

MaksVV
Offline
Зарегистрирован: 06.08.2015

Может это поможет. Вам нужно два таймера. Один будет включен постоянно (без флага) и действие выполняться раз в интервал (раз в два часа). А вот действие - это запуск второго таймера (разового - с флагом) на 15 минут, при запуске которого реле вкл, при окончании - выкл. 

SLKH
Offline
Зарегистрирован: 17.08.2015

nehetos пишет:

Спасибо,можете пожалуйста подробнее обьяснить:"Кроме того, даже если бы таймеры запускались - таймеры на замыкание "каждые 2 часа на 15 минут"написаны неверно, ваш код будет каждые 15 минут включать реле, а выключать не будет никогда. Нужно делать отдельный таймер на включение, и отдельный на выключение.".Как это будет выглядеть в виде кода?Я понимаю что 15 минут должны начаться,потом закончиться и запуститься уже другой таймер на начало 2 часов и на окончание 2х часов и опять запуск 15 минут.Извиняюсь за глупость,новичок в этом деле)Пытался что то сделать ,но как вижу не получилось(

оставить в покое неведомые библиотечные таймеры.

написать функцию на русском (или лругом родном) языке ("Если", "иначе" и т.п.). Попытаться понять написанное.

(Вариант: нарисовать блок-схему программы)

заменить "если" на "if", а "иначе" на "else" и т.д.

написать скетч с одним реле и одной кнопкой, проверить (например, включать светодиод на 5 секунд каждые 20 сек). 

 

 

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый ТС!

Вы чего, издеваетесь? Простейшая программа, думаю вторая после мигания светодиодом, а Вы залезаете в какие-то неведомые библиотеки, ищите неизвестные Вам таймеры. Сходите в песочницу, помигайте чем-нибудь. Научитесь составлять алгоритмы.

nehetos
Offline
Зарегистрирован: 11.04.2020

Уважаемый, если бы я мог найти ответ на свой вопрос и свою ошибку, я бы сюда не писал. Так что или помогите пожалуйста или не возмущайтесь:)

MaksVV
Offline
Зарегистрирован: 06.08.2015

Просьба не цитировать это сообщение, т.к. будет дополняться. Можно его потом прикрепить к верху , если старожилы форума посчитают нужным и поправят меня, если я что-нибудь где-то не так написал.

Функция millis() это системные часы. Данная функция возвращает количество миллисекунд, прошедшее после старта микроконтроллера. Используя таймер на миллис, мы действуем абсолютно также, как и в жизни, например, когда ставим ужин в духовку. После того, как включили духовку (читай включили таймер) мы смотрим на часы и запоминаем время включения духовки (читай приравниваем переменную таймера к millis() ) и ставим ужин в духовку (читай выполняем нужные нам действия при включении таймера)  После этого мы периодически смотрим на часы, не прошли ли нужные, например, 40 минут от того момента, как мы включили духовку (читай проверяем в loop() не увеличилось ли системное время от засечённой точки на необходимую величину). Если очередной раз, взглянув на часы, мы видим, что нужное время прошло (читай таймер кончился), вынимаем ужин из духовки (читай выполняем необходимые действия по истечении таймера) и выключаем духовку (читай выключаем таймер). 

Естественно во всей этой ситуации в жизни мы не всегда смотрим на часы, а только когда у нас включена духовка. Т.е. для функционирования таймера нам необходима булевая переменная – флаг, в которой будет содержаться информация включен таймер или выключен. А также переменная, чтобы засечь время, когда включаем таймер.

Ниже представлен код, описывающий пример выше. Таймер мы включим в функции setup(). Вы делайте там, где вам это надо, например, по нажатию кнопки или ещё как там вам надо. Также включение таймера и проверка кончился ли таймер для удобства выведены в отдельные функции.

// пусть нашей духовкой будет встроенный LED13

unsigned long lastmillis = 0; // переменная для хранения точки начала таймера (в ней хранится время, которое засекаем)
                              // изначально время равно нулю.
bool timer = 0;               // флаг таймера (включен или выключен). Изначально выкл.

int interval =  40;           // необходимая величина (время) таймера, мин 

#define DUHOVKA_PIN 13

void startTimer()
{
 timer = 1;              // включаем таймер
 lastmillis = millis();  // засекаем время включения таймера
 digitalWrite (DUHOVKA_PIN,1);    // делаем нужные нам действия при включении таймера 
                         // в данном случае включаем духовку (LED13)
}

 
void duhovka()
{
 // здесь, при включенном таймере, каждый проход лупа, смотрим на часы - не кончился ли таймер.
 // если кончился, то выполняются действия ниже в фигурных скобках:
 if (timer && millis()-lastmillis >= (uint32_t)interval*60000UL) 
  {
    digitalWrite (DUHOVKA_PIN, 0); // делаем нужные нам действия при окончании таймера, 
                          // в данном случае выключаем духовку (LED13)
    timer = 0;            // выключаем таймер                      
  }  
}


void setup() 
{
   pinMode (DUHOVKA_PIN,OUTPUT); // пин на выход
   digitalWrite (DUHOVKA_PIN,0); // сначала выключим 

// включаем таймер:
   startTimer();    // включение таймера для удобства вывели в отдельную фукцию
}

void loop() 
{
 duhovka();   // проверку кончился ли таймер для удобства вывели в отдельную функцию 
// тут осталной код
}

Отмечу , что очень важно, чтобы проверка кончился или нет таймер (при включенном таймере) производилась регулярно часто, т.е. в цикле loop()  , либо в функциях, вызываемых из loop() и в остальном коде также отсутствовали блокирующие куски кода.  Поэтому, нельзя миллисом заменить delay() в блокирующих циклах for и while. Нужно просто отказаться от этих циклов , выполняя необходимые манипуляции просто в цикле loop().

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Сделайте на millis() счетчик по 15 минут (наименьшее общее кратное у Вас). Отсчитывайте мигания этого счетчика, 15 минут - 1 мигание, 2 часа - 8 миганий, 2 часа плюс 15 минут - 9 миганий. в остальное время делайте что хотите - кнопки там опрашивайте, порнуху включайте. Только не забываем нулить счетчик после выполнения всех циклических операций.