Реле не размыкается

litaboss
Offline
Зарегистрирован: 02.09.2017

Есть лента, которая должна автоматически включаться с 6:57 до 7:03 ежедневно, кроме воскресенья. Питается она от 12В, ключём выступает реле, на которое подается сигнал от ардуино (D7), в прошивке которой написаны условия, при которых сигнал на D7 поступает. Эти условия используют информацию полученную с датчика времени DS1302. Прошивка датчика скачана отсюда: http://iarduino.ru/file/235.html. Проблема в том, что реле не размыкается даже когда условный оператор ложен. Включается реле тогда, когда запрограммировано. Код программы:

#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1302,2,4,3);
void setup() {
    delay(300);
    Serial.begin(9600);
    time.begin();
   // time.settime(-1,-1,-1,-1,-1,-1,-1);  // 0  сек, 31 мин, 20 час, 2, сентября, 2017 года, суббота
    pinMode(7, OUTPUT);
}
void loop(){
  if(millis()%1000==0){
      time.gettime();
      Serial.println(time.Hours);
      Serial.println(time.minutes);
      Serial.println(time.seconds);
      Serial.println(time.weekday);
     delay(1); // проверка работы датчика выводом данных с переменных
     }   
time.gettime();
  if ((time.Hours==6) && (time.minutes==57) && (time.minutes<=59)){  
    if ((time.weekday>=1) && (time.weekday<=6))
digitalWrite(7,HIGH); else digitalWrite(7,LOW);
      }
  if ((time.Hours==7)&&(time.minutes>=0)&&(time.minutes<=3)){
    if ((time.weekday>=1) && (time.weekday<=6))
      digitalWrite(7,HIGH); else digitalWrite(7,LOW);     
//      if (atoi(time.gettime("H"))==19) digitalWrite(7,HIGH);    
//if (strncmp(time.gettime("H"), "3",2) > 0) digitalWrite(7,HIGH); //другие варианты условных операторов 
}
delay(3); 
}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

Реле никогда не размыкается? - это странно Судя по коду должно размыкаться раз в неделю по воскресеньям в 6:57 :)

Emeljanowich
Emeljanowich аватар
Offline
Зарегистрирован: 30.04.2015
b707
Онлайн
Зарегистрирован: 26.05.2017

Emeljanowich, автору не нужен чужой код (да еще такой :), ему элементарные ошибки в своем надо поправить...

 

 

litaboss
Offline
Зарегистрирован: 02.09.2017

Это нормально замкнутое реле, и в 6:57 по коду оно должно подавать ток на ленту, что оно и делает, а перестать подавать ток не может...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/**/
//-------------------------------------------------
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1302, 2, 4, 3);
byte Hours, minutes, seconds, weekday;
//-----main-----------------------------------------
void setup() {
  Serial.begin(9600);
  time.begin();
  // time.settime(-1,-1,-1,-1,-1,-1,-1);  // 0  сек, 31 мин, 20 час, 2, сентября, 2017 года, суббота
  pinMode(7, OUTPUT);
  digitalWrite(7, LOW);
}
void loop() {
  if (millis() % 1000 == 0) {
    time.gettime();
    Hours = time.Hours;
    minutes = time.minutes;
    seconds = time.seconds;
    weekday = time.weekday;
    Serial.println(Hours);
    Serial.println(minutes);
    Serial.println(seconds);
    Serial.println(weekday);
    if (Hours == 6 && minutes <= 59 && weekday >= 1 && weekday <= 6)
      digitalWrite(7, HIGH);
    else if (Hours == 7 && minutes <= 3 && weekday >= 1 && weekday <= 6)
      digitalWrite(7, HIGH);
    else digitalWrite(7, LOW);
    //      if (atoi(time.gettime("H"))==19) digitalWrite(7,HIGH);
    //if (strncmp(time.gettime("H"), "3",2) > 0) digitalWrite(7,HIGH); //другие варианты условных операторов
  }
}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

qwone - у тебя в коде ошибка

