Zegar RTC DS3231 Arduino
Moduł DS3231 to precyzyjny RTC (Real-Time Clock – zegar czasu rzeczywistego), który pozwala na śledzenie czasu nawet po odłączeniu zasilania, dzięki wbudowanej baterii.
DS3231 zawiera oscylator kwarcowy z kompensacją temperaturową, co minimalizuje wpływ wahań temperatury na dokładność czasu.
Oscylator pracuje z częstotliwością 32.768 kHz, co zapewnia wysoką precyzję ( ±2 ppm (parts per million), co oznacza odchylenie rzędu kilku minut w ciągu roku).
DS3231 przechowuje czas w formacie: godzin, minut, sekund, dni, miesięcy i lat. Może pracować w formacie 24-godzinnym lub 12-godzinnym (z obsługą AM/PM).
Typowy prąd zużywany przez DS3231 to około 3.5 μA w trybie podtrzymywania bateryjnego, co pozwala na bardzo długą żywotność baterii.
Adresowanie
Adresy I2C DS3231 dla zapisu i odczytu:
Write: 0x68 (7-bit address)
Read: 0x69 (7-bit address shifted for read operation)
Domyślny adres 7bitowy dla pamięci Eeprom: 0x57 [1010111]
Adresy Eeprom można modyfikować za pomocą zworek w zakresie od 0x50 do 0x57 (złączenie zworki daje 0).
1 | 0 | 1 | 0 | A2 | A1 | A0 | R/W |
Wyjście SQR pozwala generować przebieg fali prostokątnej o częstotliwościach 1Hz, 4kHz, 8kHz i 32kHz.
Wyjście 32kHz to bezpośredni sygnał z TCXO.
Rejestry DS3231
DS3231 przechowuje czas w rejestrach, które zawierają wartości w formacie BCD (Binary Coded Decimal). Aby odczytać lub zapisać czas, musisz konwertować liczby pomiędzy formatem dziesiętnym a BCD.
Rejestry przechowywania czasu
- Sekundy: [0x00]
- Minuty: [0x01]
- Godziny: [0x02]
- Dzień tygodnia: [0x03]
- Dzień miesiąca: [0x04]
- Miesiąc: [0x05]
- Rok: [0x06]
Alarmy
DS3231 ma dwa niezależne alarmy, które mogą być skonfigurowane do wyzwalania o określonej godzinie, minucie, dniu tygodnia, itp. Alarmy mogą być wykorzystywane do budzenia mikrokontrolera lub wyzwalania zdarzeń w określonych interwałach czasu.
Pomiar temperatury
DS3231 ma wbudowany czujnik temperatury, który mierzy temperaturę wewnętrzną co 64 sekundy. Wynik tego pomiaru jest wykorzystywany do kompensacji temperaturowej oscylatora, co zapewnia stabilność zegara.
Pomiar temperatury jest dostępny dla użytkownika i można go odczytać przez rejestry I2C.
Temperatura w DS3231 jest przechowywana w dwóch rejestrach:
[0x11] (MSB) – wyższy bajt (8 bitów) temperatury, który zawiera całkowitą wartość stopni Celsjusza.
[0x12] (LSB) – niższy bajt (2 najstarsze bity), który zawiera część ułamkową temperatury w krokach co 0.25°C.
Aby odczytać temperaturę, musimy pobrać te dwa bajty, połączyć je i przekształcić na wartość temperatury w stopniach Celsjusza.
#include <Wire.h>
#define DS3231_ADDRESS 0x68 // Adres I2C modułu DS3231
void setup() {
Serial.begin(9600); // Uruchomienie komunikacji szeregowej
Wire.begin(); // Inicjalizacja magistrali I2C
}
void loop() {
float temperature = getTemperature(); // Odczytaj temperaturę
Serial.print("Temperatura: ");
Serial.print(temperature);
Serial.println(" °C");
delay(1000); // Odczekaj 1 sekundę przed kolejnym odczytem
}
float getTemperature() {
Wire.beginTransmission(DS3231_ADDRESS); // Rozpocznij komunikację z DS3231
Wire.write(0x11); // Ustaw wskaźnik na rejestr MSB temperatury
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 2); // Poproś o 2 bajty danych (MSB + LSB)
byte msb = Wire.read(); // Odczytaj MSB temperatury (całkowita część)
byte lsb = Wire.read(); // Odczytaj LSB temperatury (ułamkowa część)
// Całkowita część temperatury
int temp = msb;
if (temp & 0x80) { // Jeśli najwyższy bit MSB jest ustawiony, oznacza to ujemną temperaturę
temp |= 0xFF00; // Rozszerzanie znaku dla ujemnych temperatur
}
// Ułamkowa część temperatury (2 najstarsze bity LSB) to kroki co 0.25°C
float fraction = (lsb >> 6) * 0.25;
// Zwracamy końcowy wynik
return temp + fraction;
}