Включение и отключение реле по времени не отрабатывает уставки

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

Добрый вечер!

В скетче какой то глюк или это мои кривые руко но, никак не могу настроить работу скетча. Реле 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 и в диапазоне заданных температур 
    
  
}//------------Конец ЦИКЛА-----------------------------

 

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

А с чего оно должно по времени выключаться? По темепратуре вижу - в строках 219 и 223. А по времени где оно выключается?

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

ЕвгенийП пишет:

А с чего оно должно по времени выключаться? По темепратуре вижу - в строках 219 и 223. А по времени где оно выключается?

Евгений, Вы не туда посмотрели :) Автор большой затейник, у него "четвертое реле" обозначено в скетче переменной relay_1, а соответсвенно relay_4 - это первое реле :)

Вообще скетч полон несуразностей.

Для работы с реле создан целый класс, но используется он только для Реле1 (то бишь 4). Реле два и три тупо довольствуются обычным digitalWrite без всяких классов.

А вот еще удачно названные переменные :)

#define RelPin4 A0                                  // Реле 1 вентилятор
#define RelPin3 A1                                  // Реле 2 насос
#define RelPin2 A2                                  // Реле 3 компрессор
#define RelPin1 A3                                  // Реле 4 общее питание

 

В общем, диагноз - ТС утащил где чужой код, в котором почти ничего не понял и попытался его переделать, но неудачно.

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

Не - это не заработает по определению. А что Вы, сэр, хотели получить в итоге? Может проще написать, чем чужим овном пользоваться?

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

b707 пишет:
"четвертое реле" обозначено в скетче переменной relay_1, а соответсвенно relay_4 - это первое реле :)

Да?

ну, в таком случае он непоследователен. Если четвёртое - relay1, то с чего первому быть relay4?

Вот как это решалось в класической кино:

  • Где вы разместите правый фланг?
  • Слева.
  • Слева. Чудесная мысль. А левый фланг - справа?
  • Нет, сир, в центре.

 

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

Добрый день господа!

Да, все верно. Это не мой код, а смесь нескольких чужих скетчей. Дело в том, что я только начинаю и самому написать такой скетч мне просто не под силам. Очень много еще не понимаю, но я учусь. Просто обучение проходит очень медленно, так как без грамотного учителя приходится все познавать методом проб и ошибок.

Это проект для моей домашней гидропонной установки. Данный проект состоит из следующих компонентов:

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).

Прошу помочь с оптимизацией скетча. Схема устройства во вложении.

vvadim
Offline
Зарегистрирован: 23.05.2012

restiv пишет:

Прошу помочь с оптимизацией скетча.

 

здесь проще и дешевле с нуля написать.

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

vvadim пишет:

здесь проще и дешевле с нуля написать.

Тогда хотя бы помогите с включением и отключением одного реле. Все остальное работает нормально. Вот только реле 4 не хочет работать.

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

restiv пишет:

Тогда хотя бы помогите с включением и отключением одного реле. Все остальное работает нормально. Вот только реле 4 не хочет работать.

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

kalapanga
Offline
Зарегистрирован: 23.10.2016

На всякий случай спрошу. restiv, Вы часы-то на правильное время установили или так и живёте включая прибор ровно в 21:47:30?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

restiv пишет:

... смесь нескольких чужих скетчей. Дело в том, что я только начинаю и самому написать такой скетч мне просто не под силам. Очень много еще не понимаю, но я учусь.

Вот интересно, Вы в школе учились?

Как Вас учили писать сочинения? Взять "Войну и Мир" и "Капитанскую дочку" и при помощи ножниц и клея сварганить из них собственную нетленку на тему "Как я провел лето"?

Программирование в этом отношщении ничем не отличается от литературного творчества.

Так что Вам нужно вспомнить, чему Вас учили на уроках русского языка и литературы (как писать сочинения) и на уроках иностраного языка - как переводить с одного языка на другой.

Так что Вам нужно сделать 3 вещи:

1. Написать план (ТЗ).

2. Написать сочинение (подробный алгоритм работы).

3. Перевести с русского на Си.

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

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

ЕвгенийП пишет:

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

строка 82-83. Номер реле 4, а пин - RelPin1 подключенный к пину А3.

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

kalapanga пишет:

На всякий случай спрошу. restiv, Вы часы-то на правильное время установили или так и живёте включая прибор ровно в 21:47:30?

Нет, это я таким образом выяснял в какое время отключается реле. И методом тыка выяснил, что реле отключается в 21:48:00, вместо 23:00:00, которые я прописал в скетче.

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

restiv пишет:

строка 82-83. Номер реле 4, а пин - RelPin1 подключенный к пину А3.

Понятно, номер реле 4, а переменная называется relay_1 .

В общем работаете Вы с ним на в строках 82-83, там Вы только объявляете интервалы времени. Работаете с нимВы в строке 228, только Вы этого не поняли, похоже. Но работаете через зад. На кой-то хрен Вы там закомментировали получение текущего времени и почему-то ждёте, что она у Вас будет правильно по времени переключаться. С чего?

В общем, если если Вам нужна помощь, то

1. Прекратите издеваться над нами и переименуйте нормально переменные. Ну или уж называте реле, которое в программе называется relay_1, первым, а не четвёртым.

2. Восстановите получение времени и поставьте его (времени) печать.

3. Присваивайте условие в строке 228 переменной логического типа и печатайте её вместе со временем.