b707
Онлайн
Зарегистрирован: 26.05.2017

litaboss пишет:

Это нормально замкнутое реле, и в 6:57 по коду оно должно подавать ток на ленту, что оно и делает, а перестать подавать ток не может...

сможет, если вы исправите ошибку в коде, на которую я указал

litaboss
Offline
Зарегистрирован: 02.09.2017

Загрузил ваш код. В 18:57 лента начала мигать с частотой чуть больше герца, а потом сама отключилась в 19:03...

litaboss
Offline
Зарегистрирован: 02.09.2017

На какую ошибку вы указали?

b707
Онлайн
Зарегистрирован: 26.05.2017

litaboss пишет:

На какую ошибку вы указали?

В твоем коде лента замыкается каждый будний день, а размыкается только по воскресеньям. Отследи внимательнее, как стоят if и else - и ты убедишься в этом.

Amfeon
Offline
Зарегистрирован: 08.09.2017

Добрый день.

Дабы не плодить темы, так же есть проблема с релюшками. Суть: нужно включать лампу с 8 до 20:00. Скетч работает на половину, то есть включает лампу в 8:00 но не выключает в 20:00. Если переподключиться к последовательному порту (или просто сбросить), то лампа гаснет (реле отрабатывает согласно времени), вреня сохранятеся и показывается правильно.

Есть предположение что забивается какой то буфер и не происходит сравнение часов

Оборудование: Uno, DS1307, 4 channel relay.

#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <dht.h>
#define DHTPIN 2 //2 цифровой термометр
#define DHTTYPE DHT21   // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);

int Rele=3; // Лампа
int Rele2=4; //для включения вытяжки
int Rele_pump=5; //помпа
int Rel5=6; // тестовый клон реле 3
void setup() {
    pinMode(Rele, OUTPUT);    //3 выход лампа
  //  pinMode(Rele2, OUTPUT);   //4 вытяжка
    pinMode(Rele_pump, OUTPUT);   //5 помпа
    pinMode(Rel5, OUTPUT);
    dht.begin();
  Serial.begin(9600);
  while (!Serial) ; 
  delay(200);
}

void loop() {
  tmElements_t tm;
  if (RTC.read(tm)) {
  float h = dht.readHumidity(); //влажность
  float t = dht.readTemperature(); // температура
  int  x=tm.Hour; //часы
  int  m=tm.Minute; //минуты
    if(x>=8 && x<20){// если день или утро лампу включить
    Serial.println("day");
  //  print2digits(tm.Hour);
      digitalWrite(Rele,LOW);
      digitalWrite(Rel5,LOW); // тестовая без фазы
          if((m>50&&m<54)||(m>20&&m<24)){ // 2 раза в час запускать помпу
            digitalWrite(Rele_pump,LOW); //запуск насоса
            }else{
              digitalWrite(Rele_pump,HIGH); //остановка насоса
              }
      delay(1000);
      }else{ //вечер лампу выключить
        Serial.println("nigth");
      //  print2digits(tm.Hour);
        digitalWrite(Rele,HIGH); // гасим лампу
        digitalWrite(Rel5,HIGH);
      //   Serial.println(time.gettime("H:i:s")); // выводим время
         if((m>50&&m<53)||(m>20&&m<23)){
            digitalWrite(Rele_pump,LOW); //запуск насоса
            }else{
              digitalWrite(Rele_pump,HIGH); //остановка насоса
              }
        delay(1000);
        }

  } else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped.  Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
   // delay(9000);
  }
 // delay(1000);
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

навскидку ошибок в логике не вижу. Если раскомментить строки 33, 44 и 47 - время правильно показывает?

PS В строке 20 точка с запятой не нужна.

Amfeon
Offline
Зарегистрирован: 08.09.2017

Да время показывает верно. Более того, с минутами стр 36 все работает верно.  Проблемма с часами.

b707
Онлайн
Зарегистрирован: 26.05.2017

добавьте вывод в сериал переменной х после строки 30

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

