Реле не размыкается
- Войдите на сайт для отправки комментариев
Пнд, 04/09/2017 - 19:21
Есть лента, которая должна автоматически включаться с 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);
}
Реле никогда не размыкается? - это странно Судя по коду должно размыкаться раз в неделю по воскресеньям в 6:57 :)
http://arduino.ru/forum/proekty/vklyuchenie-sveta-po-raspisaniyu
Emeljanowich, автору не нужен чужой код (да еще такой :), ему элементарные ошибки в своем надо поправить...
Это нормально замкнутое реле, и в 6:57 по коду оно должно подавать ток на ленту, что оно и делает, а перестать подавать ток не может...
/**/ //------------------------------------------------- #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); //другие варианты условных операторов } }qwone - у тебя в коде ошибка
Это нормально замкнутое реле, и в 6:57 по коду оно должно подавать ток на ленту, что оно и делает, а перестать подавать ток не может...
сможет, если вы исправите ошибку в коде, на которую я указал
Загрузил ваш код. В 18:57 лента начала мигать с частотой чуть больше герца, а потом сама отключилась в 19:03...
На какую ошибку вы указали?
На какую ошибку вы указали?
В твоем коде лента замыкается каждый будний день, а размыкается только по воскресеньям. Отследи внимательнее, как стоят if и else - и ты убедишься в этом.
Добрый день.
Дабы не плодить темы, так же есть проблема с релюшками. Суть: нужно включать лампу с 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); }навскидку ошибок в логике не вижу. Если раскомментить строки 33, 44 и 47 - время правильно показывает?
PS В строке 20 точка с запятой не нужна.
Да время показывает верно. Более того, с минутами стр 36 все работает верно. Проблемма с часами.
добавьте вывод в сериал переменной х после строки 30
А часы случаем не в 12 часовом формате возвращаются? Может там 20 и не наступает?
Ситуация такая, последовательный порт после примерно часа перестает получать данные (или выводить), Если переподключиться то все выводится (какое то время, закономерности нет).
На скрине видно, что программа заходит в цикл дня, затем правильно выводит часы и минуты.
Если залить скетч на границе перехода в другой цикл (день/ночь), то реле работает. То есть если тестировать все в ближайшей перспективе 20-30 минут то все работает.
В общем вопроса 2, почему в последовательном порте перестает идти вывод ну и где же косяк в программе =).
PS: формат часов 24 судя по переменной х (часы)
единственная мысль - не слишком ли часто опрашиваете датчики. Поскольку у вас программа вообще ничего критичного по времени не делает, я б добавил в цикл ЛУП задержку подлиннее - секунд в 30, минуту или больше
Спасибо, поставлю задержку после выходных посмотрим что вышло.
Ну или как вариант - оставить цикл как есть, но считывать датчики температуры раз в 5-10 минут (а зачем чаще?), а время с RTC - и того реже
Итак результат выставления задержки в 30 секунд.
В Пятницу в 14:30 программа была залита. ПЕрешла в ночь в 20:00, в субботу перешла в день в 8:00, перешла в ночь, в воскресенье перешла в день в 8:00, а в 13:31 в последовательный порт перестали поступать данные и далее реле уже не переключалось.
Таким образом, задержка не решение, попоробую делать опрос через millis().
PS есть ошушение что количество опросов конечно, что loop это не бесконечный цикл, а с константой, Если задержки нет - зависает через час, если честь через пару дней (в зависимости от delay())
PS есть ошушение что количество опросов конечно, что loop это не бесконечный цикл, а с константой
за такие утверждения месные гуру тутже поднимают на вилы.
На вилы то поднять всегда успеют , но после решения проблемы =) (ну и это был тонкий намек на какой нить скрытый буфер/массив, который из-за моей криворукости как то переполняется, так то понятно что Loop бесконечен)
PS: Для так сказать чистоты эксперимента запустил вывод времени из примера, пока все работает, ждем 24 часа, по факту пример отличается лишь отсутствием логических операций.
за такие утверждения месные гуру тутже поднимают на вилы.
...на гыляку. или берьозку.
в 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 последовательынй порт перестал выводить данные. Почему?
забился.
Можно поподробней?
Повторю вопрос, чем может вызваться "забивание" сом порта после пары часов работы (или это зависание самой ардуины)? Светодиод 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); }