- Урок 30. Автоматический полив растений
- Нам понадобится:
- Видео:
- Схема подключения:
- Алгоритм работы:
- Код программы:
- Ссылки:
- Автополивщик растений на Arduino
- Что для этого необходимо?
- Как это собрать?
- Калибровка
- Масштабирование решения
- Исходный код
- Демонстрация работы устройства
- Что ещё можно сделать?
- Инструменты страницы
Урок 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 > Ссылки:
Источник
Автополивщик растений на Arduino
В этой статье мы расскажем о том, как собрать устройство для автоматического полива с контролем влажности почвы — ирригатор. Необходимость полива будем определять по показаниям датчика влажности почвы. Одновременно можно будет поливать несколько растений.
Что для этого необходимо?
Мы собрали все необходимые детали в сет компонентов. В набор входят:
Так же удобно для индикации использовать:
Как это собрать?
Установите Troyka Shield на Arduino Uno
Подключите датчик влажности почвы через Troyka Shield к аналоговому пину A0
Пины SPI дисплея к разъёму SPI на Troyka Shiled
Подключите силовой ключ к контакту 4
Подведите коммутирующее напряжение к силовому ключу в разъём P+ и P−
Подключите помпу к силовому ключу через клеммник с разъёмами L+ и L− .
В итоге должна получится схема.
Другой конец шланга вставьте с водой в землю. Если горшок с землёй весит менее 2 кг, рекомендуется отдельно закрепить трубку, чтобы она не перевернула растение.
Опустите помпу в ёмкость с водой.
Калибровка
Показания датчика влажности сильно зависят от кислотности почвы. Поэтому перед началом пользования ирригатором требуется провести простую процедуру калибровки.
Полейте цветок и дождитесь пока вода полностью впитается в землю и показания сенсора установятся на одном уровне. Запишите их. Это — максимум влажности.
В скетче исправьте значения константы HUMIDY_MIN на значение минимальной влажности и HUMIDY_MAX на значение максимальной влажности. Заново прошейте Arduino Uno.
Масштабирование решения
Мы описали решение для одного растения. Но обычно требуется поливать несколько растений. Помимо очевидного решения — подключения к Arduino нескольких помп и датчиков влажности — существует более простое и дешёвое. Достаточно в трубке, которая идёт в комплекте с помпой проделать шилом дырочки на расстоянии около 30 см и воткнуть в эти дырочки куски стержней от обычных шариковых ручек. Выглядеть это будет так:
Горшки с цветами дома часто стоят в ряд на подоконнике. Вам достаточно просто положить трубку на горшки так, чтобы отверстия в ней приходились по одному на горшок. Теперь наше устройство может поливать сразу несколько горшков. Однако в таком случае принимать решение о необходимости полива можно только по одному горшку. Однако обычно горшки примерно одинаковые по размерам и, соответственно, сохнут с примерно равной скоростью. Можно так же комбинировать два решения, разделяя все горшки на группы примерно равных по размерам.
Исходный код
Для работы скетча вам понадобиться скачать и установить библиотеку для работы с дисплеем QuadDisplay2
// Подключаем библиотеку для работы с дисплеем #include "QuadDisplay2.h" // даём разумное для пина, к которому подключена помпа #define POMP_PIN 4 // даём разумное для пина, к которому подключён датчик влажности почвы #define HUMIDITY_PIN A0 // минимальный порог влажности почвы #define HUMIDITY_MIN 200 // максимальный порог влажности почвы #define HUMIDITY_MAX 700 // интервал между проверкой на полив растения #define INTERVAL 60000 * 3 // переменная для хранения показания влажности почвы unsigned int humidity = 0; // статическая переменная для хранения времени unsigned long waitTime = 0; // создаём объект класса QuadDisplay и передаём номер пина CS QuadDisplay qd(9); void setup(void) { // начало работы с дисплеем qd.begin(); // пин помпы в режим выхода pinMode(POMP_PIN, OUTPUT); // выводим 0 на дисплей qd.displayInt(0); } void loop(void) { // считываем текущее показания датчика влажности почвы int humidityNow = analogRead(HUMIDITY_PIN); // если показания текущей влажности почвы // не равняется предыдущему запросу if(humidityNow != humidity) { // сохраняем текущие показания влажности humidity= humidityNow; // и выводим показания влажности на дисплей qd.displayInt(humidityNow); } // если прошёл заданный интервал времени // и значения датчика влажности меньше допустимой границы if ((waitTime == 0 || millis() - waitTime > INTERVAL) && humidity HUMIDITY_MIN ) { // включаем помпу digitalWrite(POMP_PIN, HIGH); // ждём 2 секунды delay(2000); // выключаем помпу digitalWrite(POMP_PIN, LOW); // приравниваем переменной waitTime // значение текущего времени плюс 3 минуты waitTime = millis(); } }
Демонстрация работы устройства
Что ещё можно сделать?
Несмотря на золочение, контакты сенсора влажности со временем корродируют. Быстрее всего корродирование происходит при подключённом питании. Срок жизни сенсора можно значительно увеличить, если подключить питание к нему через силовой ключ. Когда надо получить данные — включаем питание сенсора, снимаем показания и тут же выключаем питание.
Если оставить наш ирригатор работающим на длительный срок без присмотра, вода в резервуаре может закончиться. При работе без воды помпа быстро выходит из строя. Решением проблемы может быть автоматическое определение опустошения резервуара. Сенсор подбирается исходя из типа резервуара. Если он не глубок, то подойдёт ещё один датчик влажности. Когда же высоты его не хватает, можно воспользоваться УЗ-дальномером, сделать поплавок с датчиком наклона или просто опустить на дно два провода.
Устройство, работающее от батареек, будет значительно безопасней питающегося от сети. Идеальным вариантом было бы питание ирригатора от батареек. Но Arduino Uno, как известно, даже в режиме сна потребляет более 10 мА. Выходом может являться использование Arduino Mini, способный в режиме сна снижать потребляемый ток до сотен мкА.
Существует много правил полива домашних растений, как, например: не стоит поливать зимой вечером. Можно добавить сенсоров света или часы реального времени и скорректировать программу так, чтобы она старалась поливать в нужное время.
А ещё можно собрать автополив на Slot Shield — инструкция по сборке и прошивка.
Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC Attribution-Noncommercial-Share Alike 4.0 International
Производные работы должны содержать ссылку на http://wiki.amperka.ru, как на первоисточник, непосредственно перед содержимым работы.
Вики работает на суперском движке DokuWiki.Инструменты страницы
Источник