Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Gartenautomation
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Deutsch
  • English
Menu

Arduino Lektion 45: RealTimeClock DS3231 (Mini)

Posted on 28. April 20185. März 2024 by Stefan Draeger

Die RealTimeClock DS3231SN ist der kleinste Vertreter der RTC’s (jedenfalls von denen die ich kenne).

Die RTC ist in diesem falle so klein das meine Kamera Probleme hat die Details korrekt aufzunehmen. Daher bitte ich die Bilder in diesem Tutorial etwas zu entschuldigen.

RTC - DS3231SN
RTC – DS3231SN
RTC - DS3231SN - Rückseite
RTC – DS3231SN – Rückseite

Auf der Rückseite des DS3231SN ist die Batterie aufgebracht sowie die 5 Pinleiste.

Die Pinleiste ist etwas angewinkelt das liegt vielmehr daran das hier die Batterie zu dicht an der Pinleiste montiert wurde.

Der Vorteil von dieser RTC gegenüber der RTC DS3231 ist das die Batterie gleich dabei ist.

  • Bezug
  • Technische Daten des DS3231SN
  • Anschluss
  • Schaltung
  • Quellcode
    • Einstellen eines Zeitstempels
  • Fazit

Bezug

Das Modul kann über den ebay Shop – Makershop.de* für ca. 3,75 € gekauft werden.

Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!

Technische Daten des DS3231SN

  • Betriebsspannung – 2.3V bis 5.5V
  • valide Daten bis ins Jahr 2100
  • messbarer Temperaturbereich von -40 °C bis +85 °C
  • High speed I2C Bus (mit 400kHz)
  • Abmaße (L x B x H) 12 mm x 14 mm x 13 mm

Anschluss

Das RTC Modul verfügt über 5 Pins welche wie folgt an den Arduino UNO angeschlossen werden.

RTC DS3231SNArduino UNO
+5V
DSDA – analoger PIN A4
CSCL – analoger PIN A5
NC -nicht belegt-
–GND

Schaltung

Wie die RTC an den MakerUNO angeschlossen wird, möchte ich in einem kleinen Video erläutern.

Anschluss der RealTimeClock DS3231SN an den MakerUNO
Dieses Video auf YouTube ansehen.

Quellcode

Da die RTC DS3231SN baugleich mit dem bereits vorgestellten Modul DS3231 ist, konnte ich hier den Code 1:1 übernehmen.

#include <Wire.h>
#define RTC_I2C_ADDRESS 0x68 // I2C Adresse des RTC  DS3231
 
//Membervariablen
int jahr,monat,tag,stunde,minute,sekunde, wochentag;
int daysInMonth[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
String daysInWeek[7] = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"};
String monthInYear[12] = {"Januar","Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"};
String outputFormat = "%s, %02d.%s %04d %02d:%02d:%02d Uhr";
 
//Ließt den aktuellen Zeitstempel aus dem RTC Modul.
void rtcReadTime(){
  Wire.beginTransmission(RTC_I2C_ADDRESS); //Aufbau der Verbindung zur Adresse 0x68
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(RTC_I2C_ADDRESS, 7);
  sekunde    = bcdToDec(Wire.read() & 0x7f);
  minute     = bcdToDec(Wire.read()); 
  stunde     = bcdToDec(Wire.read() & 0x3f); 
  //Der Wochentag wird hier nicht ausgelesen da dieses mit 
  //dem Modul RTC DS3231 nicht über die Wire.h zuverlässig funktioniert.
  /* wochentag  =*/ bcdToDec(Wire.read());
  tag        = bcdToDec(Wire.read());
  monat      = bcdToDec(Wire.read());
  jahr       = bcdToDec(Wire.read())+2000;    
}
 
//Funktion zum schreiben / setzen der Uhrzeit.
void rtcWriteTime(int jahr, int monat, int tag, int stunde, int minute, int sekunde){
  Wire.beginTransmission(RTC_I2C_ADDRESS);
  Wire.write(0); // Der Wert 0 aktiviert das RTC Modul.
  Wire.write(decToBcd(sekunde));    
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(stunde));                                  
  Wire.write(decToBcd(0)); // Wochentag unberücksichtigt
  Wire.write(decToBcd(tag));
  Wire.write(decToBcd(monat));
  Wire.write(decToBcd(jahr-2000));  
  Wire.endTransmission();  
}
 
//Berechnet den Tag der Woche aus dem übergebenen Datumswerten.
byte calcDayOfWeek(int jahr, byte monat, byte tag) {
  static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
  jahr -= monat < 3;
  return ((jahr + jahr/4 - jahr/100 + jahr/400 + t[monat-1] + tag) % 7); 
}
 
