Parçalar · 14 dk okuma

Arduino RTC Modülü: DS3231, DS1307 ve DS1302 ile Saat ve Alarm

Arduino RTC modülü nasıl kullanılır? DS3231, DS1307 ve DS1302 farkları, RTClib ile saat ayarlama, LCD'de saat, zamanlı sulama, CR2032 şarj tuzağı ve ESP32 NTP.

Arduino RTC modülü, kartın elektriği kesilse bile tarihi ve saati saymaya devam eden küçük bir saat kartıdır. RTC, "Real Time Clock" yani gerçek zaman saati demektir. Arduino'nun kendi millis() sayacı her açılışta sıfırdan başlar ve günler içinde dakikalarca kayabilir; RTC modülü ise üzerindeki düğme pil (CR2032) sayesinde yıllarca saniyesi saniyesine çalışır. Masa saati, otomatik sulama, evcil hayvan mama makinesi, zaman damgalı veri kaydı ve zamanlayıcılı aydınlatma gibi projelerin hepsinde bu modülü görürsün.

Bu rehberde en yaygın üç yongayı, DS1307, DS3231 ve DS1302'yi karşılaştıracak ve hangisini neden seçmen gerektiğini göreceksin. Ardından RTClib kütüphanesiyle saati ayarlamayı ve okumayı, I2C LCD'de saat ve tarih göstermeyi, her gün belirli saatlerde pompa çalıştıran zamanlayıcıyı ve DS3231'in donanım alarmını adım adım kuracağız. Son bölümlerde pek çok modülü bozan CR2032 şarj devresi tuzağını, ESP32'de internetten saat alan NTP yöntemini ve Raspberry Pi Pico'nun dahili RTC'sini anlatıyoruz.

DS1307 RTC saat modülü
DS1307 RTC modülü: solda GND, 5V, SDA, SCL ve SQW pinleri, ortada DS1307 yongası, sağda CR1220 düğme pil yuvası.

RTC modülü nedir, nasıl çalışır?

Bir RTC yongasının kalbinde 32.768 Hz'lik bir saat kristali vardır. Bu sayı rastgele seçilmemiştir: 32.768, 2'nin 15. kuvvetidir; yonga bu frekansı 15 kez ikiye bölerek tam 1 saniyelik bir tik elde eder. Her tikte saniye, dakika, saat, gün, ay ve yıl kayıtları güncellenir; ayların kaç gün çektiği ve artık yıllar 2100 yılına kadar otomatik hesaplanır. Arduino bu kayıtları I2C hattından okur ya da onlara yeni bir saat yazar. Değerler kayıtlarda BCD biçiminde tutulur (örneğin 59 saniye 0x59 olarak saklanır); kütüphaneler bu dönüşümü senin yerine yapar.

RTC'nin asıl marifeti iki güç girişidir. VCC kesildiğinde yonga kendiliğinden pil girişine (VBAT) geçer ve yalnızca saati saymaya yetecek kadar, mikroamperin altında ya da birkaç mikroamper akım çeker. DS1307 bu sırada I2C iletişimini kapatır, DS3231 ise pilden çalışırken de okunabilir; iki durumda da saat durmaz. Elektrik geri geldiğinde Arduino açılır, RTC'den doğru saati okur ve kaldığı yerden devam eder. Arduino Uno'daki seramik rezonatörün toleransı yüzünden millis() ile tutulan bir saat günde dakikalarca sapabilir ve her resetle sıfırlanır; bu yüzden saate bağlı her projede ayrı bir RTC gerekir.

DS1307, DS3231 ve DS1302 farkları

ÖzellikDS1307DS3231DS1302
ArayüzI2C (100 kHz), adres 0x68I2C (400 kHz'e kadar), adres 0x683 telli seri: CE (RST), I/O (DAT), SCLK (CLK)
Besleme gerilimi4,5–5,5 V2,3–5,5 V2,0–5,5 V
KristalHarici 32,768 kHz (12,5 pF)Yonganın içinde, sıcaklık telafili (TCXO)Harici 32,768 kHz (6 pF)
DoğrulukKristale bağlı; ±20 ppm ile günde ~1,7 s, ayda ~1 dk±2 ppm (0–40 °C): ayda ~5 s, yılda ~1 dkKristale bağlı; DS1307'ye benzer ya da daha kötü
Ek özellikler56 bayt pil destekli RAM, kare dalga çıkışı (SQW)2 alarm, INT/SQW çıkışı, sıcaklık sensörü (±3 °C), yaşlanma ayarı31 bayt RAM, dahili şarj devresi (trickle charger)
Pilden çektiği akımYaklaşık 300–500 nAYaklaşık 1–3 µA2 V'ta 300 nA'den az
Arduino kütüphanesiRTClib (Adafruit)RTClib (Adafruit)Rtc by Makuna
Kimin için?5 V'luk basit saat projeleriNeredeyse her proje; ESP32 ve Pico için de idealEski kitler ve öğrenme projeleri

Doğruluk farkını somut düşünelim: 1 ppm milyonda bir demektir ve bir günde 86.400 saniye vardır. ±20 ppm'lik sıradan bir kristal günde 1,7 saniyeye, ayda yaklaşık 52 saniyeye kadar kayabilir; oda sıcaklığından uzaklaştıkça kristalin frekansı da değişir ve hata büyür. DS3231 ise kristali yonganın içinde taşır, sıcaklığı her 64 saniyede bir ölçer ve frekansı buna göre düzeltir. Böylece 0–40 °C arasında ±2 ppm, yani yılda yaklaşık bir dakika hata verir; -40 ile +85 °C arasında bile ±3,5 ppm'de kalır.

Hangi RTC modülünü seçmeliyim?

  • Yeni bir proje, ESP32 ya da Pico: DS3231 al. 3,3 V ile de 5 V ile de çalışır, alarmları vardır ve en doğru saat budur. Fiyat farkı birkaç kahve parası kadardır.
  • Elinde DS1307 var ve Arduino Uno kullanıyorsan: Gönül rahatlığıyla kullan; yalnızca ayda yaklaşık bir dakikalık kaymayı hesaba kat ve saati ara sıra düzelt.
  • Hazır kitten DS1302 çıktıysa: RTC mantığını öğrenmek için uygundur ama aylarca doğru kalacak bir saat bekleme.
  • ESP32 ve sürekli internet bağlantısı: Modül almadan NTP ile başla; elektrik kesintisinden sonra internet gelmeden saatin bilinmesi gerekiyorsa DS3231 ekle.

Piyasada en çok iki hazır kart görürsün: DS3231 yongalı ZS-042 ve DS1307 yongalı Tiny RTC. İkisinin üzerinde de veri saklamak için 4 KB'lık bir AT24C32 EEPROM bulunur. Bu yüzden I2C tarayıcı çalıştırdığında 0x68'in yanında ikinci bir adres (ZS-042'de genellikle 0x57, Tiny RTC'de 0x50) görmen normaldir; bu adres saate değil EEPROM'a aittir. DS1302 ise I2C kullanmaz, kendine özgü 3 telli bir protokolle konuşur ve üç dijital pin harcar.

DS1307'yi 3,3 V ile çalıştırmayı deneme. Yonga, VCC gerilimi pil geriliminin yaklaşık 1,25 katının (3 V'luk pille ~3,75 V) altına düşünce elektriğin kesildiğini varsayar ve I2C'den cevap vermez. ESP32 ve Pico gibi 3,3 V'luk kartlarda DS3231 doğrudan çalışır. I2C adresleri ve pull-up dirençleri hakkında daha fazlası için I2C Nedir? yazısına bakabilirsin.

