Modul RTC Arduino: DS3231 vs DS1307 vs DS1302, Jam dan Alarm
Panduan modul RTC Arduino: DS3231 vs DS1307 vs DS1302, mengatur waktu dengan RTClib, jam di LCD, penyiraman terjadwal, jebakan pengisian CR2032, dan NTP di ESP32.
Modul RTC Arduino adalah board jam kecil yang terus menghitung tanggal dan waktu meskipun board-mu kehilangan daya. RTC adalah singkatan dari “Real Time Clock”, yaitu jam waktu nyata. Penghitung millis() bawaan Arduino mulai lagi dari nol setiap kali dinyalakan dan bisa melenceng beberapa menit dalam hitungan hari, sedangkan modul RTC tetap berjalan akurat sampai ke detiknya selama bertahun-tahun berkat baterai koinnya (CR2032). Kamu akan menemukan modul ini di jam meja, sistem penyiraman otomatis, alat pemberi makan hewan peliharaan, data logger dengan stempel waktu, dan proyek lampu berpewaktu.
Di panduan ini kamu akan membandingkan tiga chip yang paling umum, DS1307, DS3231, dan DS1302, lalu melihat mana yang sebaiknya dipilih dan kenapa. Setelah itu, langkah demi langkah, kita akan mengatur dan membaca waktu dengan library RTClib, menampilkan jam dan tanggal di LCD I2C, membuat timer yang menyalakan pompa pada jam tertentu setiap hari, dan memakai alarm hardware DS3231. Bagian akhir membahas jebakan rangkaian pengisian CR2032 yang merusak banyak modul, mengambil waktu dari internet dengan NTP di ESP32, dan RTC bawaan Raspberry Pi Pico.

