Проблеммы с реле
- Войдите на сайт для отправки комментариев
Добрый день форумчане!
Снова прошу вас помочь с кодом. Ранее вы мне помогли решить поставленную задачу. И код исправно работал с задачей включения и отключения 3-х реле с определенной периодичностью. Теперь решил доработать код и дополнительно установить датчик температуры и задействовать четвертое реле для включения вентилятора и тут возникла проблема. А именно, не происходит срабатывание включения/отключения реле. В сом-порте все красиво и четко прописывается включение/отключение реле, но на практике этого не происходит. Точнее реле включается и через какое то время отключается, даже если условие по температуре еще не выполнено, но при этом в сом-порте пишется все правильно, что реле включено, хотя на самом деле оно отключено. Не могу поянть в чем дело. Подскажите пожалуйста в чем косяк? И сразу по пути подскажите как сделать так, чтобы информация о включенном/отключенном реле не выводилать каждый раз, а только когда произошел цикл отключения или включения?
#include <OneWire.h>
#include <Wire.h> //Подключаем библиотеку для использования I2C интерфейса с модулем RTC
#include <RTClib.h> //Подключаем библиотеку для использования модуля часов реального времени RTC
#define DS1307_I2C_ADDRESS 0x68 //Указываем адресс RTC модуля
#define RelPin1 A0 //Реле 1 насос
#define RelPin2 A1 //Реле 2 компрессор
#define RelPin3 A2 //Включение реле 3 общее питание
#define RelPin4 A3 //Включение вентилятора охлаждения
OneWire ds(2); // подключен к 2 пину (резистор на 4.7к обязателен)
enum {sRel_12ON = 0, sRel_1OFF, sRel_2OFF, sRel_4OFF};
uint32_t time1 = 0;
uint8_t state = sRel_12ON;
uint32_t period = 0;// Период для ВК 1го и 2го-реле
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(RelPin3); // Реле 1
//------------------------------------------------------------------
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
long sunrise_start = 07*hr+05*mn; //Начало восхода в 9 - 45
long sunrise_duration = 55*mn; //Длительность восхода 30 минут
long sunset_start = 21*hr+00*mn; //начало заката в 21-15
long sunset_duration = 55*mn; //Длительность заката 30 минут
//********************************************************************************************
void setup(){
pinMode(RelPin1, OUTPUT);
pinMode(RelPin2, OUTPUT);
pinMode(RelPin3, OUTPUT);
pinMode(RelPin4, OUTPUT);
Wire.begin(); //Инициируем I2C интерфейс
RTC.begin(); //Инициирум RTC модуль
analogWrite(PWM_PIN, PWM_MIN); //Пишем в порт минимальное значение
Serial.begin(9600); //Запускаем сом-порт
Serial.println("Test start");
//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, 17, 10, 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); //Пишем в порт вычисленное значение
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr))
{
Serial.println();
ds.reset_search();
delay(250);
return;
}
for( i = 0; i < 8; i++)
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // начало коммуникации
delay(1000);
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // читаем значение
Serial.print(" ");
for ( i = 0; i < 9; i++)
{ // смотрим 9 байтов
data[i] = ds.read();
Serial.print(" ");
}
// Преобразуем получненный данные в температуру
// Используем int16_t тип, т.к. он равен 16 битам
// даже при компиляции под 32-х битный процессор
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3;
if (data[7] == 0x10) {
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw & ~7;
else if (cfg == 0x20) raw = raw & ~3;
else if (cfg == 0x40) raw = raw & ~1;
}
celsius = (float)raw / 16.0;
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(celsius);
Serial.print(" C, ");
Serial.println();
delay(1000);
if (celsius > 31) // устанавливаем значение температуры при котором включается реле
{
digitalWrite(RelPin4, HIGH);
Serial.print("Relay 4 ON");
// Serial.print();
}
if (celsius < 30) // устанавливаем значение температуры при котором отключается реле
{
digitalWrite(RelPin4, LOW);
Serial.print("Relay 4 OFF");
// Serial.print();
}
if ((millis() - time1) >= period) {
time1 = millis();
switch (state) {
case sRel_12ON:
state = sRel_1OFF;
digitalWrite(RelPin1, LOW );
digitalWrite(RelPin2, HIGH );
period = 10000; // Период для включения 1-го реле насоса 10 секунд
Serial.print("Relay 1 ON");
Serial.println();
break;
case sRel_1OFF:
state = sRel_2OFF;
digitalWrite(RelPin1, HIGH);
period = 60000;// Период для включения 2го-реле компрессора 60 секунд
Serial.print("Relay 2 ON");
Serial.println();
break;
case sRel_2OFF:
state = sRel_12ON;
digitalWrite(RelPin2, LOW);
period = 1200000;// Период для выключения 1го и 2го-реле 20 минут
Serial.print("Relay 1 & Relay 2 OFF");
Serial.println();
break;
}
}
}