Хелпикс

Главная

Контакты

Случайная статья





Студент А.И. Панасенков. Устройство автоматического полива растений  на базе микроконтроллерной платы «Ардуино».. Принцип работы



 Студент А.И. Панасенков

(ФГБОУ ВО СПбГАУ)
Канд. техн. наук Ю.В. Иванов

(ФГБОУ ВО СПбГАУ)

 

Устройство автоматического полива растений  на базе микроконтроллерной платы «Ардуино».

Автоматический полив – это комплекс мероприятий, связанных с насыщением почвы влагой по заранее запрограммированному графику.  Полив (орошение) - подвод воды на поля, испытывающие недостаток влаги, и увеличение её запасов в корнеобитаемом слое почвы в целях увеличения плодородия почвы.

В состав автоматического устройства входит :

  • . Arduino х 1шт.
  • Аналоговый датчик влажности почвы х 1шт.
  • Мембранный насос х 1шт.
  • Trema-модуль Силовой ключ х 1шт.
  • Trema-модуль Четырехразрядный LED индикатор х 1шт.
  • Trema-модуль Кнопка х 2шт.
  • Trema Shield х 1шт.
  • Коннектор Power Jack с клемником х 1шт.

Схема подключения

Принцип работы

При подаче питания, устройство не активно (на индикаторе мигает текущее значение влажности почвы).

В рабочем режиме устройство выводит на индикатор показания: текущей влажности почвы, пороговой влажности почвы и времени прошедшего с момента последнего полива. (Пороговая влажность почвы отображается тусклее чем остальные показания). Если устройство находится в рабочем режиме и значение текущей влажности почвы упадёт ниже значения пороговой влажности почвы, то устройство перейдёт в режим пол

В режиме полива устройство выводит на индикатор количество секунд до окончания полива и мигает точками, а также подаёт сигнал ШИМ на силовой ключ, который включает насос. Значение ШИМ (скорость мотора насоса) указывается в скетче. Длительность полива устанавливается в режиме ввода значений. По окончании полива, устройство переходит в режим ожидания.

В режиме ожидания устройство выводит на индикатор надпись STOP и мигает точками. Данный режим предусмотрен для того, что бы влага равномерно распределилась по грунту до перехода устройства в рабочий режим. Время нахождения в режиме ожидания указывается в скетче. По истечении времени режима ожидания, устройство перейдёт в рабочий режим.

 

Программа:

#include <iarduino_4LED.h>                             // подключаем библиотеку для работы с четырёхразрядным 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){timWatering=0;}            // обнуляем время начала последнего полива, если произошло переполнение millis()

valMoisture = 0; for(int i=0; i<9; i++){arrMoisture[i]=arrMoisture[i+1];} arrMoisture[9]=analogRead(pinSensor); for(int i=0; i<10; i++){valMoisture+=arrMoisture[i];} valMoisture/=10; // вычисляем среднее значение влажности почвы

//*******Управление устройством:*******

