Echtzeituhr DS3231

(RTC - Real Time Clock)

Bei bisherigen Projekten habe ich, wenn ich die Uhrzeit benötigte, das RTC-Modul DS1307 verwendet. Dieses Modul hat allerdings den Nachteil, dass es schon nach einigen Tagen eine Abweichung von einigen Sekunden aufweist und daher häufig nachgestellt oder - wie in einem meiner Projekte gezeigt - mittels einer Funkuhr, z.B. der DCF77, laufend abgeglichen werden muss (siehe DCF77-Empfänger).

Bild 1: Realt Time Clock D3231 Modul

Hier geht's zum Sketch  "Set_DS3231" zum Einstellen von Datum, Uhrzeit und Wochentag: Datum/Uhrzeit stellen

Wesentlich genauer läuft da die RTC DS3231, da hier - mit Hilfe eines auf dem Modul integrierten Temperatursensor - Abweichungen des Quarzes, die durch Temperatureinfluss entstehen, kompensiert werden. Wie auch der DS1307 wird der DS3231 über die I2C-Schnittstelle angesprochen. Um Schaltjahre braucht man sich keine Gedanken zu machen, diese sollen bis zum Jahr 2100 berücksichtigt sein, nur die Umstellung auf Sommer-/Winterzeit muss händisch erfolgen.

Auch ein AT24C32 EEPROM befindet sich auf dem Modul, welches für eigene Zwecke verwendet werden kann. Über zwei einstellbare Alarme können über einen Ausgang Interrupts bei einem Mikrocontroller ausgelöst werden. Ein Ausgang (mit Pullup-Widerstand) für ein 32 kHz Signal, welches über ein Register ein- und ausgeschaltet werden kann, steht dem Anwender zur Verfügung. Die für die Temperaturkompensation des Quarzes gemessene Temperatur, kann auch aus den Registern des DS3231 ausgelesen werden, wobei die mögliche Abweichung (lt. Datenblatt) mit +/-3°C jedoch sehr hoch sein kann.


Batterie:

Damit die RTC auch ohne Stromversorgung weiterläuft, kann sie über eine Batterie mit Strom versorgt werden. Auf der Rückseite des Moduls ist ein Batteriehalter für eine wiederaufladbare Knopfzelle (LIR2023) vorgesehen, die über einen 200 Ohm Widerstand aufgeladen wird. Wird anstelle der wiederaufladbaren Knopfzelle eine nicht aufladbare Zelle verwendet, so muss der Widerstand entfernt werden (siehe roter Pfeil im Bild 2)!

     

Bild 2: Ausschnitt des DS3231 Moduls. Der Pfeil zeigt auf den 200 Ohm Widerstand, der bei Verwendung einer nicht aufladbaren Knopfzelle entfernt werden muss!


I2C-Schnittstelle:

  • RTC DS3231        : fest eingestellt auf 0x68
  • EEPROM AT24C32: eingestellt auf 0x57, einstellbar über Lötbrücken 0x50 bis 0x56

Die beiden I2C-Leitungen SDA und SCL sind auf dem Modul mit Pullup-Widerständen versehen.


Testaufbau:

Verwendete Bauteile:

  • 1 Arduino Nano
  • 1 DS3231 Modul



Library MyDS3231 für Arduino und Attiny45/85:

Es gibt im Internet einige umfangreiche Libraries zum DS3231 zu finden, die alle Möglichkeiten die der Baustein bietet, abdecken können.

Mit meiner Library wollte ich mich auf das Wesentliche des DS3231 beschränken, nämlich Datum und Uhrzeit einzustellen und abzufragen.

Deshalb habe ich mich auch auf den Zeitraum "21. Jahrhundert" beschränkt. Eine Eingabe eines Datums vor dem Jahr 2000 und nach 2099 habe ich in meiner Library nicht vorgesehen.

Folgende Funktionen stehen zur Verfügung:


  • Abfrage, ob der Baustein über I2C ansprechbar ist
  • Auslesen des Datums, der Uhrzeit und des Wochentages
  • Setzen des Datums
  • Setzen der Uhrzeit
  • Sommerzeit ein- bzw. ausschalten
  • Setzen des Wochentages
  • Ausgabe jeweils als char-String von Datum, Uhrzeit und Wochentag