RTC modülü bağlantısı: Arduino Uno, ESP32 ve Pico

RTC piniArduino UnoESP32Raspberry Pi Pico
VCC5V3V3 (DS3231)3V3(OUT), fiziksel pin 36 (DS3231)
GNDGNDGNDGND
SDAA4GPIO 21GP4 (I2C0)
SCLA5GPIO 22GP5 (I2C0)
SQW / INT (isteğe bağlı)D2 (kesme pini)Herhangi bir GPIO (ör. GPIO 4)Herhangi bir GP pini (ör. GP15)

Uno R3'te AREF pininin yanındaki SDA ve SCL başlıkları da A4 ve A5'e bağlıdır; hangisini kullandığın fark etmez. RTC ile I2C LCD ya da OLED ekran aynı iki kabloyu paylaşabilir; her cihazın adresi farklı olduğu için çakışma olmaz. Kabloları 20–30 cm'den kısa tutmak, özellikle breadboard üzerinde rastgele okuma hatalarını önler. SQW/INT pinini yalnızca donanım alarmını kullanacaksan bağlaman gerekir.

DS1307 ve ZS-042 gibi modüller 5 V ile beslendiğinde kart üzerindeki pull-up dirençleri SDA ve SCL hatlarını da 5 V'a çeker. ESP32 ve Raspberry Pi Pico'nun pinleri 5 V'a dayanıklı değildir. Bu kartlarda modülü mutlaka 3V3 pininden besle; DS1307 gibi 5 V isteyen bir yongayı kullanmak zorundaysan araya bir lojik seviye dönüştürücü koy.

RTClib kurulumu ve saati ayarlama

  1. Arduino IDE'de Kütüphane Yöneticisi'ni aç, RTClib yaz ve Adafruit'in kütüphanesini kur. Bağımlılıklar sorulduğunda Install all seçerek Adafruit BusIO'yu da kur. Daha önce hiç kütüphane eklemediysen Arduino Kütüphane Ekleme yazısı adım adım anlatıyor.
  2. Modülü yukarıdaki tablodaki gibi bağla ve pil yuvasına pili tak.
  3. Aşağıdaki kodu yükle. İlk çalıştırmada modül saati bilmediği için kod, bilgisayarındaki derleme saatini RTC'ye yazar.
  4. Seri Monitör'ü 9600 baud ve "Newline" satır sonu ayarıyla aç. Saati saniyesine kadar düzeltmek istersen 2026-11-03 14:30:00 biçiminde yazıp Enter'a bas.
  5. USB kablosunu çıkar, birkaç dakika bekle ve yeniden tak. Saat kaldığı yerden doğru devam ediyorsa pil yedeklemesi çalışıyor demektir.
Arduino (C++)
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc;   // DS1307 kullanıyorsan: RTC_DS1307 rtc; / for a DS1307: RTC_DS1307 rtc;
5
6void setup() {
7  Serial.begin(9600);
8  if (!rtc.begin()) {                         // modül I2C hattında yok / module not found on the I2C bus
9    Serial.println(F("RTC bulunamadi / RTC not found"));
10    while (true);
11  }
12  if (rtc.lostPower()) {                      // ilk çalıştırma ya da pil bitmiş / first run or dead battery
13    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));   // derleme saatini yaz / write the compile time
14    Serial.println(F("Saat derleme zamanina ayarlandi / Clock set to compile time"));
15  }
16  Serial.println(F("Ayar icin yaz / To set, type: 2026-11-03 14:30:00"));
17}
18
19void loop() {
20  // Seri monitörden saat geldiyse ayarla / set the time sent from the Serial Monitor
21  if (Serial.available()) {
22    String line = Serial.readStringUntil('\n');
23    int y, mo, d, h, mi, s;
24    if (sscanf(line.c_str(), "%d-%d-%d %d:%d:%d", &y, &mo, &d, &h, &mi, &s) == 6) {
25      rtc.adjust(DateTime(y, mo, d, h, mi, s));
26      Serial.println(F("Saat ayarlandi / Time set"));
27    }
28  }
29
30  DateTime now = rtc.now();
31  char buf[] = "DD.MM.YYYY hh:mm:ss";         // biçim şablonu / format template
32  Serial.print(now.toString(buf));
33  Serial.print(F("  "));
34  Serial.print(rtc.getTemperature());         // yalnız DS3231 / DS3231 only
35  Serial.println(F(" C"));
36  delay(1000);
37}

rtc.begin() modül I2C hattında bulunamazsa false döner; bu durumda önce kabloları kontrol et. rtc.lostPower(), DS3231'in osilatör durdu bayrağını (OSF) okur: modül ilk kez çalışıyorsa ya da pil bittiği için saat durduysa true döner ve kod saati derleme anına ayarlar. DateTime(F(__DATE__), F(__TIME__)) derleyicinin kodu derlediği anı kullanır; yükleme birkaç saniye sürdüğü için saat biraz geride kalır, bu yüzden Seri Monitör'den ince ayar yapmak işe yarar. toString() ise "DD.MM.YYYY hh:mm:ss" şablonundaki harfleri gerçek değerlerle değiştirir.

