таймер

shakhatov
Offline
Зарегистрирован: 24.12.2014


#include <Wire.h>
#include "RTClib.h"
RTC_DS1307  _RTC1; // GND - земля VCC - +5B SDA - A-4 SCL- A-5
DateTime  _tRTC1;
bool _RTCAlO1 = 0;
bool _trgrt1 = 0;
bool _trgrt1I = 0;
bool _tim1I = 0;
bool _tim1O = 0;
unsigned long _tim1P = 0UL;
void setup()
{
Wire.begin();
_RTC1.begin();
pinMode(13, OUTPUT);
}
void loop()
{_tRTC1 = _RTC1.now();
if (1)
{ _RTCAlO1 =  ((_tRTC1.hour()) == 10) && ((_tRTC1.minute()) == 43) || 
((_tRTC1.hour()) == 10) && ((_tRTC1.minute()) == 44) ||
((_tRTC1.hour()) == 10) && ((_tRTC1.minute()) == 45) ||
((_tRTC1.hour()) == 10) && ((_tRTC1.minute()) == 46) ||
((_tRTC1.hour()) == 10) && ((_tRTC1.minute()) == 47);}

    else
{_RTCAlO1 = 0;}
if (_RTCAlO1) { if (_trgrt1I) { _trgrt1 = 0;} else {_trgrt1 = 1; _trgrt1I = 1;} } else {_trgrt1 = 0; _trgrt1I = 0;}; 
 if(_trgrt1) {_tim1O = 1; _tim1I = 1;} else { if(_tim1I) {_tim1I = 0; _tim1P = millis();} else { if (_tim1O) {if ( _isTimer(_tim1P, 8000)) _tim1O = 0;}}}
digitalWrite(13, _tim1O);
}
bool _isTimer(unsigned long startTime, unsigned long period )
  {unsigned long currentTime;currentTime = millis();
if (currentTime>= startTime) {return (currentTime>=(startTime + period));} else {return (currentTime >=(4294967295-startTime+period));}
  }

не могу разобраться с таймером в 10:43 и в 10:44 светодиод 13 светился а в 10:45 10:46 и 10:47 не работает.

vov4ik
Offline
Зарегистрирован: 10.09.2013

Что-то знакомое, как-то удивительно что не только одно условие срабатывает.

if ((_tRTC1.hour()) == 10) { if (
   ((_tRTC1.minute()) == 43) || 
   ((_tRTC1.minute()) == 44) ||
   ((_tRTC1.minute()) == 45) ||
   ((_tRTC1.minute()) == 46) ||
   ((_tRTC1.minute()) == 47) ) {_RTCAlO1 = 1;} }

вообще тут надо понимать что вы его усложнили.

К примеру если 10 часов 46 минут в раскладе должно было

_RTCAlO1 = 1*0+1*0+1*0+1*0+1*1+1*0 вроде как должна быть 1 когда умножение выполняется первым (в логике такова понятия нет), но если считать последоватьно не обращая на првило матиматики то будет 0. 

Сейчас расписанно _RTCAlO1 = 1*(0+0+0+1+0).

Kolchugin
Offline
Зарегистрирован: 15.12.2013

shakhatov пишет:

не могу разобраться с таймером в 10:43 и в 10:44 светодиод 13 светился а в 10:45 10:46 и 10:47 не работает.

Попробуйте вот так:

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307  _RTC1;
DateTime  _tRTC1;
bool _comp1 = 0;
bool _comp2 = 0;
bool _comp3 = 0;
void setup()
{
Wire.begin();
_RTC1.begin();
pinMode(13, OUTPUT);
}
void loop()
{_tRTC1 = _RTC1.now();
if(((_tRTC1.hour()))==(10))
{_comp1 = 1;}
else
{_comp1 = 0;}
if(((_tRTC1.minute()))>=(43))
{_comp2 = 1;}
else
{_comp2 = 0;}
if(((_tRTC1.minute()))<=(47))
{_comp3 = 1;}
else
{_comp3 = 0;}
digitalWrite (13, ((((_comp1) &&(_comp2))) &&(_comp3)));
}

 

shakhatov
Offline
Зарегистрирован: 24.12.2014

мне нужно что бы он в заданное время подавал сигнал на 2 сек 

shakhatov
Offline
Зарегистрирован: 24.12.2014

например в 14:30 в 14:35 в 15:30 16:45 17:30 

