Stacja kontroli warunków wegetacji roślin


Tomasz Bartuś



2017-09-02
Stacja kontroli warunków wegetacji roślin

Wstęp

Podczas wakacyjnej nieobecności, nasze domowe rośliny, z powodu braku regularnego podlewania i odpowiedniego oświetlenia, narażone są często na uschnięcie. Prezentowany układ (Fig. 1) umożliwia kontrolę podstawowych parametrów wegetacji roślin, t.j. wilgotności gleby i stopnia nasłonecznienia. W zależności od wartości tych parametrów układ umożliwia podjęcie automatycznych akcji nawadniania i/lub doświetlania rośliny. Projekt wykorzystuje tanie i łatwo dostępne komponenty elektroniczne: płytkę prototypową Arduino oraz czujniki, silnik pompy wody i inne.

Układ kontroli warunków wegetacji roślin
Fig. 1. Układ kontroli warunków wegetacji roślin

Lista części

  1. Arduino (Leonardo),
  2. czujnik wilgotności gleby FC-28,
  3. fotorezystor 5-10kΩ,
  4. silnik pompy wody RS-360SH,
  5. 2-kanałowy moduł przekaźnika,
  6. wyświetlacz Nokia 5110,
  7. rezystory 10kΩ (5 szt.),
  8. rezystor 1,5kΩ (1 szt.),
  9. płytka prototypowa,
  10. przewody.

Zasada działania

Projekt wykorzystuje dwa rodzaje czujników: wilgotności oraz nasłonecznienia. Do pomiaru wilgotności gleby wykorzystuje się tzw. higrometry. Są to czujniki rezystancyjne. Tanie sensory dostępne w handlu składają się z dwóch części: małej płytki z elektroniką oraz czujnika złożonego z dwóch elektrod, służącego do kontroli zawartości wody w glebie (Fig. 2). Czujnik posiada potencjometr slużący do regulacji czułości wyjścia cyfrowego oraz diodę LED zasilania oraz diodę LED wyjścia cyfrowego. Układ posiada piny: VCC, GND, oraz dwa sygnały wyjściowe: cyfrowe (D0) oraz analogowe (A0). W handlu znajduje się wiele podobnych czujników np. typu YL-69, HL-69 czy FC-28.

Czujnik wilgotności gleby FC-28
Fig. 2. Czujnik wilgotności gleby FC-28

Czujnik umożliwia skorzystanie z dwóch rodzajów sygnałów wyjściowych: cyfrowego (stan niski bądź wysoki) oraz analogowego. Napięcie na wyjściu analogowym czujnika wilgtności zmienia się płynnie w zależności od zawartości wilgoci w glebie. Kiedy gleba jest wilgotna, napięcie wyjściowe jest niskie. Gdy gleba jest sucha, napięcie wyjściowe jest wysokie (Tab. 1). Przetwornik analogowo-cyfrowy układu arduino zmienia to napięcie na odpowiadające mu wartości sygnałów wyrażone w skali od 0-1023. Wartość cyfrowego sygnału wyjściowego uzależniona jest od predefiniowanej wartości progowej. Poniżej niej wartość sygnalu cyfrowego będzie niska (0), a powyżej - wysoka (1). Wartość progową reguluje się za pomocą potencjometra.

Tab. 1. Charakterystyka parametrów użytkowych czujnika wilgotności gleby FC-28
Gleba Napięcie na wy analogowym Wartość na wy przetwornika AC Arduino
sucha wysokie (np. 4,2V) 1023
wilgotna niskie (0V) 0

Jako czujnik oświetlenia wykorzystano fotorezystor. Wykonano dzielnik napięcia, który podłączono do pinu analogowego mierzącego napięcie wyjściowe. Wartość rezystora dobrano eksperymentalnie (około 1,5kΩ).

Elementem odpowiedzialnym za nawadnianie roślin jest silnik (pompa) RS-360SH (Fig. 3). Wymaga ona zasilania 3-12V (do ciągłej pracy rekomendowane jest napięcie 5V 2A). Nie powinno się go podłączać na dłuższy czas do napięcia większego niż 7,5V.

Pompa RS-360SH
Fig. 3. Pompa RS-360SH

Działanie

