Automatsko zalivanje bašte sa ESP32 i Wi-Fi-jem
U lekciji automatsko zalivanje sa Arduinom bašta se zalivala sama, ali smo stanje videli samo u Serial Monitor-u. ESP32 ima ugrađen Wi-Fi, pa može da napravi malu veb stranu: na telefonu vidiš vlažnost zemlje, da li pumpa radi, i možeš da je pokreneš jednim dodirom. Pumpu i relej već poznaješ iz lekcije pumpa za vodu sa ESP32.
Razlike u odnosu na Arduino Uno
| Arduino Uno | ESP32 | |
|---|---|---|
| napon pinova | 5 V | 3,3 V – ulaz ne sme da dobije više |
| analogni ulaz | A0, vrednosti 0–1023 | GPIO34 (ADC1), vrednosti 0–4095 |
| napajanje senzora | 5V | 3V3 (kapacitivni senzor v1.2 radi i na 3,3 V) |
| relej | običan 5 V modul | modul koji pouzdano radi sa signalom od 3,3 V |
| mreža | nema | Wi-Fi i Bluetooth |
Povezivanje
SENZOR VLAŽNOSTI ESP32
VCC --------------> 3V3
GND --------------> GND
AOUT --------------> GPIO34
RELEJ MODUL ESP32
VCC --------------> VIN (5 V sa USB-a)
GND --------------> GND
IN --------------> GPIO23
BATERIJA (+) -> COM releja, NO releja -> (+) pumpe, (-) pumpe -> BATERIJA (-)
Relej modul napajamo sa pina VIN (5 V iz USB kabla), a upravljamo ga signalom od 3,3 V sa GPIO23. Ako relej „klikće“ nepouzdano, potreban je modul predviđen za 3,3 V logiku.
Kalibracija
Kao i kod Arduina, prvo izmeri vrednosti SUVO (senzor na vazduhu) i MOKRO (senzor u čaši vode). Kod ESP32 brojevi su veći jer je opseg 0–4095 – na primer oko 3000 na vazduhu i oko 1300 u vodi. Za merenje možeš da koristiš program iz lekcije o LDR senzoru – samo ga ostavi na GPIO34.
Program
U program upiši ime svoje Wi-Fi mreže i lozinku, kao i svoje vrednosti kalibracije. Posle učitavanja otvori Serial Monitor (115200): ESP32 će ispisati adresu, na primer http://192.168.1.45. Otvori je na telefonu ili računaru u istoj Wi-Fi mreži.
// ESP32 – automatsko zalivanje sa veb stranom (Wi-Fi)
#include <WiFi.h>
#include <WebServer.h>
const char* SSID = "IME_MREZE"; // upiši ime svoje Wi-Fi mreže
const char* LOZINKA = "LOZINKA"; // i lozinku
const int SENZOR_PIN = 34; // analogni ulaz (ADC1), samo ulaz
const int RELEJ_PIN = 23;
const int RELEJ_UKLJ = HIGH; // za LOW-trigger relej zameni HIGH i LOW
const int RELEJ_ISKLJ = LOW;
const int SUVO = 3000; // kalibracija: senzor na vazduhu (0–4095)
const int MOKRO = 1300; // kalibracija: senzor u čaši vode
const int PRAG = 35; // ispod 35 % zemlja je suva
const unsigned long PORCIJA_MS = 3000; // pumpa radi 3 s
const unsigned long UPIJANJE_MS = 30000; // pauza za upijanje 30 s
WebServer server(80);
int vlaznost = 0;
bool pumpaRadi = false;
bool automatski = true;
unsigned long pumpaUkljucena = 0;
unsigned long krajZalivanja = 0;
unsigned long poslednjeMerenje = 0;
int procitajVlaznost() {
long zbir = 0;
for (int i = 0; i < 10; i++) {
zbir += analogRead(SENZOR_PIN);
delay(2);
}
int procenat = map(zbir / 10, SUVO, MOKRO, 0, 100);
return constrain(procenat, 0, 100);
}
void pumpa(bool ukljuci) {
digitalWrite(RELEJ_PIN, ukljuci ? RELEJ_UKLJ : RELEJ_ISKLJ);
pumpaRadi = ukljuci;
if (ukljuci) pumpaUkljucena = millis();
else krajZalivanja = millis();
}
String stranica() {
String s = "<!DOCTYPE html><html><head><meta charset='utf-8'>";
s += "<meta name='viewport' content='width=device-width'>";
s += "<meta http-equiv='refresh' content='5'><title>Basta</title></head><body>";
s += "<h1>Pametna basta</h1>";
s += "<p>Vlaznost zemlje: <b>" + String(vlaznost) + " %</b></p>";
s += "<p>Pumpa: <b>" + String(pumpaRadi ? "radi" : "ne radi") + "</b></p>";
s += "<p>Automatski rezim: <b>" + String(automatski ? "ukljucen" : "iskljucen") + "</b></p>";
s += "<p><a href='/zalij'>Zalij sada</a> | <a href='/auto'>Promeni rezim</a></p>";
s += "</body></html>";
return s;
}
void nazadNaPocetnu() {
server.sendHeader("Location", "/");
server.send(303, "text/plain", "");
}
void setup() {
Serial.begin(115200);
pinMode(RELEJ_PIN, OUTPUT);
digitalWrite(RELEJ_PIN, RELEJ_ISKLJ);
WiFi.begin(SSID, LOZINKA);
Serial.print("Povezivanje");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Otvori u pregledacu: http://");
Serial.println(WiFi.localIP());
server.on("/", []() { server.send(200, "text/html", stranica()); });
server.on("/zalij", []() { if (!pumpaRadi) pumpa(true); nazadNaPocetnu(); });
server.on("/auto", []() { automatski = !automatski; nazadNaPocetnu(); });
server.begin();
}
void loop() {
server.handleClient(); // odgovaramo pregledaču
if (millis() - poslednjeMerenje >= 1000) { // merenje jednom u sekundi
poslednjeMerenje = millis();
vlaznost = procitajVlaznost();
Serial.println(vlaznost);
}
// pumpa se sama gasi posle jedne porcije
if (pumpaRadi && millis() - pumpaUkljucena >= PORCIJA_MS) {
pumpa(false);
}
// automatski režim: suva zemlja i prošlo je vreme za upijanje
if (automatski && !pumpaRadi && vlaznost < PRAG &&
millis() - krajZalivanja >= UPIJANJE_MS) {
pumpa(true);
}
}
Zašto ovde nema delay(30000)?
Veb server mora stalno da odgovara pregledaču – to radi server.handleClient() u petlji. Kada bismo pisali delay(30000) kao u Arduino verziji, strana se 30 sekundi ne bi otvarala. Zato vreme merimo funkcijom millis() (broj milisekundi od uključenja) i samo proveravamo „da li je prošlo dovoljno vremena“:
- pumpa se gasi kada od uključenja prođe
PORCIJA_MS; - nova porcija može tek kada od poslednjeg zalivanja prođe
UPIJANJE_MS; - vlažnost se meri jednom u sekundi.
Veb strana
server.on("/", …)– na adresi/šalje stranu sa vlažnošću i stanjem pumpe. Strana se sama osvežava na 5 sekundi (meta refresh)./zalij– pokreće jednu porciju zalivanja, pa vraća na početnu stranu./auto– uključuje ili isključuje automatski režim (npr. kada presađuješ biljku).
Zadaci za vežbu
- Dodaj na stranu i broj zalivanja od uključenja.
- Dodaj zaštitu iz Arduino verzije: posle 5 porcija zaredom bez uspeha, isključi automatski režim i na strani ispiši upozorenje.
- Dodaj na stranu dugme „Stop“ koje odmah gasi pumpu.
- Istraži: kako bi ESP32 slao vlažnost na neki IoT servis da bi se videla i van kuće? (vidi lekcije o Internetu stvari)
Proveri znanje
Otvori kviz
Kviz: zalivanje sa ESP32
1. Zašto se senzor vezuje na GPIO34?
2. Koji opseg vraća analogRead() na ESP32?
3. Zašto se u programu ne koristi delay(30000)?
4. Ko može da otvori veb stranu bašte?