shakhatov
Offline
Зарегистрирован: 24.12.2014
if((_tRTC1.hour()))==(14)  && ((_tRTC1.minute()))>=(40)
{_comp2 = 1;}
else
{_comp2 = 0;}вот так чтобы было 
shakhatov
Offline
Зарегистрирован: 24.12.2014
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307  _RTC1;
DateTime  _tRTC1;
bool _comp1 = 0;
bool _comp2 = 0;
bool _comp3 = 0;
void setup()
{
Wire.begin();
_RTC1.begin();
pinMode(13, OUTPUT);
}
void loop()
{_tRTC1 = _RTC1.now();
if(((_tRTC1.hour()) == 14) && ((_tRTC1.minute()) == 55))
{_comp1 = 1;}
else
{_comp1 = 0;}
digitalWrite (13, ((((_comp1) &&(_comp2))) &&(_comp3)));
}

не работает 

 

Kolchugin
Offline
Зарегистрирован: 15.12.2013

Вот так чтобы было, не вижу чтобы на 2 секунды светодиод но D13 светил.

Так будет светить на 14:30 и 14:35

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307  _RTC1;
DateTime  _tRTC1;
bool _comp1 = 0;
bool _comp2 = 0;
bool _gen1I = 0;
bool _gen1O = 0;
unsigned long _gen1P = 0UL;
bool _kgen1 = 0;
bool _comp3 = 0;
bool _comp4 = 0;
bool _gen2I = 0;
bool _gen2O = 0;
unsigned long _gen2P = 0UL;
bool _kgen2 = 0;
void setup()
{
  Wire.begin();
  _RTC1.begin();
  pinMode(13, OUTPUT);

}
void loop()
{ _tRTC1 = _RTC1.now();
  if (((_tRTC1.hour())) == (14))
  {
    _comp1 = 1;
  }
  else
  {
    _comp1 = 0;
  }
  if (((_tRTC1.hour())) == (14))
  {
    _comp3 = 1;
  }
  else
  {
    _comp3 = 0;
  }
  if (((_tRTC1.minute())) == (30))
  {
    _comp2 = 1;
  }
  else
  {
    _comp2 = 0;
  }
  if (((_tRTC1.minute())) == (35))
  {
    _comp4 = 1;
  }
  else
  {
    _comp4 = 0;
  }
  if (((_comp1) && (_comp2))) {
    if (! _gen1I) {
      _gen1I = 1;
      _gen1O = 1;
      _gen1P = millis();
    }
  } else {
    _gen1I = 0 ;
    _gen1O = 0;
  } if (_gen1I &&  _gen1O)   _gen1O = !( _isTimer( _gen1P , 2000 ));
  if (_gen1O)
  {
    _kgen1 = 1;
  }
  else
  {
    _kgen1 = 0;
  }
  digitalWrite (13, ((_kgen1) || (_kgen2)));
  if (((_comp3) && (_comp4))) {
    if (! _gen2I) {
      _gen2I = 1;
      _gen2O = 1;
      _gen2P = millis();
    }
  } else {
    _gen2I = 0 ;
    _gen2O = 0;
  } if (_gen2I &&  _gen2O)   _gen2O = !( _isTimer( _gen2P , 2000 ));
  if (_gen2O)
  {
    _kgen2 = 1;
  }
  else
  {
    _kgen2 = 0;
  }
}
bool _isTimer(unsigned long startTime, unsigned long period )
{
  unsigned long currentTime;
  currentTime = millis();
  if (currentTime >= startTime) {
    return (currentTime >= (startTime + period));
  } else {
    return (currentTime >= (4294967295 - startTime + period));
  }
}

 

shakhatov
Offline
Зарегистрирован: 24.12.2014

а как мне еще несколько точек веремени прописать 

Kolchugin
Offline
Зарегистрирован: 15.12.2013

Это уже вопрос серьёзный. Сейчас подумал, что лучше и проще светодиод зажигать вот таким образом, брать секунды с 1307.  По скетчу, диод будет светить в 14:30, 2 секунды.

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307  _RTC1;
DateTime  _tRTC1;
bool _comp1 = 0;
bool _comp2 = 0;
bool _comp3 = 0;
bool _comp4 = 0;
void setup()
{
Wire.begin();
_RTC1.begin();
pinMode(13, OUTPUT);
}
void loop()
{_tRTC1 = _RTC1.now();
if(((_tRTC1.hour()))==(14))
{_comp1 = 1;}
else
{_comp1 = 0;}
if(((_tRTC1.second()))>=(0))
{_comp3 = 1;}
else
{_comp3 = 0;}
digitalWrite (13, ((((((_comp1) &&(_comp2))) &&(_comp3))) &&(_comp4)));
if(((_tRTC1.minute()))==(30))
{_comp2 = 1;}
else
{_comp2 = 0;}
if(((_tRTC1.second()))<=(2))
{_comp4 = 1;}
else
{_comp4 = 0;}
}

 

