Не корректная работа RTC модуля
- Войдите на сайт для отправки комментариев
Пнд, 30/04/2018 - 13:20
Добрый день форумчане!
Не пойму что за глюк у 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);
}//------------Конец ЦИКЛА-----------------------------
Вчера пролетарский праздник отмечал? Строка 37.
Так Вы ж его при перезагрузке и устанавливаете каждый раз.
Спасибо.
Доброго времени суток!
Снова возникла проблемка с 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 и в диапазоне заданных температур }//------------Конец ЦИКЛА-----------------------------1. Батарея на месте?
2. Если на месте, то каково питание модуля, микросхемы? Оно должно превышать напряжение батареи как минимум на 0,2В
Да, батарея на месте. Питаю через ЮСБ. И когда отдельно пробую RTC модуль с любым примером из программы IDE, то он работает нормально. А с данным скетчем почему то глючит.