FonksiyonNe yapar?
rtc.begin()Modülü başlatır; bulunamazsa false döner
rtc.adjust(DateTime(...))Saati ve tarihi yazar
rtc.now()O anki zamanı DateTime nesnesi olarak okur
now.year(), now.month(), now.day()Yıl, ay, gün
now.hour(), now.minute(), now.second()Saat (0–23), dakika, saniye
now.dayOfTheWeek()Haftanın günü: 0 = Pazar, 6 = Cumartesi
now.unixtime()1 Ocak 1970'ten beri geçen saniye; iki zamanı karşılaştırmak için ideal
now + TimeSpan(0, 1, 30, 0)Zamana 1 saat 30 dakika ekler (gün, saat, dakika, saniye)
rtc.lostPower() / rtc.isrunning()Saatin geçerli olup olmadığını söyler (DS3231 / DS1307)
rtc.getTemperature()Yonganın sıcaklığı, °C (yalnız DS3231)

DS1307 kullanıyorsan tek fark nesne adıdır: RTC_DS1307 rtc; yaz, lostPower() yerine !rtc.isrunning() kontrolünü kullan ve getTemperature() satırını sil. DS1307 ilk kez enerjilendiğinde osilatörü durmuş hâlde (CH biti 1) başlar; adjust() bu biti temizleyip saati çalıştırır. DS1307'nin 56 baytlık pil destekli RAM'ine rtc.writenvram() ve rtc.readnvram() ile alarm saati gibi küçük ayarları kaydedebilirsin; bu bilgiler de pil sayesinde elektrik kesintisinde kaybolmaz.

En sık yapılan hata, rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); satırını koşulsuz olarak setup() içinde bırakmaktır. Bu durumda Arduino her resetlendiğinde ya da elektrik gidip geldiğinde saat, kodun derlendiği ana geri döner. Saati yalnızca lostPower() true döndüğünde ayarla ya da ayarladıktan sonra satırı yoruma alıp kodu yeniden yükle.

LCD ekranda saat ve tarih göstermek

Saati Seri Monitör yerine bir ekranda görmek projeyi gerçek bir masa saatine dönüştürür. 16x2 I2C LCD ve RTC aynı SDA-SCL hattına bağlanır: LCD genellikle 0x27 ya da 0x3F, RTC ise 0x68 adresindedir. Aşağıdaki kod üst satıra tarihi ve günün kısaltmasını, alt satıra saati ve DS3231'in ölçtüğü sıcaklığı yazar. LCD bağlantısı ve kütüphane kurulumu için I2C LCD Ekran Kullanımı yazısına göz atabilirsin.

Arduino (C++)
1#include <Wire.h>
2#include <RTClib.h>
3#include <LiquidCrystal_I2C.h>
4
5RTC_DS3231 rtc;
6LiquidCrystal_I2C lcd(0x27, 16, 2);           // adres 0x27 ya da 0x3F / address 0x27 or 0x3F
7
8// dayOfTheWeek(): 0 = Pazar / 0 = Sunday
9const char* const days[7] = {"Paz", "Pzt", "Sal", "Car", "Per", "Cum", "Cmt"};
10int lastSecond = -1;
11
12void setup() {
13  lcd.init();
14  lcd.backlight();
15  if (!rtc.begin()) {
16    lcd.print("RTC yok!");                     // modül bulunamadı / module not found
17    while (true);
18  }
19  if (rtc.lostPower()) rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
20}
21
22void loop() {
23  DateTime now = rtc.now();
24  if (now.second() == lastSecond) return;      // saniye değişmediyse yazma / skip until the second changes
25  lastSecond = now.second();
26
27  char line1[17], line2[17];
28  snprintf(line1, sizeof(line1), "%02d.%02d.%04d %s",
29           now.day(), now.month(), now.year(), days[now.dayOfTheWeek()]);
30  snprintf(line2, sizeof(line2), "%02d:%02d:%02d   %2dC",
31           now.hour(), now.minute(), now.second(), (int)rtc.getTemperature());
32  lcd.setCursor(0, 0);
33  lcd.print(line1);                            // ör. / e.g. 03.11.2026 Sal
34  lcd.setCursor(0, 1);
35  lcd.print(line2);                            // ör. / e.g. 14:05:09   23C
36}

snprintf içindeki %02d, tek haneli sayıların önüne sıfır ekler; böylece saat 9:5:3 yerine 09:05:03 görünür ve satırın uzunluğu hiç değişmez. Sabit uzunluk sayesinde lcd.clear() çağırmaya gerek kalmaz; ekranı her döngüde silmek titremeye yol açar. Kod ekrana yalnızca saniye değiştiğinde yazar, bu da I2C hattını boşuna meşgul etmez. Gün kısaltmalarını days dizisinde istediğin gibi değiştirebilirsin; dizinin ilk elemanı Pazar olmalıdır.

Saati uzaktan okunacak büyüklükte göstermek istersen 4 haneli 7 segment display ya da MAX7219 LED matris kullanabilirsin. Saat ile dakika arasındaki iki noktayı her saniye yakıp söndürmek, saatin çalıştığını gösteren klasik bir dokunuştur.

Alarm ve zamanlı görev: otomatik sulama ve mama verme

RTC'nin en kullanışlı tarafı işleri saatine göre yaptırmaktır: her sabah 08:00'de bitkileri sulamak, akşam 19:30'da kedinin mamasını dökmek ya da akvaryum ışığını gece kapatmak gibi. Bunun iki yolu var. Birincisi yazılımla karşılaştırmadır: loop() içinde saati okur, görev saatine gelinip gelinmediğine bakarsın. Basittir ve istediğin kadar görev ekleyebilirsin. İkincisi DS3231'in donanım alarmıdır: yonga belirlenen anda INT pinini LOW yapar ve Arduino'yu bir kesmeyle uyarır; uyku modundaki bir mikrodenetleyiciyi bile uyandırabilir.