shakhatov
Offline
Зарегистрирован: 24.12.2014

здесь же попроше будет прописать несколько точек 

Kolchugin
Offline
Зарегистрирован: 15.12.2013

Только я там ошибся, он будет 3 секунды светить, а не 2, нужно подправить 30 строчку:

if(((_tRTC1.second()))<=(1))

shakhatov
Offline
Зарегистрирован: 24.12.2014

Да это я подправлю. Спасибо вам !

shakhatov
Offline
Зарегистрирован: 24.12.2014
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307  _RTC1;
DateTime  _tRTC1;
bool _comp1 = 0;
bool _comp2 = 0;
bool _comp3 = 0;
bool _comp4 = 0;
bool _comp5 = 0;
bool _comp6 = 0;
bool _comp7 = 0;
bool _comp8 = 0;
bool _comp9 = 0;
bool _comp10 = 0;
bool _comp11 = 0;
bool _comp12 = 0;
bool _comp13 = 0;
bool _comp14 = 0;
bool _comp15 = 0;
bool _comp16 = 0;
void setup()
{
Wire.begin();
_RTC1.begin();
pinMode(13, OUTPUT);
}
void loop() {
{_tRTC1 = _RTC1.now();
if(((_tRTC1.hour()))==(15))
{_comp1 = 1;}
else
{_comp1 = 0;}
if(((_tRTC1.second()))>=(0))
{_comp3 = 1;}
else
{_comp3 = 0;}
digitalWrite (13, ((((((_comp1) &&(_comp2))) &&(_comp3))) &&(_comp4)));
if(((_tRTC1.minute()))==(40))
{_comp2 = 1;}
else
{_comp2 = 0;}
if(((_tRTC1.second()))<=(8))
{_comp4 = 1;}
else
{_comp4 = 0;}
}
{_tRTC1 = _RTC1.now();
if(((_tRTC1.hour()))==(15))
{_comp5 = 1;}
else
{_comp5 = 0;}
if(((_tRTC1.second()))>=(0))
{_comp7 = 1;}
else
{_comp7 = 0;}
digitalWrite (13, ((((((_comp5) &&(_comp6))) &&(_comp7))) &&(_comp8)));
if(((_tRTC1.minute()))==(41))
{_comp6 = 1;}
else
{_comp6 = 0;}
if(((_tRTC1.second()))<=(8))
{_comp8 = 1;}
else
{_comp8 = 0;}
}}

сделал вот так 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

second() >= 0 это прикольно.

Море bool переменных тоже забавно. Достаточно двух, одна - срабатывание по времени (любое условие) и то это может быть и не переменной. Вторая переменная - что сработало условие и нужно от момента срабатывания считать n секунд. Те тупой автомат, который срабатывает при условии и переходит в режим обратного отсчёта.

Для читабельности и простоты, вынесите все сравнения в отдельную функцию, будет меньше мусора.

 

shakhatov
Offline
Зарегистрирован: 24.12.2014

я хотел так сделать не получилось 

 

vov4ik
Offline
Зарегистрирован: 10.09.2013

shakhatov пишет:

например в 14:30 в 14:35 в 15:30 16:45 17:30 

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

 bool_RTCAlO1 = 0; bool _trgrt1 = 0; bool _trgrt1I = 0;

Когда _RTCAlO1 = 1 запускается if (_RTCAlO1) { if (_trgrt1I) { _trgrt1 = 0;} else {_trgrt1 = 1; _trgrt1I = 1;} } else {_trgrt1 = 0; _trgrt1I = 0;}; и действует один такт в программе сброс таймера производится если _RTCAlO1 = 0 

Тут оптимально воспользоватся обманкой задать условия которые вам нужны если условие выполняется задать _RTCAlO1 = 1 если ни одно условие не выполняется тогда _RTCAlO1 = 0 при этом не использовать иначе (else) для этого подходит команда goto 