Apa itu modul RTC dan bagaimana cara kerjanya?
Inti dari sebuah chip RTC adalah kristal jam tangan 32,768 kHz. Angka ini bukan kebetulan: 32.768 adalah 2 pangkat 15, sehingga chip membagi dua frekuensi ini sebanyak 15 kali untuk mendapatkan detak yang tepat 1 detik. Pada setiap detak, register detik, menit, jam, hari, bulan, dan tahun diperbarui; panjang tiap bulan dan tahun kabisat dihitung otomatis sampai tahun 2100. Arduino membaca register ini lewat I2C atau menulis waktu baru ke dalamnya. Nilainya disimpan dalam format BCD (misalnya, 59 detik disimpan sebagai 0x59); library mengurus konversi itu untukmu.
Kunci sebenarnya dari RTC adalah dua input dayanya. Ketika VCC hilang, chip otomatis beralih ke input baterai (VBAT) dan hanya menarik arus secukupnya untuk terus menghitung: kurang dari satu mikroampere atau beberapa mikroampere. Selama itu DS1307 mematikan akses I2C, sedangkan DS3231 tetap bisa dibaca ketika berjalan dari baterai; apa pun chipnya, jamnya tidak berhenti. Ketika daya kembali, Arduino menyala, membaca waktu yang benar dari RTC, dan melanjutkan dari titik terakhirnya. Karena toleransi resonator keramik di Arduino Uno, jam yang dijaga dengan millis() bisa meleset beberapa menit sehari dan hilang setiap kali reset; itulah sebabnya setiap proyek berbasis waktu butuh RTC terpisah.
DS1307 vs DS3231 vs DS1302: perbedaannya
| Fitur | DS1307 | DS3231 | DS1302 |
|---|---|---|---|
| Antarmuka | I2C (100 kHz), alamat 0x68 | I2C (sampai 400 kHz), alamat 0x68 | Serial 3 kabel: CE (RST), I/O (DAT), SCLK (CLK) |
| Tegangan catu | 4,5–5,5 V | 2,3–5,5 V | 2,0–5,5 V |
| Kristal | Eksternal 32,768 kHz (12,5 pF) | Terpasang di dalam chip, terkompensasi suhu (TCXO) | Eksternal 32,768 kHz (6 pF) |
| Akurasi | Tergantung kristal; dengan ±20 ppm sekitar 1,7 dtk/hari, sekitar 1 mnt/bulan | ±2 ppm (0–40 °C): sekitar 5 dtk/bulan, sekitar 1 mnt/tahun | Tergantung kristal; mirip DS1307 atau lebih buruk |
| Fitur tambahan | RAM 56 byte dengan cadangan baterai, output gelombang kotak (SQW) | 2 alarm, output INT/SQW, sensor suhu (±3 °C), koreksi penuaan (aging trim) | RAM 31 byte, trickle charger bawaan |
| Arus dari baterai | Sekitar 300–500 nA | Sekitar 1–3 µA | Di bawah 300 nA pada 2 V |
| Library Arduino | RTClib (Adafruit) | RTClib (Adafruit) | Rtc by Makuna |
| Paling cocok untuk | Proyek jam 5 V yang sederhana | Hampir semua proyek; ideal juga untuk ESP32 dan Pico | Kit lama dan proyek belajar |
Supaya perbedaan akurasinya lebih terasa: 1 ppm berarti satu per sejuta, dan satu hari punya 86.400 detik. Kristal biasa ±20 ppm bisa melenceng hingga 1,7 detik sehari, sekitar 52 detik sebulan, dan makin jauh dari suhu ruang, makin berubah frekuensi kristalnya dan makin besar kesalahannya. Sebaliknya, DS3231 membawa kristalnya di dalam chip, mengukur suhu setiap 64 detik, dan mengoreksi frekuensinya sesuai suhu tersebut. Hasilnya ±2 ppm antara 0 dan 40 °C, kira-kira satu menit per tahun, dan tetap dalam ±3,5 ppm bahkan dari -40 sampai +85 °C.
Modul RTC mana yang sebaiknya kupilih?
- Proyek baru, ESP32, atau Pico: ambil DS3231. Modul ini berjalan di 3,3 V maupun 5 V, punya alarm, dan menjaga waktu paling akurat. Selisih harganya kecil sekali.
- Kamu sudah punya DS1307 dan memakai Arduino Uno: silakan pakai; cukup perhitungkan pergeseran sekitar satu menit per bulan dan koreksi waktunya sesekali.
- Starter kit-mu berisi DS1302: cukup bagus untuk belajar cara kerja RTC, tetapi jangan berharap jamnya tetap akurat selama berbulan-bulan.
- ESP32 dengan koneksi internet permanen: mulailah dengan NTP tanpa modul; tambahkan DS3231 kalau waktu harus sudah diketahui setelah listrik padam, sebelum internet kembali.
Kamu paling sering akan menemui dua board siap pakai: ZS-042 dengan chip DS3231 dan Tiny RTC dengan DS1307. Keduanya juga membawa EEPROM AT24C32 4 KB untuk menyimpan data. Karena itu wajar kalau kamu melihat alamat kedua di samping 0x68 ketika menjalankan I2C scanner (biasanya 0x57 di ZS-042 dan 0x50 di Tiny RTC); alamat itu milik EEPROM, bukan milik jamnya. DS1302 sama sekali tidak memakai I2C: chip ini berkomunikasi lewat protokol 3 kabelnya sendiri dan memakan tiga pin digital.
Pengkabelan modul RTC: Arduino Uno, ESP32, dan Pico
| Pin RTC | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | 3V3 (DS3231) | 3V3(OUT), pin fisik 36 (DS3231) |
| GND | GND | GND | GND |
| SDA | A4 | GPIO 21 | GP4 (I2C0) |
| SCL | A5 | GPIO 22 | GP5 (I2C0) |
| SQW / INT (opsional) | D2 (pin interrupt) | GPIO mana saja (mis. GPIO 4) | Pin GP mana saja (mis. GP15) |
Di Uno R3, header SDA dan SCL di sebelah pin AREF juga terhubung ke A4 dan A5, jadi tidak masalah mana yang kamu pakai. RTC bisa berbagi dua kabel yang sama dengan LCD I2C atau layar OLED; setiap perangkat punya alamatnya sendiri, jadi tidak ada bentrok. Menjaga kabel lebih pendek dari 20–30 cm mencegah error pembacaan acak, terutama di breadboard. Pin SQW/INT hanya perlu dihubungkan kalau kamu berencana memakai alarm hardware.
Menginstal RTClib dan mengatur waktu
- Buka Library Manager di Arduino IDE, ketik RTClib, lalu instal library buatan Adafruit. Ketika ditanya soal dependensi, pilih Install all supaya Adafruit BusIO ikut terinstal. Kalau kamu belum pernah menambahkan library, Cara Instal Library Arduino akan memandumu langkah demi langkah.
- Hubungkan modul seperti pada tabel di atas dan pasang baterai di dudukannya.
- Upload kode di bawah. Ketika pertama kali berjalan, modul belum tahu waktunya, jadi kode menulis waktu kompilasi di komputermu ke RTC.
- Buka Serial Monitor pada 9600 baud dengan akhir baris “Newline”. Untuk mengoreksi waktu sampai ke detiknya, ketik dengan format 2026-11-03 14:30:00 lalu tekan Enter.
- Cabut kabel USB, tunggu beberapa menit, lalu colokkan lagi. Kalau jamnya melanjutkan dengan benar dari titik terakhir, cadangan baterainya berfungsi.
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() mengembalikan false kalau modul tidak ditemukan di bus I2C; kalau begitu, cek pengkabelan dulu. rtc.lostPower() membaca flag oscillator stop (OSF) milik DS3231: nilainya true kalau modul baru pertama kali berjalan atau jamnya berhenti karena baterai habis, lalu kode mengatur jam ke waktu kompilasi. DateTime(F(__DATE__), F(__TIME__)) memakai momen ketika compiler membangun kodemu; karena upload memakan beberapa detik, jamnya jadi sedikit tertinggal, sehingga penyetelan halus dari Serial Monitor sangat membantu. toString() mengganti huruf-huruf di templat “DD.MM.YYYY hh:mm:ss” dengan nilai sebenarnya.
| Fungsi | Kegunaannya |
|---|---|
| rtc.begin() | Memulai modul; mengembalikan false kalau modul tidak ditemukan |
| rtc.adjust(DateTime(...)) | Menulis waktu dan tanggal |
| rtc.now() | Membaca waktu sekarang sebagai objek DateTime |
| now.year(), now.month(), now.day() (komponen tanggal) | Tahun, bulan, tanggal |
| now.hour(), now.minute(), now.second() (komponen waktu) | Jam (0–23), menit, detik |
| now.dayOfTheWeek() | Hari dalam seminggu: 0 = Minggu, 6 = Sabtu |
| now.unixtime() | Detik sejak 1 Januari 1970; ideal untuk membandingkan dua waktu |
| now + TimeSpan(0, 1, 30, 0) | Menambahkan 1 jam 30 menit (hari, jam, menit, detik) |
| rtc.lostPower() / rtc.isrunning() (cek validitas) | Memberi tahu apakah waktunya valid (DS3231 / DS1307) |
| rtc.getTemperature() | Suhu chip dalam °C (khusus DS3231) |
Kalau kamu memakai DS1307, satu-satunya perbedaan ada di nama objeknya: tulis RTC_DS1307 rtc;, pakai pengecekan !rtc.isrunning() sebagai ganti lostPower(), dan hapus baris getTemperature(). Ketika DS1307 diberi daya untuk pertama kalinya, osilatornya mulai dalam keadaan berhenti (bit CH bernilai 1); adjust() menghapus bit ini dan menjalankan jamnya. Kamu bisa menyimpan pengaturan kecil seperti waktu alarm di RAM 56 byte milik DS1307 yang didukung baterai dengan rtc.writenvram() dan rtc.readnvram(); berkat baterai, data itu juga tetap ada ketika listrik padam.
Menampilkan jam dan tanggal di LCD
Melihat jam di layar, bukan di Serial Monitor, mengubah proyek ini menjadi jam meja sungguhan. LCD I2C 16x2 dan RTC terhubung ke bus SDA-SCL yang sama: LCD biasanya ada di alamat 0x27 atau 0x3F dan RTC di 0x68. Kode di bawah menulis tanggal dan singkatan nama hari di baris atas, serta jam dan suhu yang diukur DS3231 di baris bawah. Untuk pengkabelan LCD dan pemasangan library-nya, lihat Cara Memakai Layar LCD I2C.
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}%02d di dalam snprintf menambahkan nol di depan angka satu digit, jadi jam tampil sebagai 09:05:03, bukan 9:5:3, dan panjang barisnya tidak pernah berubah. Berkat panjang yang tetap, kamu tidak perlu lcd.clear(); menghapus layar di setiap loop malah membuatnya berkedip. Kode hanya menulis ke layar ketika detiknya berganti, jadi bus I2C tidak sibuk tanpa alasan. Array days berisi singkatan hari dalam bahasa Turki; ganti dengan Min, Sen, Sel, dan seterusnya, dengan Minggu tetap sebagai elemen pertama.
Alarm dan tugas terjadwal: penyiraman otomatis dan pemberian makan hewan peliharaan
Hal paling berguna dari RTC adalah menyelesaikan pekerjaan sesuai jadwal: menyiram tanaman setiap pagi pukul 08.00, mengeluarkan makanan kucing pukul 19.30, atau mematikan lampu akuarium di malam hari. Ada dua cara untuk melakukannya. Yang pertama adalah perbandingan lewat software: kamu membaca waktu di loop() dan mengecek apakah waktu sebuah tugas sudah tiba. Caranya sederhana, dan kamu bisa menambahkan tugas sebanyak yang kamu mau. Yang kedua adalah alarm hardware DS3231: pada momen yang diatur, chip menarik pin INT-nya ke LOW dan memberi tahu Arduino lewat interrupt; alarm ini bahkan bisa membangunkan mikrokontroler yang sedang tidur.
Kesalahan umum pada perbandingan lewat software adalah mengecek detik yang persis, seperti now.second() == 0. Kalau ada delay() panjang di loop(), detik itu bisa terlewat dan tugasnya tidak pernah jalan. Kode di bawah membandingkan jam dan menit, menyimpan kunci yang terdiri dari hari dan menit supaya tugas tidak berjalan dua kali di menit yang sama, dan mengatur lama nyala pompa dengan millis(). Pompa dikendalikan lewat modul relay; pengkabelan pompanya ada di artikel pompa air mini.
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}Memasukkan hari ke dalam kunci itu penting: kalau kamu hanya menyimpan menitnya dan cuma punya satu tugas, kuncinya akan tetap sama di menit itu keesokan harinya dan tugasnya tidak akan pernah jalan lagi. Untuk membuat alat pemberi makan hewan peliharaan, pakai motor servo sebagai ganti relay: memutar servo ke 90 derajat pada waktu tugas lalu mengembalikannya sedetik kemudian akan membuka tutup wadah pakan dan menjatuhkan satu porsi makanan. Agar penyiramannya lebih pintar, baca sensor kelembapan tanah pada waktu tugas dan lewati pompa kalau tanahnya sudah lembap. Contoh kedua di bawah melakukan pekerjaan yang sama dengan alarm hardware DS3231.
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 punya dua alarm. Alarm 1 beresolusi satu detik; mode DS3231_A1_Hour aktif ketika jam, menit, dan detik cocok, dengan kata lain pada jam yang sama setiap hari. Dengan mode lainnya kamu bisa memasang alarm setiap detik (PerSecond), setiap menit (Second), setiap jam (Minute), pada tanggal tertentu dalam sebulan (Date), atau pada hari tertentu dalam seminggu (Day). Alarm 2 beresolusi satu menit. Pin SQW/INT adalah output open-drain yang aktif LOW: pin ini menjadi LOW ketika alarm aktif dan tetap begitu sampai clearAlarm() dipanggil. Karena itu, sebaiknya fungsi interrupt hanya menyalakan sebuah flag, sedangkan pekerjaan sebenarnya dilakukan di loop(). Untuk cara kerja interrupt, lihat interrupt Arduino.
Berapa lama baterai RTC bertahan?
Memperkirakan umur baterai itu mudah: lama pakai (jam) = kapasitas baterai (mAh) ÷ arus yang ditarik (mA). CR2032 menyimpan sekitar 220 mAh. Dalam mode baterai, DS3231 menarik sekitar 3 µA pada kondisi terburuk, yaitu 0,003 mA: 220 ÷ 0,003 ≈ 73.000 jam, atau kira-kira 8 tahun. Baterai hanya dipakai ketika VCC mati; kalau modul berada di perangkat yang selalu mendapat daya, baterainya hampir tidak tersentuh dan bertahan jauh lebih lama. Dalam praktiknya, batasnya biasanya ditentukan oleh umur simpan baterai itu sendiri dan rangkaian pengisian di modul.
| Chip | Arus dari baterai | Perkiraan lama pakai dengan CR2032 (220 mAh) |
|---|---|---|
| DS1307 | ~0,5 µA | ~50 tahun; dalam praktiknya dibatasi umur simpan baterai (sekitar 10 tahun) |
| DS3231 | ~3 µA (kondisi terburuk) | ~8 tahun |
| DS1302 | ~0,3 µA | Dibatasi umur simpan baterai |
| Modul dengan pengisi aktif + CR2032 | Arus dipaksa masuk ke baterai | Tidak bisa diprediksi; baterai bisa menggembung dan cepat mati |
Jebakan baterai CR2032 dan rangkaian pengisian
Sebagian besar modul DS3231 (ZS-042) dan DS1307 (Tiny RTC) yang murah punya rangkaian pengisian sederhana yang sebenarnya dirancang untuk baterai LIR2032 yang bisa diisi ulang. Di ZS-042, arus mengalir dari VCC ke baterai lewat dioda 1N4148 dan resistor 200 Ω; Tiny RTC punya rangkaian yang mirip. Masalahnya, modul-modul ini sering dijual dengan baterai CR2032 yang tidak bisa diisi ulang. Ketika modul berjalan di 5 V, sisa tegangan sekitar 4,3 V setelah dioda terus mendorong arus ke sel litium 3 V. Baterai yang tidak dirancang untuk diisi ini lama-kelamaan bisa menggembung, bocor, dan cepat mati, lalu kamu akhirnya mengalami masalah “baterainya ada, tapi jamnya terus reset”.
- Kalau kamu memakai CR2032, putuskan jalur pengisiannya: di ZS-042, lepas solderan resistor SMD 200 Ω bertanda “201” di dekat header pin, atau dioda di sebelahnya. Untuk resistor yang kodenya tidak bisa kamu baca, pakai dekoder kode SMD. Ini perbaikan yang paling umum dan paling aman.
- Kalau rangkaiannya dibiarkan apa adanya, pasang LIR2032: kapasitas baterai isi ulang ini (sekitar 40 mAh) kira-kira seperlima dari CR2032 (sekitar 220 mAh), tetapi baterainya selalu terisi penuh selama modul mendapat daya.
- Kalau modul diberi daya dari 3,3 V: hanya sekitar 2,6 V yang sampai ke baterai setelah dioda; LIR2032 tidak pernah terisi penuh, dan hampir tidak ada arus yang mengalir ke CR2032. Melepas resistornya tetap menjadi solusi paling bersih.
- Trickle charger bawaan DS1302 dalam keadaan mati ketika chip pertama kali menyala; kalau kamu memakai CR2032, jangan aktifkan lewat kode.
- Ukur baterainya: CR2032 baru menunjukkan 3,0–3,2 V; ganti kalau tegangannya sudah turun di bawah 2,5 V.
Memakai DS1302 (koneksi 3 kabel)