Вот когда всё это сделаете, если проблема ещё останется, возвращайтесь, выкладывайте свежий код и ту печать, что он выдаёт.

kalapanga
Offline
Зарегистрирован: 23.10.2016

Получение времени у него есть, в начало loop перетащено (134 строка). 

Для переменных времени два типа используются - свой класс time и DateTime, тут не напутано ли чего. В общем да, напечатать надо всё. 

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

ЕвгенийП пишет:

В общем, если если Вам нужна помощь, то

1. Прекратите издеваться над нами и переименуйте нормально переменные. Ну или уж называте реле, которое в программе называется relay_1, первым, а не четвёртым.

2. Восстановите получение времени и поставьте его (времени) печать.

3. Присваивайте условие в строке 228 переменной логического типа и печатайте её вместе со временем.

Вот когда всё это сделаете, если проблема ещё останется, возвращайтесь, выкладывайте свежий код и ту печать, что он выдаёт.

С п.1 и п.2 проблем нет. Исправил.

с п.3 не знаю как это сделать.

Исправленный код во вложении:

//----------ИМПОРТ БИБЛИОТЕК-------------------------
#include <Wire.h>                                   //Подключаем библиотеку для использования I2C интерфейса с модулем RTC 
#include <OneWire.h>                                //Подключаем библиотеку для использования однопроводного интерфейса 
#include <DallasTemperature.h>                      //Температурного датчика DS18B20
#include <RTClib.h>                                 //Подключаем библиотеку для использования модуля часов реального времени RTC

//----------Объявляем разные переменные--------------
#define DS1307_I2C_ADDRESS 0x68                     // Указываем адресс RTC модуля
#define relay_1 A3                                  // Реле 1 общее питание
#define relay_2 A2                                  // Реле 2 компрессор
#define relay_3 A1                                  // Реле 3 насос
#define relay_4 A0                                  // Реле 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    relay1_on(07, 00, 00);          // Время включения 1-ого реле
time    relay1_off(22, 19, 00);        // Время отключения 1-ого реле  
relay   relay1(relay_1);                // Реле 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(relay_1, OUTPUT); 
pinMode(relay_2, OUTPUT);   
pinMode(relay_3, OUTPUT);
pinMode(relay_4, 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 =");
relay1_on.print();
Serial.print("relay_1 OFF =");
relay1_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(relay_2, LOW );
        digitalWrite(relay_3, LOW );
        period = 10000; // Период для включения 1-го реле насоса 10 секунд
        Serial.print("Waterpump and Airpump ON");
        Serial.println();
        break;
      case sRel_2OFF:
        state = sRel_3OFF;
        digitalWrite(relay_3, HIGH);
        period = 60000;// Период для включения 2го-реле компрессора 60 секунд
        Serial.print("Waterpump OFF");
        Serial.println();
        break;
      case sRel_3OFF:
        state = sRel_23ON;
        digitalWrite(relay_2, HIGH);
        period = 18000000;// Период для выключения 1го и 2го-реле 30 минут
        Serial.print("Airpump OFF");
        Serial.println();
        break;
    }
  }
                                                                                          //Проверка условия включения/выключения вентилятора
if (temp > 30) // устанавливаем значение температуры при котором включается реле
  {
    digitalWrite(relay_4, LOW); 
  }
if (temp < 30) // устанавливаем значение температуры  при котором отключается реле
  { 
    digitalWrite(relay_4, HIGH);
  }
    cur_time.print();                                                                      // Выводим текущее время
    cur_time.set_time(myTime.hour(), myTime.minute(), myTime.second());                    // Устанавливаем часы, минут, секунды в cur_time
    relay1 = (cur_time>=relay1_on) && (cur_time<relay1_off);                               // Состояние реле 1 = нахождение текущего времени в диапазоне от relay1_on до relay1_off

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

 

kalapanga
Offline
Зарегистрирован: 23.10.2016

Зачем нужен вывод переменной до того как ей присвоили значание? Строки 225 и 226 местами поменяйте. И Вы как думаете, для чего Вас печать включить попросили? Чтобы Вы результат рассказали! Какое время печатается в момент включения реле?

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

restiv пишет:

с п.3 не знаю как это сделать.

Тут два варианта: либо проблема таки есть, либо Вы троллите и издеваетесь над нами. На кой чёрт печатать переменную до того, как ей что-то прислвоили?

    cur_time.print();                                                                      // Выводим текущее время
    cur_time.set_time(myTime.hour(), myTime.minute(), myTime.second());                    // Устанавливаем часы, минут, секунды в cur_time

И кроме того, где то, что она печатает? Вы для чего ставили печать? Чтобы никому не показать, что печатается?

restiv пишет:

с п.3 не знаю как это сделать.

Чего именно Вы не знаете? Вы не можете ввести промежуточную переменную? 

// вместо
relay1 = (cur_time>=relay1_on) && (cur_time<relay1_off); 

// написать
bool kaka = (cur_time>=relay1_on) && (cur_time<relay1_off); 
relay1 = kaka;

и эту kaka напечатать? Или чего Вы не можете?

Делайте всё, выкладывайте скетч и печать. Еще раз будет что-то не так. я окончательно убежусь, что это троллинг.

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

ЕвгенийП пишет:

Чего именно Вы не знаете? Вы не можете ввести промежуточную переменную?

К сожалению, промежуточную переменную я так и не осилил. Вроде просто, а я туплю. Но я нашел где была ошибка. Теперь все работает корректно. Спасибо!