Układ stale dokonuje pomiarów wilgotności gleby i usłonecznienia. Pomierzone wartości z czujników przekazywane są na wejścia analogowe Arduino (kolejno: A0 i A5). Po przeworzeniu, parametry w postaci procentowej są wyświetlane na wyświetlaczu ciekłokrystalicznym Nokia 5110. Pomiary dokonywane są z częstotliwością wyznaczaną za pomocą zmienej MeasurementBreak. W zależności od ustawienia zmiennej NumberOfMeasurements, układ dokonuje zliczeń n pomiarów. Wartości analogowe są sumowane, a następnie obliczana jest z nich średnia arytmetyczna. Wartość uśredniona decyduje o uruchomieniu urządzenia nawadniającego i lampy doświetlającej roślinę. Wartości progowe wilgotności gleby oraz usłonecznienia dobrano eksperymentalnie. W przypadku wilgotności, włączenie przekaźnika następuje wtedy gdy średni pomiar parametru staje się mniejszy bądź równy 850. Spadek wilgotności gleby poniżej wartości krytycznej powoduje załączenie przekaźnika pompy, co uruchamia silnik. Woda zaczyna być pompowana ze zbiornika źródłowego do doniczki. Silnik popmpuje wodę przez okres 3 sek. Po tym czasie pompa zostaje wyłączona i następuje okres 10-sekundowej przerwy, potrzebnej na wsiąknięcie wody i rozprowadzenie jej w przestrzeniach porowych gruntu. Po tym okresie układ przechodzi do trybu wykonania kolejnej serii pomiarów i sytuacja zaczyna się powtarzać. Bezpośrednio po dokonaniu pomiaru wilgotności, układ dokonuje pomiaru usłonecznienia. Aby zapobiec sytuacji ciągłego włączenia oświetlenia w godzinach nocnych, zdarzenie załączenia lampy uzależniono od zaistnienia warunków niepełnego oświetlenia. Jeżeli przeciętny pomiar oświetlenia obliczony jako średnia arytmetyczna z n pomiarów, wskaże wartość z przedziału (700, 850>, mikrokontroler zaświeci lampę. Będzie ona zapalona do momentu kolejnego pomiaru. W praktyce, kolejny pomiar dokonywany jest w warunkach doświetlenia i kolejna uśredniona wartość pomiarów wyłączy lampę. Jeśli w kolejnym okresie czasu warunki pomiarowe światła nie pogorszą się (np. z powodu nocy), światło zostanie ponownie zapalone. Sytuacja zacznie się od tego momentu powtarzać. Wartości chwilowe czujników oraz wartości uśrednione, wysyłane są na port szeregowy.

Schemat ideowy

Schemat układu automatycznego nawadniania roślin
Fig. 4. Schemat układu automatycznego nawadniania roślin

Film



Kod

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

#define MeasurementBreak 1000               // time interval between measurements 5min - 300.000ms
#define NumberOfMeasurements 20             // number of measurements to averaging

// Adafruit_PCD8544 display = Adafruit_PCD8544(SCLK, DIN, D/C, CS, RST);
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);

int relay_pump = 8;                         // pin of the pump relay
int relay_light = 10;                       // pin of the light relay

int moistureValue = 0;                      // initial values of the measurements of the percent of the moisture
int moisturePercent = 0;
String percentMoistureString = "0";
int stringMoistureLength = 0;

int lightValue = 0;                         // initial values of the measurements of the percent of the light
int lightPercent = 0;
String percentLightString = "0";
int stringLightLength = 0;

int sum_of_moisture = 0;                    // initial value of the sum of the moisture measurements
int sum_of_light = 0;                       // initial value of the sum of the light measurements
int mesurement = 0;                         // initial value of the measurement item
unsigned long LastTime = 0;

int convertMoistureToPercent(int value) {   // function to convert moisture analog values to percent values
  int percentMoistureValue = 0;
  percentMoistureValue = map(value, 1023, 410, 0, 100);
  if (percentMoistureValue > 100)
    percentMoistureValue = 100;
  return percentMoistureValue;
}

int convertLightToPercent(int value) {     // function to convert light analog values to percent values
  int percentLightValue = 0;
  percentLightValue = map(value, 970, 160, 0, 100);
  if (percentLightValue > 100)
    percentLightValue = 100;
  return percentLightValue;
}

void displayMoisturePercent(int length) {  // function to display percent moisture values in Nokia LCD display
  switch (length) {
    case 1:  display.setCursor(58, 5); display.print(percentMoistureString); break;
    case 2:  display.setCursor(45, 5); display.print(percentMoistureString); break;
    case 3:  display.setCursor(34, 5); display.print(percentMoistureString); break;
    default:  display.setCursor(34, 5); display.print(percentMoistureString); break;
  }
}