Yazılımla karşılaştırmada sık yapılan hata, now.second() == 0 gibi tam saniye eşitliği aramaktır. loop() içinde uzun bir delay() varsa o saniye kaçabilir ve görev hiç çalışmaz. Aşağıdaki kod saat ve dakikayı karşılaştırır, görevin aynı dakikada ikinci kez çalışmaması için gün ve dakikadan oluşan bir anahtar saklar ve pompanın çalışma süresini millis() ile tutar. Pompa bir röle modülü üzerinden sürülür; pompanın bağlantısını mini su pompası yazısında bulabilirsin.

Arduino (C++)
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc;
5
6const byte RELAY_PIN = 7;
7const byte RELAY_ON = LOW;                    // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
8const byte RELAY_OFF = HIGH;
9const unsigned long RUN_MS = 10000;           // pompa 10 saniye çalışır / the pump runs for 10 seconds
10
11struct Task { byte hour; byte minute; };
12Task tasks[] = { {8, 0}, {19, 30} };          // her gün 08:00 ve 19:30 / every day at 08:00 and 19:30
13const byte TASK_COUNT = sizeof(tasks) / sizeof(tasks[0]);
14
15long lastRunKey = -1;                         // aynı dakikada ikinci kez çalışmasın / never run twice in one minute
16bool running = false;
17unsigned long startMs = 0;
18
19void setup() {
20  pinMode(RELAY_PIN, OUTPUT);
21  digitalWrite(RELAY_PIN, RELAY_OFF);         // açılışta kapalı / off at start-up
22  rtc.begin();
23}
24
25void loop() {
26  DateTime now = rtc.now();
27  long key = (long)now.day() * 1440 + now.hour() * 60 + now.minute();   // gün + dakika / day + minute
28
29  for (byte i = 0; i < TASK_COUNT; i++) {
30    if (now.hour() == tasks[i].hour && now.minute() == tasks[i].minute && key != lastRunKey) {
31      lastRunKey = key;
32      running = true;
33      startMs = millis();
34      digitalWrite(RELAY_PIN, RELAY_ON);      // pompayı aç / pump on
35    }
36  }
37
38  if (running && millis() - startMs >= RUN_MS) {
39    running = false;
40    digitalWrite(RELAY_PIN, RELAY_OFF);       // pompayı kapat / pump off
41  }
42  delay(200);
43}

Anahtarda günün de bulunması önemlidir: yalnızca dakikayı saklasaydın ve tek bir görev olsaydı, ertesi gün aynı dakikada anahtar hâlâ aynı olacağı için görev bir daha çalışmazdı. Mama makinesi yapmak istersen röle yerine bir servo motor kullan: görev anında servoyu 90 dereceye çevirip bir saniye sonra geri getirmek haznenin kapağını açar ve bir porsiyon mama döker. Sulamayı akıllı hâle getirmek için görev anında bir toprak nem sensörü oku ve toprak zaten nemliyse pompayı hiç çalıştırma. Aşağıdaki ikinci örnek ise aynı işi DS3231'in donanım alarmıyla yapar.

Arduino (C++)
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc;
5const byte ALARM_PIN = 2;                     // DS3231 SQW/INT -> D2 (kesme pini / interrupt pin)
6volatile bool alarmFlag = false;
7
8void onAlarm() {                              // kesme fonksiyonu kısa olmalı / keep the ISR short
9  alarmFlag = true;
10}
11
12void setup() {
13  Serial.begin(9600);
14  rtc.begin();
15  rtc.disable32K();                           // 32K çıkışını kapat / turn off the 32K output
16  rtc.writeSqwPinMode(DS3231_OFF);            // SQW pini alarm çıkışı olur / SQW becomes the alarm output
17  rtc.clearAlarm(1);
18  rtc.clearAlarm(2);
19  rtc.disableAlarm(2);
20
21  // Her gün 07:30:00; tarih kısmı yok sayılır / every day at 07:30:00; the date part is ignored
22  rtc.setAlarm1(DateTime(2026, 1, 1, 7, 30, 0), DS3231_A1_Hour);
23
24  pinMode(ALARM_PIN, INPUT_PULLUP);           // INT çıkışı open-drain / INT is an open-drain output
25  attachInterrupt(digitalPinToInterrupt(ALARM_PIN), onAlarm, FALLING);
26}
27
28void loop() {
29  if (alarmFlag) {
30    alarmFlag = false;
31    rtc.clearAlarm(1);                        // temizlenmezse pin LOW kalır / the pin stays LOW until cleared
32    Serial.println(F("Alarm: mama vakti / Feeding time"));
33    // Servo, röle ya da buzzer kodunu buraya yaz / put your servo, relay or buzzer code here
34  }
35}

DS3231'in iki alarmı vardır. Alarm 1 saniye çözünürlüklüdür; DS3231_A1_Hour modu saat, dakika ve saniye eşleştiğinde, yani her gün aynı anda tetiklenir. Diğer modlarla her saniye (PerSecond), her dakika (Second), her saat (Minute), ayın belirli bir gününde (Date) ya da haftanın belirli bir gününde (Day) alarm kurabilirsin. Alarm 2 ise dakika çözünürlüklüdür. SQW/INT pini open-drain, aktif LOW bir çıkıştır: alarm çalınca LOW olur ve clearAlarm() çağrılana kadar öyle kalır. Bu yüzden kesme fonksiyonunda yalnızca bir bayrak kaldırıp asıl işi loop() içinde yapmak en doğrusudur. Kesmelerin mantığı için Arduino Interrupt yazısına bakabilirsin.

RTC pili ne kadar dayanır?

Pil ömrünü kabaca hesaplamak kolaydır: süre (saat) = pil kapasitesi (mAh) ÷ çekilen akım (mA). Bir CR2032 yaklaşık 220 mAh'tir. DS3231 pil modunda en kötü durumda yaklaşık 3 µA, yani 0,003 mA çeker: 220 ÷ 0,003 ≈ 73.000 saat, bu da yaklaşık 8 yıl eder. Pil yalnızca VCC kesikken kullanılır; modül sürekli enerjili bir cihazdaysa pil neredeyse hiç harcanmaz ve bu süre çok daha uzar. Pratikte sınırı çoğu zaman pilin kendi raf ömrü ve modüldeki şarj devresi belirler.

