Прошу помощи со скетчем автополива
- Войдите на сайт для отправки комментариев
Добрый день!
Сделал в подарок жене систему автоматического орошения сада по секциям + капельное. Вся "механическая" часть работает как часы, но с программной как то все не ладится. В начале DS1307 по непонятной причине начинали очень сильно отставать, заменил на 3231, вроде норм. Теперь первая секция полива включается, через заданное время выключается, включается вторая + капельное, но через заданное время не выключается. Предполагаю, что проблема может быть в том, что параллельно идет проверка наполнения емкостей, и т.к. уровень воды в садовой емкости падает, выполняется условие набора, а условие отключения полива остается позади. Так ли это? Просьба сильно не пинать за синтаксис программы, понимаю, что наверняка его можно было сделать не таким огромным с кучей условий. Готов прислушаться к адекватной критике. Прошу помощи в победе такой не сложной задачи. Заранее спасибо!
#include <EtherCard.h> // Подключаем скачанную библиотеку. https://yadi.sk/d/R57sVoglbhTRN #include <EEPROM.h> // Для Записи / восстановление из EEPROM состояния LedPins. #include <iarduino_RTC.h> // Подключаем библиотеку часов iarduino_RTC watch(RTC_DS3231); int const Thour = 20;// Час начала полива int const Tmin = 00; //Минуты начала полива int const Tmin1 = 21; //Минуты начала полива 2-й секции //int const Tmin2 = 18; //Минуты начала капельного полива int const Tsec = 00; //Секунды начала полива // Массив задействованных пинов. int Dp1 = 22;//поплавок дом int Dp2 = 23;//поплавок колодец int Dp3 = 24;//поплавок сад int Rp1 = 25;//клапан набора в сад int Rp2 = 26;//клапан 1 секции полива int Rp3 = 27;//клапан 2 секции полива int Rp4 = 28;//клапан капельного орошения int Rp5 = 29;//насос дно колодца int Rp6 = 30;//насос колодец int Rp7 = 31;//насос сад int VDp1 = 1;//состояние поплавка дома int VDp2 = 1;//состояние поплавка колодца int VDp3 = 1;//состояние поплавка сад void setup() { Serial.begin(9600); watch.begin(); pinMode(Dp1, INPUT_PULLUP);//поплавок дом с внутренним подтягивающим резистором pinMode(Dp2, INPUT_PULLUP);//поплавок колодец с внутренним подтягивающим резистором pinMode(Dp3, INPUT_PULLUP);//поплавок сад с внутренним подтягивающим резистором pinMode(Rp1, OUTPUT);//клапан набора в сад pinMode(Rp2, OUTPUT);//клапан 1 секции полива pinMode(Rp3, OUTPUT);//клапан 2 секции полива pinMode(Rp4, OUTPUT);//клапан капельного орошения pinMode(Rp5, OUTPUT);//насос дно колодца pinMode(Rp6, OUTPUT);//насос колодец pinMode(Rp7, OUTPUT);//насос сад Serial.begin(9600); digitalWrite(Rp7, HIGH); digitalWrite(Rp2, HIGH); digitalWrite(Rp3, HIGH); digitalWrite(Rp4, HIGH); } void loop() { watch.gettime();// получение текущего времени if (watch.Hours == Thour && watch.minutes == Tmin && watch.seconds == Tsec) { //Сравнение текущего времени с заданным временем полива 1-й секции digitalWrite(Rp7, LOW); digitalWrite(Rp2, LOW); } if (watch.Hours == Thour && watch.minutes == Tmin+20 && watch.seconds == Tsec){ //Таймаут полива 1-й секции digitalWrite(Rp7, HIGH); digitalWrite(Rp2, HIGH); } if (watch.Hours == Thour && watch.minutes == Tmin1 && watch.seconds == Tsec){ //Сравнение текущего времени с заданным временем полива 2-й секции digitalWrite(Rp7, LOW); digitalWrite(Rp3, LOW); digitalWrite(Rp4, LOW); } if (watch.Hours == Thour && watch.minutes == Tmin1+20 && watch.seconds == Tsec){ //Таймаут полива 2-й секции digitalWrite(Rp7, HIGH); digitalWrite(Rp3, HIGH); digitalWrite(Rp4, HIGH); } //проверки для набора воды в емкости VDp1 = digitalRead(Dp1); VDp2 = digitalRead(Dp2); VDp3 = digitalRead(Dp3); if (VDp1 == HIGH && VDp2 == HIGH && VDp3 == LOW) {//если вода есть везде digitalWrite(Rp1, HIGH); digitalWrite(Rp5, HIGH); digitalWrite(Rp6, HIGH); } if (VDp1 == LOW && VDp2 == HIGH && VDp3 == LOW) {//если воды нет только в доме digitalWrite(Rp1, HIGH); digitalWrite(Rp5, LOW); digitalWrite(Rp6, LOW); } if (VDp1 == HIGH && VDp2 == HIGH && VDp3 == HIGH) {//если воды нет только в саду digitalWrite(Rp1, LOW); digitalWrite(Rp5, LOW); digitalWrite(Rp6, LOW); } if (VDp1 == LOW && VDp2 == LOW && VDp3 == LOW) {//если воды нет в доме и колодце digitalWrite(Rp1, HIGH); digitalWrite(Rp5, LOW); digitalWrite(Rp6, HIGH); } if (VDp1 == LOW && VDp2 == HIGH && VDp3 == HIGH) {//если воды нет в доме и саду digitalWrite(Rp1, HIGH); digitalWrite(Rp5, LOW); digitalWrite(Rp6, LOW); } if (VDp1 == LOW && VDp2 == LOW && VDp3 == HIGH) {//если воды нет нигде digitalWrite(Rp1, HIGH); digitalWrite(Rp5, LOW); digitalWrite(Rp6, HIGH); } if (VDp1 == HIGH && VDp2 == LOW && VDp3 == HIGH) {//если воды нет в колодце и в саду digitalWrite(Rp1, HIGH); digitalWrite(Rp5, LOW); digitalWrite(Rp6, HIGH); } if (VDp1 == HIGH && VDp2 == LOW && VDp3 == LOW) {//если воды нет только в колодце digitalWrite(Rp1, HIGH); digitalWrite(Rp5, LOW); digitalWrite(Rp6, HIGH); } Serial.println(watch.gettime("d-m-Y, H:i:s, D")); }
Навскидку:
1. в поливалке (054 - 078) 4 if'а, и все они начинаются с "watch.Hours == Thour". Вот и сделай эти 20 часов одним условием, а внутри него 4 включения/выключения насосов и клапанов по минутам. секунды из условий выбрось, закуске эта точность не нужна, а программе лишняя путаница.
2. управление подкачкой (073 - 132) никак не должно мешать отключению второй секции полива (067).
Подправил, так ?
А есть идеи, почему не срабатывает отключение?
С подкачкой вроде проблем нет, вот только с работой по часам
Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца.
Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца.
Это уже мне не понятно, к сожалению...
Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца.
Это уже мне не понятно, к сожалению...
Это значит, например, в виде "количество секунд, прошедших с начала суток". Т.е.
Тогда не придется возиться с кучей условий - достаточно будет сравнивать одно число
Прочитайте про unix time. В инклюде time.h есть подпрограммы для конвертации времени в число и обратно. Программу проще писать, когда время представлено одним числом, а не часы минуты секунды.
Да ему и без секунд можно, число минут в сутках 24*60 = 1440, влезет в 2 байта
Дело может быть не в программе, а в наводках от срабатывающих клапанов.
Как часто зависает? - если всегда, то попробуйте без подключенных внешних устройств. Посмотрите поможет - или нет.
В общем-то там и без клапанов наводок хватит - сигнальные линии, поди, десятками метров измеряются. Да по улице
Да, так и есть сигнальные линии метров по 30. Тоже посещали такие мысли. Если подтвердится, что с этим делать?
Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца.
Это уже мне не понятно, к сожалению...
Это значит, например, в виде "количество секунд, прошедших с начала суток". Т.е.
Тогда не придется возиться с кучей условий - достаточно будет сравнивать одно число
Вот как раз в таком виде в uint16_t не поместится.
Зато никто не запрещает считать время в единицах по 1,318359375 секунды.
Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца.
Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца.
ТС-у - во вложенных if.
и схему пора выложить.
Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца.
ТС-у - во вложенных if.
я бы вообще ещё тупее, без лишних переменных, написал
По скетчу в варианте #2 отсутствует проверка секунд. Я правильно понимаю, что всю минуту, по условию в if происходят повторные включения ( или выключения) пока минута не сменится?
В общем приехал домой, залил скетч в данном варианте и все сработало четко. Либо просто повезло и не глюкануло, либо за счёт того, что условие выполняется минуту, оно на какой то из повторных проверок сработало...
Лишнюю скобку нашел, все ок)))
Оно не на скобку ругалось, а на переменную ниже, но быстро разобрался)))
Переменные добавил, потому что там еще и эзернет есть, в будущем хотелось управление с веб морды
А если оставить секунды в условиях - будет то же самое, но фраза будет выглядеть "... всю секунду... пока секунда не сменится".
А если оставить секунды в условиях - будет то же самое, но фраза будет выглядеть "... всю секунду... пока секунда не сменится".
Включения или выключения я имел ввиду, в зависимости от выполняемого условия. То есть повторные подачи сигнала все таки идут всю минуту, правильно? Если так, то раньше была всего секунда для проверки условия и выполнения команды, а в эту секунду могло глюкануть систему из за наводок, а теперь есть целая минута, за которую, возможно не с первого раза, но система сработала. В таком случае остаётся только наблюдать.
А если оставить секунды в условиях - будет то же самое, но фраза будет выглядеть "... всю секунду... пока секунда не сменится".
"не думай о секунде свысока"
А если оставить секунды в условиях - будет то же самое, но фраза будет выглядеть "... всю секунду... пока секунда не сменится".
"не думай о секунде свысока"
Да понятно, что не один раз))
Но как то же она умудрялась пропустить команду
Ну что ж. Второй день система срабатывает как задумано. Тьфу-тьфу.
Подозреваю, что удаление секунд помогло. Осталось самое простое- эзернет прикрутить)))) С ним я думаю намучаюсь побольше.
Всем большое спасибо за советы!