//Convertiert Dezimalzeichen in binäre Zeichen.
byte decToBcd(byte val){
  return ( (val/10*16) + (val%10) );
}
 
//Convertiert binäre Zeichen in Dezimal Zeichen.
byte bcdToDec(byte val){
  return ( (val/16*10) + (val%16) );
}
 
//Ließt einen String und liefert einen Integer Wert von einer 
//definierten Stelle (byte num) des Stringwertes.
int getIntFromString (char *stringWithInt, byte num){
  char *tail; 
  while (num>0){
    num--;
    //Bei Kommanseparierten Listen werden die Kommata 
    //übersprungen und geben damit die Unterteilung des Strings an.
    while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)){
      stringWithInt++;
    }
    tail=stringWithInt;
    //Schleife solange ausführen bis eine Zahl gefunden wurde
    //welche größer 0 ist.
    while ((isdigit(*tail))&&(*tail!=0)){
      tail++;
    }
   
    if (num>0){
      stringWithInt=tail;
    }
  }  
  return(strtol(stringWithInt, &tail, 10));
}  
 
//Setup Methode
void setup(){
  Wire.begin(); //Kommunikation über die Wire.h bibliothek beginnen.       
  Serial.begin(57600);  //Übertragungsgeschwindigkeit 9600 Baud
  Serial.println("Mit dem Befehl kann das Datum und die Uhrzeit gesetzt oder veraendert werden.");
  Serial.println("Beispiel: set 28.08.2013 10:54");
}
 
//Gibt einen Zeitstempel auf der Seriellen Schnittstelle aus.
void printRTCDateTime(){
  char linebuf[60];
  int dOW = calcDayOfWeek(jahr, monat, tag);
  String wochentagC = daysInWeek[dOW];
  String monatC = monthInYear[monat];
 
  String result = "";
  result += wochentagC;
  result += ", ";
  result += tag;
  result += ".";
  result += monatC;
  result += " ";  
  result += jahr;  
  result += " "; 
  if(stunde<10) { result += "0"; }
  result += stunde;  
  result += ":";  
  if(minute<10) { result += "0"; }
  result += minute;  
  result += ":"; 
  if(sekunde<10) { result += "0"; }
  result += sekunde;  
  Serial.println(result); 
}
 
//Manuelles setzen der Uhrzeit über den Seriellen Monitor der IDE.
void setRTCTime(){
  char linebuf[30];
  byte counter;
  if (Serial.available()){
    delay(100); // Warte auf das Eintreffen aller Zeichen vom seriellen Monitor
    memset(linebuf,0,sizeof(linebuf)); // Zeilenpuffer löschen
    counter=0; // Zähler auf Null
    while (Serial.available()){
      linebuf[counter]=Serial.read(); // Zeichen in den Zeilenpuffer einfügen
      if (counter<sizeof(linebuf)-1) counter++; // Zeichenzähler erhöhen
    }
    // Wenn in der gelesenen Zeile das Wort 'set' vorkommt dann...
    //(Hier muss man bedenken das die Suche nach 'set' auch nach x Zeichen ein positives Ergebnis liefern wird, zbsp. 123set 09.01.2016 12:00:00)
    if (strstr(linebuf,"set")==linebuf){ 
      tag=getIntFromString (linebuf,1);
      monat=getIntFromString (linebuf,2);
      jahr=getIntFromString (linebuf,3);
      stunde=getIntFromString (linebuf,4);
      minute=getIntFromString (linebuf,5);
      sekunde=getIntFromString (linebuf,6);
    } else {
      Serial.println("Befehl unbekannt.");
      return;
    }
    // Ausgelesene Werte einer groben Plausibilitätsprüfung unterziehen:
    if (!checkDateTime(jahr, monat, tag, stunde, minute, sekunde)){
      Serial.println(linebuf);
      Serial.println("Fehlerhafte Zeitangabe im 'set' Befehl");
      Serial.println("Beispiel: set 28.08.2013 10:54");
      return;
    }
    rtcWriteTime(jahr, monat, tag, stunde, minute, sekunde);
    Serial.println("Zeit und Datum wurden auf neue Werte gesetzt.");
  }
}
 