YongaPilden çektiği akımCR2032 (220 mAh) ile hesaplanan süre
DS1307~0,5 µA~50 yıl; pratikte pilin raf ömrüyle (yaklaşık 10 yıl) sınırlı
DS3231~3 µA (kötü durum)~8 yıl
DS1302~0,3 µAPilin raf ömrüyle sınırlı
Şarj devresi açık modül + CR2032Pile dışarıdan akım basılırÖngörülemez; pil şişip erken bitebilir
Kendi projen için hesap yapmak istersen pil ömrü hesaplayıcısına pil kapasitesini ve ortalama akımı girmen yeterli. Aynı hesap, RTC ile birlikte pille çalışan bir Arduino'nun kaç gün dayanacağını bulmak için de işine yarar.

CR2032 pil ve şarj devresi tuzağı

Ucuz DS3231 (ZS-042) ve DS1307 (Tiny RTC) modüllerinin çoğunda, aslında şarj edilebilir LIR2032 pil için tasarlanmış basit bir şarj devresi bulunur. ZS-042'de VCC'den bir 1N4148 diyot ve 200 Ω'luk bir dirençle pile akım verilir; Tiny RTC'de de benzer bir devre vardır. Sorun şu ki bu modüller çoğu zaman şarj edilemeyen CR2032 pille satılır. Modül 5 V ile beslendiğinde diyottan sonra kalan yaklaşık 4,3 V, 3 V'luk lityum pile sürekli akım basar. Şarj edilmemesi gereken bu pil zamanla şişebilir, akabilir ve erkenden boşalır; sonuçta "pil var ama saat hep sıfırlanıyor" sorunu ortaya çıkar.

  • CR2032 kullanacaksan şarj yolunu kes: ZS-042'de pin başlığının yakınındaki, üzerinde "201" yazan 200 Ω'luk SMD direnci ya da yanındaki diyotu havyayla sök. Kodunu çözemediğin dirençler için SMD kod çözücüyü kullanabilirsin. En yaygın ve güvenli çözüm budur.
  • Devreyi olduğu gibi bırakacaksan LIR2032 tak: Şarj edilebilir pilin kapasitesi (yaklaşık 40 mAh) CR2032'nin (yaklaşık 220 mAh) beşte biri kadardır ama modül enerjili kaldıkça dolu tutulur.
  • Modülü 3,3 V ile besliyorsan: Diyottan sonra pile ancak 2,6 V civarı ulaşır; LIR2032 hiçbir zaman tam dolmaz, CR2032'ye ise neredeyse hiç akım gitmez. Yine de en temiz yol direnci sökmektir.
  • DS1302'nin dahili şarj devresi açılışta kapalıdır; CR2032 kullanıyorsan onu kodla açma.
  • Pilin durumunu ölç: Yeni bir CR2032 3,0–3,2 V gösterir; 2,5 V'un altına düştüyse değiştir.
Pilin üzerindeki harflere bak: CR şarj edilemeyen lityum pil, LIR ise şarj edilebilir lityum iyon pildir. Şarj devresi açık bir modüle CR2032 takıp aylarca 5 V'ta çalıştırmak pili şişirebilir ve akıtabilir. Şişmiş bir pili hemen çıkar ve atık pil kutusuna at.

DS1302 kullanımı (3 telli bağlantı)

DS1302 RTC saat modülü
DS1302 RTC modülü: solda VCC, GND, CLK, DAT ve RST pinleri, ortada 8 bacaklı DS1302 yongası ve kristali, sağda CR2032 pil yuvası.

DS1302 modülünün beş pini vardır: VCC, GND, CLK, DAT ve RST. I2C kullanmadığı için A4-A5'e değil, herhangi üç dijital pine bağlanır; aşağıdaki örnekte DAT D4'e, CLK D5'e, RST D2'ye gider ve modül 5V ile beslenir. Adafruit'in RTClib'i DS1302'yi desteklemez; bunun için Kütüphane Yöneticisi'nden Rtc by Makuna kütüphanesini kur. DS1302'de iki koruma biti vardır: yazma koruması açıkken saat ayarlanamaz, saat durdurma biti açıkken de saat ilerlemez. Kod ikisini de kontrol eder ve saat geçersizse derleme anına ayarlar.

Arduino (C++)
1#include <RtcDS1302.h>
2
3ThreeWire myWire(4, 5, 2);                    // DAT, CLK, RST pinleri / DAT, CLK, RST pins
4RtcDS1302<ThreeWire> rtc(myWire);
5
6void setup() {
7  Serial.begin(9600);
8  rtc.Begin();
9  if (rtc.GetIsWriteProtected()) rtc.SetIsWriteProtected(false);   // yazma korumasını kaldır / remove write protection
10  if (!rtc.GetIsRunning()) rtc.SetIsRunning(true);                  // saati başlat / start the clock
11
12  RtcDateTime compiled(__DATE__, __TIME__);
13  if (!rtc.IsDateTimeValid() || rtc.GetDateTime() < compiled) {
14    rtc.SetDateTime(compiled);                                      // derleme saatine ayarla / set to compile time
15  }
16}
17
18void loop() {
19  RtcDateTime now = rtc.GetDateTime();
20  char buf[20];
21  snprintf(buf, sizeof(buf), "%02u.%02u.%04u %02u:%02u:%02u",
22           now.Day(), now.Month(), now.Year(), now.Hour(), now.Minute(), now.Second());
23  Serial.println(buf);
24  delay(1000);
25}

DS1302 modüllerinde en sık şikâyet saatin haftada dakikalarca kaymasıdır. Bunun bir nedeni yonganın 6 pF yük kapasitesine göre ayarlanmış bir kristal istemesi, ucuz modüllerde ise farklı değerde kristaller kullanılabilmesidir. Uzun ve gevşek kablolar da DS1302'nin seri hattında okuma hatalarına yol açar. Elinde DS1302 varsa RTC mantığını öğrenmek için harika bir başlangıçtır; ama aylarca doğru kalması gereken bir saat yapıyorsan DS3231'e geç.

ESP32'de RTC yerine NTP: internetten saat almak

