Automatsko zalivanje bašte sa Arduinom

Lekcija 10 od 17 · Arduino i ESP32

Spajamo dve stvari koje već znamo: senzor vlažnosti zemljišta meri koliko je zemlja suva, a relej i pumpa dovode vodu. Arduino donosi odluku: kada je zemlja suva – zalij. Ovo je prvi pravi automatski sistem: senzor → odluka → izvršni uređaj, bez čoveka.

Šta je potrebno

  • Arduino Uno i USB kabl
  • senzor vlažnosti zemljišta – preporuka je kapacitivni (ne korodira)
  • relej modul (5 V), mala potapajuća pumpa 3–6 V, crevo (silikonsko, prečnika oko 5 mm)
  • 4 baterije AA ili adapter 5–6 V za pumpu
  • posuda sa vodom i saksija sa zemljom (ili biljkom)

Povezivanje

Povezivanje je zbir dve prethodne lekcije:

SENZOR VLAŽNOSTI     ARDUINO
VCC  --------------> 5V
GND  --------------> GND
AOUT --------------> A0

RELEJ MODUL          ARDUINO
VCC  --------------> 5V
GND  --------------> GND
IN   --------------> D7

BATERIJA (+) -> COM releja,  NO releja -> (+) pumpe,  (-) pumpe -> BATERIJA (-)
Raspored u prostoru: senzor zabodi u zemlju između biljke i mesta gde crevo izliva vodu – ne tik uz crevo, jer bi odmah „video“ mokru zemlju i prerano zaustavio zalivanje. Elektronika ide dalje od vode i iznad posude.

Korak 1: kalibracija senzora

Svaki senzor daje malo drugačije brojeve. Zato ih prvo izmerimo:

// Kalibracija senzora vlažnosti: ispisuje sirovu vrednost dva puta u sekundi
const int SENZOR_PIN = A0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println(analogRead(SENZOR_PIN));   // zapiši vrednost na vazduhu (SUVO) i u čaši vode (MOKRO)
  delay(500);
}
  1. Drži senzor na vazduhu i zapiši vrednost – to je SUVO (kod kapacitivnog senzora obično oko 500–600).
  2. Stavi senzor u čašu vode (samo do oznake na pločici!) i zapiši vrednost – to je MOKRO (obično oko 250–300).

Kod kapacitivnog senzora suva zemlja daje veći broj, a mokra manji. Funkcija map(sirovo, SUVO, MOKRO, 0, 100) to sama „okrene“, pa dobijamo procenat vlažnosti od 0 do 100.

Korak 2: zalivanje u porcijama

Zašto ne bismo jednostavno držali pumpu uključenom dok senzor ne javi „mokro“? Zato što voda treba vremena da se upije i stigne do senzora. Pumpa bi za to vreme preplavila saksiju. Zato zalivamo u porcijama: 3 sekunde vode, pa 30 sekundi čekanja, pa novo merenje.

// Automatsko zalivanje: kada je zemlja suva, pumpa radi kratko,
// pa se čeka da voda upije pre sledećeg merenja (zalivanje „u porcijama“)
const int SENZOR_PIN = A0;
const int RELEJ_PIN  = 7;
const int LED_PIN    = 13;        // ugrađena LED svetli dok pumpa radi
const int RELEJ_UKLJ  = LOW;      // za HIGH-trigger modul zameni LOW i HIGH
const int RELEJ_ISKLJ = HIGH;

// vrednosti iz kalibracije – zameni svojim brojevima
const int SUVO  = 600;            // senzor na vazduhu
const int MOKRO = 270;            // senzor u čaši vode

const int PRAG = 35;                          // ispod 35 % zemlja je suva
const unsigned long PORCIJA_MS = 3000;        // pumpa radi 3 sekunde
const unsigned long UPIJANJE_MS = 30000;      // zatim 30 s čekamo da voda upije
const int NAJVISE_PORCIJA = 5;                // zaštita: najviše 5 porcija zaredom

int porcijaZaredom = 0;

int procitajVlaznost() {
  long zbir = 0;
  for (int i = 0; i < 10; i++) {              // prosek 10 merenja – mirnija vrednost
    zbir += analogRead(SENZOR_PIN);
    delay(10);
  }
  int sirovo = zbir / 10;
  int procenat = map(sirovo, SUVO, MOKRO, 0, 100);
  return constrain(procenat, 0, 100);         // ne dozvoljavamo -5 % ili 110 %
}

void setup() {
  Serial.begin(115200);
  pinMode(RELEJ_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(RELEJ_PIN, RELEJ_ISKLJ);
}

void loop() {
  int vlaznost = procitajVlaznost();
  Serial.print("Vlaznost: ");
  Serial.print(vlaznost);
  Serial.println(" %");

  if (vlaznost < PRAG && porcijaZaredom < NAJVISE_PORCIJA) {
    Serial.println("Zemlja je suva - zalivam...");
    digitalWrite(RELEJ_PIN, RELEJ_UKLJ);
    digitalWrite(LED_PIN, HIGH);
    delay(PORCIJA_MS);
    digitalWrite(RELEJ_PIN, RELEJ_ISKLJ);
    digitalWrite(LED_PIN, LOW);
    porcijaZaredom++;
    delay(UPIJANJE_MS);                       // voda treba da stigne do senzora
  } else {
    if (vlaznost >= PRAG) {
      porcijaZaredom = 0;                     // zemlja je opet vlažna – brojač ispočetka
    } else {
      Serial.println("UPOZORENJE: zemlja i dalje suva - proveri vodu u posudi i crevo!");
    }
    delay(5000);                              // sledeće merenje za 5 sekundi
  }
}

Kako program radi

  • procitajVlaznost() računa prosek 10 merenja i vraća procenat. constrain sprečava vrednosti ispod 0 i iznad 100.
  • Ako je vlažnost ispod praga (35 %), pumpa radi jednu porciju, a zatim program čeka da voda upije.
  • Zaštita: posle 5 porcija zaredom, ako je zemlja i dalje suva, program prestaje da zaliva i javlja upozorenje. To se dešava kada je posuda sa vodom prazna, crevo ispalo ili senzor izvađen iz zemlje – bez ove zaštite pumpa bi radila „na suvo“ ili bi poplavila sto. Kada popraviš problem, pritisni taster RESET na Arduinu.
Prag i porcija zavise od biljke i saksije. Kaktus voli suvu zemlju (prag 15–20 %), a paradajz vlažniju (40–50 %). Za malu saksiju porcija od 2–3 s je dovoljna.

Ideje za nadogradnju

  1. Histerezis: uvedi dva praga – zalivanje počinje ispod 30 %, a „zemlja je dovoljno vlažna“ tek iznad 45 %. Tako sistem ne skače stalno između dva stanja kada je vlažnost tačno oko praga.
  2. Dodaj senzor nivoa vode u posudi (ili plovak) i ne pokreći pumpu kada vode nema.
  3. Pošalji vlažnost u Processing i nacrtaj grafik kako se menja tokom dana (kao u lekciji o senzoru vlažnosti).
  4. Zalivaj samo ujutru: dodaj LDR senzor i zalivaj tek kada je svetlo.
  5. Prebaci projekat na ESP32 i prati baštu preko telefona: automatsko zalivanje sa ESP32.

Proveri znanje

Otvori kviz

Kviz: automatsko zalivanje

1. Zašto se zaliva u porcijama, a ne dok senzor ne javi „mokro“?




2. Šta radi kalibracija senzora?




3. Čemu služi ograničenje od 5 porcija zaredom?




4. Šta je histerezis?