void displayLightPercent(int length) {     // function to display percent light values in Nokia LCD display
  switch (length) {
    case 1:  display.setCursor(58, 29); display.print(percentLightString); break;
    case 2:  display.setCursor(45, 29); display.print(percentLightString); break;
    case 3:  display.setCursor(34, 29); display.print(percentLightString); break;
    default:  display.setCursor(34, 29); display.print(percentLightString); break;
  }
}
void setup() {
  pinMode(relay_pump, OUTPUT);                              // set the relay_pump pin as an OUTPUT
  pinMode(relay_light, OUTPUT);                             // set the relay_light pin as an OUTPUT
  digitalWrite(relay_pump, HIGH);                           // initialy turn OFF pump relay
  digitalWrite(relay_light, HIGH);                          // initialy turn OFF light relay

  display.begin();                                          // start of the Nokia LCD display
  display.setContrast(40);                                  // Nokia LCD display contrast settings
  Serial.begin(9600);                                       // start of the serial port
}
void loop() {
  unsigned long CurrentTime = millis();                     // time from start of the sketch

  if (CurrentTime - LastTime > MeasurementBreak) {          // if the time of the mesurements is longer than MeasurementBreak value:
    LastTime = CurrentTime;
    mesurement += 1;                                        // add the current mesurement to the total measurement no 
    sum_of_moisture += analogRead(A0);                      // add the current moisture value to the sum of the moisture measurements
    sum_of_light += analogRead(A5);                         // add the current light value to the sum of the light measurements

    if (mesurement >= NumberOfMeasurements) {
      int mean_moisture = ceil(sum_of_moisture / mesurement);
      int mean_light = ceil(sum_of_light / mesurement);

      Serial.print("Mean of moisture: ");                   // send to serial port the string "Mean of moisture: "
      Serial.print(mean_moisture);                          // send to serial port the mean_moisture value
      Serial.print(" Mean of light: ");                     // send to serial port the string "Mean of light: "
      Serial.println(mean_light);                           // send to serial port the mean_light value

      if (mean_moisture <= 800) {                           // if the soil is wet:
        digitalWrite(relay_pump, HIGH);                     // turn OFF of the pump
      } else {                                              // if the soil is dry:
        digitalWrite(relay_pump, LOW);                      // turn ON of the pump 
        delay(3000);                                        // watering 3 sek.
        digitalWrite(relay_pump, HIGH);
        delay(10000);                                       // wait 10 sec. until a water soaks
      }
      if ((mean_light > 700) && (mean_light <= 850)) {      // if there is too little light (but there is not yet night)-
        digitalWrite(relay_light, LOW);                     // turn OFF of the light 
      } else {                                              // if there is too much light -
        digitalWrite(relay_light, HIGH);                    // turn ON of the light 
      }

      mesurement = sum_of_moisture = sum_of_light = 0;      // reset the variables values calculated in the loops
    }

    display.clearDisplay();                                 // clear of the display
    display.setTextSize(1);                                 // font size settings to 1
    display.setTextColor(BLACK);                            // display font color settings
    display.setCursor(3, 14);                               // set cursor in column no 3 and row no 14 position
    display.print("Wilg.");                                 // write "Wilg" (moisture symbol)
    display.setTextSize(2);                                 // font size settings to 2

    moistureValue = analogRead(0);                          // read the moisture value from the analog pin A0
    moisturePercent = convertMoistureToPercent(moistureValue);
    percentMoistureString = String(moisturePercent);
    stringMoistureLength = percentMoistureString.length();
    displayMoisturePercent(stringMoistureLength);

    display.setCursor(70, 5);                               // set cursor at the end of the moisture mesurement frame
    display.print("%");                                     // write "%"
    display.drawRect(32, 2, 51, 19, BLACK);                 // draw a rectangle from (x1,y1) to (x2,y2)
    display.drawLine(2, 24, 81, 24, BLACK);                 // draw a line from (x1,x2) to (y1,y2)

    display.setTextSize(1);                                 // font size settings to 1
    display.setCursor(3, 37);                               // set cursor in column no 3 and row no 37 position
    display.print("Nasl.");                                 // write "Nasl" (light symbol)
    display.setCursor(34, 29);                              // set cursor in column no 34 and row no 29 position
    display.setTextSize(2);                                 // font size settings to 2

    lightValue = analogRead(5);                             // read the light value from the analog pin A5
    lightPercent = convertLightToPercent(lightValue);
    percentLightString = String(lightPercent);
    stringLightLength = percentLightString.length();
    displayLightPercent(stringLightLength);

    display.setCursor(70, 29);                               // set cursor at the end of the light mesurement frame
    display.print("%");                                      // write "%"
    display.drawRect(32, 27, 51, 18, BLACK);                 // draw a rectangle from (x1,y1) to (x2,y2)
    display.drawLine(2, 47, 81, 47, BLACK);                  // draw a line from (x1,x2) to (y1,y2)
    display.display();

    Serial.print(mesurement);                                // send to serial port the masurement no
    Serial.print(" ");
    Serial.print(analogRead(A0));                            // send to serial port the moisture instantaneous value
    Serial.print(" ");
    Serial.print(analogRead(A5));                            // send to serial port the light instantaneous value
    Serial.println(" ");
  }
}

Wykorzystane materiały


ElektroMaras, 2014. Jak z pomocą Arduino uratować paprotkę od zagłady?
educ8s in arduino. DIY Soil Moisture Monitor With Arduino and a Nokia 5110 Display
Elektroprzewodnik, 2013. Piny analogowe | Port szeregowy | #22 [Arduino]
myinventions.pl, 2009. Pomiar natężenia światła
 
 

Doktorat

Spis treści
Rozdzialy
Abstrakt [pl]
Abstract [eng]