Modul DS1302 punya lima pin: VCC, GND, CLK, DAT, dan RST. Karena tidak memakai I2C, modul ini terhubung ke tiga pin digital mana saja, bukan ke A4-A5; pada contoh di bawah DAT masuk ke D4, CLK ke D5, dan RST ke D2, dan modulnya diberi daya dari 5V. RTClib dari Adafruit tidak mendukung DS1302, jadi instal library Rtc by Makuna dari Library Manager sebagai gantinya. DS1302 punya dua bit proteksi: selama proteksi tulis aktif, waktu tidak bisa diatur, dan selama bit clock-halt menyala, jamnya tidak maju. Kode mengecek keduanya dan mengatur jam ke waktu kompilasi kalau waktu yang tersimpan tidak valid.
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}Keluhan paling umum soal modul DS1302 adalah jamnya melenceng beberapa menit per minggu. Salah satu penyebabnya, chip ini butuh kristal yang disetel untuk kapasitansi beban 6 pF, sedangkan modul murah bisa memakai kristal dengan rating berbeda. Kabel yang panjang dan longgar juga menyebabkan error pembacaan di jalur serial DS1302. Kalau kamu punya DS1302, modul ini cara yang bagus untuk belajar cara kerja RTC; tetapi kalau kamu membuat jam yang harus tetap akurat selama berbulan-bulan, beralihlah ke DS3231.
NTP sebagai ganti RTC di ESP32: mengambil waktu dari internet
Karena ESP32 bisa terhubung ke Wi-Fi, sering kali ESP32 sama sekali tidak butuh modul RTC: dengan NTP (Network Time Protocol), ESP32 mendapatkan waktu yang benar dari server waktu seperti pool.ntp.org dalam beberapa detik. Core Arduino ESP32 menyediakan fungsi siap pakai configTzTime() dan getLocalTime() untuk ini, dan zona waktunya diberikan sebagai string aturan. Turki memakai UTC+3 tanpa waktu musim panas sejak 2016, jadi aturan di kode adalah selisih tetap +3 jam. Indonesia juga tidak memakai waktu musim panas: untuk WIB (UTC+7) aturannya cukup “WIB-7”, untuk WITA “WITA-8”, dan untuk WIT “WIT-9”. Di wilayah yang memakai waktu musim panas, seperti sebagian besar Eropa, aturan Eropa Tengah di komentar kode menghitung sendiri tanggal pergantiannya; di Inggris pakai “GMT0BST,M3.5.0/1,M10.5.0”.
Kelemahan NTP adalah ketergantungannya pada internet: setelah listrik padam, sampai router selesai menyala, atau ketika kata sandi Wi-Fi berubah, ESP32 tidak bisa mengetahui waktu. Timer RTC internal milik ESP32 tetap menjaga waktu selama deep sleep, tetapi ter-reset begitu daya benar-benar hilang. Solusi paling andal menggabungkan keduanya: ketika mulai, ESP32 menyinkronkan DS3231 ke waktu internet kalau NTP bisa dijangkau; kalau tidak, ESP32 membaca waktu dari DS3231, lalu menyinkronkan ulang sekali sehari. Untuk penjelasan lebih lanjut tentang NTP, lihat jam NTP ESP32.
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}RTC bawaan Raspberry Pi Pico
Chip RP2040 di Raspberry Pi Pico berisi blok RTC, sedangkan RP2350 di Pico 2 melakukan pekerjaan yang sama dengan timer yang selalu menyala (AON timer). Di MicroPython keduanya dipakai lewat kelas machine.RTC yang sama: RTC().datetime() membaca atau menulis waktu dalam bentuk (tahun, bulan, tanggal, hari dalam seminggu, jam, menit, detik, subdetik), dan time.localtime() juga memakai jam ini. Tapi jam ini tidak punya baterai: ketika Pico kehilangan daya, MicroPython memulai jamnya dari 1 Januari 2021, 00:00.
Ada perangkap yang sering mengecoh pemula di sini: secara default, Thonny menyinkronkan jam Pico ke jam komputermu ketika terhubung. Jadi semuanya terlihat benar selama pengujian, tetapi begitu Pico kamu colokkan ke charger ponsel atau baterai, jamnya melompat kembali ke 2021. Solusinya adalah menghubungkan DS3231 ke Pico dan mengatur RTC internal dari modul itu ketika mulai. Kode di bawah tidak butuh file driver apa pun; kode ini membaca tujuh register pertama DS3231 lewat I2C dan mengubahnya dari BCD ke desimal. Di Pico W kamu juga bisa mengambil waktu dari internet dengan ntptime.settime(); karena hasilnya dalam UTC, kamu perlu menambahkan sendiri selisih zona waktumu (misalnya 7 jam untuk WIB). Kalau kamu baru mengenal Pico, mulailah dari Apa Itu Raspberry Pi Pico?.
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)Ide proyek dengan modul RTC
- Jam meja digital dan kalender: tampilkan jam, tanggal, dan suhu yang diukur DS3231 di LCD, OLED, atau LED matrix.
- Penyiraman tanaman otomatis: cek kelembapan tanah setiap pagi dan nyalakan pompa selama waktu tertentu kalau perlu.
- Alat pemberi makan hewan peliharaan: buka tutup wadah pakan dengan servo dua atau tiga kali sehari dan jatuhkan satu porsi makanan.
- Data logger dengan stempel waktu: tulis pembacaan suhu dan kelembapan beserta tanggal dan jamnya ke modul kartu SD, lalu buat grafiknya di Excel.
- Bel sekolah atau bengkel: bunyikan buzzer atau bel yang dikendalikan relay di awal dan akhir setiap pelajaran, dan lewati akhir pekan dengan dayOfTheWeek().
- Timer akuarium dan lampu tanaman: nyalakan lampu di pagi hari dan matikan di sore hari, sambil mengubah kecerahannya perlahan dengan PWM untuk efek matahari terbit dan terbenam.
Kesalahan umum dan cara memperbaikinya
- “RTC not found”, begin() mengembalikan false: SDA dan SCL tertukar, GND tidak terhubung bersama, atau modul tidak mendapat daya. Jalankan sketch I2C scanner dan cek apakah alamat 0x68 muncul.
- Nilai tak masuk akal seperti tahun 2165, 165, atau 85: tidak ada data yang datang dari chip dan setiap byte yang terbaca bernilai 0xFF. Cek pengkabelannya; kalau kamu memberi daya DS1307 dari 3,3 V, pindah ke 5 V.
- Jam melompat kembali ke momen yang sama setelah setiap reset: baris rtc.adjust() masih ada di setup() tanpa kondisi; kaitkan baris itu dengan lostPower().
- Jam ter-reset setelah listrik padam: baterainya habis, terpasang terbalik, atau tidak ada. Ukur tegangannya, dan ingat bahwa rangkaian pengisian mungkin sudah merusak CR2032-nya.
- Jam melenceng beberapa menit per minggu: penyebabnya kristal DS1307 atau DS1302 dan perubahan suhu. Beralihlah ke DS3231 atau sinkronkan waktunya secara rutin dengan NTP.
- Waktunya selisih tepat satu jam atau lebih: pengaturan zona waktu atau waktu musim panasnya salah. Tulis waktu lokal ke RTC; kalau kamu memakai NTP, pilih aturan zona waktu yang tepat.
- DS3231 menunjukkan suhu lebih hangat daripada ruangan: nilai itu adalah suhu chip itu sendiri, akurat sampai ±3 °C dan terpengaruh oleh board yang memanas. Pakai sensor terpisah untuk suhu sekitar.
Singkatnya, DS3231 adalah pilihan tepat untuk hampir semua proyek yang butuh jam dan tanggal; DS1307 cukup untuk proyek 5 V yang sederhana dan DS1302 cocok untuk belajar. Di ESP32, pakai NTP kalau ada internet dan DS3231 kalau tidak ada; di Pico, mengatur RTC internal dari DS3231 ketika mulai adalah cara paling andal. Di aplikasi BlueGrays kamu akan menemukan proyek langkah demi langkah lengkap dengan skema rangkaian dan kode: menyiapkan modul jam RTC DS1302 dan jam dengan layar LCD, jam dan kalender dot matrix DS1307, jam digital ESP32 dengan RTC, waktu internet dengan NTP, dan pencatat suhu dengan stempel waktu.
Pertanyaan umum
Apakah modul RTC bisa bekerja tanpa baterai?
Selama VCC terhubung, jamnya berjalan dan bisa dibaca. Tetapi begitu daya hilang, jamnya berhenti atau ter-reset dan kamu harus mengaturnya lagi ketika board menyala berikutnya. Karena tujuan utama RTC adalah menjaga waktu selama listrik padam, kamu hampir selalu butuh baterai; kalau kamu memakai DS1307 tanpa baterai, pin VBAT-nya harus dihubungkan ke GND.
Mana yang lebih bagus, DS3231 atau DS1307?
DS3231 lebih bagus di hampir semua kasus. Berkat kristal bawaannya yang terkompensasi suhu, DS3231 hanya meleset sekitar satu menit per tahun, sedangkan DS1307 bisa melenceng hingga satu menit per bulan. DS3231 juga berjalan di 2,3–5,5 V, jadi langsung bekerja dengan ESP32 dan Pico, dan punya dua alarm serta sensor suhu. Dengan RTClib, kode untuk keduanya hampir sama persis.
Berapa lama baterai modul RTC bertahan?
Ketika modul hanya berjalan dari baterai, DS3231 menarik arus hingga sekitar 3 µA dan DS1307 sekitar 0,5 µA. Di atas kertas, CR2032 220 mAh bertahan lebih dari 8 tahun dengan arus sekecil ini. Dalam praktiknya, umur simpan baterai dan rangkaian pengisian di modul bisa memperpendeknya; di modul dengan pengisi aktif, CR2032 bisa mati jauh lebih cepat.
Kenapa modul RTC-ku terus me-reset waktunya?
Ada tiga penyebab umum: baris rtc.adjust() di setup() yang mengembalikan jam ke waktu kompilasi setiap kali board mulai, baterai yang habis atau terpasang terbalik, dan rangkaian pengisian yang sudah merusak CR2032. Pertama, kaitkan baris adjust() dengan lostPower(), lalu ukur tegangan baterai dengan multimeter dan ganti baterainya kalau di bawah 2,5 V.
Apakah aku butuh modul RTC untuk ESP32?
Tidak, kalau perangkatnya selalu online; ESP32 mendapatkan waktu yang benar lewat NTP dalam beberapa detik. Untuk proyek yang internetnya bisa terputus, yang waktunya harus sudah diketahui setelah listrik padam sebelum router menyala lagi, atau yang berjalan sepenuhnya offline, menambahkan DS3231 adalah pilihan paling aman. Yang terbaik, pakai keduanya dan sinkronkan DS3231 dengan NTP sekali sehari.
Bisakah aku memasang CR2032 di modul DS3231?
Bisa, tetapi pada modul dengan rangkaian pengisian seperti ZS-042, kamu perlu memutus jalur pengisiannya dulu. Kalau kamu melepas resistor 200 Ω (kode 201) atau dioda di sebelahnya, CR2032 akan berjalan aman selama bertahun-tahun. Kalau kamu tidak mau memodifikasi board-nya, pakai LIR2032 yang bisa diisi ulang sebagai gantinya.
Proyek untuk dibuat setelah membaca ini
Lihat semua proyek
Menyiapkan Modul Jam RTC DS1302
Kamu menjalankan modul jam kecil yang tidak pernah lupa waktu, bahkan ketika Arduino dimatikan. Modul ini punya baterai mungilnya sendiri, dan begitu jamnya diatur, tanggal dan waktu tercetak di layar

