Не корректная работа RTC модуля

restiv
Offline
Зарегистрирован: 03.01.2016

Добрый день форумчане!

Не пойму что за глюк у RTC модуля (DS1307). Залил скетч, установил дату и время. И время вывожу в сом-порт. Все нормально часики тикают. Но стоит закрыть монитор порта и занова запустить, как отсчет времени начинается занова, с того времени, когда был залит скетч. И так каждый раз. при перезапуске монитор порта, время начинает занова отсчитывать с момента заливки скетча. Подскажите в чем может быть глюк? Раньше такого не наблюдалось на этом RTC модуле. Скетч прилагаю.

#include <Wire.h>                                                                           //Подключаем библиотеку для использования I2C интерфейса с модулем RTC 
#include <RTClib.h>                                                                         //Подключаем библиотеку для использования модуля часов реального времени RTC


#define PWM_MIN 0                                                                            //Если необходим ток покоя на LED - изменить эту константу
#define PWM_MAX 20                                                                          //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_PIN 6                                                                            //Пин порта, где будет ШИМ

#define mn 60UL                                                                              //Дополнительные константы для удобства
#define hr 3600UL                                                                            //Отражают соответствующие количества секунд 
#define d 86400UL

RTC_DS1307 RTC;     

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

long sunrise_start = 11*hr+15*mn;                                                             //Начало восхода в 9 - 45 
long sunrise_duration = 30*mn;                                                                //Длительность восхода 30 минут     
long sunset_start = 20*hr+00*mn;                                                              //начало заката в 21-15
long sunset_duration = 30*mn;                                                                 //Длительность заката 30 минут 
//********************************************************************************************
void setup(){

     
  Wire.begin();                                                                               //Инициируем I2C интерфейс
  RTC.begin();                                                                                //Инициирум RTC модуль
  analogWrite(PWM_PIN, PWM_MIN);                                                              //Пишем в порт минимальное значение 
  Serial.begin(9600);                                                                         //Запускаем сом-порт
  delay(3000);                                                                                //Ожидаем открытия консоли

  if (! RTC.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

     // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));

}                                                                                             // КОНЕЦ ИНИЦИАЛИЗАЦИИ

//********************************************************************************************
void loop()                                                                                   // ПРОГРАММЫй безусловный ЦИКЛ 
{
  
    long pwm; 
    DateTime myTime = RTC.now();                                                              //Читаем данные времени из RTC при каждом выполнении цикла
    long Day_time = myTime.unixtime() % 86400;                                                //сохраняем в переменную - время в формате UNIX
//*********************************************************************************************
//           обработка интервала до восхода и после заката
//*********************************************************************************************
    if ((Day_time<sunrise_start) ||                                                           //Если с начала суток меньше чем начало восхода 
        (Day_time>=sunset_start+sunset_duration)) {                                           //Или больше чем начало заката + длительность
            pwm = PWM_MIN;                                                                    //Величина для записи в порт равна минимуму  

//*********************************************************************************************
//           обработка интервала восхода 
//*********************************************************************************************
    }else if ((Day_time>=sunrise_start) &&                                                    //Если с начала суток больше чем начало восхода
              (Day_time<sunrise_start+sunrise_duration)){                                     //И меньше чем начало восхода + длительность 
                  pwm =  ((Day_time - sunrise_start)*(PWM_MAX-PWM_MIN)) / sunrise_duration;   //Вычисляем для рассвета величину для записи в порт ШИМ

//*********************************************************************************************
//           обработка интервала заката 
//*********************************************************************************************
    }else if ((Day_time>=sunset_start) &&                                                     //Если  начала суток больше чем начало заката и меньше чем  
              (Day_time<sunset_start+sunset_duration)){                                       //начало заката плюс длительность
      pwm = ((sunset_start+sunset_duration - Day_time)*(PWM_MAX-PWM_MIN)) / sunrise_duration; //Вычисляем для заката величину для записи в порт ШИМ
 
//********************************************************************************************
//           обработка интервала от конца рассвета и до начала заката,
//           когда свет должен быть включен на максимальную яркость 
//********************************************************************************************
    }else {
                  pwm = PWM_MAX;                                                              //Устанавливаем максимальную величину для записи в порт ШИМ 
    }
    analogWrite(PWM_PIN, pwm);                                                                //Пишем в порт вычисленное значение           
  
 DateTime now = RTC.now();
    
    Serial.print(now.day(), DEC);
    Serial.print('.');
    Serial.print(now.month(), DEC);
    Serial.print('.');
    Serial.print(now.year(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    delay(1000);

}//------------Конец ЦИКЛА-----------------------------

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Вчера пролетарский праздник отмечал? Строка 37.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так Вы ж его при перезагрузке и устанавливаете каждый раз.

restiv
Offline
Зарегистрирован: 03.01.2016

Спасибо.

restiv
Offline
Зарегистрирован: 03.01.2016

Доброго времени суток!

Снова возникла проблемка с RTC модулем. Микроконтроллер должен в определенное время включать освещение, плавно его увеличивать до мах и вечером плавно его отключать. При этом еще в течении дня должен включаться и отключаться насос. Все работает вроде нормально, но проблема возникает при обесточивании устройства. Часы сразу же сбиваются на 01.01.2000 число. Подскажите где я накосячил пожалуйста.

#include <Wire.h>                                                                           //Подключаем библиотеку для использования I2C интерфейса с модулем RTC 
#include <RTClib.h>                                                                         //Подключаем библиотеку для использования модуля часов реального времени RTC

#define relay1 5
#define RelayChn1 8

unsigned long prevMillis;

#define PWM_MIN 0                                                                            //Если необходим ток покоя на LED - изменить эту константу
#define PWM_MAX 200                                                                          //Если необходимо ограничить максимальную яркость - уменьшить значение
#define PWM_PIN 6                                                                            //Пин порта, где будет ШИМ

#define mn 60UL                                                                              //Дополнительные константы для удобства
#define hr 3600UL                                                                            //Отражают соответствующие количества секунд 
#define d 86400UL

//------------------------------------------------------------------
class time{
public:
        time(unsigned char h=0, unsigned char m=0, unsigned char s=0){
            set_time(h, m, s);
        }
        time&   operator = (time &t){hour = t.hour; min = t.min; sec = t.sec; seconds = t.seconds; return *this;}
        boolean operator ==(time &t){return seconds==t.get_time();}
        boolean operator !=(time &t){return !(*this==t);}
        boolean operator > (time &t){return seconds>t.get_time();}
        boolean operator < (time &t){return seconds<t.get_time();}
        boolean operator >=(time &t){return seconds>=t.get_time();}
        boolean operator <=(time &t){return seconds<=t.get_time();}
        void set_time(unsigned char h, unsigned char m, unsigned char s){
            hour=h; min=m; sec=s;
            seconds=(unsigned long)h*1440 + (unsigned long)m*60 + s;
        }
        unsigned long get_time(){return seconds;};
        void print()    {Serial.print(hour); Serial.print(':');Serial.print(min); Serial.print(':');Serial.println(sec);}
private:
        unsigned char   hour;
        unsigned char   min;
        unsigned char   sec;
        unsigned long   seconds;
};
//------------------------------------------------------------------
class relay{
public:
    relay(unsigned char pin){
        pin_num = pin;
        pinMode(pin_num, OUTPUT);
        digitalWrite(pin_num, 1); 
        state=0;
    }
    void operator =(boolean val) {digitalWrite(pin_num, !val); state=val;}
    operator boolean()  {return state;}
private:
    unsigned char   pin_num;
    boolean         state;
};                    
//------------------------------------------------------------------

RTC_DS1307 RTC;     

//------------------------------------------------------------------
time    cur_time;
time    relay_1_on(07, 00, 00);         // Время включения 1-ого реле
time    relay_1_off(22, 00, 00);        // Время отключения 1-ого реле  
relay   relay_1(RelayChn1);             // Реле 1 
//------------------------------------------------------------------

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

long sunrise_start = 07*hr+05*mn;                                                             //Начало восхода в 7 - 05 
long sunrise_duration = 55*mn;                                                                //Длительность восхода 55 минут     
long sunset_start = 21*hr+00*mn;                                                              //начало заката в 21-00
long sunset_duration = 55*mn;                                                                 //Длительность заката 55 минут 
//********************************************************************************************
void setup(){
  pinMode(relay1, OUTPUT); 
  //pinMode(relay2, OUTPUT);   
  Wire.begin();                                                                               //Инициируем I2C интерфейс
  RTC.begin();                                                                                //Инициирум RTC модуль
  analogWrite(PWM_PIN, PWM_MIN);                                                              //Пишем в порт минимальное значение 
  Serial.begin(9600);                                                                         //Запускаем сом-порт
  delay(3000);                                                                                //Ожидаем открытия консоли

  if (! RTC.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

    //RTC.adjust(DateTime(F(__DATE__), F(__TIME__)));                                         //Текущая строка выводит дату и время компиляции скетча. После заливки скетча нужно закомментировать. 
    //RTC.adjust(DateTime(2018, 4, 30, 16, 36, 0));                                           //Текущая строка предназначена для ручного ввода даты и времени в формате: Мес. день, год часы, минуты, секунды. 
    
}                                                                                             // КОНЕЦ ИНИЦИАЛИЗАЦИИ

//********************************************************************************************
void loop()                                                                                   // ПРОГРАММЫй безусловный ЦИКЛ 
{
  
    long pwm; 
    DateTime myTime = RTC.now();                                                              //Читаем данные времени из RTC при каждом выполнении цикла
    long Day_time = myTime.unixtime() % 86400;                                                //сохраняем в переменную - время в формате UNIX
//*********************************************************************************************
//           обработка интервала до восхода и после заката
//*********************************************************************************************
    if ((Day_time<sunrise_start) ||                                                           //Если с начала суток меньше чем начало восхода 
        (Day_time>=sunset_start+sunset_duration)) {                                           //Или больше чем начало заката + длительность
            pwm = PWM_MIN;                                                                    //Величина для записи в порт равна минимуму  

//*********************************************************************************************
//           обработка интервала восхода 
//*********************************************************************************************
    }else if ((Day_time>=sunrise_start) &&                                                    //Если с начала суток больше чем начало восхода
              (Day_time<sunrise_start+sunrise_duration)){                                     //И меньше чем начало восхода + длительность 
                  pwm =  ((Day_time - sunrise_start)*(PWM_MAX-PWM_MIN)) / sunrise_duration;   //Вычисляем для рассвета величину для записи в порт ШИМ

//*********************************************************************************************
//           обработка интервала заката 
//*********************************************************************************************
    }else if ((Day_time>=sunset_start) &&                                                     //Если  начала суток больше чем начало заката и меньше чем  
              (Day_time<sunset_start+sunset_duration)){                                       //начало заката плюс длительность
      pwm = ((sunset_start+sunset_duration - Day_time)*(PWM_MAX-PWM_MIN)) / sunrise_duration; //Вычисляем для заката величину для записи в порт ШИМ
 
//********************************************************************************************
//           обработка интервала от конца рассвета и до начала заката,
//           когда свет должен быть включен на максимальную яркость 
//********************************************************************************************
    }else {
                  pwm = PWM_MAX;                                                              //Устанавливаем максимальную величину для записи в порт ШИМ 
    }
    analogWrite(PWM_PIN, pwm);                                                                //Пишем в порт вычисленное значение           
  
    DateTime now = RTC.now();
    
    Serial.print(now.day(), DEC);
    Serial.print('.');
    Serial.print(now.month(), DEC);
    Serial.print('.');
    Serial.print(now.year(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.print("  ");
    Serial.print("PWM=");
    Serial.print(pwm);
    Serial.println();
    delay(1000);

     static bool state;
  static unsigned long time;
  if((millis() - time) > (state ? 10000 : 20000)) // первое число отображает время одного положения в мск, второе число отображает длительность второго состояния реле
 {
  state = !state;
  digitalWrite(relay1, state);
  time = millis();
 }
 
    cur_time.set_time(myTime.hour(), myTime.minute(), myTime.second());  // Устанавливаем часы, минут, секунды в cur_tim
//------------КАНАЛ 1 (Контроль температуры по времени) -------
//    sensors.requestTemperatures();

    relay_1 = (cur_time>=relay_1_on) && (cur_time<relay_1_off);     // Состояние реле 1 = нахождение текущего времени в диапазоне от relay_1_on до relay_1_off и в диапазоне заданных температур 
}//------------Конец ЦИКЛА-----------------------------

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

1. Батарея на месте?

2. Если на месте, то каково питание модуля, микросхемы? Оно должно превышать напряжение батареи как минимум на 0,2В

restiv
Offline
Зарегистрирован: 03.01.2016

Да, батарея на месте. Питаю через ЮСБ. И когда отдельно пробую RTC модуль с любым примером из программы IDE, то он работает нормально. А с данным скетчем почему то глючит.