switch(modState){

// Устройство не активно

case 0: if(btnState){                              // если зафиксировано нажатие или удержание кнопок

         if(btnState==6){modState=4;}

         if(btnState==3){modState=2; limMoisture=valMoisture;}

       }

       if(timSketch%100==0){                      // если начинается десятая доля секунды

         if(timSketch/1000%2){dispLED.print(valMoisture);}else{dispLED.print(" ");}

       }

break;

// Устройство в режиме ожидания (после полива)

case 1: if(btnState){                              // если зафиксировано нажатие или удержание кнопок

         if(btnState==6){modState=4;}

         if(btnState==1){modState=2;}

         if(btnState==2){modState=2;}

         if(btnState==3){modState=2;}

       }

       if(timSketch%100==0){                      // если начинается десятая доля секунды

         dispLED.print("stop");

         dispLED.point((timSketch/100%4)+1,true);

       }

       if(timDuration+timWaiting-((timSketch-timWatering)/1000)<=0){// если закончилось время ожидания

         modState=2;

       }

break;

// Устройство активно

case 2: if(btnState){                              // если зафиксировано нажатие или удержание кнопок

         if(btnState==6){modState=4; dispLED.light(7);}

       }

       if(timSketch%100==0){                      // если начинается десятая доля секунды

         if(timSketch/1000%15<5 ){dispLED.light(7); dispLED.print(valMoisture);}else

         if(timSketch/1000%15<10){dispLED.light(1); dispLED.print(limMoisture,LEN4);}else

                                 {dispLED.light(7); if(timWatering){dispLED.print(int((timSketch-timWatering)/1000%3600/60),int((timSketch-timWatering)/1000%3600%60),TIME);}else{dispLED.print("----");}}

       }

       if(valMoisture<=limMoisture){               // если текущая влажность почвы меньше пороговой

         timWatering=timSketch; modState=3; dispLED.light(7); analogWrite(pinPump,pwmPump);

       }

break;

// Устройство в режиме полива

case 3: if(btnState){                              // если зафиксировано нажатие или удержание кнопок

         if(btnState==6){modState=4;}else{modState=1;} 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){// если закончилось время полива

         modState=1; analogWrite(pinPump,0);

       }

break;

// Устройство в режиме установки пороговой влажности почвы

case 4: if(btnState){                              // если зафиксировано нажатие или удержание кнопок

         if(btnState==6){modState=5;}

         if(btnState==1){if(limMoisture>0 ){limMoisture--;}}

         if(btnState==2){if(limMoisture<999){limMoisture++;}}

                     if(btnState==4){while(digitalRead(pinButtonA)){if(limMoisture>0 ){limMoisture--;} delay(100); dispLED.print(limMoisture);}}

         if(btnState==5){while(digitalRead(pinButtonB)){if(limMoisture<999){limMoisture++;} delay(100); dispLED.print(limMoisture);}}

       }

       if(timSketch%100==0){                      // если начинается десятая доля секунды

         dispLED.print(limMoisture);

       }

break;

// Устройство в режиме установки длительность полива

case 5: if(btnState){                              // если зафиксировано нажатие или удержание кнопок

         if(btnState==6){modState=2;}

         if(btnState==1){if(timDuration>0 ){timDuration--;}}

         if(btnState==2){if(timDuration<99){timDuration++;}}

         if(btnState==4){while(digitalRead(pinButtonA)){if(timDuration>0 ){timDuration--;} delay(100); dispLED.print(timDuration);}}

         if(btnState==5){while(digitalRead(pinButtonB)){if(timDuration<99){timDuration++;} 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)){if(a<200){a++;}}      // если удерживается кнопка A, то увеличиваем время её удержания

if(digitalRead(pinButtonB)){if(b<200){b++;}}      // если удерживается кнопка B, то увеличиваем время её удержания

if(a>20 && b>20){dispLED.print("----");}          // если обе кнопки удерживаются дольше 2 секунд, выводим на экран прочерки, указывая что их пора отпустить

if(a>20 && b==0){return 4;}                       // если кнопка A удерживается дольше 2 секунд, возвращаем 4

if(a==0 && b>20){return 5;}                       // если кнопка B удерживается дольше 2 секунд, возвращаем 3

delay(100);                                       // задержка на 0,1 секунды, для подавления дребезга

} if(a>20 && b>20){return 6;}                       // если обе кнопки удерживались дольше 2 секунд, возвращаем 6

if(a> 0 && b> 0){return 3;}else                   // если обе кнопки удерживалась меньше 2 секунд, возвращаем 5

if(a> 0 && b==0){return 1;}else                   // если кнопка A удерживалась меньше 2 секунд, возвращаем 2

if(a==0 && b> 0){return 2;}else                   // если кнопка B удерживалась меньше 2 секунд, возвращаем 1

                {return 0;}                       // если ни одна из кнопок не была нажата,   возвращаем 0

 

Литература:

1. Интернет источник https://lesson.iarduino.ru/page/urok-30-avtomaticheskiy-poliv-rasteniy/

2. Интернет источник http://www.poliv77.ru/articles/26-avtomaticheskiy-poliv.html#:~:text

3. Интернет источник https://iarduino.ru/shop/Expansion-payments/knopka-trema-modul.html

 



  

© helpiks.su При использовании или копировании материалов прямая ссылка на сайт обязательна.