Jam RTC DS1302 dengan Layar LCD
Jam meja kecil yang tetap menjaga waktu meskipun listrik padam. Modul jam DS1302 menjaga waktu berkat baterai mungilnya sendiri; setiap detik Arduino membacanya lalu menulis waktu dan tanggal di baris

Jam Digital dengan ESP32 dan RTC DS1307 (I2C + LCD)
Di proyek ini, kita menampilkan waktu dan tanggal di layar LCD I2C 16x2 memakai modul jam real-time (RTC) DS1307. DS1307 adalah RTC berbaterai cadangan yang tetap menjaga waktu meskipun ESP32 dimatikan. Kedua modul berbagi bus I2C yang sama (SDA/SCL), sehingga kita belajar mengendalikan beberapa perangkat hanya dengan dua kabel sinyal. Lewat proyek ini kamu mendapat pengetahuan praktis tentang protokol komunikasi I2C, cara kerja modul RTC, dan tampilan data dinamis di LCD.

Jam dan Kalender Dot Matrix (MAX7219, DS1307)
Papan bercahaya untuk meja atau dinding yang menampilkan waktu dan tanggal dengan teks berjalan. Layar LED 8x32 menampilkan jam berangka besar dengan dua titik yang berkedip setiap detik; di awal seti

Jam, Kalender, dan Stasiun Cuaca Dot Matrix (MAX7219, DS1307)
Papan teks berjalan untuk meja atau dinding yang menampilkan waktu, tanggal, dan cuaca ruangan secara bergantian. Di layar LED 8x32, kamu pertama melihat suhu dalam Celsius dan Fahrenheit, lalu kelemb

