Modulo RTC Arduino: DS3231, DS1307 e DS1302, ora e allarmi
Modulo RTC Arduino: DS3231, DS1307 e DS1302, impostare l'ora con RTClib, orologio su LCD, irrigazione programmata, trappola di ricarica CR2032 e NTP su ESP32.
Un modulo RTC per Arduino è una piccola scheda orologio che continua a contare data e ora anche quando la tua scheda resta senza alimentazione. RTC sta per «Real Time Clock», cioè orologio in tempo reale. Il contatore millis() di Arduino riparte da zero a ogni accensione e può sbagliare di minuti nel giro di pochi giorni; un modulo RTC invece funziona al secondo per anni grazie alla sua batteria a bottone (CR2032). Lo trovi negli orologi da scrivania, nell'irrigazione automatica, nei distributori di crocchette, nei data logger con data e ora e nell'illuminazione temporizzata.
In questa guida confronterai i tre chip più diffusi, il DS1307, il DS3231 e il DS1302, e vedrai quale scegliere e perché. Poi, passo dopo passo, imposteremo e leggeremo l'ora con la libreria RTClib, mostreremo ora e data su un LCD I2C, costruiremo un timer che accende una pompa a orari fissi ogni giorno e useremo l'allarme hardware del DS3231. Le ultime sezioni spiegano la trappola del circuito di ricarica della CR2032 che rovina molti moduli, come ottenere l'ora da internet con NTP sull'ESP32 e l'RTC integrato del Raspberry Pi Pico.

