Проблема с работоспособностью скетка
- Войдите на сайт для отправки комментариев
Пнд, 12/08/2019 - 19:05
Господа, всем привет!
Пару месяцев назад я создавал темы в которых просил помощи в реализации кода и мне очень сильно помогли.
Сейчас у меня снова возникла потребность в помощи.
Прикладываю скетч, который идеально работал до какого-то момента. Но теперь есть проблема. По какой-то причине релею включения дренажа и реле включения полива не срабатывает по установленному расписанию и срабатванию датчика (геркона) уровня воды. Если отключить Ардуино и потом включит, то скетч продолжает нормально работать. Прошу помощи у опытных коллег, так как не знаю в каком направлении копать.
Спасибо большое за помощь!
#include <Wire.h> // Библиотека iarduino_RTC будет использовать методы и функции библиотеки Wire. #include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени. iarduino_RTC time(RTC_DS3231); // Объявляем объект time для работы с RTC модулем на базе чипа DS3231, используется аппаратная шина I2C int relay = 5; // Определение пина для реле включения насоса полива int relay_lights = 3; // Определение пина для реле включения света певрого стеллажа int relay_lights2 = 4; // Определение пина для реле включения света второго стеллажа String RT = "50"; String TimeOn = "00:00:00"; // Время включения первого полива String TimeOff = "00:00:00"; // Время выключения первого полива String TimeOn2 = "08:00:00"; // Время включения второго полива String TimeOff2 = "08:02:00"; // Время выключения второго полива String TimeOn3 = "16:00:00"; // Время включения третьего полива String TimeOff3 = "16:02:00"; // Время выключения третьего полива String LightsOn = "05:00:00"; // Время включения освещения String LightsOff = "22:00:00"; // Время выключения освещения #define pumpPin 6 // Определение пина для реле включения дренажного насоса #define waterSensorPin 2 //при отсутствии воды замыкается на GND #define pump_ON digitalWrite (pumpPin, HIGH) #define pump_OFF digitalWrite(pumpPin, LOW) #define noWater digitalRead(waterSensorPin) == LOW unsigned long timeON; unsigned long workTime = 120000; // 2 минуты boolean flag = true; void setup(){ // delay(300); // Ждем готовности модуля отвечать на запросы Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод. time.begin(); // Инициируем работу с модулем. pinMode(relay, OUTPUT); pinMode(relay_lights, OUTPUT); pinMode(relay_lights2, OUTPUT); digitalWrite(relay, LOW); digitalWrite(relay_lights, HIGH); digitalWrite(relay_lights2, HIGH); pinMode(waterSensorPin, INPUT_PULLUP); pinMode(pumpPin, OUTPUT); } // void loop(){ // if(millis()%1000==0){ // Если прошла 1 секунда. Serial.println(time.gettime("d-m-Y, H:i:s, D")); // Выводим время. delay(1); // Приостанавливаем скетч на 1 мс, чтоб не выводить время несколько раз за 1мс. } // RT = time.gettime("H:i:s"); if (RT == TimeOn){ digitalWrite(relay, HIGH); } if (RT == TimeOff){ digitalWrite(relay, LOW); } if (RT == TimeOn2){ digitalWrite(relay, HIGH); } if (RT == TimeOff2){ digitalWrite(relay, LOW); } if (RT == TimeOn3){ digitalWrite(relay, HIGH); } if (RT == TimeOff3){ digitalWrite(relay, LOW); } if (noWater && flag){ pump_ON; timeON = millis(); flag = false; } if (millis() - timeON > workTime){ pump_OFF; flag = true; } if (RT == LightsOn){ digitalWrite(relay_lights, HIGH); digitalWrite(relay_lights2, HIGH); } if (RT == LightsOff){ digitalWrite(relay_lights, LOW); digitalWrite(relay_lights2, LOW); } }
у вас для первого полива время включения и выключения совпадают. Не знаю, важно ли это для вас - но как-то "неакууратненько"
Да, действительно помарка. Не заметил сразу. Я просто вчера перенастраивал время и не углядел. Спасибо, что обратили внимание!
А по основному вопросу может быть есть какие-то мысли? Из-за чего такая штука может происходить?
Просмотрел внимательно код - явных ошибок не вижу. Если именно этот код раньше работал, а теперь нет - боюсь, найти ошибку в нем сможет только человек, работающий с девайсом непосредственно, то есть Вы сами.
кривовато написано => кривовато работает (работает через раз). Явные ошибки не в синтаксе, явные ошибки в проектировании программы.
Согласен, что программа кривоватая, потому что знания у меня кривоватые. НО она работала несколько месяцев, а тут БАЦ и перестала хорошо работать ))))
Сейчас еще раз подключился к Ардуино, все перепроверил, прогнал несколько циклов включения-выключения полива - все четко работает, по секундам. Свет так же по таймингу включается-выключается. Как-будто какая-то барабашка. Посмотрю завтра утром, может нормально будет работать.
Еще вот что я заметил. Когда подключается к последовательному порту, чтобы мониторить время на RTC, то время обновляется не каждую секунду, как это по идее должно быть (судя по коду), а каждые несколько секунд, иногда подвисает на секунд двадцать. Но при этом это зависание не влияет на срабатывание включения-выключения, я по таймеру засекал.
Вы сравниваете не абсолютную величину а некую стринговую переменную и на полное совпадение. Если у вас идет проскок на секунды, то и нужная сработка не происходит.
ПС: Я тут форум уже подз***л про автоматы. Но если форумчанам это давно известно, то у ваше неприятие автоматов скорее связано с религией.
Если честно, все что после "ПС" я не понял )))))
Какие автоматы?
А как именно реализована схема включения реле полива? Какое именно реле применяется?
Схема такая:
Насос 12 Вольт подключен к блоку питания на 12 Вольт. К ардуино подключено вот такое реле (https://iarduino.ru/shop/Expansion-payments/rele-elektromehanicheskoe-do-250v-10-a-1--kanal-5v.html) (это не реклама, просто именно его и покупал там). Реле подключено к пину 6 на Ардуно. И вот когда наступает время полива, которая сравнивается с RTC включается реле и идет полив. Так же вылючается.
Вы сравниваете не абсолютную величину а некую стринговую переменную и на полное совпадение. Если у вас идет проскок на секунды, то и нужная сработка не происходит.
Тоже обратил на это внимание, идёт сравнение на совпадение (четкое совпадение) «несравнимых величин».
Однакоесли раньше работало - значит сейчас что то «не даёт работать». Не исключено что погрешности в секунду вносит что из исполнимой цепи.
Если честно, все что после "ПС" я не понял )))))
Какие автоматы?
Спасибо за инфу! Буду просвещатся!
Может тогда поставить знак не "==" времени включения, а "=>"?
И еще, может нюанс с тем, что при мониторинге серийного порта время не каждую секунду обновляется? Но тоже пока не ложится как теория, так как при тестовых прогонах это не влияло на включение-выключение.
Может тогда поставить знак не "==" времени включения, а "=>"?
Может тогда поставить знак не "==" времени включения, а "=>"?
А пройдет ли такой финт:
объявить стринговую переменную со временем, далее некая переменная преобразует стринг в юникс и сравнивает юникс время расписания с юникс текущего времени?
Или я херню сейчас написал?)
Так я об этом и говорил, я это понимаю. Только в данной реализации такое «или» не возможно.
на юниксе сейчас постоено практически все. Все Оси на компьютерах, интернет и так далее. Но вам хватит свой местный юникс- сколько секунд прошло с начала дня. На определеных секундах включать и на других выключать . А когда настал новый день перевзодить.
на юниксе сейчас постоено практически все. Все Оси на компьютерах, интернет и так далее. Но вам хватит свой местный юникс- сколько секунд прошло с начала дня. На определеных секундах включать и на других выключать . А когда настал новый день перевзодить.
Другими словами - используйте интервалы времени, а не привычные для человека «штампы».
То есть, вы предлагаете использовать millis вместо RTC?
https://youtu.be/kTMjaj7U3RY - вот видео как сейчас работает. Извините за мою ногу и качество видео. Я настроел полив каждый 15 секунд, чтобы проверить. И все включалось четко. Но видимо где-то сбоит.
А чем вам millis() плохи? )))
То есть, вы предлагаете использовать millis вместо RTC?
нет, вам советуют выкинуть строки и вместо них кодировать время числами.
Да лично мне ничем не плохи))))
Просто захотелось построить на RTC и вроде как работает, но сбоит по всей видимости )))
Просто если Ардуино выключать чтобы перенастроить или там с электрикой позаниматься придется наверняка помучаться с миллис, так как не всегда ты включишь ардуно в тоже время как и выключил, а полив и свет для растений лучше по расписанию делать. Так вот у RTC своя батарейка и ничего не сбивается после отключения Ардуино ) полагаю с millis() такое не прокатит )
А чем вам millis() плохи? )))
тем, что миллис не привязаны к реальному времени. Если полив надо включать именно в 8 утра, а не раз в 15 секунд - RTC удобнее.
Просто непонятно, с чего ТС выбрал такую странную систему условий по времени - строками "08:00:00"
у RTC своя батарейка и ничего не сбивается после отключения Ардуино ) полагаю с millis() такое не прокатит )
все правильно, оставьте RTC, но перейдите на числа в представлении времени
Потому что время в часа сейчас в таком формате выводится, если по сериал порту мониторить, соответствено такой формат и выбрал. Это мне коллеги с формума помогли, я пару месяцев назад советовался по этому скетчу и мне сильно помогли.
для вас RTC лучше. он не сбивается при отключении питания
ПС: посмотрите. #82 Может вам это пригодится.
Потому что время в часа сейчас в таком формате выводится
и что с того? - поменяйте на числовой
это они или задачу не поняли, либо вы их совет по своему переиначили. Этот метод контроля интервалов однозначно плохой
Понял, принял, буду курить мат часть. На текущем этапе не умею переводить в числа время ))) буду учиться
для вас RTC лучше. он не сбивается при отключении питания
ПС: посмотрите. #82 Может вам это пригодится.
Буду изучать, спасибо!
Понял, принял, буду курить мат часть. На текущем этапе не умею переводить в числа время ))) буду учиться
изучите свою библиотеку RTC - в любой подобной библиотеке есть методы, возвращающие отдельно часы, отдельно минуты и отдельно секунды в виде целых чисел. А из этих данных, думаю, числовое время в любом удобном вам формате вы рассчитаете сами...
Спасибо большое за советы!
Буду изучать.
Согласен, что программа кривоватая, потому что знания у меня кривоватые. НО она работала несколько месяцев, а тут БАЦ и перестала хорошо работать ))))
Чудес, имхо, не бывает. По личному опыту, если что-то работало без нареканий несколько месяцев, а потом, вдруг (при условии, что действительно софт не трогали), стало работать некорректно - иди тщательно мыть плату и датчики.
Согласен! Я в чудеса тоже не верю.
Сегодня снова произошел сбой, но теперь уже не только насос не включился, но и подстветка с ночи не включилась по расписанию. Отключение и снова включение системы возобновило работу контроллера.
Я сейчас грешу на тройник. Раньше все подключал к розетке, а теперь через тройник и возможно что-то там происходит. Но я не уверен. Надо будет копаться, но куда пока не знаю)))
Если память не тикеть, то вачдог тебе в сумку
Я очень извиняюсь, но поясните, пожалуйста, для особо одаренных. Что вы сейчас сказали?)
Все же тема в "Песочнице", а значит я нуб)))
Если вешается не из-за утечек памяти или неверной работы с указателями, а из-за сбоев по питанию, то правильная настройка watchdog может помочь тебе.
Опять нипанятна?
Теперь понятно, спасибо!))))
Вот читаю про watchdog. Не все так просто. Оказывается не на всех ардуино он работает корректно и надо с бубнами потанцевать. Но вроде пишут, что на Уно (а у меня именно такая) работает все нормально. Но у меня уно не на оригинальном чипе. Он не вытянутый, то есть не Atmega на сколько я понимаю. Будет ли там работать этот вотчдог. Надо будет протестить.
Будет. Потестено.
Супер! Тогда пойду прописывать код)) спасибо!
Если вешается не из-за утечек памяти или неверной работы с указателями, а из-за сбоев по питанию, то правильная настройка watchdog может помочь тебе.
Старая народная мудрость гласит - "Если у вас была проблема и вы решили использовать ватчдог что бы ее решить, то теперь у вас будет две проблемы."
Может попытаться решить проблему с зависанием?
Если вешается не из-за утечек памяти или неверной работы с указателями, а из-за сбоев по питанию, то правильная настройка watchdog может помочь тебе.
Может попытаться решить проблему с зависанием?
Зависит от ТС. Но если зависания праисходют от искрения в тройнике, который отчего-то поменять трудно, или вапще невозможно, тут то на сцэну и выскочит вачдог, как чорт из табакерки.
Лопатить чужой код спахмелья, выискивая утечки, как по мне, - так себе занятие.
Что то мне подсказывает, что данный код является бедой этого шедевра простоты
Вот прям нутром чую.
А как это побороть, для начала надо задать себе вопрос, нужна ли такая точность, до 1 секунды?
Я бы не стал сильно замарачиваться на вашем месте, не губите время, попробуйте скетч ниже:
DAK - по комментам в вашем коде о переполнении миллис - если интервалы вычислять правильно, оно(переполнение) никак не влияет на работу программы. И до 50 суток, и после. и прямо во время перехода через ноль интервалы будут работать верно
У вас в коде - правильно
Спасибо за комментарий!
Попробуй сегодня протестировать.
Еще вопрос. В коде стоит два раза delay. Первый раз на 300, второй (как вы поставили) на 1000.
Вообще имеет смысл два раза delay указывать? И нужен ли он в первом случае?
Спасибо за комментарий!
Если вешается не из-за утечек памяти или неверной работы с указателями, а из-за сбоев по питанию, то правильная настройка watchdog может помочь тебе.
Старая народная мудрость гласит - "Если у вас была проблема и вы решили использовать ватчдог что бы ее решить, то теперь у вас будет две проблемы."
Может попытаться решить проблему с зависанием?
Знать бы как ее решить, эту проблему с зависанием. Грешу на тройник, сегодня переподключу на другой. Просто у меня моя мини ферма расширилась с одного до трех стеллажей и пришлось ставить этот самый тройник. Он вроде работает, но мало ли что там у него происходит. До этого этот же самый код с одним стеллажом работал без нареканий в течении месяц, может даже больше без перезагрузок и выключений.
Если вешается не из-за утечек памяти или неверной работы с указателями, а из-за сбоев по питанию, то правильная настройка watchdog может помочь тебе.
Может попытаться решить проблему с зависанием?
Зависит от ТС. Но если зависания праисходют от искрения в тройнике, который отчего-то поменять трудно, или вапще невозможно, тут то на сцэну и выскочит вачдог, как чорт из табакерки.
Лопатить чужой код спахмелья, выискивая утечки, как по мне, - так себе занятие.
Нет, конечно. Не надо мой код лопатить и я меньше всего хотел бы кого-то напрягать. То, что все присутствующие здесь так или иначе направляют меня давая пищу для размышления и изучения - уже очень ценно. Спасибо! )
DAK - по комментам в вашем коде о переполнении миллис - если интервалы вычислять правильно, оно(переполнение) никак не влияет на работу программы. И до 50 суток, и после. и прямо во время перехода через ноль интервалы будут работать верно
У вас в коде - правильно
Представим, что в исходном коде таймер 71-то строки зафиксируется за 1 секунду до переполнения условия
тогда таймер отключения (74 строка) не сработает никогда, просто не должно сработать по определению.
millis()-timeON будет отрицательным почти 50 дней.
он бы висел вечно, пока я туда не дописал условие (если я правильно читаю мануалы, то я не зря добавил условие)