Прошу помощи со скетчем автополива

SeLL19
Offline
Зарегистрирован: 04.08.2021

Добрый день!

Сделал в подарок жене систему автоматического орошения сада по секциям + капельное. Вся "механическая" часть работает как часы, но с программной как то все не ладится. В начале 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"));

}

 

SLKH
Offline
Зарегистрирован: 17.08.2015

Навскидку:

1. в поливалке (054 - 078) 4 if'а, и все они начинаются с "watch.Hours == Thour". Вот и сделай эти 20 часов одним условием, а внутри него 4 включения/выключения насосов и клапанов по минутам. секунды из условий выбрось, закуске эта точность не нужна, а программе лишняя путаница. 

2. управление подкачкой (073 - 132) никак не должно мешать отключению второй секции полива (067).

 

SeLL19
Offline
Зарегистрирован: 04.08.2021

Подправил, так ?

watch.gettime();// получение текущего времени
  if (watch.Hours == Thour) {
    if (watch.minutes == Tmin) { //Сравнение текущего времени с заданным временем полива 1-й секции
  }
    digitalWrite(Rp7, LOW);
    digitalWrite(Rp2, LOW);
    }
    if (watch.minutes == Tmin+20){ //Таймаут полива 1-й секции
    digitalWrite(Rp7, HIGH);
    digitalWrite(Rp2, HIGH);
    }
    if (watch.minutes == Tmin1){ //Сравнение текущего времени с заданным временем полива 2-й секции и капельного орошения
    digitalWrite(Rp7, LOW);
    digitalWrite(Rp3, LOW);
    digitalWrite(Rp4, LOW);
    }
    if (watch.minutes == Tmin1+20){ //Таймаут полива 2-й секции и капельного орошения
    digitalWrite(Rp7, HIGH);
    digitalWrite(Rp3, HIGH);
    digitalWrite(Rp4, HIGH);
    }
    }

А есть идеи, почему не срабатывает отключение?

С подкачкой вроде проблем  нет, вот только с работой по часам

 

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

Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца. 

SeLL19
Offline
Зарегистрирован: 04.08.2021

DetSimen пишет:

Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца. 

Это уже мне не понятно, к сожалению...

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

SeLL19 пишет:

DetSimen пишет:

Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца. 

Это уже мне не понятно, к сожалению...

Это значит, например, в виде "количество секунд, прошедших с начала суток". Т.е.

time = hour * 3600 + min * 60 + sec;

Тогда не придется возиться с кучей условий - достаточно будет сравнивать одно число

nik182
Offline
Зарегистрирован: 04.05.2015

Прочитайте про unix time. В инклюде time.h есть подпрограммы для конвертации времени в число и обратно. Программу проще писать, когда время представлено одним числом, а не часы минуты секунды.

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

Да ему и без секунд можно, число минут в сутках 24*60 = 1440, влезет в 2 байта

Upper
Offline
Зарегистрирован: 23.06.2020

Дело может быть не в программе, а в наводках от срабатывающих клапанов.

Как часто зависает? - если всегда, то попробуйте без подключенных внешних устройств. Посмотрите поможет - или нет.

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

В общем-то там и без клапанов наводок хватит - сигнальные линии, поди, десятками метров измеряются. Да по улице

SeLL19
Offline
Зарегистрирован: 04.08.2021

Да, так и есть сигнальные линии метров по 30. Тоже посещали такие мысли. Если подтвердится, что с этим делать?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

v258 пишет:

SeLL19 пишет:

DetSimen пишет:

Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца. 

Это уже мне не понятно, к сожалению...

Это значит, например, в виде "количество секунд, прошедших с начала суток". Т.е.

time = hour * 3600 + min * 60 + sec;

Тогда не придется возиться с кучей условий - достаточно будет сравнивать одно число

Вот как раз в таком виде в uint16_t не поместится.

Зато никто не запрещает считать время в единицах по 1,318359375 секунды.

SLKH
Offline
Зарегистрирован: 17.08.2015

DetSimen пишет:

Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца. 

в варианте #2 чего путаться-то?

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

SLKH пишет:

DetSimen пишет:

Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца. 

в варианте #2 чего путаться-то?

ТС-у - во вложенных if.

SLKH
Offline
Зарегистрирован: 17.08.2015

SeLL19 пишет:
Да, так и есть сигнальные линии метров по 30. Тоже посещали такие мысли. Если подтвердится, что с этим делать?
3 сигнала от поплавков не связаны с поливом, так что их во вторую очередь отодвинуть. начинать с питания (см. №8)

и схему пора выложить.

SLKH
Offline
Зарегистрирован: 17.08.2015

DetSimen пишет:

SLKH пишет:

DetSimen пишет:

Время храни в packed формате, в uint16_t влезет, да и не будешь в условиях путаца. 

в варианте #2 чего путаться-то?

ТС-у - во вложенных if.

думаешь, в paked не запутается? 

я бы вообще ещё тупее, без лишних переменных, написал 

