#define BLYNK_TEMPLATE_ID "TMPL4JiQEY997"
#define BLYNK_TEMPLATE_NAME "öntözö"
#define BLYNK_AUTH_TOKEN "JW4IZVu9XiaRNAX5kGDV2lfG8wfNBfGf"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <TimeLib.h>
#include "time.h"
#include <WidgetRTC.h>
#include <Preferences.h> // <-- ESP32 beépített állandó memória könyvtára
// --- BEÁLLÍTÁSOK ---
//char ssid[] = "wireless";
//char pass[] = "00DoNo0515";
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600 * 1;
const int daylightOffset_sec = 3600;
const int relePinek[] = {32, 33, 25, 26, 27, 14, 12, 13};
const int relekSzama = 8;
const int LED_PIN = 17; // 2 visszajelzés LED)
const int reset_PIN = 19; // D19 (Start gomb kimenet)
const int TIME_RELAY_PIN = 18;
BlynkTimer timer;
WidgetRTC rtc; // RTC objektum létrehozása wokwi
Preferences prefs; // Memória objektum létrehozása
long startMasodperc = -1, stopMasodperc = -1;
bool napokKivalasztva[8] = {true, true, true, true, true, true, true, true};
bool idozitoFokapcsolo = false;
bool ntpSzinkronizalt = false;
// --- IDŐSZINKRONIZÁCIÓ ---
void frissitsBelsoOratNTProl() {
struct tm timeinfo;
if(getLocalTime(&timeinfo, 0)){
setTime(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, timeinfo.tm_mday, timeinfo.tm_mon -2, timeinfo.tm_year + 1900);
if (!ntpSzinkronizalt) {
ntpSzinkronizalt = true;
Serial.println("[NTP] Óra sikeresen szinkronizálva az internettel!");
}
}
}
const bool HIGH_TRIGGER = true; // true = HIGH-ra kapcsol | false = LOW-ra kapcsol
void kapcsoliPin(int pin, bool bekapcsol) {
if (HIGH_TRIGGER) {
digitalWrite(pin, bekapcsol ? HIGH : LOW);
} else {
digitalWrite(pin, bekapcsol ? LOW : HIGH);
}
}
// Újraindításkor csak a V9-et kérjük le, a V11-et már a saját memóriából olvassuk!
BLYNK_CONNECTED() {
Serial.println("[Blynk] Csatlakozva! V9 szinkronizálása...");
Blynk.syncVirtual( V9);
}
// V1 - V8 Relék automatikus kezelése
BLYNK_WRITE_DEFAULT() {
int pin = request.pin;
int ertek = param.asInt();
if (pin >= 1 && pin <= relekSzama) {
int fizikaiPin = relePinek[pin - 1];
kapcsoliPin(fizikaiPin, ertek == 1);
}
}
// V10 KÉZI START GOMB -D18
BLYNK_WRITE(V10) {
int gombAllapot = param.asInt();
digitalWrite(TIME_RELAY_PIN, gombAllapot);
}
// 1. V13 START GOMB -D19
BLYNK_WRITE(V13) {
int gombAllapot = param.asInt();
digitalWrite( reset_PIN, gombAllapot);
}
//WidgetLED ledVisszajelzes(V0); // LED widget a V0 virtuális csatornán
void checkButton() {
int pinState = digitalRead(LED_PIN);
if (pinState == HIGH) {
Blynk.virtualWrite(V14, 1);
Serial.println("LED be ");
} else {
Blynk.virtualWrite(V14, 0);
Serial.println("LED ki ");
}
}
BLYNK_WRITE(V9) {
idozitoFokapcsolo = param.asInt();
Serial.print("[V9] Főkapcsoló állapota: "); Serial.println(idozitoFokapcsolo);
// Elmentjük a főkapcsolót is a Flash memóriába
prefs.begin("idozito", false);
prefs.putBool("fokapcs", idozitoFokapcsolo);
prefs.end();
Serial.print("[V9] Érték érkezett: "); Serial.println(param.asInt());
}
// Amikor a telefonról módosítod az időt, elmentjük az ESP32 állandó memóriájába!
BLYNK_WRITE(V11) {
TimeInputParam t(param);
if (t.hasStartTime()) {
startMasodperc = t.getStartHour() * 3600 + t.getStartMinute() * 60;
} else {
startMasodperc = -1;
}
if (t.hasStopTime()) {
stopMasodperc = t.getStopHour() * 3600 + t.getStopMinute() * 60;
} else {
stopMasodperc = -1;
}
for (int i = 1; i <= 7; i++) {
napokKivalasztva[i] = t.isWeekdaySelected(i);
}
// --- MENTÉS AZ ESP32 FLASH MEMÓRIÁJÁBA ---
prefs.begin("idozito", false); // Megnyitjuk az "idozito" nevű tárhelyet
prefs.putLong("startSec", startMasodperc);
prefs.putLong("stopSec", stopMasodperc);
// Napok tömb mentése byte-onként
char kulcs[8];
for(int i=1; i<=7; i++) {
sprintf(kulcs, "nap%d", i);
prefs.putBool(kulcs, napokKivalasztva[i]);
}
prefs.end(); // Bezárjuk és rögzítjük
Serial.println("[Memória] Új időzítési adatok elmentve a Flash-be!");
}
// Az időzítő ellenőrzése
void offlineIdozitoEllenorzes() {
if (!ntpSzinkronizalt || startMasodperc == -1 || stopMasodperc == -1) return;
if (!idozitoFokapcsolo) {
if (digitalRead(TIME_RELAY_PIN) == HIGH) {
digitalWrite(TIME_RELAY_PIN, LOW);
Serial.println("[Relé] Kikapcsolva (Főkapcsoló OFF)");
}
return;
}
long mostaniMasodperc = hour() * 3600 + minute() * 60 + second();
int maiNap = weekday();
if (napokKivalasztva[maiNap]) {
if (mostaniMasodperc >= startMasodperc && mostaniMasodperc < stopMasodperc) {
if (digitalRead(TIME_RELAY_PIN) == LOW) {
digitalWrite(TIME_RELAY_PIN, HIGH);
Serial.println("[Relé] BEKAPCSOLVA.");
}
} else {
if (digitalRead(TIME_RELAY_PIN) == HIGH) {
digitalWrite(TIME_RELAY_PIN, LOW);
Serial.println("[Relé] KIKAPCSOLVA.");
}
}
}
}
void setup() {
Serial.begin(115200);
delay(10);
for (int i = 0; i < relekSzama; i++) {
pinMode(relePinek[i], OUTPUT);
kapcsoliPin(relePinek[i], false);
}
pinMode(LED_PIN, INPUT);
pinMode(reset_PIN, OUTPUT);
pinMode(TIME_RELAY_PIN, OUTPUT);
digitalWrite(reset_PIN, LOW);
digitalWrite(TIME_RELAY_PIN, LOW);
digitalWrite(LED_PIN, false);
Serial.println("\n[Rendszer] Indítás...");
// --- ADATOK BETÖLTÉSE A FLASH MEMÓRIÁBÓL ---
prefs.begin("idozito", true); // Megnyitás csak olvasható módban
startMasodperc = prefs.getLong("startSec", -1); // Ha nincs elmentve semmi, -1-et ad vissza
stopMasodperc = prefs.getLong("stopSec", -1);
idozitoFokapcsolo = prefs.getBool("fokapcs", false);
char kulcs[8];
for(int i=1; i<=7; i++) {
sprintf(kulcs, "nap%d", i);
napokKivalasztva[i] = prefs.getBool(kulcs, true); // alapértelmezetten true
}
prefs.end();
Serial.println("[Memória] Korábbi időzítési adatok sikeresen betöltve a Flash-ből!");
Serial.print("-> Mentett Kezdés: "); Serial.println(startMasodperc);
Serial.print("-> Mentett Leállítás: "); Serial.println(stopMasodperc);
// Kapcsolódás
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
timer.setInterval(15000L, frissitsBelsoOratNTProl);
timer.setInterval(2000L, offlineIdozitoEllenorzes);
timer.setInterval(1000L, checkButton);
}
void loop() {
Blynk.run();
timer.run();
}
////////////////////////////////////////////////////////////////////////////////////////////
/*
#define BLYNK_TEMPLATE_ID "TMPL4JiQEY997"
#define BLYNK_TEMPLATE_NAME "öntözö"
#define BLYNK_AUTH_TOKEN "JW4IZVu9XiaRNAX5kGDV2lfG8wfNBfGf"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <TimeLib.h>
#include "time.h"
// --- BEÁLLÍTÁSOK ---
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600 * 1; // UTC + 1 óra (Téli)
const int daylightOffset_sec = 3600; // +1 óra nyári korrekció
const int TIME_RELAY_PIN = 18;
BlynkTimer timer;
long startMasodperc = -1, stopMasodperc = -1;
bool napokKivalasztva[8] = {true, true, true, true, true, true, true, true};
bool idozitoFokapcsolo = false;
bool ntpSzinkronizalt = false;
// Az NTP frissítés most már teljesen külön fut
void frissitsBelsoOratNTProl() {
struct tm timeinfo;
// A 0 paraméter miatt egy tizedmásodpercet sem vár, ha nincs kész az NTP, azonnal továbblép
if(getLocalTime(&timeinfo, 0)){
setTime(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, timeinfo.tm_mday, timeinfo.tm_mon -2, timeinfo.tm_year + 1900);
if (!ntpSzinkronizalt) {
ntpSzinkronizalt = true;
Serial.println("[NTP] Óra sikeresen szinkronizálva a hálózattal!");
}
}
}
// EZ FUT LE, AMIKOR SIKERESEN MEGTÖRTÉNT A KAPCSOLÓDÁS A BLYNK SZERVERHEZ
BLYNK_CONNECTED() {
Serial.println("[Blynk] Csatlakozva! Pinek felébresztése és lekérése...");
// 1. LÉPÉS: Megrázzuk a pineket (Küldünk egy frissítést a szervernek, hogy élünk)
// Ez kényszeríti a Blynk felhőt, hogy élesítse a Datastream memóriát
Blynk.virtualWrite(V9, idozitoFokapcsolo);
Blynk.virtualWrite(V11, TIME_RELAY_PIN);
delay(100);
// 2. LÉPÉS: Most kérjük le a szerverről a mentett értékeket sorban, szünetekkel
Serial.println("[Blynk] V1 lekérése...");
Blynk.syncVirtual(V1);
delay(200);
Serial.println("[Blynk] V9 lekérése...");
Blynk.syncVirtual(V9);
delay(200);
// A Time Input (V11) elé berakunk egy extra kényszerítést
Serial.println("[Blynk] V11 (Időzítő) lekérése...");
Blynk.syncVirtual(V11);
delay(200);
}
// Virtuális pinek fogadása a szerverről
BLYNK_WRITE(V9) {
idozitoFokapcsolo = param.asInt();
Serial.print("[V9] Főkapcsoló állapota: "); Serial.println(idozitoFokapcsolo);
}
BLYNK_WRITE(V10) {
// V10 KÉZI START GOMB -D18
int gombAllapot = param.asInt();
digitalWrite(TIME_RELAY_PIN, gombAllapot);
Serial.print("[V10] kézi start: "); Serial.println(param.asInt());
}
BLYNK_WRITE(V11) {
TimeInputParam t(param);
if (t.hasStartTime()) {
startMasodperc = t.getStartHour() * 3600 + t.getStartMinute() * 60;
Serial.print("[V11] Kezdés elmentve: "); Serial.println(startMasodperc);
}
if (t.hasStopTime()) {
stopMasodperc = t.getStopHour() * 3600 + t.getStopMinute() * 60;
Serial.print("[V11] Leállítás elmentve: "); Serial.println(stopMasodperc);
}
for (int i = 1; i <= 7; i++) {
napokKivalasztva[i] = t.isWeekdaySelected(i);
}
}
// Az időzítő ellenőrzése (2 másodpercenként fut, teljesen független a Blynktől)
void offlineIdozitoEllenorzes() {
// Ha az NTP még nem futott le, vagy nincsenek adatok, nem csinál semmit
if (!ntpSzinkronizalt || startMasodperc == -1 || stopMasodperc == -1) return;
// Ha a főkapcsoló ki van kapcsolva, a relét lekapcsoljuk és kilépünk
if (!idozitoFokapcsolo) {
if (digitalRead(TIME_RELAY_PIN) == HIGH) {
digitalWrite(TIME_RELAY_PIN, LOW);
Serial.println("[Relé] Kikapcsolva (Főkapcsoló OFF miatt)");
}
return;
}
long mostaniMasodperc = hour() * 3600 + minute() * 60 + second();
int maiNap = weekday();
if (napokKivalasztva[maiNap]) {
if (mostaniMasodperc >= startMasodperc && mostaniMasodperc < stopMasodperc) {
if (digitalRead(TIME_RELAY_PIN) == LOW) {
digitalWrite(TIME_RELAY_PIN, HIGH);
Serial.println("[Relé] Időzítő által bekapcsolva.");
}
} else {
if (digitalRead(TIME_RELAY_PIN) == HIGH) {
digitalWrite(TIME_RELAY_PIN, LOW);
Serial.println("[Relé] Időzítő által kikapcsolva.");
}
}
}
}
void setup() {
Serial.begin(115200);
delay(10);
pinMode(TIME_RELAY_PIN, OUTPUT);
digitalWrite(TIME_RELAY_PIN, LOW);
Serial.println("\n[Rendszer] Indítás...");
// A stabil Blynk működés alapja: A Blynk.begin() intéz MINDENT (WiFi + Blynk egyszerre)
// Ez belsőleg kezeli az ESP32 WiFi reconnect rutinját, nem kell kézzel loopolni!
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
// NTP óra konfigurálása
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
// Időzítők beállítása (Megemeltük az NTP-t 15 másodpercre, hogy ne terhelje az ESP-t)
timer.setInterval(15000L, frissitsBelsoOratNTProl);
timer.setInterval(2000L, offlineIdozitoEllenorzes);
}
void loop() {
// A loop-ot teljesen tisztán kell tartani! Semmilyen WiFi ellenőrzés vagy if feltétel nem mehet ide.
Blynk.run();
timer.run();
}
*/
/////////////////////////////////////////////////////////////////////////////////
/*
#define BLYNK_TEMPLATE_ID "TMPL4JiQEY997"
#define BLYNK_TEMPLATE_NAME "öntözö"
#define BLYNK_AUTH_TOKEN "JW4IZVu9XiaRNAX5kGDV2lfG8wfNBfGf"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <TimeLib.h>
#include "time.h" // ESP32 gyári internetes óra könyvtára
//#include <WidgetRTC.h>
// --- FINOMHANGOLÁS ÉS BEÁLLÍTÁSOK ---
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600 * 1; // UTC + 1 óra (Téli)
const int daylightOffset_sec = 3600; // +1 óra nyári korrekció (Összesen +2)
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
const int relePinek[] = {32, 33, 25, 26, 27, 14, 12, 13};
const int relekSzama = 8;
const int LED_PIN = 17; // 2 visszajelzés LED)
const int reset_PIN = 19; // D19 (Start gomb kimenet)
const int TIME_RELAY_PIN = 18; // D18 (Időzített kimenet)
BlynkTimer timer;
//WidgetRTC rtc; // RTC objektum létrehozása wokwi
long startMasodperc = -1, stopMasodperc = -1;
bool napokKivalasztva[8] = {true, true, true, true, true, true, true, true};
bool idozitoFokapcsolo = false;
bool ntpSzinkronizalt = false; // Új változó a szinkronizáció követésére
// --- Fő funkciók (NTP szinkronizáció) ---
bool frissitsBelsoOratNTProl() {
struct tm timeinfo;
// Csak akkor állítjuk be a TimeLib-et, ha az ESP32 gyári órája már sikeresen le kérte az időt
if(getLocalTime(&timeinfo)){
setTime(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec, timeinfo.tm_mday, timeinfo.tm_mon - 2, timeinfo.tm_year + 1900);
return true;
}
return false;
}
const bool HIGH_TRIGGER = true; // true = HIGH-ra kapcsol | false = LOW-ra kapcsol
void kapcsoliPin(int pin, bool bekapcsol) {
if (HIGH_TRIGGER) {
digitalWrite(pin, bekapcsol ? HIGH : LOW);
} else {
digitalWrite(pin, bekapcsol ? LOW : HIGH);
}
}
// V1 - V8 Relék automatikus kezelése
BLYNK_WRITE_DEFAULT() {
int pin = request.pin;
int ertek = param.asInt();
if (pin >= 1 && pin <= relekSzama) {
int fizikaiPin = relePinek[pin - 1];
kapcsoliPin(fizikaiPin, ertek == 1);
}
}
// 4. ÉLETJEL ÉS KAPCSOLAT ELLENŐRZÉS
WidgetLED ledVisszajelzes(V0); // LED widget a V0 virtuális csatornán
void checkButton() {
boolean buttonState = digitalRead(LED_PIN);
if (buttonState == HIGH) {
// Ha a gomb megnyomva, LED bekapcsolása a Blynk-en
ledVisszajelzes.on();
Serial.println("LED be ");
} else {
// Kikapcsolás
ledVisszajelzes.off();
Serial.println("LED ki ");
}
}
// V9 VIRTUÁLIS GOMB -> IDŐZÍTŐ FŐKAPCSOLÓ
BLYNK_WRITE(V9) {
idozitoFokapcsolo = param.asInt(); // 1 = Engedélyezve, 0 = Tiltva
Serial.print("[Fokapcsolo] Idozito rendszere: ");
Serial.println(idozitoFokapcsolo ? "ENGEDÉLYEZVE" : "LEZÁRVA / KIKAPCSOLVA");
// Ha kikapcsoljuk a főkapcsolót, azonnal lőjük le a D15-ös kimenetet is a biztonság kedvéért
if (!idozitoFokapcsolo) {
digitalWrite(TIME_RELAY_PIN, LOW);
}
}
// V10 KÉZI START GOMB -D18
BLYNK_WRITE(V10) {
int gombAllapot = param.asInt();
digitalWrite(TIME_RELAY_PIN, gombAllapot);
// 1. V13 START GOMB -D19
BLYNK_WRITE(V13) {
int gombAllapot = param.asInt();
digitalWrite( reset_PIN, gombAllapot);
}
// Ez a függvény fut le, amikor a Blynk csatlakozik a szerverhez
BLYNK_CONNECTED() {
// A V1 és V9 azonnal szinkronizálható
Blynk.syncVirtual(V10, V9);
// A V11-et (Time Input) NEM szinkronizáljuk azonnal, mert megvárjuk az NTP-t a loop-ban!
}
// Időzítő widget kezelése (V11) -D18
BLYNK_WRITE(V11) {
TimeInputParam t(param);
if (t.hasStartTime()) {
// A TimeLib aktuális napjának kezdetétől számított másodpercek
startMasodperc = t.getStartHour() * 3600 + t.getStartMinute() * 60;
Serial.print("Kezdési idő elmentve: ");
Serial.println(startMasodperc);
}
if (t.hasStopTime()) {
stopMasodperc = t.getStopHour() * 3600 + t.getStopMinute() * 60;
}
for (int i = 1; i <= 7; i++) {
napokKivalasztva[i] = t.isWeekdaySelected(i);
}
}
void offlineIdozitoEllenorzes() {
// Nem hívjuk meg 2 másodpercenként a getLocalTime-ot feleslegesen, ha már egyszer szinkronizált
if (!ntpSzinkronizalt) {
if (frissitsBelsoOratNTProl()) {
ntpSzinkronizalt = true;
// Serial.println("NTP sikeresen szinkronizálva, most már lekérhető a V11!");
Serial.printf("Belső óra beállítva: %02d:%02d:%02d\n", hour(), minute(), second());
// MOST, hogy az óra pontos, biztonságosan lekérhetjük a Time Input értékét!
if (Blynk.connected()) {
Blynk.syncVirtual(V11);
}
} else {
Serial.println("Várakozás az NTP kiszolgálóra...");
return; // Ha még nincs kész az óra, átugorjuk a logikát
}
}
// 1. Ha a V9 főkapcsoló KI van kapcsolva, ne csináljon semmit
if (!idozitoFokapcsolo) {
digitalWrite(TIME_RELAY_PIN, LOW);
return;
}
if ( startMasodperc == -1 || stopMasodperc == -1) return;
// Időzítési logika (TimeLib használatával)
long mostaniMasodperc = hour() * 3600 + minute() * 60 + second();
int maiNap = weekday(); // 1 = Vasárnap, 2 = Hétfő ... 7 = Szombat
if (napokKivalasztva[maiNap]) {
if (mostaniMasodperc >= startMasodperc && mostaniMasodperc < stopMasodperc) {
digitalWrite(TIME_RELAY_PIN, HIGH); // Relé BE
} else {
digitalWrite(TIME_RELAY_PIN, LOW); // Relé KI
}
}
}
void setup() {
Serial.begin(115200);
for (int i = 0; i < relekSzama; i++) {
pinMode(relePinek[i], OUTPUT);
kapcsoliPin(relePinek[i], false);
}
pinMode(LED_PIN, INPUT);
pinMode(reset_PIN, OUTPUT);
pinMode(TIME_RELAY_PIN, OUTPUT);
digitalWrite(TIME_RELAY_PIN, LOW);
digitalWrite(reset_PIN, LOW);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // ESP32 NTP indítás
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
timer.setInterval(2000L, offlineIdozitoEllenorzes);
timer.setInterval(1000L, checkButton);
}
void loop() {
Blynk.run();
timer.run();
}
*/