ESP32 Projeleri
#08Başlangıç

NTP Zaman Senkronizasyonlu Otomatik Eylem Planlayıcı

~1 saatYok, ilk ESP32 projeniz olabilir

Proje Amacı

WiFi üzerinden NTP (Network Time Protocol) sunucusuyla gerçek dünya saatini senkronize edip, bu saate göre belirli zamanlarda (örn. her gün 07:00 ve 19:00) bir röleyi otomatik tetiklemeyi öğretir — harici bir RTC modülüne veya manuel saat girişine hiç gerek kalmadan. ESP32'nin WiFi bağlantısı sayesinde configTime() ile saniyeler içinde internetten doğru zamanı alıp dahili saatini senkronize edebilir. Arduino Uno'da aynı otomatiklik sağlanamaz: kartın NTP sunucusuna ulaşacak hiçbir ağ bağlantısı yoktur; zaman bilgisi için mutlaka harici bir pilli RTC modülü (DS3231 gibi) eklenip elle veya USB üzerinden bir kerelik saat ayarlanması gerekir, kendiliğinden senkronizasyon mümkün değildir.

Gerekli Malzemeler

  • ESP32 DevKit V1 (38 pin)
  • Röle modülü (5V, optokuplörlü)
  • Breadboard
  • Jumper kablolar

Gerekli Kütüphaneler

WiFi.h, time.h (ikisi de ESP32 core ile gelir, ek kurulum gerekmez).

Pin Bağlantıları

Bileşen PiniBağlantı
Röle IN
GPIO4
Röle VCC
5V (VIN)
Röle GND
GND

Devre Şeması

ESP32 Kodu

esp32-08-ntp-zaman-senkronizasyonlu-otomatik-eylem-planlayici.ino
1#include <WiFi.h>
2#include <time.h>
3
4const char* ssid = "WIFI_ADINIZ";
5const char* password = "WIFI_SIFRENIZ";
6const int ROLE = 4;
7
8const char* ntpSunucu = "pool.ntp.org";
9const long gmtOfsetSn = 3 * 3600; // Türkiye: UTC+3
10const int yazSaatiOfsetSn = 0;
11
12// Planlanmış eylemler: {saat, dakika, hedef durum}
13struct Plan { int saat, dakika; bool durum; };
14Plan planlar[] = {
15 {7, 0, true}, // 07:00 -> röleyi AÇ
16 {19, 0, false}, // 19:00 -> röleyi KAPAT
17};
18const int planSayisi = sizeof(planlar) / sizeof(planlar[0]);
19int sonCalisanPlanIndex = -1;
20int sonCalisanGun = -1;
21
22void setup() {
23 Serial.begin(115200);
24 pinMode(ROLE, OUTPUT);
25 digitalWrite(ROLE, LOW);
26
27 WiFi.begin(ssid, password);
28 Serial.print("WiFi'ye bağlanıyor");
29 while (WiFi.status() != WL_CONNECTED) { delay(400); Serial.print("."); }
30 Serial.println("\nBağlandı.");
31
32 configTime(gmtOfsetSn, yazSaatiOfsetSn, ntpSunucu);
33 Serial.println("NTP zaman senkronizasyonu bekleniyor...");
34 struct tm zamanBilgisi;
35 while (!getLocalTime(&zamanBilgisi)) { delay(500); Serial.print("."); }
36 Serial.println(&zamanBilgisi, "\nSenkronize edildi: %d.%m.%Y %H:%M:%S");
37}
38
39void loop() {
40 struct tm simdi;
41 if (getLocalTime(&simdi)) {
42 for (int i = 0; i < planSayisi; i++) {
43 bool zamanTuttu = (simdi.tm_hour == planlar[i].saat && simdi.tm_min == planlar[i].dakika);
44 // Aynı dakika içinde tekrar tetiklenmesini önlemek için gün+index kontrolü
45 if (zamanTuttu && !(sonCalisanPlanIndex == i && sonCalisanGun == simdi.tm_yday)) {
46 digitalWrite(ROLE, planlar[i].durum ? HIGH : LOW);
47 Serial.printf("Plan çalıştı: %02d:%02d -> röle %s\n",
48 planlar[i].saat, planlar[i].dakika, planlar[i].durum ? "AÇIK" : "KAPALI");
49 sonCalisanPlanIndex = i;
50 sonCalisanGun = simdi.tm_yday;
51 }
52 }
53 }
54 delay(1000); // dakika hassasiyeti yeterli, saniyede bir kontrol kâfi
55}

Çalışma Açıklaması

getLocalTime() içindeki tm_year alanı 1900'den itibaren sayıldığı için gerçek yılı almak isterseniz +1900 eklenmelidir (bu projede kullanılmıyor ama ileride tarih bazlı planlama eklenirse dikkat edilmelidir). Aynı dakika içinde loop() birden fazla kez çalışıp röleyi tekrar tekrar tetiklememesi için sonCalisanPlanIndex ve sonCalisanGun değişkenleriyle 'bu plan bugün zaten çalıştı' kontrolü yapılmıştır — bu basit ama etkili bir tekrar-önleme (debounce) tekniğidir.