void loop()
{
	watch.gettime();// получение текущего времени
	if (watch.Hours == 20)
		{
			if (watch.minutes == 0)   //Сравнение текущего времени с заданным временем полива 1-й секции
				{
					digitalWrite(Rp7, LOW);
					digitalWrite(Rp2, LOW);
				}
			if (watch.minutes == 20)   //Таймаут полива 1-й секции
				{
					digitalWrite(Rp7, HIGH);
					digitalWrite(Rp2, HIGH);
				}
			if (watch.minutes == 21)   //Сравнение текущего времени с заданным временем полива 2-й секции и капельного орошения
				{
					digitalWrite(Rp7, LOW);
					digitalWrite(Rp3, LOW);
					digitalWrite(Rp4, LOW);
				}
			if (watch.minutes == 41)   //Таймаут полива 2-й секции и капельного орошения
				{
					digitalWrite(Rp7, HIGH);
					digitalWrite(Rp3, HIGH);
					digitalWrite(Rp4, HIGH);
				}
		}
}

 

 

SeLL19
Offline
Зарегистрирован: 04.08.2021

По скетчу в варианте #2 отсутствует проверка секунд. Я правильно понимаю, что всю минуту, по условию в if происходят повторные включения ( или выключения) пока минута не сменится?
В общем приехал домой, залил скетч в данном варианте и все сработало четко. Либо просто повезло и не глюкануло, либо за счёт того, что условие выполняется минуту, оно на какой то из повторных проверок сработало...

SeLL19
Offline
Зарегистрирован: 04.08.2021

Лишнюю скобку нашел, все ок)))
Оно не на скобку ругалось, а на переменную ниже, но быстро разобрался)))

SeLL19
Offline
Зарегистрирован: 04.08.2021

Переменные добавил, потому что там еще и эзернет есть, в будущем хотелось управление с веб морды

SLKH
Offline
Зарегистрирован: 17.08.2015

SeLL19 пишет:
По скетчу в варианте #2 отсутствует проверка секунд. Я правильно понимаю, что всю минуту, по условию в if происходят повторные включения ( или выключения) пока минута не сменится?
Нет там никаких повторных включений/выключений. Подача на пин такого же сигнала, как и ранее, не приводит к каким-либо изменениям состояния.

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

SeLL19
Offline
Зарегистрирован: 04.08.2021

SLKH пишет:

SeLL19 пишет:
По скетчу в варианте #2 отсутствует проверка секунд. Я правильно понимаю, что всю минуту, по условию в if происходят повторные включения ( или выключения) пока минута не сменится?
Нет там никаких повторных включений/выключений. Подача на пин такого же сигнала, как и ранее, не приводит к каким-либо изменениям состояния.

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


Включения или выключения я имел ввиду, в зависимости от выполняемого условия. То есть повторные подачи сигнала все таки идут всю минуту, правильно? Если так, то раньше была всего секунда для проверки условия и выполнения команды, а в эту секунду могло глюкануть систему из за наводок, а теперь есть целая минута, за которую, возможно не с первого раза, но система сработала. В таком случае остаётся только наблюдать.

SLKH
Offline
Зарегистрирован: 17.08.2015

SeLL19 пишет:
SLKH пишет:

SeLL19 пишет:
По скетчу в варианте #2 отсутствует проверка секунд. Я правильно понимаю, что всю минуту, по условию в if происходят повторные включения ( или выключения) пока минута не сменится?
Нет там никаких повторных включений/выключений. Подача на пин такого же сигнала, как и ранее, не приводит к каким-либо изменениям состояния.

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

Включения или выключения я имел ввиду, в зависимости от выполняемого условия. То есть повторные подачи сигнала все таки идут всю минуту, правильно?
Да.

 

Цитата:
Если так, то раньше была всего секунда для проверки условия и выполнения команды, а в эту секунду
в эту секунду условия проверялись и команды выполнялись/повторялись несколько десятков тысяч раз.

"не думай о секунде свысока"

SeLL19
Offline
Зарегистрирован: 04.08.2021

SLKH пишет:

SeLL19 пишет:
SLKH пишет:

SeLL19 пишет:
По скетчу в варианте #2 отсутствует проверка секунд. Я правильно понимаю, что всю минуту, по условию в if происходят повторные включения ( или выключения) пока минута не сменится?
Нет там никаких повторных включений/выключений. Подача на пин такого же сигнала, как и ранее, не приводит к каким-либо изменениям состояния.

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

Включения или выключения я имел ввиду, в зависимости от выполняемого условия. То есть повторные подачи сигнала все таки идут всю минуту, правильно?
Да.

 

Цитата:
Если так, то раньше была всего секунда для проверки условия и выполнения команды, а в эту секунду
в эту секунду условия проверялись и команды выполнялись/повторялись несколько десятков тысяч раз.

"не думай о секунде свысока"


Да понятно, что не один раз))
Но как то же она умудрялась пропустить команду

SeLL19
Offline
Зарегистрирован: 04.08.2021

Ну что ж. Второй день система срабатывает как задумано. Тьфу-тьфу.
Подозреваю, что удаление секунд помогло. Осталось самое простое- эзернет прикрутить)))) С ним я думаю намучаюсь побольше.
Всем большое спасибо за советы!

SLKH
Offline
Зарегистрирован: 17.08.2015

SeLL19 пишет:
Осталось
а защищать поливочный насос от работы всухую кто будет? или он это спокойно переносит?