Componenti · 18 min di lettura

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.

Modulo orologio RTC DS1307
Modulo RTC DS1307: a sinistra i pin GND, 5V, SDA, SCL e SQW, al centro il chip DS1307 e a destra il portabatteria per la batteria a bottone CR1220.

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

CaratteristicaDS1307DS3231DS1302
InterfacciaI2C (100 kHz), indirizzo 0x68I2C (fino a 400 kHz), indirizzo 0x68Seriale a 3 fili: CE (RST), I/O (DAT), SCLK (CLK)
Tensione di alimentazione4,5–5,5 V2,3–5,5 V2,0–5,5 V
QuarzoEsterno da 32,768 kHz (12,5 pF)Integrato nel chip, compensato in temperatura (TCXO)Esterno da 32,768 kHz (6 pF)
PrecisioneDipende 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/annoDipende dal quarzo; simile al DS1307 o peggiore
Funzioni extra56 byte di RAM con batteria tampone, uscita onda quadra (SQW)2 allarmi, uscita INT/SQW, sensore di temperatura (±3 °C), regolazione dell'invecchiamento31 byte di RAM, caricatore integrato (trickle charger)
Corrente dalla batteriaCirca 300–500 nACirca 1–3 µAMeno di 300 nA a 2 V
Libreria ArduinoRTClib (Adafruit)RTClib (Adafruit)Rtc by Makuna
Ideale perOrologi semplici a 5 VQuasi ogni progetto; ideale anche per ESP32 e PicoKit 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.

Non provare ad alimentare un DS1307 a 3,3 V. Quando VCC scende sotto circa 1,25 volte la tensione della batteria (circa 3,75 V con una cella da 3 V), il chip pensa che sia mancata la corrente e smette di rispondere sull'I2C. Sulle schede a 3,3 V come ESP32 e Pico il DS3231 funziona direttamente. Per saperne di più su indirizzi I2C e resistenze pull-up, leggi Cos'è l'I2C?.

Collegamento del modulo RTC: Arduino Uno, ESP32 e Pico

Pin RTCArduino UnoESP32Raspberry Pi Pico
VCC5V3V3 (DS3231)3V3(OUT), pin fisico 36 (DS3231)
GNDGNDGNDGND
SDAA4GPIO 21GP4 (I2C0)
SCLA5GPIO 22GP5 (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.

Quando moduli come il DS1307 o la ZS-042 sono alimentati a 5 V, le resistenze pull-up sulla scheda portano a 5 V anche le linee SDA e SCL. I pin di ESP32 e Raspberry Pi Pico non tollerano i 5 V. Su queste schede alimenta sempre il modulo dal pin 3V3; se devi usare un chip che richiede 5 V, come il DS1307, metti in mezzo un convertitore di livello logico.

Installare RTClib e impostare l'ora

  1. 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.
  2. Collega il modulo come nella tabella sopra e inserisci la batteria nel portabatteria.
  3. 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.
  4. 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.
  5. Scollega il cavo USB, aspetta qualche minuto e ricollegalo. Se l'orologio riprende correttamente da dove si era fermato, la batteria tampone funziona.
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() 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.

FunzioneCosa 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.

L'errore più comune è lasciare la riga rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); senza condizioni dentro setup(). Così, ogni volta che Arduino si resetta o torna la corrente, l'orologio torna al momento in cui il codice è stato compilato. Imposta l'ora solo quando lostPower() restituisce true, oppure commenta la riga dopo averla impostata e ricarica il codice.

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.

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}

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.

Per mostrare l'ora abbastanza grande da leggerla da lontano, usa un display a 7 segmenti a 4 cifre o una matrice LED MAX7219. Far lampeggiare ogni secondo i due punti tra ore e minuti è un tocco classico che mostra che l'orologio sta funzionando.

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.

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}

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.

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}

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.

ChipCorrente dalla batteriaDurata 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 µALimitata dalla durata di conservazione della batteria
Modulo con caricatore attivo + CR2032Viene spinta corrente nella batteriaImprevedibile; la batteria può gonfiarsi e scaricarsi presto
Per fare il calcolo del tuo progetto, inserisci semplicemente la capacità della batteria e la corrente media nel calcolatore di durata della batteria. Lo stesso calcolo ti aiuta anche a capire quanti giorni durerà un Arduino a batteria con RTC.

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.
Guarda le lettere sulla batteria: CR indica una pila al litio non ricaricabile, LIR una batteria ricaricabile agli ioni di litio. Far lavorare una CR2032 per mesi a 5 V in un modulo con il circuito di ricarica attivo può farla gonfiare e perdere liquido. Togli subito una batteria gonfia e portala in un contenitore per la raccolta delle pile.

Usare il DS1302 (collegamento a 3 fili)

Modulo orologio RTC DS1302
Modulo RTC DS1302: a sinistra i pin VCC, GND, CLK, DAT e RST, al centro il chip DS1302 a 8 pin con il suo quarzo, a destra il portabatteria CR2032.

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.

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}

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.

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}

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?.

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)

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.
Quando qualcosa non va, esegui prima lo scanner I2C: se l'RTC non compare all'indirizzo 0x68, il problema è nei collegamenti, non nel codice. Per controllare la tensione della batteria e l'alimentazione del modulo ti sarà utile la guida Come usare il multimetro.

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.

Vedi tutti i progetti
Configurazione del modulo orologio RTC DS1302
#45Principiante
Premium

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

4.5(23)
31
DS1302 Orologio RTC con display LCD
#46Intermedio
Premium

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

4.7(41)
51
Orologio digitale con ESP32 e RTC DS1307 (I2C + LCD)
#120Intermedio
Premium

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.

4.6(26)
40
Orologio e calendario a matrice di punti (MAX7219, DS1307)
#84Intermedio
Premium

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

5.0(37)
58
Orologio a matrice di punti, calendario e stazione meteo (MAX7219, DS1307)
#85Intermedio
Premium

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

5.0(50)
66
Data Logger di Temperatura ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Avanzato
Premium

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

4.7(7)
12
ESP32: ora reale da Internet tramite NTP
#128Avanzato
Premium

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

4.5(13)
21
Orologio digitale con display a 7 segmenti a 4 cifre
#48Intermedio
Premium

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

4.8(56)
73