- Умный автополив растений на базе Arduino
- Компоненты и их описания
- Arduino Uno
- Датчик влажности почвы
- Фоторезистор
- Релейный модуль
- Водяной насос
- Макетная плата
- Перемычки
- Программный код
- Схема автополива растений на arduino
- Урок 30. Автоматический полив растений
- Нам понадобится:
- Видео:
- Схема подключения:
- Алгоритм работы:
- Код программы:
- Ссылки:
Умный автополив растений на базе Arduino
Растения играют важную роль в жизни человека. Мы получаем множество преимуществ, живя в соседстве с растениями – это свежий воздух, приятная атмосфера и конечно же полезное питание.
Многие люди пытаются окружить себя растениями как в квартире, так и на своих участках. И неважно будь это комнатные растения или посадки на дачном участке, растения требуют к себе внимания и ухода. Всё же иногда из-за напряжённого образа жизни мы элементарно забываем вовремя полить их. Это негативно сказывается на состоянии растений. Чтобы избавиться от этой проблемы, придуманы системы автополива.
Многие из готовых систем не подходят нам по конструктиву или по цене. Да и многим радиолюбителям интересней собрать своё устройство, чем покупать готовое.
В этой статье подробно расписано как сделать автополив для комнатных и уличных растений на базе Arduino своими руками.
Наш автополив на Ардуино поливает растение только днём, когда почва пересыхает. В системе используются датчик влажности почвы и фоторезистор.
Основная цель этой системы заключается в отслеживание времени суток и влажности. Если днём земля просыхает, микроконтроллер включает водяной насос. Когда земля достаточно увлажнится, насос выключается.
Компоненты и их описания
Arduino Uno
Arduino взаимодействует через датчики с окружающей средой и обрабатывает поступившую информацию в соответствии с заложенной в неё программой. Подробнее с платой Ардуино Уно можно ознакомиться здесь.
Датчик влажности почвы
Измерение влажности почвы на базе Arduino производится с помощью датчика влажности. Датчик имеет два контакта. Через эти контакты при погружении их в грунт протекает ток. Величина тока зависит от сопротивления грунта. Поскольку вода является хорошим проводником тока, наличие влаги в почве сильно влияет на показатель сопротивления. Это значит, чем больше влажность почвы, тем меньше она оказывает сопротивление току.
Этот датчик может выполнять свою работу в цифровом и аналоговом режимах. В нашем проекте используется датчик в цифровом режиме.
На модуле датчика есть потенциометр. С помощью этого потенциометра устанавливается пороговое значение. Также на модуле установлен компаратор. Компаратор сравнивает данные выхода датчика с пороговым значением и после этого даёт нам выходной сигнал через цифровой вывод. Когда значение датчика больше чем пороговое, цифровой выход передаёт 5 вольт (HIGH), земля сухая. В противном случае, когда данные датчика будут меньше чем пороговые, на цифровой вывод передаётся 0 вольт (LOW), земля влажная.
Этим потенциометром необходимо отрегулировать степень сухости почвы, когда как вы считаете нужно начать полив.
Фоторезистор
Фоторезистор (LDR) — это светочувствительное устройство, которое используются для определения интенсивности освещения. Значение сопротивления LDR зависит от освещённости. Чем больше света, тем меньше сопротивление. Совместно с резистором, фоторезистор образует делитель напряжения. Резистор в нашем случае взяли 10кОм.
Подключив выход делителя Uin к аналоговому входу Ардуино, мы сможем считывать напряжения на выходе делителя. Напряжение на выходе будет меняться в зависимости от сопротивления фоторезистора. Минимальное напряжение соответствует темноте, максимальное – максимальной освещённости.
В этом проекте полив начинается в соответствии с пороговым значением напряжения. В утренние часы, когда считается целесообразным начать полив, напряжение на выходе делителя равно 400. Примем это значение как пороговое. Так если напряжения на делителе меньше или равно 400, это означает, что сейчас ночь и насос должен быть выключен.
Меняя пороговое значение можно настроить период работы автополива.
Релейный модуль
Реле представляет собой переключатель с электромеханическим или электрическим приводом.
Привод реле приводится в действие небольшим напряжением, например, 5 вольт от микроконтроллера, при этом замыкается или размыкается цепь высокого напряжения.
В этом проекте используется 12 вольтовый водяной насос. Arduino Uno не может управлять напрямую насосом, поскольку максимальное напряжение на выводах Ардуино 5 вольт. Здесь нам приходит на помощь релейный модуль.
Релейный модуль имеет два типа контактов: нормально замкнутые и нормально разомкнутые контакты. Нормально замкнутые без управляющего напряжения замкнуты, при подаче напряжения размыкаются. Соответственно нормально разомкнутые без напряжения разомкнуты, при подаче управляющего напряжения замыкаются. В проекте используются нормально разомкнутые контакты.
Водяной насос
В проекте используем 12-и вольтовый погружной насос с 18-ваттным двигателем. Он может поднимать воду до 1,7 метра.
Этот насос можно эксплуатировать только тогда, когда он полностью погружен в воду. Это налагает некие обязательства по контролю уровня воды в ёмкости. Если водяной насос будет работать без воды, он просто-напросто сгорит.
Макетная плата
Макетная плата представляет собой соединительную плату, используемую для создания прототипов проектов электроники, без пайки.
Перемычки
В данном проекте перемычки используются для соединения компонентов оборудования.
Программный код
#define WATERPUMP 13 // насос подключен к контакту 13 #define SENSOR 8 // цифровой контакт датчика влажности подключен к контакту 8 #define LDR A0// фоторезистор подключен к A0 #define PORTNUMBER 9600 // открываем последовательный порт, устанавливаем скорость передачи данных 9600 бит void setup() < Serial.begin(PORTNUMBER); pinMode(WATERPUMP,OUTPUT); // Определяем вывод 13 как вывод pinMode(SENSOR,INPUT); // Определяем вывод 8 в качестве входного, чтобы получать данные от датчика влажности почвы. pinMode(LDR,INPUT); // Определяем А0 как ввод digitalWrite(WATERPUMP,LOW);// Насос выключен >void loop() < int val = digitalRead(SENSOR); // сохраняет значение, полученное от датчика влажности почвы, в переменной val int LDRValue=analogRead(LDR);// сохраняет значение, полученное от фоторезистора, в переменной LDRValue if(LDRValue//Если неравенство не выполняется, значит день, необходима проверить влажность if( val == HIGH)// Если влажность низкая < Serial.print("День, влажность низкая, необходим полив"); Serial.println(LDRValue);// Выводим значение фоторезистора Serial.println(val);// Выводим значение влажности digitalWrite(WATERPUMP,LOW); //Насос включен >else < Serial.print("День, влажность высокая, полива не требуется"); Serial.println(LDRValue);// Выводим значение фоторезистора digitalWrite(WATERPUMP,HIGH);//Насос выключен >delay(400); >
Схема автополива растений на arduino
Данный проект подразумевает полив одного растения или одной группы одинаковых растений. Но Uno имеет 6 аналоговых выходов, следовательно возможно подключить 6 насосов. Так же можем добавить к каждому насосу свой датчик влажности. Так мы получим 6-ти канальную систему автополива. Причем каждый канал будет работать в не зависимости друг от друга.
Источник
Урок 30. Автоматический полив растений
Система автоматического полива растений — незаменимый помощник, как для ухода за комнатными растениями, так и на огороде. Система включает мембранный насос для полива растений, если влажность почвы снизилась ниже определённого (порогового) значения. Пороговое значение влажности почвы и время на которое требуется включать насос, устанавливается при помощи кнопок.
Нам понадобится:
- Arduino х 1шт.
- Аналоговый датчик влажности почвы х 1шт.
- Мембранный насос х 1шт.
- Trema-модуль Силовой ключ х 1шт.
- Trema-модуль Четырехразрядный LED индикатор х 1шт.
- Trema-модуль Кнопка х 2шт.
- Trema Shield х 1шт.
- Коннектор Power Jack с клемником х 1шт.
Для реализации проекта нам необходимо установить библиотеку:
О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki — Установка библиотек в Arduino IDE .
Видео:
Схема подключения:
LED индикатор и кнопки, подключаются к любым выводам Arduino (как цифровым, так и аналоговым), номера указываются в скетче.
Датчик влажности почвы подключается к любому аналоговому входу, номер указывается в скетче.
Силовой ключ (для управления насосом) подключается к цифровому выводу с ШИМ, номер указывается в скетче.
В данном уроке, LED индикатор подключён к цифровым выводам 2 и 3, кнопки подключены к цифровым выводам 11 и 12, силовой ключ к цифровому выводу 10 (с ШИМ), датчик влажности почвы к аналоговому входу A0.
Алгоритм работы:
- При подаче питания, устройство не активно (на индикаторе мигает текущее значение влажности почвы).
- Если однократно нажать на обе кнопки «A» и «B», то текущее состояние влажности почвы будет сохранено как пороговое (то при котором требуется начать полив) и устройство перейдёт в рабочий режим. Пороговое значение влажности почвы можно изменить в режиме ввода значений.
- Если нажать и удерживать обе кнопки «A» и «B» дольше 2 секунд, то устройство перейдёт в режим ввода значений.
Код программы:
#include // подключаем библиотеку для работы с четырёхразрядным LED индикатором iarduino_4LED dispLED(2,3); // объявляем объект для работы с функциями библиотеки iarduino_4LED, с указанием выводов индикатора ( CLK , DIO ) const uint8_t pinSensor = A0; // объявляем константу с указанием номера аналогового входа, к которому подключен датчик влажности почвы const uint8_t pinButtonA = 12; // объявляем константу с указанием номера вывода, к которому подключена кнопка A const uint8_t pinButtonB = 11; // объявляем константу с указанием номера вывода, к которому подключена кнопка B const uint8_t pinPump = 10; /* вывод с ШИМ */ // объявляем константу с указанием номера вывода, к которому подключен силовой ключ uint8_t btnState; // объявляем переменную для хранения состояний кнопок: 0-не нажаты, 1-нажата A, 2-нажата B, 3-нажата A и B, 4-удерживается A, 5-удерживается B, 6-удерживались A и B uint16_t arrMoisture[10]; // объявляем массив для хранения 10 последних значений влажности почвы uint32_t valMoisture; // объявляем переменную для расчёта среднего значения влажности почвы uint32_t timWatering; // объявляем переменную для хранения времени начала последнего полива (в миллисекундах) uint32_t timSketch; // объявляем переменную для хранения времени прошедшего с момента старта скетча (в миллисекундах) const uint8_t timWaiting = 60; // объявляем константу для хранения времени ожидания после полива (в секундах) от 0 до 99 const uint8_t pwmPump = 100; // объявляем константу для хранения скорости вращения мотора насоса (коэффициент) от 0 до 255 uint16_t timDuration = 5; /* по умолчанию */ // объявляем переменную для хранения длительности полива (в секундах) от 0 до 99 uint16_t limMoisture = 0; /* по умолчанию */ // объявляем переменную для хранения пороговой влажности почвы (для вкл насоса) от 0 до 999 uint8_t modState = 0; /* при старте */ // объявляем переменную для хранения состояния устройства: 0-не активно, 1-ожидание, 2-активно, 3-полив, 4-установка пороговой влажности, 5-установка времени полива void setup() < dispLED.begin(); // инициируем LED индикатор pinMode(pinButtonA, INPUT); // переводим вывод pinButtonA в режим входа pinMode(pinButtonB, INPUT); // переводим вывод pinButtonB в режим входа pinMode(pinPump, OUTPUT); // переводим вывод pinPump в режим выхода digitalWrite(pinPump, LOW); // выключаем насос timWatering = 0; // сбрасываем время начала последнего полива >void loop()< //*******Чтение данных:******* btnState = Func_buttons_control(); // читаем состояние кнопок, но не дольше 2 секунд timSketch = millis(); // читаем текущее время с момента старта скетча if(timWatering>timSketch) // обнуляем время начала последнего полива, если произошло переполнение millis() valMoisture = 0; for(int i=0; i arrMoisture[9]=analogRead(pinSensor); for(int i=0; i valMoisture/=10; // вычисляем среднее значение влажности почвы //*******Управление устройством:******* switch(modState) < // Устройство не активно case 0: if(btnState)< // если зафиксировано нажатие или удержание кнопок if(btnState==6)if(btnState==3) > if(timSketch%100==0)< // если начинается десятая доля секунды if(timSketch/1000%2)else
> break; // Устройство в режиме ожидания (после полива) case 1: if(btnState) < // если зафиксировано нажатие или удержание кнопок if(btnState==6)if(btnState==1) if(btnState==2) if(btnState==3) > if(timSketch%100==0) < // если начинается десятая доля секунды dispLED.print("stop"); dispLED.point((timSketch/100%4)+1,true); >if(timDuration+timWaiting-((timSketch-timWatering)/1000) <=0)/>break; // Устройство активно case 2: if(btnState) < // если зафиксировано нажатие или удержание кнопок if(btnState==6)> if(timSketch%100==0)< // если начинается десятая доля секунды if(timSketch/1000%15else if(timSketch/1000%15<10) else else> > if(valMoisture <=limMoisture)< // если текущая влажность почвы меньше пороговой timWatering=timSketch; modState=3; dispLED.light(7); analogWrite(pinPump,pwmPump); >break; // Устройство в режиме полива case 3: if(btnState)< // если зафиксировано нажатие или удержание кнопок if(btnState==6)else analogWrite(pinPump,0); > if(timSketch%100==0) < // если начинается десятая доля секунды dispLED.print(timDuration-((timSketch-timWatering)/1000)); dispLED.point(0,true); dispLED.point((timSketch/100%4)+1,true); >if(timDuration-((timSketch-timWatering)/1000) <=0)/>break; // Устройство в режиме установки пороговой влажности почвы case 4: if(btnState) < // если зафиксировано нажатие или удержание кнопок if(btnState==6)if(btnState==1) 0 )> if(btnState==2) > if(btnState==3) if(btnState==4) 0 ) delay(100); dispLED.print(limMoisture);>> if(btnState==5) delay(100); dispLED.print(limMoisture);>> > if(timSketch%100==0) < // если начинается десятая доля секунды dispLED.print(limMoisture); >break; // Устройство в режиме установки длительность полива case 5: if(btnState) < // если зафиксировано нажатие или удержание кнопок if(btnState==6)if(btnState==1) 0 )> if(btnState==2) > if(btnState==4) 0 ) delay(100); dispLED.print(timDuration);>> if(btnState==5) delay(100); dispLED.print(timDuration);>> > if(timSketch%100==0) < // если начинается десятая доля секунды dispLED.print(timDuration); dispLED.point(0,true); >break; > > // Функция определения состояния кнопок uint8_t Func_buttons_control()< uint8_t a=0, b=0; // время удержания кнопок A и B (в десятых долях секунды) while(digitalRead(pinButtonA)||digitalRead(pinButtonB))< // если нажата кнопка A и/или кнопка B, то создаём цикл, пока они нажаты if(digitalRead(pinButtonA)) > // если удерживается кнопка A, то увеличиваем время её удержания if(digitalRead(pinButtonB)) > // если удерживается кнопка B, то увеличиваем время её удержания if(a>20 && b>20) // если обе кнопки удерживаются дольше 2 секунд, выводим на экран прочерки, указывая что их пора отпустить if(a>20 && b==0) // если кнопка A удерживается дольше 2 секунд, возвращаем 4 if(a==0 && b>20) // если кнопка B удерживается дольше 2 секунд, возвращаем 3 delay(100); // задержка на 0,1 секунды, для подавления дребезга > if(a>20 && b>20) // если обе кнопки удерживались дольше 2 секунд, возвращаем 6 if(a> 0 && b> 0)else // если обе кнопки удерживалась меньше 2 секунд, возвращаем 5 if(a> 0 && b==0)else // если кнопка A удерживалась меньше 2 секунд, возвращаем 2 if(a==0 && b> 0)else // если кнопка B удерживалась меньше 2 секунд, возвращаем 1 // если ни одна из кнопок не была нажата, возвращаем 0 > Ссылки:
Источник