RTC-DS3231

 

 

 

Vedi tutorial qui

 

Indirizzi I2C:

 

Cip DS3231 - 0x68 (su RTC)

Cip AT24C32 - 0x50 (su RTC)

 

Orologio per Arduino

 

Collegamenti:

Pin abilitati agli interrupt hardware sull'Arduino Nano:

 

Pin digitale Interrupt n.
D2 0
D3 1

 

Questi due pin sono gli unici che possono essere usati con la funzione attachInterrupt() per gli interrupt hardware.

💡 Esempio di utilizzo:

attachInterrupt(digitalPinToInterrupt(2), funzioneInterrupt, FALLING);

 

Oppure con D3:

 

attachInterrupt(digitalPinToInterrupt(3), funzioneInterrupt, FALLING);

 

Cosa significa "SQW"?

Il pin SQW (Square Wave Output) del DS3231 ha due funzioni:

  1. Generatore di onda quadra programmabile (1 Hz, 4.096 kHz, 8.192 kHz, 32.768 kHz).

  2. Uscita di interrupt per gli allarmi (ALARM 1 o ALARM 2).

⚠️ Quando configuri un allarme, il DS3231 disattiva automaticamente l'onda quadra e usa il pin SQW come segnale di interrupt, portandolo a LOW quando l'allarme scatta.

🔌 Come usarlo per l’interrupt allarme:

  • Collega il pin SQW del DS3231 al pin D2 o D3 dell'Arduino Nano.

  • Imposta l’allarme nella libreria.

  • Abilita attachInterrupt() con FALLING, perché il segnale va da HIGH a LOW quando l’allarme scatta.

  • Nella tua routine ISR (Interrupt Service Routine), cancella l’allarme o disabilita l'interrupt se necessario.

📌 Riassunto collegamenti consigliati:

DS3231 Pin Arduino Nano Note
VCC 5V Alimentazione
GND GND Massa
SDA A4 I2C dati
SCL A5 I2C clock
SQW D2 Interrupt (per allarmi)

 

📘 Sintassi di attachInterrupt()

 

attachInterrupt(digitalPinToInterrupt(pin), funzione, modalità);

 

Argomento Significato
pin Numero del pin digitale abilitato agli interrupt (es. 2 o 3)
funzione Nome della funzione da eseguire quando scatta l’interrupt (deve essere molto veloce)
modalità Tipo di variazione del segnale che fa scattare l’interrupt

 

📊 Modalità disponibili:

Modalità Descrizione
LOW L'interrupt scatta finché il pin rimane LOW
CHANGE L'interrupt scatta a ogni cambiamento (da HIGH a LOW o da LOW a HIGH)
RISING L'interrupt scatta quando il segnale passa da LOW a HIGH
FALLING L'interrupt scatta quando il segnale passa da HIGH a LOW
HIGH ⚠️ Non disponibile su tutti i microcontrollori

 

🕒 Per il DS3231: quale modalità usare?

Quando il modulo DS3231 fa scattare un allarme, il pin SQW passa da HIGH a LOW. Quindi:

 
      

attachInterrupt(digitalPinToInterrupt(2), funzioneAllarme, FALLING);

 

Questa è la modalità corretta, perché l’interrupt scatta appena il pin passa a LOW, che è il comportamento dell’allarme del DS3231.

 

Il pin SQW (Square Wave/Alarm Output) dell’RTC (es. DS3231) non distingue tra allarme 1 e allarme 2 a livello di segnale elettrico: manda semplicemente un impulso LOW sul pin SQW quando uno qualsiasi dei due allarmi scatta.

🔧 Quindi come fa Arduino a capire quale allarme è scattato?

Risposta: Lo capisce interrogando il registro di stato dell'RTC tramite I2C.
Ecco il meccanismo completo:


🧠 Funzionamento:

  1. Scatta un allarme (Alarm 1 o Alarm 2)
    Il modulo RTC mette LOW il pin SQW/INT, che è collegato a D2 di Arduino → si scatena l’interrupt.

  2. Nel codice dell’interrupt (o subito dopo), Arduino deve:

    • Leggere il registro di stato 0x0F del DS3231 (RTC).

    • Controllare quale dei due flag A1F o A2F è impostato a 1.

    • Fare l’azione corrispondente (es. apertura o chiusura tenda).

    • Infine azzerare quel flag, scrivendo 0 per evitare futuri falsi positivi.


🧾 Registro di stato 0x0F (DS3231):

Bit Nome Significato
7 OSF Oscillator Stop Flag
1 A2F Alarm 2 Flag (1 = scattato)
0 A1F Alarm 1 Flag (1 = scattato)

✅ Codice di esempio per leggere quale allarme è scattato

#include <Wire.h>
#define DS3231_ADDRESS 0x68
#define STATUS_REG 0x0F

void verificaAllarme() {
  Wire.beginTransmission(DS3231_ADDRESS);
  Wire.write(STATUS_REG);
  Wire.endTransmission();
  
  Wire.requestFrom(DS3231_ADDRESS, 1);
  byte status = Wire.read();

  if (status & 0b00000001) {
    Serial.println("Allarme 1 scattato (es. apertura tenda)");
    // Azioni per Allarme 1
    resetAllarme(1);
  }

  if (status & 0b00000010) {
    Serial.println("Allarme 2 scattato (es. chiusura tenda)");
    // Azioni per Allarme 2
    resetAllarme(2);
  }
}

void resetAllarme(int num) {
  Wire.beginTransmission(DS3231_ADDRESS);
  Wire.write(STATUS_REG);
  Wire.endTransmission();

  Wire.requestFrom(DS3231_ADDRESS, 1);
  byte status = Wire.read();

  if (num == 1) status &= ~0b00000001;  // reset A1F
  if (num == 2) status &= ~0b00000010;  // reset A2F

  Wire.beginTransmission(DS3231_ADDRESS);
  Wire.write(STATUS_REG);
  Wire.write(status);
  Wire.endTransmission();
}

 

CopiQui