Cos'è un modulo RTC e come funziona?
Nel cuore di un chip RTC c'è un quarzo da orologio a 32,768 kHz. Questo numero non è casuale: 32.768 è 2 elevato alla 15, quindi il chip divide questa frequenza per due 15 volte e ottiene un battito esatto di 1 secondo. A ogni battito vengono aggiornati i registri di secondi, minuti, ore, giorno, mese e anno; la durata dei mesi e gli anni bisestili sono gestiti automaticamente fino al 2100. Arduino legge questi registri tramite I2C oppure ci scrive un nuovo orario. I valori sono salvati in formato BCD (per esempio 59 secondi viene memorizzato come 0x59); le librerie fanno questa conversione al posto tuo.
Il vero punto di forza di un RTC sono i suoi due ingressi di alimentazione. Quando VCC viene a mancare, il chip passa automaticamente all'ingresso della batteria (VBAT) e assorbe solo la corrente necessaria per continuare a contare: meno di un microampere o pochi microampere. Nel frattempo il DS1307 disattiva la comunicazione I2C, mentre il DS3231 resta leggibile anche a batteria; in entrambi i casi l'orologio non si ferma. Quando torna la corrente, Arduino si avvia, legge l'ora corretta dall'RTC e riprende da dove era rimasto. A causa della tolleranza del risuonatore ceramico dell'Arduino Uno, un orologio tenuto con millis() può sbagliare di minuti al giorno e si perde a ogni reset; per questo ogni progetto che dipende dall'ora ha bisogno di un RTC separato.
Differenze tra DS1307, DS3231 e DS1302
| Caratteristica | DS1307 | DS3231 | DS1302 |
|---|---|---|---|
| Interfaccia | I2C (100 kHz), indirizzo 0x68 | I2C (fino a 400 kHz), indirizzo 0x68 | Seriale a 3 fili: CE (RST), I/O (DAT), SCLK (CLK) |
| Tensione di alimentazione | 4,5–5,5 V | 2,3–5,5 V | 2,0–5,5 V |
| Quarzo | Esterno da 32,768 kHz (12,5 pF) | Integrato nel chip, compensato in temperatura (TCXO) | Esterno da 32,768 kHz (6 pF) |
| Precisione | Dipende dal quarzo; con ±20 ppm circa 1,7 s/giorno, circa 1 min/mese | ±2 ppm (0–40 °C): circa 5 s/mese, circa 1 min/anno | Dipende dal quarzo; simile al DS1307 o peggiore |
| Funzioni extra | 56 byte di RAM con batteria tampone, uscita onda quadra (SQW) | 2 allarmi, uscita INT/SQW, sensore di temperatura (±3 °C), regolazione dell'invecchiamento | 31 byte di RAM, caricatore integrato (trickle charger) |
| Corrente dalla batteria | Circa 300–500 nA | Circa 1–3 µA | Meno di 300 nA a 2 V |
| Libreria Arduino | RTClib (Adafruit) | RTClib (Adafruit) | Rtc by Makuna |
| Ideale per | Orologi semplici a 5 V | Quasi ogni progetto; ideale anche per ESP32 e Pico | Kit datati e progetti didattici |
Rendiamo concreta la differenza di precisione: 1 ppm significa una parte per milione, e un giorno ha 86.400 secondi. Un quarzo comune da ±20 ppm può sbagliare fino a 1,7 secondi al giorno, circa 52 secondi al mese, e più ci si allontana dalla temperatura ambiente, più cambia la frequenza del quarzo e più cresce l'errore. Il DS3231 invece porta il quarzo dentro il chip, misura la temperatura ogni 64 secondi e corregge la frequenza di conseguenza. Così ottiene ±2 ppm tra 0 e 40 °C, circa un minuto all'anno, e resta entro ±3,5 ppm anche da -40 a +85 °C.
Quale modulo RTC scegliere?
- Nuovo progetto, ESP32 o Pico: prendi un DS3231. Funziona sia a 3,3 V sia a 5 V, ha gli allarmi e dà l'ora più precisa. La differenza di prezzo è minima.
- Hai già un DS1307 e usi un Arduino Uno: usalo tranquillamente; considera solo uno scarto di circa un minuto al mese e rimetti l'ora ogni tanto.
- Nel tuo starter kit c'era un DS1302: va bene per imparare come funziona un RTC, ma non aspettarti un orologio che resti preciso per mesi.
- ESP32 sempre connesso a internet: parti con NTP senza modulo; aggiungi un DS3231 se dopo un blackout l'ora deve essere nota prima che torni internet.
Le schede pronte che incontrerai più spesso sono due: la ZS-042 con chip DS3231 e la Tiny RTC con DS1307. Entrambe montano anche una EEPROM AT24C32 da 4 KB per salvare dati. Per questo è normale che uno scanner I2C trovi un secondo indirizzo accanto a 0x68 (di solito 0x57 sulla ZS-042 e 0x50 sulla Tiny RTC); quell'indirizzo appartiene alla EEPROM, non all'orologio. Il DS1302 invece non usa l'I2C: comunica con un suo protocollo a 3 fili e occupa tre pin digitali.
Collegamento del modulo RTC: Arduino Uno, ESP32 e Pico
| Pin RTC | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| VCC | 5V | 3V3 (DS3231) | 3V3(OUT), pin fisico 36 (DS3231) |
| GND | GND | GND | GND |
| SDA | A4 | GPIO 21 | GP4 (I2C0) |
| SCL | A5 | GPIO 22 | GP5 (I2C0) |
| SQW / INT (facoltativo) | D2 (pin di interrupt) | Qualsiasi GPIO (es. GPIO 4) | Qualsiasi pin GP (es. GP15) |
Sull'Uno R3 i connettori SDA e SCL accanto al pin AREF sono collegati anch'essi ad A4 e A5, quindi non importa quali usi. L'RTC può condividere gli stessi due fili con un LCD I2C o un display OLED; ogni dispositivo ha il proprio indirizzo, perciò non ci sono conflitti. Tenere i cavi sotto i 20–30 cm evita errori di lettura casuali, soprattutto sulla breadboard. Il pin SQW/INT va collegato solo se intendi usare l'allarme hardware.
Installare RTClib e impostare l'ora
- Apri il Gestore librerie dell'IDE di Arduino, scrivi RTClib e installa la libreria di Adafruit. Quando ti chiede delle dipendenze, scegli Install all così viene installata anche Adafruit BusIO. Se non hai mai aggiunto una libreria, Come aggiungere una libreria Arduino ti guida passo dopo passo.
- Collega il modulo come nella tabella sopra e inserisci la batteria nel portabatteria.
- Carica il codice qui sotto. Al primo avvio il modulo non conosce l'ora, quindi il codice scrive nell'RTC l'ora di compilazione del tuo computer.
- Apri il Monitor seriale a 9600 baud con il fine riga «A capo (NL)». Per regolare l'ora al secondo, scrivila nel formato 2026-11-03 14:30:00 e premi Invio.
- Scollega il cavo USB, aspetta qualche minuto e ricollegalo. Se l'orologio riprende correttamente da dove si era fermato, la batteria tampone funziona.
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() restituisce false se il modulo non viene trovato sul bus I2C; in quel caso controlla prima i collegamenti. rtc.lostPower() legge il flag di oscillatore fermo (OSF) del DS3231: restituisce true se il modulo funziona per la prima volta o se l'orologio si è fermato perché la batteria era scarica, e allora il codice imposta l'orologio all'ora di compilazione. DateTime(F(__DATE__), F(__TIME__)) usa il momento in cui il compilatore ha generato il tuo codice; dato che il caricamento richiede qualche secondo, l'orologio resta leggermente indietro, per questo è comodo rifinirlo dal Monitor seriale. toString() sostituisce le lettere del modello «DD.MM.YYYY hh:mm:ss» con i valori reali.
| Funzione | Cosa fa |
|---|---|
| rtc.begin() | Avvia il modulo; restituisce false se non lo trova |
| rtc.adjust(DateTime(...)) | Scrive ora e data |
| rtc.now() | Legge l'ora attuale come oggetto DateTime |
| now.year(), now.month(), now.day() | Anno, mese, giorno |
| now.hour(), now.minute(), now.second() | Ora (0–23), minuto, secondo |
| now.dayOfTheWeek() | Giorno della settimana: 0 = domenica, 6 = sabato |
| now.unixtime() | Secondi trascorsi dal 1° gennaio 1970; ideale per confrontare due istanti |
| now + TimeSpan(0, 1, 30, 0) | Aggiunge 1 ora e 30 minuti (giorni, ore, minuti, secondi) |
| rtc.lostPower() / rtc.isrunning() | Indica se l'ora è valida (DS3231 / DS1307) |
| rtc.getTemperature() | Temperatura del chip in °C (solo DS3231) |
Se usi un DS1307, cambia solo il nome dell'oggetto: scrivi RTC_DS1307 rtc;, controlla !rtc.isrunning() al posto di lostPower() e cancella la riga di getTemperature(). Alla primissima accensione il DS1307 parte con l'oscillatore fermo (bit CH a 1); adjust() azzera questo bit e avvia l'orologio. Nei 56 byte di RAM con batteria tampone del DS1307 puoi salvare piccole impostazioni, come l'ora di una sveglia, con rtc.writenvram() e rtc.readnvram(); grazie alla batteria, anche questi dati sopravvivono ai blackout.
Mostrare ora e data su un LCD
Vedere l'ora su un display invece che nel Monitor seriale trasforma il progetto in un vero orologio da scrivania. Un LCD I2C 16x2 e l'RTC si collegano allo stesso bus SDA-SCL: l'LCD di solito ha l'indirizzo 0x27 o 0x3F, l'RTC 0x68. Il codice qui sotto scrive sulla riga superiore la data e l'abbreviazione del giorno, e su quella inferiore l'ora e la temperatura misurata dal DS3231. Per il collegamento dell'LCD e l'installazione della libreria, dai un'occhiata a Come usare un display 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}Il %02d dentro snprintf aggiunge uno zero davanti ai numeri a una cifra, così l'ora appare come 09:05:03 invece di 9:5:3 e la lunghezza della riga non cambia mai. Grazie alla lunghezza fissa non serve lcd.clear(); cancellare il display a ogni ciclo provoca sfarfallio. Il codice scrive sul display solo quando cambia il secondo, così non occupa il bus I2C inutilmente. L'array days contiene abbreviazioni in turco; sostituiscile con Dom, Lun, Mar e così via, lasciando la domenica come primo elemento.
Allarmi e attività programmate: irrigazione automatica e distributore di crocchette
La cosa più utile di un RTC è far eseguire le attività all'orario giusto: annaffiare le piante ogni mattina alle 08:00, dare le crocchette al gatto alle 19:30 o spegnere la luce dell'acquario di notte. Ci sono due modi per farlo. Il primo è un confronto via software: leggi l'ora in loop() e controlli se è arrivato il momento di un'attività. È semplice e puoi aggiungere tutte le attività che vuoi. Il secondo è l'allarme hardware del DS3231: all'istante impostato il chip porta il pin INT a LOW e avvisa Arduino con un interrupt; può persino risvegliare un microcontrollore in sleep.
Un errore frequente nel confronto via software è cercare un secondo esatto, come now.second() == 0. Se in loop() c'è un delay() lungo, quel secondo può sfuggire e l'attività non parte mai. Il codice qui sotto confronta ora e minuto, memorizza una chiave composta da giorno e minuto perché l'attività non parta due volte nello stesso minuto e cronometra la pompa con millis(). La pompa è comandata tramite un modulo relè; trovi il collegamento della pompa nell'articolo sulla mini pompa d'acqua.
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}Includere il giorno nella chiave è importante: se memorizzassi solo il minuto e avessi un'unica attività, il giorno dopo a quel minuto la chiave sarebbe ancora la stessa e l'attività non partirebbe più. Per costruire un distributore di crocchette usa un servomotore al posto del relè: ruotarlo a 90 gradi al momento dell'attività e riportarlo indietro un secondo dopo apre lo sportello del serbatoio e fa cadere una porzione. Per un'irrigazione più intelligente, leggi un sensore di umidità del terreno in quel momento e non accendere la pompa se la terra è già umida. Il secondo esempio qui sotto fa la stessa cosa con l'allarme hardware del 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}Il DS3231 ha due allarmi. L'allarme 1 ha una risoluzione di un secondo; la modalità DS3231_A1_Hour scatta quando ore, minuti e secondi coincidono, cioè ogni giorno alla stessa ora. Con le altre modalità puoi impostare un allarme ogni secondo (PerSecond), ogni minuto (Second), ogni ora (Minute), in un giorno preciso del mese (Date) o in un giorno preciso della settimana (Day). L'allarme 2 ha una risoluzione di un minuto. Il pin SQW/INT è un'uscita open-drain attiva bassa: va a LOW quando scatta l'allarme e resta così finché non chiami clearAlarm(). Per questo conviene limitarsi ad alzare un flag nella funzione di interrupt e svolgere il lavoro vero in loop(). Per capire come funzionano gli interrupt, leggi Gli interrupt di Arduino.
Quanto dura la batteria di un RTC?
Stimare la durata della batteria è facile: durata (ore) = capacità della batteria (mAh) ÷ corrente assorbita (mA). Una CR2032 ha circa 220 mAh. In modalità batteria il DS3231 assorbe nel caso peggiore circa 3 µA, cioè 0,003 mA: 220 ÷ 0,003 ≈ 73.000 ore, circa 8 anni. La batteria viene usata solo quando manca VCC; se il modulo si trova in un apparecchio sempre alimentato, si consuma pochissimo e dura molto di più. In pratica il limite lo fissano quasi sempre la durata di conservazione della batteria stessa e il circuito di ricarica del modulo.
| Chip | Corrente dalla batteria | Durata calcolata con una CR2032 (220 mAh) |
|---|---|---|
| DS1307 | ~0,5 µA | ~50 anni; in pratica limitata dalla durata di conservazione della batteria (circa 10 anni) |
| DS3231 | ~3 µA (caso peggiore) | ~8 anni |
| DS1302 | ~0,3 µA | Limitata dalla durata di conservazione della batteria |
| Modulo con caricatore attivo + CR2032 | Viene spinta corrente nella batteria | Imprevedibile; la batteria può gonfiarsi e scaricarsi presto |
La trappola della batteria CR2032 e del circuito di ricarica
La maggior parte dei moduli economici con DS3231 (ZS-042) e DS1307 (Tiny RTC) include un semplice circuito di ricarica pensato in realtà per una batteria ricaricabile LIR2032. Sulla ZS-042 la corrente va da VCC alla batteria attraverso un diodo 1N4148 e una resistenza da 200 Ω; la Tiny RTC ha un circuito simile. Il problema è che questi moduli vengono spesso venduti con una CR2032 non ricaricabile. Quando il modulo è alimentato a 5 V, i circa 4,3 V che restano dopo il diodo spingono continuamente corrente nella cella al litio da 3 V. Una batteria che non dovrebbe mai essere ricaricata può gonfiarsi, perdere liquido e scaricarsi in anticipo, e ti ritrovi con il problema «la batteria c'è, ma l'orologio si azzera sempre».
- Se usi una CR2032, interrompi il percorso di ricarica: sulla ZS-042 dissalda la resistenza SMD da 200 Ω con la sigla «201» vicino al connettore dei pin, oppure il diodo accanto. Per le resistenze di cui non riesci a leggere il codice, usa il decodificatore di codici SMD. È la soluzione più diffusa e più sicura.
- Se lasci il circuito così com'è, monta una LIR2032: la capacità della batteria ricaricabile (circa 40 mAh) è circa un quinto di quella di una CR2032 (circa 220 mAh), ma resta carica finché il modulo è alimentato.
- Se alimenti il modulo a 3,3 V: dopo il diodo alla batteria arrivano solo circa 2,6 V; una LIR2032 non si carica mai del tutto e in una CR2032 non passa quasi corrente. Togliere la resistenza resta comunque la soluzione più pulita.
- Il caricatore integrato del DS1302 è disattivato all'accensione; se usi una CR2032, non attivarlo dal codice.
- Misura la batteria: una CR2032 nuova segna 3,0–3,2 V; sostituiscila quando scende sotto i 2,5 V.
Usare il DS1302 (collegamento a 3 fili)

