Модификация скетча
- Войдите на сайт для отправки комментариев
Чт, 09/05/2019 - 16:08
Уважаемые господа, добрый день!
У меня есть сектч, с помощью некоторых из вас написанный, для полива растений.
Сейчас сделано так, что Relay2 включается в том случае если срабатывает датчик уровня воды и выключается когда уровень воды падает. Но реальность такова, что мне требуется, чтобы после включения Relay2 работал еще какое-то время после падения уровня. Направьте, пожалуйста, куда копать?
Спасибо за помощь!
Скетч во вложении:
#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени. iarduino_RTC time(RTC_DS3231); // Объявляем объект time для работы с RTC модулем на базе чипа DS3231, используется аппаратная шина I2C #include <LiquidCrystal.h> // #define DIODE_DROP 0.7 LiquidCrystal lcd(13, 12, 11, 10, 9, 8); int relay = 5; int relay2 = 6; String RT = "50"; String RT2 = "50"; String TimeOn = "12:00:00"; String TimeOff = "12:05:00"; String TimeOn2 = "23:00:00"; String TimeOff2 = "23:05:00"; const uint8_t L1 = 2; void setup(){ pinMode(L1, INPUT_PULLUP); pinMode(relay, OUTPUT); pinMode(relay2, OUTPUT); digitalWrite(relay, LOW); // digitalWrite(relay2, LOW); delay(300); // Ждем готовности модуля отвечать на запросы Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод. time.begin(); // Инициируем работу с модулем. lcd.begin(16, 2); lcd.print("Current time:"); } // void loop() { if(millis()%1000>=0) { // Если прошла 1 секунда. lcd.setCursor(0, 1); lcd.print(time.gettime("d-m H:i:sA")); // Выводим время. } RT = time.gettime("H:i:s"); RT2 = time.gettime("H:i:s"); if (RT == TimeOn) { digitalWrite(relay, HIGH); } if (RT == TimeOff) { digitalWrite(relay, LOW); } if (RT2 == TimeOn2) { digitalWrite(relay, HIGH); } if (RT2 == TimeOff2) { digitalWrite(relay, LOW); } if (!digitalRead(L1)) digitalWrite(relay2, HIGH); else digitalWrite(relay2, LOW); }
Вместо отключения реле2(стр 62) запомните время в новой переменной события(как стр37) и добавьте к нему время на ожидание. Добавте провеку события так же как в строках 45-47 и выключитите реле2.
Спасибо большое за подсказку!
Сделал вот так:
А теперь при проверки скетча пишет "Ошибка для компиляции платы".
Пардонте. Нашел ошибку вот тут: digitalWrite(relay2. LOW);
Исправил "точку" на "запятую". Сейчас пойду и проверю, работает ли )))
Спасибо за помощь!
В таком виде может пропускать отключение. Если датчик сработает позже 2 минут, то условие в сторке 64 никогда не выполнится. Нужно поставить знак сравнения больше. У Вас отчёт от включения, а надо от срабатывания датчика.
Спасибо за совет!
Сейчас попробовал первоначальный вариант и Ваш. Но в итоге все равно не работает. Если поплавок поднять, то реле начинает выдавать "автоматную очередь". За секунду включается и выключается неисчислимое количество раз. :)
64 строка вообще не работает, да что предполагается во всей связки строк 61-65 я могу только догадываться. Уважаемый ТС, Вы конечно крутой программист, но пока я бы посоветовал использовать if(){Ваши действия }
В строках:
61: Если поднимается датчик уровня воды
62: Включить реле
63: В переменную RT3 записываем текущее время с часов.
64: Если текущее время + время в переменной TimeOff3 равно текущему времени
65: Выключить реле.
Суть в том, что я хочу сделать так, чтобы после срабатывания датчика уровня воды реле было включено 2 минуты, даже если датчик опустится вниз. Сейчас получается так, что когда датчик опускается, то реле вылючается, но так как это поплавок и он не стабильный в течении какого-то времени реле все равно включается и выключается множество раз, а я хочу убрать этот баг.
Тогда должно быть вот так:
Спасибо большое за помощь!
Сделал так, но чет не работает. Реле включается, но работает бесконечно, не реагируя на условие. Не выключается по заданному промежутку времени.
Главная ошибка - запоминать время нужно не в момент включения а в момент выключения. А потом делать отдельную проверку полученного времени и потом только отключать реле. В одно if этого не сделать. Они разнесены у вас по времени. Это отдельные процессы и для каждого нужен свой отдельный if.
Имеется ввиду: момент выключения датчика уровня воды?
Момент когда надо отключить реле. Как это момент связан с датчиком я не знаю. У вас нет комментариев что чему соответствует в программе.
Спасибо большое за помощь!
Сделал так, но чет не работает. Реле включается, но работает бесконечно, не реагируя на условие. Не выключается по заданному промежутку времени.
Да оно и не должно работать.
Пока я Вам показал только неправильность синтаксиса. Теперь перейдем к логике Вашей программы. Итак - у Вас упал уровень Вы зафиксировали это время (реле не трогаем), когда нужное время прошло мы выключаем реле.
Но есть у меня сомнения: первое в строке 66 надо ставить не ==, а >=, и второе - а выдайте на порт (RT3 + TimeOff3) и
time.gettime(
"H:i:s"
) из строки 65. Чет мне кажется, что они не сравнимы.
1) Поставил ">=" - при поднятии уровня воды реле начинает выдавать "автоматную очередь".
2) Вывел на порт и действительно, они не сравнимы. time.gettime выдает 12:32:56, а (RT3 + TimeOff3) выдает 5000:00:05.
Просто RT3 выдает значение "50" - изначально заложенное
Просто TimeOff3 выдает "00:02:00" - изначальное заложенное
Получается, что RT3 не записывает текущее время после If.
А если сделать так, чтобы сработал датчик уровня воды, то значение в (RT3 + TimeOff3) принимает вот такой вид: "12:45:2500:02:00".
То есть он не плюсует время, а просто добавляет в строку.
А я и вообще не понял - на кой там вообще RTC, кроме как для запутывания мозгов?
А я и вообще не понял - на кой там вообще RTC, кроме как для запутывания мозгов?
Здравая мысль! А почему Вам после того, как опустился уровень просто не подождать с помоцью delay() и не выключить реле? delay() пугает? Так Вы его не бойтесь - он хороший и многие программы на ассемблере написаны именно с подобной функцией.
Суть в том, что я хочу сделать так, чтобы после срабатывания датчика уровня воды реле было включено 2 минуты, даже если датчик опустится вниз. Сейчас получается так, что когда датчик опускается, то реле вылючается, но так как это поплавок и он не стабильный в течении какого-то времени реле все равно включается и выключается множество раз, а я хочу убрать этот баг.
loop()
{
если (сработал датчик) { включили реле; запомнили t1=millis(); }
если (millis()-t1 > 2 минут) { выключили реле; }
}
Уфф...
А я и вообще не понял - на кой там вообще RTC, кроме как для запутывания мозгов?
Видимо да, я из-за незнания многих вещей путаю сам себе и вам мозги )))
А я и вообще не понял - на кой там вообще RTC, кроме как для запутывания мозгов?
Здравая мысль! А почему Вам после того, как опустился уровень просто не подождать с помоцью delay() и не выключить реле? delay() пугает? Так Вы его не бойтесь - он хороший и многие программы на ассемблере написаны именно с подобной функцией.
Если честно, то да. Побаиваюсь Delay, так как у меня время выведено на LCD экран и если ставить delay, но оно перестает "тикать". Чисто эстетическая "заморочка". :) Да еще я подумал, раз есть RTC, то почему бы к нему все и не привязывать, но видимо криво все получается у меня. ))
Суть в том, что я хочу сделать так, чтобы после срабатывания датчика уровня воды реле было включено 2 минуты, даже если датчик опустится вниз. Сейчас получается так, что когда датчик опускается, то реле вылючается, но так как это поплавок и он не стабильный в течении какого-то времени реле все равно включается и выключается множество раз, а я хочу убрать этот баг.
loop()
{
если (сработал датчик) { включили реле; запомнили t1=millis(); }
если (millis()-t1 > 2 минут) { выключили реле; }
}
Уфф...
Спасибо большое за помощь! Сегодня вечером доеду еще раз до гаража и попробую это реализовать.
Спасибо Вам большое за помощь!
Код работает, но с существенным нюансом. Если срабатывает датчик уровня воды, то включается реле и работает 2 минуты (либо любое другое заданное время). Но если датчик уровня воды срабатывает повторно, то ничего не происходит. Цикл не выполняется. :)
Спасибо Вам большое за помощь!
Код работает, но с существенным нюансом. Если срабатывает датчик уровня воды, то включается реле и работает 2 минуты (либо любое другое заданное время). Но если датчик уровня воды срабатывает повторно, то ничего не происходит. Цикл не выполняется. :)
Давай весь код.
Может так (стоит 2 мин - не проверял)
Вот так выглядит код.
Элемент Вашего кода сейчас закомментирован, так как новые культуры уже посадил и загрузил старую прошивку, чтобы полив осущствлялся. Но когда пробовал, то второй раз не включалось. Вручную активировал датчик уровня воды, а релюшка не включалась. Строки с 69.
Рабочая программа, можно собрать на столе и проверить.
Скорее так получше.Так как во втором if нет проверки на флаг
А еще лучше через автомат Пуха.
во втором if нет проверки на флаг
Ардуина протрется - это ладно. Перелива не боитесь?
Господа SLKH и qwone, спасибо Вам огромнейшее за помощь! На днях доеду до гаража и загружу Ваши коды и потом отпишусь.
sadman41, поясните, пожалуйста, что Вы имели ввиду?
Я вижу, что в последних вариантах насос включается по датчику, но выключается по интервалу. А это потенциальная проблема.
Так я писал выше, что это нужно для того, чтобы насос не срабатывал по нескольку раз после откачки воды, так как там у меня стоит поплавок (геркон) и когда попалвок опускается насос отключается, но так как он китайский и не стабильный (плавает какое-то время), насос включается и выключается еще несколько раз. Именно эта часть кода управляет не насосом полива, а насосом перекачки воды от "отсойного" бака в основной. Поэтому там никакого перелива и не будет.
Я вижу, что в последних вариантах насос включается по датчику, но выключается по интервалу. А это потенциальная проблема.
Нда, интересная логика. Не совсем понимаю что там где плавает, но интуитивно чувствую жопу )
Во-вторых, вызовы функции set() при каждом проходе loop() сотрут ардуину гораздо больше, чем мой вариант.
В-третьих, автоматный код вообще нерабочий.
Подскажите, пожалуйста, что означает "сотрут Ардуино"? Имеется ввиду, что у такой код быстро вырабатывает ресурс микроконтроллера?
Нда, интересная логика. Не совсем понимаю что там где плавает, но интуитивно чувствую жопу )
Так почему от края бочки?)
Для общего понимания распишу полный цикл:
Есть стеллаж из 5 полок на котором я выращиваю различную травушку-муравушку. На каждой полке стоит по 4 поддона с посевами. Над каждым поддоном есть форсунка, которая распрыскивает воду (поливает всходы). Вода к форсункам подается из основного бака и этим поливом управляется первая реле, которая включается по расписанию 2 раза в сутки по 2-3 минуты. Далее, у каждого поддона есть дренажные отверстия через которые излишки воды стекают на стеллаж и самотеком по системе труб стекает в бак, в котором отстаивается (это нужно потому что выращиваю на земле и мне надо, чтобы вода немного отстоялась перед тем как вернуть ее в основной бак). В баке в котором вода отстаивается стоит насос, который отдалет от дна (чтобы не захватывать грязь) и в этом баке стоит поплавок. Поплавок стоит у края этого отстоечного бака. Как только срабатывает поплавок - включается насос. Но когда поплавок падает, то получается, что насос выкачал ровно столько, сколько требуется, чтобы поплавок упал. И получается, что поплавок плавает на поверхности и иногда провоцирует включаение насоса на пару секунд (так как дренаж работает и капелька за капелькой стекает в отстоечный бак). А там помимо уровня поплавка еще есть 5 литров воды, которую можно откачать, на это и требуется дополнительные две минуты. Вот для этого я и затеял всю эту котовасию. Наверное сейчас понятно написал. )))
Ну, если объем конечный, то пусть качает по времени, конечно.
Подскажите, пожалуйста, что означает "сотрут Ардуино"? Имеется ввиду, что у такой код быстро вырабатывает ресурс микроконтроллера?
if
(millis() - timeON > workTime)
30
{
31
pump_OFF;
32
flag =
true
;
33
}
Первые 2 минуты после запуска (если за это время не сработает датчик) процессор бесполезно отработает команды в строках 31 и 32, которые ничего не меняют - ни уровня на пине, ни состояния переменной. Это никому не мешает, кроме qwone: он считает, что следует добавить ещё одну проверку ради экономии ресурсов процессора, т.к. при открытии в браузере до фига страниц он (браузер) начинает тормозить.
как-то так...
Ничего там не сотрется, ты всё-то всерьёз не принимай.
Так почему от края бочки?)
Не, это как раз не расширительный бачок, а наоборот - бак в котором скапливается вода уже после полива растений (излишки воды стекают со стеллажей, чтобы предотвратить перелив). В этом баке вода отстаивается и уже потом при наполнении перекачивается в основной бак. Такой круговорот воды. Тем самым я экономлю воду.
Вот такая "чудо" система.
Много компромисов, так как это эксперимент и все делаю в гаража в ограниченном пространстве. :)
Нда, интересная логика. Не совсем понимаю что там где плавает, но интуитивно чувствую жопу )
Мне кажется, хотели сказать про гистерезис. Но не сумели...
Конечно много компромисов. Если воды много, то будет банально гонять по кругу.2 минуты качаем- проверяем наличие воды-воды много и датчик говорить ОК - качаем 2 минуты. Или воды очень мало. - ждем до упора пока "дождь не пойдет", так как воды в системе мало.
Это стандартное поведение многих датчиков, покачаться при резком изменении измеряемых параметров. Решения разные в этом случае. Можно как дребезг клавиш устранять например. Мне нравится вариант с накоплением сигнала датчика. Если датчик в состоянии сработал, то плюсуем единицу к переменной, нет - вычитаем. Если накапливаемое значение превысило порог отключаем насос. Это решение имеет несколько плюсов. Не чувствительность к помехам. Включение рядом точила не приводит к ложному срабатыванию. Время долива можно регулировать поргом отключения.