if (((_tRTC1.hour()) == 15) && ((_tRTC1.minute()) == 45)) { _RTCAlO1 = 1; goto jump;} 
if (((_tRTC1.hour()) == 10) && ((_tRTC1.minute()) == 24)) { _RTCAlO1 = 1; goto jump;}
if (((_tRTC1.hour()) == 13) && ((_tRTC1.minute()) == 22)) { _RTCAlO1 = 1; goto jump;}
_RTCAlO1 = 0;
jump:

Правда тут может появится другая проблема нельзя будет использовать минуты подрят, тоесть 14:44 14:45

если очень будет нужно можно будет сделать фокус опрашивать 13 пин и по его состоянию сбрасывать.

if (!digitalRead(13)) {_RTCAlO1 = 0;}

 

shakhatov
Offline
Зарегистрирован: 24.12.2014

у меня почему то релюшку та прога не запускает 

 

shakhatov
Offline
Зарегистрирован: 24.12.2014
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307  _RTC1;
DateTime  _tRTC1;
bool _comp1 = 0;
bool _comp2 = 0;
bool _comp3 = 0;
bool _comp4 = 0;
void setup()
{
Wire.begin();
_RTC1.begin();
pinMode(12, OUTPUT);
}
void loop()
{_tRTC1 = _RTC1.now();
if(((_tRTC1.second()))>=(0))
{_comp3 = 1;}
else
{_comp3 = 0;}
if(((_tRTC1.second()))<=(8))
{_comp4 = 1;}
else
{_comp4 = 0;}
if(((_tRTC1.hour()))==(20))
{_comp1 = 1;}
else
{_comp1 = 0;}
if(((_tRTC1.minute()))==(4))
{_comp2 = 1;}
else
{_comp2 = 0;}
if(((_tRTC1.hour()))==(20))
{_comp1 = 1;}
else
{_comp1 = 0;}
if(((_tRTC1.minute()))==(5))
{_comp2 = 1;}
else
{_comp2 = 0;}
if(((_tRTC1.hour()))==(20))
{_comp1 = 1;}
else
{_comp1 = 0;}
if(((_tRTC1.minute()))==(6))
{_comp2 = 1;}
else
{_comp2 = 0;}
if ((_comp1) &&(_comp2) &&(_comp3) &&(_comp4) == 1)  digitalWrite(12, HIGH); else digitalWrite(12, LOW);
}

почему она не работает ?

 

vov4ik
Offline
Зарегистрирован: 10.09.2013

Замучился смотреть на всё это, вы изначально взяли код который работал один раз в тысячу лет, где устанавливался год месяц день час минута и секунда отдельно включался независимый таймер.

В общем под ваши хотелки написал заново где добавил для выбора дополнительно контакты, если нужен будет только один контакт убирате int contato[] и снимаете с ифа.

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307  _RTC1; // GND - земля VCC - +5B SDA - A-4 SCL- A-5
DateTime  _tRTC1;
      int h[] = {12, 14, 11, 13, 16}; // установка часа
      int m[] = {22, 34, 38, 23, 26}; // установка минуты
      int s[] = { 2,  4,  8,  3,  6}; // установка на сколько секунд включить контакт ( s < 60 )
int contato[] = {13, 13, 12, 13, 11}; // установка контакта на котором нужно включить
                                      // нули в начале цифр не прописывать, использовать пробел
int id = 0;
void setup()
{
Wire.begin();
_RTC1.begin();
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
}
void loop()
{
  _tRTC1 = _RTC1.now();
  // не нагружая контроллер просто сравнивается совпадение заданного контакта
  if (contato[id] == 11){digitalWrite (11, (((_tRTC1.hour()) == h[id]) && ((_tRTC1.minute()) == m[id]) && ((_tRTC1.second()) <= s[id] )));}
  if (contato[id] == 12){digitalWrite (12, (((_tRTC1.hour()) == h[id]) && ((_tRTC1.minute()) == m[id]) && ((_tRTC1.second()) <= s[id] )));}
  if (contato[id] == 13){digitalWrite (13, (((_tRTC1.hour()) == h[id]) && ((_tRTC1.minute()) == m[id]) && ((_tRTC1.second()) <= s[id] )));}
  //если совпадение есть, если совпадает час минута и меньше установленной секунде устанавливается значение HIGH, иначе LOW
  if (!digitalRead(11) && !digitalRead(12) && !digitalRead(13)) {id ++ ;} // пока хоть один контакт вкл. id изменятся не будет
  // влючить можно только один контакт в минуту.
if (id == 5) {id = 0; } // ограничение должно совпадать с количеством в массиве
}

Код не проверял, поскольку не оплачиваемо и лень собирать.