//Prüft das eingegebene Datum auf korrektheit.
boolean checkDateTime(int jahr, int monat, int tag, int stunde, int minute, int sekunde){
   boolean result = false;
   if(jahr>2000){
     result = true;  
   } else {
     return false;
   }
   // Schaltjahr prüfen
   if(jahr % 400 == 0 || (jahr % 100 != 0 && jahr % 4 == 0)){
     //Wenn es ein Schaltjahr ist dann den Wert 29 in das Array an der Stelle 1 für den Monat Februar schreiben.
     daysInMonth[1]=29;
   }
   
   //Monat muss kleiner 13 sein.
   if (monat<13){
      if( tag <= daysInMonth[monat-1] ){
        result = true;
      }
   } else {
     return false;
   }
    
  //Wert für Stunde muss zwischen 0 und 24 liegen,
  //Wert für Minute und sekunde muss zwischen 0 und 59 liegen
  if(stunde <24 && minute <60 && sekunde <60 && stunde >= 0 && minute >=0 && sekunde >=0){
        result = true;
  } else {
     return false;
   }
   
   return result;
}
 
void loop(){ 
 rtcReadTime();
 printRTCDateTime();
 setRTCTime();
 delay(1000);
}

Einstellen eines Zeitstempels

Beim ersten Starten des Mikrocontrollers sollte / muss man den korrekten Zeitstempel eingeben.

Arduino IDE - Ausgabe auf dem seriellen Monitor
Arduino IDE – Ausgabe auf dem seriellen Monitor

Den Zeitstempel stellt man mit dem Befehl „set TT.MM.YYYY HH:mm“ auf dem seriellen Monitor der Arduino IDE ein.

In diesem Beispiel gebe ich „set 29.04.2018 11:22“ ein und bestätige dieses mit der Return / Enter Taste.

Arduino IDE - Setzen eines neuen Zeitstempels
Arduino IDE – Setzen eines neuen Zeitstempels

Wurde das Datum korrekt verarbeitet, so wird dieses auf der Konsole mit der Zeile „Zeit und Datum wurden auf neue Werte gesetzt“.

Fazit

Das RTC Modul DS3231SN ist ein kleines Bauteil, welches dem großen in nichts nachsteht, einzig, dass die Batterie bereits vormontiert ist, kann Fluch und Segen gleichzeitig sein. Denn wenn diese einmal ausgetauscht werden muss, gibt es hier nur 2 Lötstellen anstatt einer „vernünftigen“ Batteriehalterung. Hier könnte das Modul noch etwas erweitert werden, aber für einen Preis von ca. 3,75 € ist dieses zu verschmerzen.

5 thoughts on “Arduino Lektion 45: RealTimeClock DS3231 (Mini)”

  1. Winfried Dams sagt:
    9. September 2018 um 18:13 Uhr

    Im Beispiel wurde ein Datum vom August gesetzt welches Daten von September liefert.

    Antworten
    1. w dams sagt:
      15. September 2018 um 08:47 Uhr

      Das Array Januar bis Dezember muß mit Dezember beginnen.
      Mein Modul geht etwa 8 Minuten pro Tag nach. Ich werde mal ein anderes ausprobieren.

      Antworten
      1. Walter sagt:
        19. April 2025 um 19:12 Uhr

        Dies geht aber auch nicht zumindest bei mir .
        für Jan bis Nov okay
        Im Dez gibt es dann
        set 12.12.2025 12:00
        19:10:53.972 -> Samstag, 1.Februar 2025 00:07:50
        19:10:54.068 -> Zeit und Datum wurden auf neue Werte gesetzt.
        19:11:04.098 -> Freitag, 12.Sonntag 2025 12:00:10
        19:11:14.102 -> Freitag, 12.Sonntag 2025 12:00:20

        Antworten
  2. Wolfgang Lachmann sagt:
    23. Juni 2024 um 20:24 Uhr

    Ich habe einige DS3231 (mini) in Fernost gekauft, davon einen Teil in Betrieb genommen (Datum und Uhrzeit gesetzt). Die meisten liegen seit fast einem Jahr bei mir auf Halde. Nun wollte ich von den in Betrieb genommenen einen weiteren benutzen und stelle fest, dass bei allen in Betrieb genommenen und gelagerten der Akku vollständig entladen ist (3,3V). Woran liegt dieser Unterschied?

    Antworten
  3. Wolfgang Lachmann sagt:
    23. Juni 2024 um 20:26 Uhr

    Korrektur:
    Ich habe einige DS3231 (mini) in Fernost gekauft, davon einen Teil in Betrieb genommen (Datum und Uhrzeit gesetzt). Die meisten liegen seit fast einem Jahr bei mir auf Halde. Nun wollte ich von den in Betrieb genommenen einen weiteren benutzen und stelle fest, dass bei allen in Betrieb genommenen und gelagerten der Akku vollständig entladen ist, bei den nicht in Betrieb genommenen ist der Akku noch voll (3,3V). Woran liegt dieser Unterschied?

    Antworten

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen
Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

link zu Fabook
link zu LinkedIn
link zu YouTube
link zu TikTok
link zu Pinterest
link zu Instagram
  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}