Il modulo DS1302 ha cinque pin: VCC, GND, CLK, DAT e RST. Dato che non usa l'I2C, non va collegato ad A4-A5 ma a tre pin digitali qualsiasi; nell'esempio qui sotto DAT va a D4, CLK a D5 e RST a D2, e il modulo è alimentato a 5V. La RTClib di Adafruit non supporta il DS1302, quindi installa la libreria Rtc by Makuna dal Gestore librerie. Il DS1302 ha due bit di protezione: con la protezione da scrittura attiva l'ora non si può impostare, e con il bit di arresto dell'orologio attivo l'orologio non avanza. Il codice controlla entrambi e imposta l'orologio all'ora di compilazione se l'ora salvata non è valida.
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}La lamentela più comune sui moduli DS1302 è che l'orologio sbaglia di minuti a settimana. Un motivo è che il chip richiede un quarzo tarato per una capacità di carico di 6 pF, mentre i moduli economici possono usare quarzi con un valore diverso. Anche cavi lunghi e allentati causano errori di lettura sulla linea seriale del DS1302. Se hai un DS1302, è un ottimo punto di partenza per capire come funziona un RTC; ma se stai costruendo un orologio che deve restare preciso per mesi, passa al DS3231.
NTP al posto dell'RTC sull'ESP32: l'ora da internet
Dato che l'ESP32 può collegarsi al Wi-Fi, spesso non ha bisogno di alcun modulo RTC: con NTP (Network Time Protocol) ottiene in pochi secondi l'ora esatta da server dell'ora come pool.ntp.org. Il core Arduino per ESP32 offre già le funzioni configTzTime() e getLocalTime(), e il fuso orario si indica con una stringa di regole. La Turchia resta su UTC+3 senza ora legale dal 2016, quindi la regola nel codice è uno scarto fisso di +3 ore. In Italia e nelle altre zone con l'ora legale usa la regola dell'Europa centrale indicata nel commento del codice; calcola da sola i giorni del cambio d'ora.
Il punto debole di NTP è la dipendenza da internet: dopo un blackout, finché il router non si riavvia, o se cambia la password del Wi-Fi, l'ESP32 non può conoscere l'ora. Il timer RTC interno dell'ESP32 mantiene l'ora durante il deep sleep, ma si azzera quando l'alimentazione manca del tutto. La soluzione più robusta combina le due cose: all'avvio, se l'ESP32 raggiunge il server NTP sincronizza il DS3231 con l'ora di internet; altrimenti legge l'ora dal DS3231, e poi si risincronizza una volta al giorno. Per maggiori dettagli su NTP, leggi L'ora NTP con l'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}L'RTC integrato del Raspberry Pi Pico
Il chip RP2040 del Raspberry Pi Pico contiene un blocco RTC, mentre l'RP2350 del Pico 2 svolge la stessa funzione con un timer sempre attivo (AON timer). In MicroPython entrambi si usano con la stessa classe machine.RTC: RTC().datetime() legge o scrive l'ora come (anno, mese, giorno, giorno della settimana, ore, minuti, secondi, sottosecondi), e anche time.localtime() usa questo orologio. Però questo orologio non ha batteria: quando il Pico resta senza alimentazione, MicroPython fa ripartire l'orologio dal 1° gennaio 2021 alle 00:00.
Qui c'è una trappola che sorprende i principianti: per impostazione predefinita Thonny sincronizza l'orologio del Pico con quello del tuo computer quando si collega. Durante i test quindi sembra tutto giusto, ma appena colleghi il Pico a un caricabatterie da telefono o a una batteria, l'orologio torna al 2021. La soluzione è collegare un DS3231 al Pico e impostare l'RTC interno partendo da lui all'avvio. Il codice qui sotto non richiede alcun file driver; legge i primi sette registri del DS3231 via I2C e li converte da BCD a decimale. Con un Pico W puoi anche prendere l'ora da internet con ntptime.settime(); dato che restituisce l'ora UTC, devi aggiungere tu lo scarto del tuo fuso orario (in Italia +1 ora d'inverno e +2 ore d'estate). Se sei alle prime armi con il Pico, parti da Cos'è il 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)Idee di progetto con un modulo RTC
- Orologio digitale da scrivania con calendario: mostra ora, data e la temperatura misurata dal DS3231 su un LCD, un OLED o una matrice LED.
- Irrigazione automatica delle piante: controlla l'umidità del terreno ogni mattina e, se serve, accendi la pompa per un tempo stabilito.
- Distributore di crocchette: apri lo sportello del serbatoio con un servo due o tre volte al giorno e fai cadere una porzione.
- Data logger con data e ora: salva le misure di temperatura e umidità insieme a data e ora su un modulo scheda SD, poi disegna il grafico in Excel.
- Campanella per scuola o laboratorio: fai suonare un buzzer o una campanella tramite relè all'inizio e alla fine di ogni lezione, e salta i fine settimana con dayOfTheWeek().
- Timer per acquario e luce di coltivazione: accendi la luce al mattino e spegnila la sera, variando lentamente la luminosità in PWM per un effetto alba e tramonto.
Errori comuni e soluzioni
- «RTC non trovato», begin() restituisce false: SDA e SCL sono invertiti, il GND non è in comune o il modulo non è alimentato. Esegui uno scanner I2C e verifica se compare l'indirizzo 0x68.
- Valori assurdi come l'anno 2165, 165 o 85: dal chip non arrivano dati e tutti i byte letti valgono 0xFF. Controlla i collegamenti; se alimenti un DS1307 a 3,3 V, passa a 5 V.
- A ogni reset l'orologio torna allo stesso istante: la riga rtc.adjust() è rimasta senza condizioni in setup(); legala a lostPower().
- Dopo un blackout l'ora si azzera: la batteria è scarica, inserita al contrario o assente. Misurane la tensione e ricorda che il circuito di ricarica potrebbe aver rovinato la CR2032.
- L'orologio sbaglia di minuti a settimana: la causa sono il quarzo del DS1307 o del DS1302 e le variazioni di temperatura. Passa a un DS3231 oppure sincronizza l'ora regolarmente con NTP.
- L'ora è sbagliata esattamente di una o più ore: il fuso orario o l'ora legale sono impostati male. Scrivi l'ora locale nell'RTC; se usi NTP, scegli la regola di fuso orario corretta.
- Il DS3231 segna una temperatura più alta di quella della stanza: quel valore è la temperatura del chip stesso, precisa a ±3 °C e influenzata dal riscaldamento della scheda. Per la temperatura ambiente usa un sensore separato.
In breve, il DS3231 è la scelta giusta per quasi ogni progetto che ha bisogno di data e ora; il DS1307 va bene nei progetti semplici a 5 V e il DS1302 serve per imparare. Sull'ESP32 usa NTP quando c'è internet e un DS3231 quando manca; sul Pico, impostare l'RTC interno da un DS3231 all'avvio è il metodo più affidabile. Nell'app BlueGrays trovi progetti passo dopo passo con schemi e codice: configurazione di un orologio DS1302 e orologio su LCD, orologio e calendario a matrice di punti con DS1307, orologio digitale con RTC su ESP32, ora da internet con NTP e un data logger di temperatura con data e ora.
Domande frequenti
Un modulo RTC funziona senza batteria?
Finché VCC è collegato, l'orologio funziona e si può leggere. Ma appena manca la corrente, l'orologio si ferma o si azzera e devi reimpostarlo all'avvio successivo. Dato che lo scopo di un RTC è proprio mantenere l'ora durante i blackout, la batteria serve quasi sempre; se usi un DS1307 senza batteria, il suo pin VBAT va collegato a GND.
Meglio il DS3231 o il DS1307?
Il DS3231, quasi sempre. Grazie al quarzo integrato e compensato in temperatura sbaglia solo di circa un minuto all'anno, mentre un DS1307 può sbagliare fino a un minuto al mese. Il DS3231 funziona inoltre da 2,3 a 5,5 V, quindi va direttamente con ESP32 e Pico, e ha due allarmi e un sensore di temperatura. Con RTClib il codice per i due è quasi identico.
Quanto dura la batteria di un modulo RTC?
Quando il modulo funziona solo a batteria, un DS3231 assorbe al massimo circa 3 µA e un DS1307 circa 0,5 µA. Sulla carta una CR2032 da 220 mAh dura più di 8 anni con queste correnti. In pratica la durata di conservazione della batteria e il circuito di ricarica del modulo possono accorciare questo tempo; in un modulo con il caricatore attivo una CR2032 può scaricarsi molto prima.
Perché il mio modulo RTC azzera l'ora?
Le cause più comuni sono tre: la riga rtc.adjust() in setup() che a ogni avvio riporta l'ora a quella di compilazione, una batteria scarica o inserita al contrario e un circuito di ricarica che ha rovinato la CR2032. Prima lega la riga adjust() a lostPower(), poi misura la tensione della batteria con il multimetro e sostituiscila se è sotto i 2,5 V.
Serve un modulo RTC con l'ESP32?
No, se il dispositivo è sempre online; l'ESP32 ottiene l'ora esatta via NTP in pochi secondi. Nei progetti in cui internet può cadere, in cui l'ora deve essere nota dopo un blackout prima che riparta il router o che funzionano del tutto offline, aggiungere un DS3231 è la scelta più sicura. L'ideale è usarli entrambi e sincronizzare il DS3231 con NTP una volta al giorno.
Si può mettere una CR2032 in un modulo DS3231?
Sì, ma sui moduli con circuito di ricarica, come la ZS-042, devi prima interrompere il percorso di ricarica. Se dissaldi la resistenza da 200 Ω (sigla 201) o il diodo accanto, una CR2032 funzionerà in sicurezza per anni. Se non vuoi modificare la scheda, usa invece una batteria ricaricabile LIR2032.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Configurazione del modulo orologio RTC DS1302
Metti in funzione un piccolo modulo orologio che non dimentica l'ora nemmeno quando l'Arduino è spento. Il modulo ha una sua minuscola batteria e, una volta regolata l'ora, data e ora compaiono ogni s