Test Bilgisi

Kodu yükleyip Seri Monitör'de doğru güncel saatin senkronize olduğunu doğrulayın. Testi hızlandırmak için planlar[] dizisindeki saatleri geçerli saatten 1-2 dakika sonrasına ayarlayıp yeniden yükleyin; belirtilen dakikada röle klik sesi çıkarıp LED/kontak durumu değişmeli, ardından ertesi gün aynı saatte tekrar tetiklenip tetiklenmediğini de kontrol ederek 'günde bir kez' mantığının doğru çalıştığını doğrulayın.

Olası Sorunlar ve Çözümleri

getLocalTime() sürekli false dönüp saat hiç senkronize olmuyorsa: kurumsal veya okul ağlarında NTP portu (UDP 123) engellenmiş olabilir, farklı bir ağda (örn. telefon hotspot'unda) test edin. Saat 3 saat kayıyorsa: gmtOfsetSn değerinin saniye cinsinden girildiğini unutmayın (3*3600, sadece '3' değil bu hesaplamayla doğru sonuç verir). Cihaz yeniden başlatıldığında plan tekrar tetikleniyorsa: sonCalisanGun değişkeni RTC memory'de tutulmadığı için bu normal bir sıfırlanmadır, kritik uygulamalarda bu değişkenler RTC_DATA_ATTR yapılmalıdır.

Alternatif Çözümler

Sabit kodlanmış planlar[] dizisi yerine, WiFiManager (proje #03) ile birlikte web arayüzünden plan ekleme/silme özelliği eklenerek kullanıcının kod yazmadan zamanlama yapabildiği bir ürün seviyesine çıkarılabilir. Hafta içi/hafta sonu için farklı planlar tanımlamak isteyenler simdi.tm_wday (0=Pazar) kontrolü ekleyebilir. NTP'ye ek olarak harici bir DS3231 RTC modülü eklenerek, WiFi kesintisi yaşansa bile pil yedekli RTC sayesinde doğru zamanın korunması sağlanabilir.

Bu projenin kodunu AI ile özelleştir

Farklı pin, ek özellik ya da başka bir sensör mü istiyorsun?

Benzer Projeler

Başlangıç

WiFiManager ile Captive Portal Kurulum Sihirbazı

Cihazı ilk açılışta WiFi ağı bilgisi olmadan bir Erişim Noktası (AP) moduna geçirip, telefon veya bilgisayarla bu ağa bağlanan kullanıcıya otomatik açılan bir web sayfasından (captive portal) ev WiFi bilgilerini girdirmeyi öğretir — kod içine SSID/şifre yazmadan, kutudan çıkar çıkmaz kurulum yapılabilen tüketici ürünlerindeki deneyimin bir benzeri. ESP32'nin WiFi çipi Erişim Noktası (AP) ve İstemci (STA) modları arasında yazılımsal olarak geçiş yapabilir ve bu esnada aynı anda basit bir DNS yönlendirme + web sunucusunu çalıştıracak yeterli RAM'e sahiptir. Bu senaryo Arduino Uno'da kurulamaz: kart hiçbir WiFi radyo donanımı içermez ve harici bir WiFi shield eklense bile 2KB RAM'i, DNS yönlendirme + web sunucusu + form işleme arabelleklerini aynı anda tutmaya yetmez.

Başlangıç

mDNS ile Otomatik Cihaz Keşfi (Zero-Config)

Cihazın IP adresini ezberlemeden, ağdaki herkesin tarayıcıdan sabit bir isimle (örn. http://devreai-lamba.local) erişebilmesini sağlamayı öğretir — DHCP her seferinde farklı bir IP verse bile isim her zaman aynı kalır. ESP32'nin ESPmDNS kütüphanesi, WiFi ağı üzerinden Bonjour/Avahi uyumlu mDNS (multicast DNS) protokolünü çalıştıracak ağ yığınına ve işlem gücüne sahiptir. Bu protokol Arduino Uno'da çalıştırılamaz: mDNS bir ağ protokolüdür ve çalışması için TCP/IP yığını ile bir ağ arayüzü gerekir, Uno'da ikisi de bulunmaz.

İleri

Firebase Cloud Functions ile Sunucusuz Otomasyon Mantığı

ESP32'nin sadece ham sensör verisini (ışık seviyesi) HTTPS ile Firebase Realtime Database'e yazıp, 'ışık şu eşiğin altına düşerse röleyi aç' gibi karar mantığını cihaz üzerinde değil, bulutta çalışan bir Firebase Cloud Function'da (sunucusuz/serverless) tutmayı öğretir — cihaz koduna hiç dokunmadan bulut tarafındaki otomasyon kuralını değiştirebilme esnekliği sunar. ESP32'nin donanımsal kripto hızlandırması ve yeterli RAM'i, Firebase'in gerektirdiği TLS/HTTPS bağlantısını ve JSON işlemeyi sorunsuz yürütür. Bu tür bir bulut entegrasyonu Arduino Uno'da kurulamaz: WiFi yoktur; olsaydı bile TLS handshake için gereken kripto işlemi ve JSON ayrıştırma belleği 2KB SRAM'e hiç sığmaz.