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:
-
Generatore di onda quadra programmabile (1 Hz, 4.096 kHz, 8.192 kHz, 32.768 kHz).
-
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:
-
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.
-
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();
} |
|