Hinweis: Für die Verwendung des auf dem Modul vorhandenem EEPROM AT24C32 enthält die Library MyDS3231 keine Funktionen! Das EEPROM kann aber z.B. mit meiner Library MyEEPROM_I2C verwendet oder mit meinem EEPROM-Monitor manipuliert werden (Achtung auf Einstellung oder Vorgabe der entsprechenden I2C-Adresse).


Die Library kann hier heruntergeladen werden:

Sollte die Library jemand verwenden oder testen, würde ich mich über eine Rückmeldung sehr freuen!

Neu: Version 2.4

MyDS3231.cpp.txt

MyDS3231.h.txt

keywords.txt

Leider kann ich hier keine "cpp"- oder "h"-Files hochladen, daher zum Verwenden der Library ".txt" aus den Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "MyDS31231" dort speichern, wo eure anderen Libraries gespeichert sind.


Zur Auflistung der Funktionen der Library geht es hier: Funktionen

Programmbeispiele MyDS3231:

Neben den beiden nachfolgenden Programmbeispielen zur Ausgabe von Datum und Uhrzeit, ist hier nocheinmal der Link zu meinem Sketch  "Set_DS3231", mit dem Datum, Uhrzeit und Wochentag eingestellt werden können: Datum/Uhrzeit stellen


Beispiel 1:

Datum und Uhrzeit werden als Bytes am Seriellen Monitor ausgegeben:

//Programmbeispiel 1 für RTC3231
//Code fuer Arduino
//Author Retian
//Version 1.0


//Prototyp
void checkVorNull(byte);


#include <MyDS3231.h>

MyDS3231 RTC(0x68);


void setup() {
  Serial.begin(115200);
  if (RTC.isReady()) Serial.println("RTC ok");
  else
  {
    Serial.println("RTC Fehler oder nicht vorhanden");
    while(1);
  }
  Serial.println();
}


void loop() {
  //Auslesen von Datum und Uhrzeit
  RTC.nowDateTime();
  //Ausgabe von Datum und Uhrzeit
  //Die Funktion checkVorNull() schreibt bei Datums- oder
  //Uhrzeitwerten eine '0' voraus, wenn der Wert kleiner 10 ist.
  Serial.print("Datum  : ");
  checkVorNull(RTC.nowDay);
  Serial.print(RTC.nowDay);
  Serial.print(".");
  checkVorNull(RTC.nowMonth);
  Serial.print(RTC.nowMonth);
  Serial.print(".");
  Serial.print("20");
  checkVorNull(RTC.nowYear);
  Serial.println(RTC.nowYear);
  Serial.print("Uhrzeit: ");
  checkVorNull(RTC.nowHour);
  Serial.print(RTC.nowHour);
  Serial.print(":");
  checkVorNull(RTC.nowMin);
  Serial.print(RTC.nowMin);
  Serial.print(":");
  checkVorNull(RTC.nowSec);
  Serial.println(RTC.nowSec);
  Serial.println();
  delay(1000);
}


void checkVorNull(byte wert)
{
  if (wert < 10) Serial.print("0");
}

Beispiel 2:

Datum und Uhrzeit wird als char-String am Seriellen Monitor ausgegeben. Anstelle der Ausgabe am Seriellen Monitor könnten so auch Datum und Uhrzeit auf einem LCD-Display, z.B. mit der LiquidCrystal-Library ausgegeben werden:

//Programmbeispiel 2 für RTC3231
//Code fuer Arduino
//Author Retian
//Version 1.1


#include <MyDS3231.h>
MyDS3231 RTC(0x68);


char dowString[11];
char dateString[11];
char timeString[9];


void setup() {
  Serial.begin(115200);
}


void loop() {
  //Auslesen von Datum und Uhrzeit
  RTC.nowDateTime();
  //Wochentag, Datum und Uhrzeit als char-String speichern und ausgeben
  RTC.getDowString(dowString);
  RTC.getDateString(dateString, YEAR_4_DIG); //Jahrzahl 4-stellig ausgeben
  RTC.getTimeString(timeString, HH_MM_SS); //Stunden, Minuten und Sekunden ausgeben
  Serial.print("Wochentag: ");
  Serial.println(dowString);
  Serial.print("Datum : ");
  Serial.println(dateString);
  Serial.print("Uhrzeit: ");
  Serial.println(timeString);
  Serial.println();
  delay(1000);
}