DS1302 Orologio RTC con display LCD
Un piccolo orologio da scrivania che non dimentica l'ora nemmeno se manca la corrente. Il modulo orologio DS1302 tiene il tempo grazie alla sua piccola batteria; ogni secondo l'Arduino lo legge e scri

Orologio digitale con ESP32 e RTC DS1307 (I2C + LCD)
In questo progetto, utilizziamo il modulo orologio in tempo reale (RTC) DS1307 per visualizzare l'ora e la data su un display LCD 16x2 I2C. Il DS1307 è un RTC con batteria di supporto che mantiene l'ora anche se l'ESP32 si spegne. Entrambi i moduli condividono la stessa linea I2C (SDA/SCL), permettendoci di imparare a controllare più dispositivi utilizzando solo due cavi di segnale. Cosi imparerai il protocollo I2C e il funzionamento dei moduli RTC nella pratica.

Orologio e calendario a matrice di punti (MAX7219, DS1307)
Un pannello luminoso per la scrivania o la parete che mostra ora e data con scritte scorrevoli. Sul display LED 8x32 c'è un orologio a cifre grandi con i due punti che lampeggiano ogni secondo; all'in

Orologio a matrice di punti, calendario e stazione meteo (MAX7219, DS1307)
Un pannello a scritte scorrevoli per la scrivania o la parete che mostra a turno l'ora, la data e il clima della stanza. Sul display LED 8x32 compaiono prima la temperatura in Celsius e Fahrenheit, po