ESP32 Wi-Fi'ye bağlanabildiği için çoğu zaman RTC modülüne ihtiyaç duymaz: NTP (Network Time Protocol) ile pool.ntp.org gibi zaman sunucularından birkaç saniyede doğru saati alır. ESP32'nin Arduino çekirdeği bunun için hazır configTzTime() ve getLocalTime() fonksiyonlarını sunar; saat dilimi bir kural metniyle verilir. Türkiye 2016'dan beri yaz saati uygulamadan UTC+3'te kaldığı için koddaki kural sabit bir +3 saat farkıdır. Avrupa'daki gibi yaz saati olan bölgelerde koddaki yorumda yer alan Orta Avrupa kuralı, geçiş günlerini kendisi hesaplar.

NTP'nin zayıf noktası internete bağımlı olmasıdır: elektrik gidip geldiğinde modem açılana kadar ya da Wi-Fi şifresi değiştiğinde ESP32 saati bilemez. ESP32'nin kendi içindeki RTC zamanlayıcısı derin uyku sırasında saati korur ama güç tamamen kesilince sıfırlanır. En sağlam çözüm ikisini birleştirmektir: ESP32 açılışta NTP'ye ulaşabiliyorsa DS3231'i internet saatine eşitler, ulaşamıyorsa saati DS3231'den okur ve günde bir kez yeniden eşitler. NTP'nin ayrıntıları için ESP32 NTP ile saat yazısına bakabilirsin.

Arduino (C++)
1#include <WiFi.h>
2#include <Wire.h>
3#include <RTClib.h>
4#include <time.h>
5
6const char* WIFI_SSID = "AgAdin";             // Wi-Fi ağ adı / Wi-Fi network name
7const char* WIFI_PASS = "Sifren";             // Wi-Fi şifresi / Wi-Fi password
8// Türkiye: UTC+3, yaz saati yok / Turkey: UTC+3, no daylight saving
9// Orta Avrupa / Central Europe: "CET-1CEST,M3.5.0,M10.5.0/3"
10const char* TZ_INFO = "<+03>-3";
11
12RTC_DS3231 rtc;
13unsigned long lastSync = 0;
14
15void syncFromNtp() {
16  struct tm t;
17  if (getLocalTime(&t, 10000)) {              // en fazla 10 sn bekle / wait up to 10 s
18    rtc.adjust(DateTime(t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec));
19    Serial.println("DS3231 NTP ile ayarlandi / DS3231 synced from NTP");
20  }
21  lastSync = millis();
22}
23
24void setup() {
25  Serial.begin(115200);
26  Wire.begin(21, 22);                         // SDA, SCL pinleri / SDA, SCL pins
27  rtc.begin();
28
29  WiFi.begin(WIFI_SSID, WIFI_PASS);
30  unsigned long start = millis();
31  while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) delay(250);
32
33  if (WiFi.status() == WL_CONNECTED) {
34    configTzTime(TZ_INFO, "pool.ntp.org", "time.google.com");
35    syncFromNtp();
36  } else {
37    Serial.println("Wi-Fi yok, DS3231 saati kullaniliyor / No Wi-Fi, using the DS3231");
38  }
39}
40
41void loop() {
42  DateTime now = rtc.now();
43  char buf[] = "DD.MM.YYYY hh:mm:ss";
44  Serial.println(now.toString(buf));
45
46  if (WiFi.status() == WL_CONNECTED && millis() - lastSync > 86400000UL) {
47    syncFromNtp();                            // günde bir kez eşitle / sync once a day
48  }
49  delay(1000);
50}

Raspberry Pi Pico'nun dahili RTC'si

Raspberry Pi Pico'daki RP2040 yongasının içinde bir RTC birimi vardır; Pico 2'deki RP2350 ise aynı işi her zaman açık bir zamanlayıcıyla (AON timer) yapar. MicroPython'da ikisi de aynı machine.RTC sınıfıyla kullanılır: RTC().datetime() zamanı (yıl, ay, gün, haftanın günü, saat, dakika, saniye, alt saniye) biçiminde okur ya da yazar, time.localtime() da bu saati kullanır. Ama bu saatin pili yoktur: Pico'nun elektriği kesilince MicroPython saati 1 Ocak 2021, 00:00'dan başlatır.

Burada yeni başlayanları şaşırtan bir tuzak var: Thonny, Pico'ya bağlandığında onun saatini varsayılan olarak bilgisayarının saatine eşitler. Bu yüzden testte her şey doğru görünür; Pico'yu bir şarj adaptörüne ya da pile taktığında ise saat 2021 yılına döner. Çözüm, Pico'ya bir DS3231 bağlamak ve açılışta dahili RTC'yi ondan ayarlamaktır. Aşağıdaki kod hiçbir sürücü dosyası gerektirmez; DS3231'in ilk yedi kaydını I2C'den okuyup BCD'den onluk sayıya çevirir. Pico W kullanıyorsan ntptime.settime() ile saati internetten de alabilirsin; bu fonksiyon UTC verdiği için Türkiye saatine 3 saat eklemen gerekir. Pico'ya yeni başlıyorsan Raspberry Pi Pico Nedir? yazısından başlayabilirsin.