А часы случаем не в 12 часовом формате возвращаются? Может там 20 и не наступает?

Amfeon
Offline
Зарегистрирован: 08.09.2017

Ситуация такая, последовательный порт после примерно часа перестает получать данные (или выводить), Если переподключиться то все выводится (какое то время, закономерности нет).

На скрине видно, что программа заходит в цикл дня, затем правильно выводит часы и минуты.

Если залить скетч на границе  перехода в другой цикл (день/ночь), то реле работает. То есть если тестировать все в ближайшей перспективе 20-30 минут то все работает.

В общем вопроса 2, почему в последовательном порте перестает идти вывод ну и где же косяк в программе =).

PS: формат часов 24 судя по переменной х (часы)

b707
Онлайн
Зарегистрирован: 26.05.2017

единственная мысль - не слишком ли часто опрашиваете датчики. Поскольку у вас  программа вообще ничего критичного по времени не делает, я б добавил в цикл ЛУП задержку подлиннее - секунд в 30,  минуту или больше

Amfeon
Offline
Зарегистрирован: 08.09.2017

Спасибо, поставлю задержку после выходных посмотрим что вышло.

b707
Онлайн
Зарегистрирован: 26.05.2017

Ну или как вариант - оставить цикл как есть, но считывать датчики температуры раз в 5-10 минут (а зачем чаще?), а время с RTC - и того реже

Amfeon
Offline
Зарегистрирован: 08.09.2017

Итак результат выставления задержки в 30 секунд.

В Пятницу в 14:30 программа была залита. ПЕрешла в ночь в 20:00, в субботу перешла в день в 8:00, перешла в ночь, в воскресенье перешла в день в 8:00, а в 13:31 в последовательный порт перестали поступать данные и далее реле уже не переключалось. 

Таким образом, задержка не решение, попоробую делать опрос через millis().

PS есть ошушение что количество опросов конечно, что loop это не бесконечный цикл, а с константой, Если задержки нет - зависает через час, если честь через пару дней (в зависимости от delay())

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Amfeon пишет:

PS есть ошушение что количество опросов конечно, что loop это не бесконечный цикл, а с константой

за такие утверждения месные гуру тутже поднимают на вилы.  

Amfeon
Offline
Зарегистрирован: 08.09.2017

На вилы то поднять всегда успеют , но после решения проблемы =) (ну и это был тонкий намек на какой нить скрытый буфер/массив, который из-за моей криворукости как то переполняется, так то понятно что Loop бесконечен)

PS: Для так сказать чистоты эксперимента запустил вывод времени из примера, пока все работает, ждем 24 часа, по факту пример отличается лишь отсутствием логических операций.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

DetSimen пишет:

за такие утверждения месные гуру тутже поднимают на вилы.  

...на гыляку. или берьозку.

Amfeon
Offline
Зарегистрирован: 08.09.2017

в 9:58 был залит скетч с выводом времени

#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <dht.h>
#define DHTPIN 2 //2 цифровой термометр
#define DHTTYPE DHT21   // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
int x;
int m;
int time1;
int Rele=3;
int Rele2=4; //для включения вытяжки
int Rele_pump=5;
void setup() {
    pinMode(Rele, OUTPUT);    //3 выход лампа
    pinMode(Rele2, OUTPUT);   //4 вытяжка
    pinMode(Rele_pump, OUTPUT);   //5 помпа
    digitalWrite(Rele,HIGH);
    digitalWrite(Rele2,HIGH);
    digitalWrite(Rele_pump,HIGH);
    dht.begin();
  Serial.begin(9600);

}