Data Logger di Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
Costruisci un data logger di temperatura con timestamp usando ESP32! Leggi temperatura/umidità dal DHT22 ogni minuto, ottieni l'ora reale dal DS1307 RTC e registra su scheda microSD in formato CSV. L'OLED mostra dal vivo temperatura (font grande), percentuale di umidità, timestamp e contatore di log. Il file `/temp_log.csv` sulla scheda SD si apre in Excel, Google Sheets o Python pandas per l'analisi — perfetto per il monitoraggio di serre, tracciamento della temperatura domestica, raccolta

ESP32: ora reale da Internet tramite NTP
L'ESP32 si connette al Wi-Fi e recupera l'ora reale con precisione al millisecondo dai server NTP (Network Time Protocol). Grazie a `configTzTime()`, il fuso orario della Turchia (TRT, UTC+3) viene applicato automaticamente e il passaggio all'ora legale è gestito tramite la stringa POSIX TZ. L'ora viene mostrata sul Serial Monitor e su un display LCD I2C opzionale. `configTzTime()` avvia il servizio SNTP; vengono eseguite risincronizzazioni periodiche finché è disponibile l'accesso alla rete, e

Orologio digitale con display a 7 segmenti a 4 cifre
Un orologio digitale luminoso a quattro cifre, simile a quello del forno in cucina. Il modulo orologio DS1302 tiene l'ora, e ogni secondo l'Arduino legge ore e minuti e li mostra sul display a quattro
Altri articoli
App BlueGrays
Costruisci questo circuito passo passo sul telefono
Schema, codice ed elenco componenti in un’unica schermata. Oltre 160 progetti Arduino, ESP32 e Pico da realizzare.
Inquadra con il telefono
Punta la fotocamera sul codice: si apre lo store del tuo telefono.
oppure apri lo store

