// Пин, к которому подключен датчик минимального уровня питательного раствора #define LowLevel 7 // Пин, к которому подключен датчик максимального уровня питательного раствора #define MaxLevel 6 // Пин, к которому подключен датчик уровня заполнения верхнего резервуара #define FloodLevel 4 // Пин, к которому подключен светодиодный индикатор #define LedPin 13 // Пин, к которому подключена помпа #define PumpPin 12 // Пин, к которому подключен потенциометр регулировки #define potPin A0 // Переменные для хранения времени long previousMillis = 0; long BlinkPreviousMillis = 0; unsigned long interval; // два часа = 7200000, 15 минут = 900000 // Переменные-флаги для хранения состояния работы гидрогоршка bool blinkState = 0; bool waterStart = 0; bool pumpState = 0; // Переменные для хранения состояния датчиков уровня bool LowLevelState; bool MaxLevelState; bool FloodLevelState; // Переменная для хранения состояния мигающего светодиода bool ledState; void setup(){ // Притянем пины датчиков уровня к плюсу pinMode(LowLevel, INPUT_PULLUP); pinMode(MaxLevel, INPUT_PULLUP); pinMode(FloodLevel, INPUT_PULLUP); // Установим пины светодиода и помпы как выходы pinMode(LedPin, OUTPUT); pinMode(PumpPin, OUTPUT); // Проверим уровень раствора. Если уровень меньше минимального - зажигаем светодиодный индикатор. // Ждем срабатывания датчика максимального уровня, после этого гасим светодиод. if (digitalRead(LowLevel)){ while (!digitalRead(MaxLevel)){ digitalWrite(LedPin, 1); } } digitalWrite(LedPin, 0); // Сохраняем текущее время для подсчета интервалов затопления. previousMillis = millis(); // Устанавливаем флаг для начала работы помпы. pumpState = 1; } void loop(){ // Считываем значение потенциометра для установки следующего затопления. interval = map(analogRead(potPin), 0, 1023, 900000, 7200000); // Присваиваем переменным состояния датчиков уровня. // Некоторые датчики установлены "вверх ногами", поэтому значения с них нужно инвертировать. LowLevelState = !digitalRead(LowLevel); MaxLevelState = digitalRead(MaxLevel); FloodLevelState = digitalRead(FloodLevel); // Проверяем, настало ли время затапливать корневую систему растения. // Если настало - устанавливаем флаг затопления. if (millis() - previousMillis > interval){ waterStart = 1; } // Если необходимо затапливать корни, и уровень в резервуаре выше минимального - // включаем помпу и сбрасываем флаг затопления. if (waterStart && LowLevelState){ pumpState = 1; waterStart = 0; } // Проверяем, в каком состоянии находится флаг работы помпы. // В зависимости от этого включаем её или выключаем. if (pumpState){ digitalWrite(PumpPin, HIGH); } else{ digitalWrite(PumpPin, LOW); } // Если сработал датчик уровня затопления - выключаем помпу и обновляем переменную хранения времени. // Если вдруг раствора стало слишком мало и сработал датчик минимального уровня - выключаем помпу. if (!LowLevelState || FloodLevelState){ pumpState = 0; previousMillis = millis(); } // Если сработал датчик минимального уровня раствора - устанавливаем флаг мигания светодиода. if (!LowLevelState){ blinkState = 1; } // Если установлен флаг мигания светодиода - мигаем им ))) if (blinkState){ Alarm (); } // Если светодиод мигает, сигнализируя о нехватке уровня раствора, и в этот момент сработал // датчик максимального уровня - значит раствор долили и светодиод гаснет. if (blinkState && MaxLevelState){ blinkState = 0; digitalWrite(LedPin, 0); } } // Функция мигания светодиодом void Alarm (){ if (millis() - BlinkPreviousMillis > 300){ BlinkPreviousMillis = millis(); if (!ledState){ ledState = 1; } else{ ledState = 0; } digitalWrite(LedPin, ledState); } }