void loop() {
tmElements_t tm;
  if (RTC.read(tm)) {
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    /***************************************/
    Serial.print("Ok, Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.println();
    /*------------------------------------*/
    if((tm.Hour>=8) && (tm.Hour<15)){// если день или утро лампу включить
    Serial.println("day");

         if(((tm.Minute>50) && (tm.Minute<54)) || ((tm.Minute>20) && (tm.Minute<25))){ // 2 раза в час запускать помпу
          Serial.println("pump on");
        //    digitalWrite(Rele_pump,LOW); //запуск насоса
            }else{
          //    digitalWrite(Rele_pump,HIGH); //остановка насоса
              }
       }else { //вечер лампу выключить
        Serial.println("nigth");
       // digitalWrite(Rele,HIGH); // гасим лампу
       // digitalWrite(Rele2,HIGH);
         if(((tm.Minute>50) && (tm.Minute<53)) || ((tm.Minute>20) && (tm.Minute<23))){
           // digitalWrite(Rele_pump,LOW); //запуск насоса
           Serial.println("pump on");
            } else{
              //digitalWrite(Rele_pump,HIGH); //остановка насоса
             }
      }
  } else {
    if (RTC.chipPresent()) {
        Serial.println("The DS1307 is stopped.  Please run the SetTime");
        Serial.println("example to initialize the time and begin running.");
        Serial.println();
    } else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
    delay(9000);
  }
  delay(500);
}
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

запустил последовательынй порт. в 10:28 последовательынй порт перестал выводить данные. Почему?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

забился.

Amfeon
Offline
Зарегистрирован: 08.09.2017

Можно поподробней? 

Amfeon
Offline
Зарегистрирован: 08.09.2017

Повторю вопрос, чем может вызваться "забивание" сом порта после пары часов работы (или это зависание самой ардуины)? Светодиод RX перестает мигать.

Можно указть хотябы направление куда копать, так как про "забивание" гугл информацию не выдает. Есть ли какие нибудь средства отладки?

Залитый скетч 

#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include <dht.h>
#define DHTPIN 2 //2 цифровой термометр
#define DHTTYPE DHT21   // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
int Rele=3;
int Rele2=4; //для включения вытяжки
int Rele_pump=5;
void (*ResetFun)(void)=0;
void setup() {
    pinMode(Rele, OUTPUT);    //3 выход лампа
    pinMode(Rele2, OUTPUT);   //4 вытяжка
    pinMode(Rele_pump, OUTPUT);   //5 помпа
    digitalWrite(Rele,HIGH);
    digitalWrite(Rele2,HIGH);
    digitalWrite(Rele_pump,HIGH);
  dht.begin();
  Serial.begin(19200);
  //delay(200);
}

void loop() {
tmElements_t tm;
  if (RTC.read(tm)) {
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    /***************************************/
    Serial.print("Ok, Time = ");
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.write(':');
    print2digits(tm.Second);
    Serial.println();
    Serial.print(h);
    Serial.print("----");
    Serial.println(t);
    /*------------------------------------*/
    if((tm.Hour>=8) && (tm.Hour<15)){// если день или утро лампу включить
    Serial.println("day");
      digitalWrite(Rele,LOW);
             if((tm.Minute==56) && (tm.Second==10)){
            Serial.println("Reset");
            delay(100);
            ResetFun();
            }
         if(((tm.Minute>50) && (tm.Minute<54)) || ((tm.Minute>20) && (tm.Minute<25))){ // 2 раза в час запускать помпу
          Serial.println("pump on");
            digitalWrite(Rele_pump,LOW); //запуск насоса
            }else{
              digitalWrite(Rele_pump,HIGH); //остановка насоса
              }
       }else { //вечер лампу выключить
        Serial.println("nigth");
        digitalWrite(Rele,HIGH); // гасим лампу
        digitalWrite(Rele2,HIGH);
         if(((tm.Minute>50) && (tm.Minute<53)) || ((tm.Minute>20) && (tm.Minute<23))){

           digitalWrite(Rele_pump,LOW); //запуск насоса
           Serial.println("pump on");
            } else{
              digitalWrite(Rele_pump,HIGH); //остановка насоса
             }
      }
  } else {
    if (RTC.chipPresent()) {
        Serial.println("The DS1307 is stopped.  Please run the SetTime");
        Serial.println("example to initialize the time and begin running.");
        Serial.println();
    } else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
    delay(9000);
  }
  delay(500);
}
void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}