MicroPython
1from machine import Pin, I2C, RTC
2import time
3
4i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
5DS_ADDR = 0x68                                  # DS3231 ve DS1307 adresi / DS3231 and DS1307 address
6
7def bcd2dec(b):
8    return (b >> 4) * 10 + (b & 0x0F)
9
10def dec2bcd(d):
11    return ((d // 10) << 4) | (d % 10)
12
13def ds_read():
14    b = i2c.readfrom_mem(DS_ADDR, 0x00, 7)      # saniyeden yıla 7 kayıt / 7 registers, seconds to year
15    return (2000 + bcd2dec(b[6]), bcd2dec(b[5] & 0x1F), bcd2dec(b[4] & 0x3F),
16            bcd2dec(b[2] & 0x3F), bcd2dec(b[1] & 0x7F), bcd2dec(b[0] & 0x7F))
17
18def ds_write(y, mo, d, h, mi, s):
19    # 24 saat biçiminde yazar; 4. bayt haftanın günü (1-7) / writes 24-hour time; 4th byte is day of week (1-7)
20    i2c.writeto_mem(DS_ADDR, 0x00, bytes([dec2bcd(s), dec2bcd(mi), dec2bcd(h), 1,
21                                          dec2bcd(d), dec2bcd(mo), dec2bcd(y - 2000)]))
22
23# İlk kurulumda bir kez çalıştır, sonra satırı sil / run once on first setup, then delete the line
24# ds_write(2026, 11, 3, 14, 30, 0)
25
26y, mo, d, h, mi, s = ds_read()
27RTC().datetime((y, mo, d, 0, h, mi, s, 0))     # dahili RTC'yi ayarla / set the internal RTC
28
29while True:
30    t = time.localtime()                        # artık dahili RTC'den okunur / now read from the internal RTC
31    print("{:02d}.{:02d}.{} {:02d}:{:02d}:{:02d}".format(t[2], t[1], t[0], t[3], t[4], t[5]))
32    time.sleep(1)

RTC modülü ile proje fikirleri

  • Dijital masa saati ve takvim: Saati, tarihi ve DS3231'in ölçtüğü sıcaklığı LCD, OLED ya da LED matris üzerinde göster.
  • Otomatik bitki sulama: Her sabah toprak nemini kontrol et ve gerekiyorsa pompayı belirli bir süre çalıştır.
  • Evcil hayvan mama makinesi: Günde iki ya da üç kez servo ile haznenin kapağını açıp bir porsiyon mama dök.
  • Zaman damgalı veri kaydedici: Sıcaklık ve nem ölçümlerini tarih-saat bilgisiyle birlikte bir SD kart modülüne yaz, sonra Excel'de grafiğini çiz.
  • Okul ya da atölye zili: Ders başlangıç ve bitiş saatlerinde bir buzzer ya da röleyle zili çaldır; hafta sonlarını dayOfTheWeek() ile atla.
  • Akvaryum ve bitki ışığı zamanlayıcısı: Işığı sabah açıp akşam kapat, gün doğumu ve gün batımı etkisi için parlaklığı PWM ile yavaşça değiştir.

Sık yapılan hatalar ve çözümleri

  • "RTC bulunamadı", begin() false dönüyor: SDA ile SCL yer değiştirmiş, GND ortak değil ya da modül beslenmiyor. Bir I2C tarayıcı kodu çalıştırıp 0x68 adresinin görünüp görünmediğine bak.
  • 2165 yılı, 165 ya da 85 gibi anlamsız değerler: Yongadan veri gelmiyor ve okunan baytların hepsi 0xFF. Kabloları kontrol et; DS1307'yi 3,3 V ile besliyorsan 5 V'a geç.
  • Her resette saat aynı ana dönüyor: rtc.adjust() satırı koşulsuz olarak setup() içinde kalmış; satırı lostPower() koşuluna bağla.
  • Elektrik gidip gelince saat sıfırlanıyor: Pil bitmiş, ters takılmış ya da hiç takılmamış. Pil voltajını ölç; şarj devresinin CR2032'yi bitirmiş olabileceğini de unutma.
  • Saat haftada dakikalarca kayıyor: DS1307 ya da DS1302'nin kristali ve sıcaklık değişimi buna yol açar. DS3231'e geç ya da saati düzenli olarak NTP ile eşitle.
  • Saat tam 1 ya da 3 saat farklı: Saat dilimi ya da yaz saati ayarı yanlış. RTC'ye yerel saati yaz; NTP kullanıyorsan doğru saat dilimi kuralını seç.
  • DS3231 sıcaklığı odadan yüksek gösteriyor: Bu değer yonganın kendi sıcaklığıdır, doğruluğu ±3 °C'dir ve kartın ısınmasından etkilenir. Ortam sıcaklığı için ayrı bir sensör kullan.
Bir sorunla karşılaştığında önce I2C tarayıcı kodunu çalıştır: RTC 0x68 adresinde görünmüyorsa sorun koddan değil kablolamadandır. Pil voltajını ve modülün beslemesini kontrol etmek için Multimetre Nasıl Kullanılır? yazısı işine yarar.

Kısacası saat ve tarih isteyen hemen her projede doğru seçim DS3231'dir; DS1307 5 V'luk basit projelerde, DS1302 ise öğrenme amaçlı işini görür. ESP32'de internet varsa NTP, yoksa DS3231; Pico'da ise dahili RTC'yi açılışta DS3231'den ayarlamak en sağlam yoldur. BlueGrays uygulamasında DS1302 ile saat kurulumu ve LCD'li saat, DS1307 ile dot matrix saat ve takvim, ESP32 ile RTC'li dijital saat, NTP ile internet saati ve tarih damgalı sıcaklık kaydedici projelerini devre şemaları ve kodlarıyla adım adım bulabilirsin.

Sıkça sorulan sorular

RTC modülü pilsiz çalışır mı?

VCC bağlı olduğu sürece saat çalışır ve okunabilir. Ancak elektrik kesildiği anda saat durur ya da sıfırlanır ve bir sonraki açılışta yeniden ayarlaman gerekir. RTC kullanmanın asıl amacı güç kesintisinde saati korumak olduğu için pil takmak neredeyse her zaman gereklidir; DS1307 pilsiz kullanılacaksa VBAT pini GND'ye bağlanmalıdır.

DS3231 mü DS1307 mi daha iyi?

Neredeyse her durumda DS3231 daha iyidir. Sıcaklık telafili dahili kristali sayesinde yılda yaklaşık bir dakika hata yapar, DS1307 ise ayda bir dakikaya kadar kayabilir. DS3231 ayrıca 2,3–5,5 V arasında çalıştığı için ESP32 ve Pico ile doğrudan kullanılabilir; iki alarmı ve bir sıcaklık sensörü vardır. RTClib ile kod tarafında ikisi neredeyse aynıdır.

RTC modülünün pili ne kadar dayanır?

Modül yalnızca pille çalışırken DS3231 en fazla yaklaşık 3 µA, DS1307 ise 0,5 µA civarında akım çeker. 220 mAh'lik bir CR2032 bu akımlarla hesapta 8 yıldan uzun dayanır. Pratikte pilin raf ömrü ve modüldeki şarj devresi bu süreyi kısaltabilir; şarj devresi açık bir modülde CR2032 çok daha erken bitebilir.

RTC modülü saati neden sıfırlıyor?

En sık üç neden vardır: setup() içindeki rtc.adjust() satırının her açılışta saati derleme anına geri alması, pilin bitmiş ya da ters takılmış olması ve şarj devresinin CR2032'yi bozmuş olması. Önce adjust() satırını lostPower() koşuluna bağla, ardından pil voltajını multimetreyle ölç; 2,5 V'un altındaysa pili değiştir.

ESP32 için RTC modülü gerekli mi?

Cihaz sürekli internete bağlıysa gerekmez; ESP32 NTP ile saati birkaç saniyede doğru olarak alır. İnternetin kesilebileceği, elektrik kesintisinden sonra modem açılmadan saatin bilinmesi gereken ya da tamamen çevrimdışı çalışan projelerde DS3231 eklemek en güvenli yoldur. En iyisi ikisini birlikte kullanıp DS3231'i günde bir kez NTP ile eşitlemektir.

DS3231 modülüne CR2032 takılır mı?

Takılır ama ZS-042 gibi şarj devresi olan modüllerde önce şarj yolunu kesmen gerekir. Kart üzerindeki 200 Ω'luk direnci (201 kodlu) ya da yanındaki diyotu sökersen CR2032 yıllarca güvenle çalışır. Devreye dokunmak istemiyorsan şarj edilebilir LIR2032 pil kullan.

Tüm projeleri gör
DS1302 RTC Saat Modülü Kurulum
#45Başlangıç
Premium

DS1302 RTC Saat Modülü Kurulum

Arduino kapansa bile zamanı unutmayan küçük bir saat modülünü çalıştırırsın. Modülün kendi minik pili vardır; saat bir kez ayarlandıktan sonra tarih ve saat her saniye bilgisayar ekranına yazılır. Ala

4.5(23)
31
DS1302 RTC Saat LCD Ekran İle Kullanımı
#46Orta
Premium

DS1302 RTC Saat LCD Ekran İle Kullanımı

Elektrik kesilse bile saati unutmayan küçük bir masa saati. DS1302 saat modülü kendi minik pili sayesinde zamanı tutar; Arduino her saniye bu bilgiyi okuyup LCD ekranın üst satırına saati ve tarihi, a

4.7(41)
51
ESP32 RTC DS1307 ile Dijital Saat (I2C + LCD)
#120Orta
Premium

ESP32 RTC DS1307 ile Dijital Saat (I2C + LCD)

Bu projede DS1307 gerçek zaman saati (RTC) modülü ile 16x2 I2C LCD ekrana saat ve tarih bilgisi yansıtıyoruz. DS1307 pil destekli bir RTC'dir; ESP32 kapansa bile zamanı korur. Her iki modül de aynı I2C hattını (SDA/SCL) paylaşır, böylece sadece iki sinyal kablosu ile çoklu cihaz kontrolü öğrenmiş oluruz. Bu proje sayesinde I2C haberleşme protokolünü, RTC modüllerinin çalışma prensibini ve LCD ekranda dinamik veri gösterimini pratik bir şekilde öğreneceksiniz.

4.6(26)
40
Dot Matrix Saat ve Takvim (MAX7219, DS1307)
#84Orta
Premium

Dot Matrix Saat ve Takvim (MAX7219, DS1307)

Masada ya da duvarda duran, saati ve tarihi kayan yazıyla gösteren ışıklı bir pano. 8x32 LED ekranda iki noktası her saniye yanıp sönen büyük rakamlı saat durur; her dakika başında günün adı ve tarih

5.0(37)
58
Dot Matrix Saat, Takvim ve Hava İstasyonu (MAX7219, DS1307)
#85Orta
Premium

Dot Matrix Saat, Takvim ve Hava İstasyonu (MAX7219, DS1307)

Masada ya da duvarda durup saati, tarihi ve odanın havasını sırayla gösteren kayan yazılı bir pano. 8x32 LED ekranda önce sıcaklık hem Celsius hem Fahrenheit olarak, sonra nem, ardından iki noktası he

5.0(50)
66
ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)
#144İleri
Premium

ESP32 Sıcaklık Loglayıcı (DHT22 + DS1307 RTC + microSD + OLED)

ESP32 ile zamanlı sıcaklık ve nem kayıt sistemi kur! Bu projede DHT22 sensörü ile dakikada bir sıcaklık/nem okuyup DS1307 RTC modülünden aldığın gerçek zaman etiketiyle microSD karta CSV formatında kaydediyoruz. OLED ekranda büyük font ile son sıcaklık değeri, nem yüzdesi, timestamp ve toplam kayıt sayısı canlı gösterilir. SD kart üzerindeki `/temp_log.csv` dosyası Excel/Google Sheets/Python pandas ile açılıp analiz edilebilir — sera monitörü, ev/oda sıcaklık takibi, laboratuvar veri toplama,

4.7(7)
12
ESP32 NTP ile İnternetten Gerçek Zaman
#128İleri
Premium

ESP32 NTP ile İnternetten Gerçek Zaman

ESP32, Wi-Fi'a bağlanıp NTP (Network Time Protocol) sunucularından milisaniye hassasiyetiyle gerçek zamanı çeker. `configTzTime()` fonksiyonu sayesinde Türkiye saat dilimi (TRT, UTC+3) otomatik uygulanır ve yaz/kış saati uygulayan ülkelerde DST geçişi POSIX TZ string'i ile otomatik yönetilir. Saat hem Serial Monitor'e hem de opsiyonel I2C LCD'ye yazdırılır. `configTzTime()` SNTP hizmetini başlatır; ağ erişimi varken periyodik yeniden senkronizasyon yapılır ve iki senkronizasyon arasında sistem s

4.5(13)
21
4'lü 7 Segment Display İle Dijital Saat
#48Orta
Premium

4'lü 7 Segment Display İle Dijital Saat

Mutfaktaki fırın saatine benzeyen dört haneli, ışıklı bir dijital saat. DS1302 saat modülü zamanı tutar, Arduino her saniye saati ve dakikayı okuyup dört rakamlık göstergeye yazar; saatle dakika arası

4.8(56)
73