Включение и отключение реле по времени не отрабатывает уставки
- Войдите на сайт для отправки комментариев
Пт, 05/10/2018 - 20:04
Добрый вечер!
В скетче какой то глюк или это мои кривые руко но, никак не могу настроить работу скетча. Реле 4 включается по установленному времени в скетче, но не отключается в установленое время. А отключается почему то в 21:48:00. Причем время отключения не зависит от значений прописанных в строке 83. Подскажите в чем может быть причина???
//----------ИМПОРТ БИБЛИОТЕК------------------------- #include <Wire.h> //Подключаем библиотеку для использования I2C интерфейса с модулем RTC #include <OneWire.h> //Подключаем библиотеку для использования однопроводного интерфейса #include <DallasTemperature.h> //Температурного датчика DS18B20 #include <RTClib.h> //Подключаем библиотеку для использования модуля часов реального времени RTC //----------Объявляем разные переменные-------------- #define DS1307_I2C_ADDRESS 0x68 // Указываем адресс RTC модуля #define RelPin4 A0 // Реле 1 вентилятор #define RelPin3 A1 // Реле 2 насос #define RelPin2 A2 // Реле 3 компрессор #define RelPin1 A3 // Реле 4 общее питание #define PWM_MIN 0 //Если необходим ток покоя на LED - изменить эту константу #define PWM_MAX 200 //Если необходимо ограничить максимальную яркость - уменьшить значение #define PWM_PIN 6 //Пин порта, где будет ШИМ #define mn 60UL //Дополнительные константы для удобства #define hr 3600UL //Отражают соответствующие количества секунд #define d 86400UL OneWire oneWire(2); // Подключаем датчик DS18B20 на цифровой пин 2 DallasTemperature sensors(&oneWire); //Создаем объект sensors, подключенный по OneWire //Создаем переменные для работы с термометром DeviceAddress tempDeviceAddress; //переменная для хранения адреса датчика float temp=0; //переменная для текущего значения температуры (то что показывает датчик) int setTmp=30; // переменная для заданного значения температуры const int t0 = 30; //Уставка температуры включения первого реле const int tGistrsis = 1; //Уставка гистерезиса - т.е отклонения от темп-ры уставки //т.е. в данном случае 1 = плюс минус 0.5 градус enum {sRel_23ON = 0, sRel_2OFF, sRel_3OFF}; uint32_t time1 = 0; uint8_t state = sRel_23ON; uint32_t period = 0; // Период для ВК 1го и 2го-реле unsigned long prevMillis; //------------------------------------------------------------------ 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, LOW); 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; //Создаем переменную класса - для использования RTC //------------------------------------------------------------------ time cur_time; time relay_1_on(07, 00, 00); // Время включения 4-ого реле time relay_1_off(23, 00, 00); // Время отключения 4-ого реле relay relay_1(RelPin1); // Реле 4 //------------------------------------------------------------------ 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(RelPin1, OUTPUT); pinMode(RelPin2, OUTPUT); pinMode(RelPin3, OUTPUT); pinMode(RelPin4, OUTPUT); sensors.begin(); //Инициализируем термодатчик sensors.getAddress(tempDeviceAddress, 0); Wire.begin(); //Инициируем I2C интерфейс RTC.begin(); //Инициирум RTC модуль analogWrite(PWM_PIN, PWM_MIN); //Пишем в порт минимальное значение Serial.begin(9600); //Запускаем сом-порт Serial.println("Test start"); Serial.print("Relay_1 ON ="); relay_1_on.print(); Serial.print("Relay_1 OFF ="); relay_1_off.print(); delay(3000); //Ожидаем открытия консоли if (! RTC.begin()) { Serial.println("Couldn't find RTC"); while (1); } RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); //Текущая строка выводит дату и время компиляции скетча. После заливки скетча нужно закомментировать. RTC.adjust(DateTime(2018, 9, 22, 21, 47, 30)); //Текущая строка предназначена для ручного ввода даты и времени в формате: Мес. день, год часы, минуты, секунды. } // КОНЕЦ ИНИЦИАЛИЗАЦИИ //-------------------------------------------------- void loop() { // delay(1000); // Задержка 1 сек. Чтобы не печаталось быстро //Запуск процедуры измерения температуры sensors.setWaitForConversion(false); sensors.requestTemperatures(); sensors.setWaitForConversion(true); //Считывание значения температуры sensors.getAddress(tempDeviceAddress, 0); temp=sensors.getTempC(tempDeviceAddress); 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.print(" Temperature = "); Serial.print(temp,1); Serial.print(" C, "); Serial.println(); delay(1000); if ((millis() - time1) >= period) { time1 = millis(); switch (state) { case sRel_23ON: state = sRel_2OFF; digitalWrite(RelPin2, LOW ); digitalWrite(RelPin3, LOW ); period = 10000; // Период для включения 1-го реле насоса 10 секунд Serial.print("Waterpump and Airpump ON"); Serial.println(); break; case sRel_2OFF: state = sRel_3OFF; digitalWrite(RelPin3, HIGH); period = 60000;// Период для включения 2го-реле компрессора 60 секунд Serial.print("Waterpump OFF"); Serial.println(); break; case sRel_3OFF: state = sRel_23ON; digitalWrite(RelPin2, HIGH); period = 18000000;// Период для выключения 1го и 2го-реле 30 минут Serial.print("Airpump OFF"); Serial.println(); break; } } //Проверка условия включения/выключения нагревателя if (temp > 30) // устанавливаем значение температуры при котором включается реле { digitalWrite(RelPin4, LOW); } if (temp < 30) // устанавливаем значение температуры при котором отключается реле { digitalWrite(RelPin4, HIGH); } // DateTime myTime = RTC.now(); // Получаем текущее время из DS1307 cur_time.set_time(myTime.hour(), myTime.minute(), myTime.second()); // Устанавливаем часы, минут, секунды в cur_time relay_1 = (cur_time>=relay_1_on) && (cur_time<relay_1_off); // Состояние реле 1 = нахождение текущего времени в диапазоне от relay_1_on до relay_1_off //cur_time.print(); // Выводим текущее время //------------КАНАЛ 1 (Контроль температуры по времени) ------- sensors.requestTemperatures(); // relay_1 = ((cur_time>=relay_1_on) && (cur_time<relay_1_off) && (temp < t0-tGistrsis/2)); // Состояние реле 1 = нахождение текущего времени в диапазоне от relay_1_on до relay_1_off и в диапазоне заданных температур }//------------Конец ЦИКЛА-----------------------------
А с чего оно должно по времени выключаться? По темепратуре вижу - в строках 219 и 223. А по времени где оно выключается?
А с чего оно должно по времени выключаться? По темепратуре вижу - в строках 219 и 223. А по времени где оно выключается?
Евгений, Вы не туда посмотрели :) Автор большой затейник, у него "четвертое реле" обозначено в скетче переменной relay_1, а соответсвенно relay_4 - это первое реле :)
Вообще скетч полон несуразностей.
Для работы с реле создан целый класс, но используется он только для Реле1 (то бишь 4). Реле два и три тупо довольствуются обычным digitalWrite без всяких классов.
А вот еще удачно названные переменные :)
В общем, диагноз - ТС утащил где чужой код, в котором почти ничего не понял и попытался его переделать, но неудачно.
Не - это не заработает по определению. А что Вы, сэр, хотели получить в итоге? Может проще написать, чем чужим овном пользоваться?
Да?
ну, в таком случае он непоследователен. Если четвёртое - relay1, то с чего первому быть relay4?
Вот как это решалось в класической кино:
Добрый день господа!
Да, все верно. Это не мой код, а смесь нескольких чужих скетчей. Дело в том, что я только начинаю и самому написать такой скетч мне просто не под силам. Очень много еще не понимаю, но я учусь. Просто обучение проходит очень медленно, так как без грамотного учителя приходится все познавать методом проб и ошибок.
Это проект для моей домашней гидропонной установки. Данный проект состоит из следующих компонентов:
1. Ардуино нано
2. RTC
3. Модуль из 4 реле
4. Блок питания на 12 В для запитывания оборудования (насос и вентилятор).
5. Блок питания на 5 В для питания ардуины и реле.
6. Диммируемый ЛЕД драйвер.
Задача данного проекта следующая:
1. В 7 утра включать свет (Реле 4).
2. Начиная с 7:05 постепенно увеличивать яркость от 10% до 100% в течении 55 минут (посредством ШИМ через операционный усилитель).
3. В течении дня запускать насос (Реле 2) на 10 сек для подачи питательного раствора для растений.
4. В течении для запускать компрессор (Реле 3) на 60 сек для насыщения питательного раствора кислородом. Причем насос и компрессор запучкаются одновременно, а после того как насос отключится компрессор еще 50 сек насыщать кислородом растров.
5 п.3 и п.4 повторяются через каждые 30 минут.
6 На LED светильник подведен датчик температуры, который по достижении определенной температуры запускает вентилятор (Реле1), чтобы охладить радиатор светильника.
7 В 21:00 начинает снижаться освещение со 100% до 10% в течении 55 минут.
8 Отключение освещения в 22:00 (Реле 4).
Прошу помочь с оптимизацией скетча. Схема устройства во вложении.
Прошу помочь с оптимизацией скетча.
здесь проще и дешевле с нуля написать.
здесь проще и дешевле с нуля написать.
Тогда хотя бы помогите с включением и отключением одного реле. Все остальное работает нормально. Вот только реле 4 не хочет работать.
Тогда хотя бы помогите с включением и отключением одного реле. Все остальное работает нормально. Вот только реле 4 не хочет работать.
Так хотя бы ответтьте на мой вопрос - где в коде Вы с ним работаете. А заодно и расскажите какой у него номер в программе, раз уж у Вас номера реле перепутаны для введения в заблуждение противника
На всякий случай спрошу. restiv, Вы часы-то на правильное время установили или так и живёте включая прибор ровно в 21:47:30?
... смесь нескольких чужих скетчей. Дело в том, что я только начинаю и самому написать такой скетч мне просто не под силам. Очень много еще не понимаю, но я учусь.
Вот интересно, Вы в школе учились?
Как Вас учили писать сочинения? Взять "Войну и Мир" и "Капитанскую дочку" и при помощи ножниц и клея сварганить из них собственную нетленку на тему "Как я провел лето"?
Программирование в этом отношщении ничем не отличается от литературного творчества.
Так что Вам нужно вспомнить, чему Вас учили на уроках русского языка и литературы (как писать сочинения) и на уроках иностраного языка - как переводить с одного языка на другой.
Так что Вам нужно сделать 3 вещи:
1. Написать план (ТЗ).
2. Написать сочинение (подробный алгоритм работы).
3. Перевести с русского на Си.
Так что, если Вы нуждаетесь в помощи, на этом форуме следует размещать не огрызки текстов, утянутых из и-нета, а результаты собственной работы на любом из этих трех этапов.
Так хотя бы ответтьте на мой вопрос - где в коде Вы с ним работаете. А заодно и расскажите какой у него номер в программе, раз уж у Вас номера реле перепутаны для введения в заблуждение противника
строка 82-83. Номер реле 4, а пин - RelPin1 подключенный к пину А3.
На всякий случай спрошу. restiv, Вы часы-то на правильное время установили или так и живёте включая прибор ровно в 21:47:30?
Нет, это я таким образом выяснял в какое время отключается реле. И методом тыка выяснил, что реле отключается в 21:48:00, вместо 23:00:00, которые я прописал в скетче.
строка 82-83. Номер реле 4, а пин - RelPin1 подключенный к пину А3.
Понятно, номер реле 4, а переменная называется relay_1 .
В общем работаете Вы с ним на в строках 82-83, там Вы только объявляете интервалы времени. Работаете с нимВы в строке 228, только Вы этого не поняли, похоже. Но работаете через зад. На кой-то хрен Вы там закомментировали получение текущего времени и почему-то ждёте, что она у Вас будет правильно по времени переключаться. С чего?
В общем, если если Вам нужна помощь, то
1. Прекратите издеваться над нами и переименуйте нормально переменные. Ну или уж называте реле, которое в программе называется relay_1, первым, а не четвёртым.
2. Восстановите получение времени и поставьте его (времени) печать.
3. Присваивайте условие в строке 228 переменной логического типа и печатайте её вместе со временем.
Вот когда всё это сделаете, если проблема ещё останется, возвращайтесь, выкладывайте свежий код и ту печать, что он выдаёт.
Получение времени у него есть, в начало loop перетащено (134 строка).
Для переменных времени два типа используются - свой класс time и DateTime, тут не напутано ли чего. В общем да, напечатать надо всё.
В общем, если если Вам нужна помощь, то
1. Прекратите издеваться над нами и переименуйте нормально переменные. Ну или уж называте реле, которое в программе называется relay_1, первым, а не четвёртым.
2. Восстановите получение времени и поставьте его (времени) печать.
3. Присваивайте условие в строке 228 переменной логического типа и печатайте её вместе со временем.
Вот когда всё это сделаете, если проблема ещё останется, возвращайтесь, выкладывайте свежий код и ту печать, что он выдаёт.
С п.1 и п.2 проблем нет. Исправил.
с п.3 не знаю как это сделать.
Исправленный код во вложении:
Зачем нужен вывод переменной до того как ей присвоили значание? Строки 225 и 226 местами поменяйте. И Вы как думаете, для чего Вас печать включить попросили? Чтобы Вы результат рассказали! Какое время печатается в момент включения реле?
с п.3 не знаю как это сделать.
Тут два варианта: либо проблема таки есть, либо Вы троллите и издеваетесь над нами. На кой чёрт печатать переменную до того, как ей что-то прислвоили?
И кроме того, где то, что она печатает? Вы для чего ставили печать? Чтобы никому не показать, что печатается?
с п.3 не знаю как это сделать.
Чего именно Вы не знаете? Вы не можете ввести промежуточную переменную?
и эту kaka напечатать? Или чего Вы не можете?
Делайте всё, выкладывайте скетч и печать. Еще раз будет что-то не так. я окончательно убежусь, что это троллинг.
Чего именно Вы не знаете? Вы не можете ввести промежуточную переменную?
К сожалению, промежуточную переменную я так и не осилил. Вроде просто, а я туплю. Но я нашел где была ошибка. Теперь все работает корректно. Спасибо!