Pencatat Data Suhu ESP32 (DHT22 + RTC DS1307 + microSD + OLED)
Buat pencatat suhu bercap waktu dengan ESP32! Baca suhu/kelembapan DHT22 setiap menit, ambil waktu sebenarnya dari RTC DS1307, dan catat ke kartu microSD sebagai CSV. OLED menampilkan suhu langsung (font besar), kelembapan, cap waktu, dan penghitung catatan. File /temp_log.csv bisa dibuka di Excel, Google Sheets, atau Python pandas; cocok untuk rumah kaca, suhu kamar, data laboratorium, penyimpanan makanan, atau sarang lebah.

Jam Real-Time dari Internet lewat NTP ESP32
ESP32 tersambung ke Wi-Fi dan mengambil waktu nyata dengan presisi milidetik dari server NTP (Network Time Protocol). Berkat fungsi configTzTime(), zona waktu Turki (TRT, UTC+3) otomatis diterapkan, dan pergantian DST di negara yang memakai waktu musim panas otomatis diatur dengan string POSIX TZ. Waktunya ditampilkan di Serial Monitor sekaligus di LCD I2C opsional. configTzTime() memulai layanan SNTP; sinkronisasi ulang berkala terjadi selama koneksi tersedia.

Jam Digital dengan Layar 7 Segmen 4 Digit
Jam digital empat digit yang menyala, mirip jam di oven dapur. Modul jam DS1302 menjaga waktu, dan setiap detik Arduino membaca jam dan menit lalu menampilkannya di layar empat digit, dengan titik kec
Artikel lainnya
Aplikasi BlueGrays
Rakit rangkaian ini langkah demi langkah di ponselmu
Skema pengkabelan, kode, dan daftar komponen dalam satu layar. 200+ proyek Arduino, ESP32, dan Pico siap dibuat.
Pindai dengan ponselmu
Arahkan kamera ke kode ini dan toko aplikasi di ponselmu akan terbuka.
atau buka toko aplikasi

