User Tools

Site Tools


ds3231

Digitaluhr mit DS3231 RTC High Precision Real-Time Clock Module

Für eine Digitaluhr, die auch eine Stromunterbrechung übersteht, wird eine Batteriegepufferte Uhr benötigt. Ich habe diesen Bausatz verwendet: DS3231 RTC High Precision Real-Time Clock Module with AT24C32 EEPROM

Für die Anzeige wird ein kleiner OLED-Screen verwendet.

Aufbau:

Verdrahtung:

Da beide Module eine I2C-Schnittstelle haben, ist die Verdrahtung denkbar einfach:

Arduino   Display    Clock
GND ..... GND ...... GND
VCC  .... VCC  ..... VCC   (3.3V)
SCL ..... SCL ...... SCL
SDA ..... SDA ...... SDA

Programmierung:

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>         // Display
#include <Adafruit_SSD1306.h> // Display
 
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
 
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
 
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
// end of Display --------------------------
 
#define DS3231_I2C_ADDRESS 0x68   // Clock-Adresse
 
void setup() {
    Wire.begin();
    Serial.begin(9600);
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // I2C addr 0x3C
    display.clearDisplay();
 
    // ** Zeit einmalig hier setzen, danach auskommentieren
    // ** DS3231 seconds, minutes, hours, day, date, month, year
    // ** day 1=Sonntag ... 7=Samstag
    // ** Mi., 4.10.2018 11:50:00
    // setDS3231time(00,50,11,4,24,10,18);
}
// 4 Strings auf Display ausgeben
void drawText(String txt1, String txt2, String txt3, String txt4) {
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(10,0);
    display.clearDisplay();
    display.println(txt1);
    display.setTextSize(1);
    display.println(txt2);
    display.println(txt3);
    display.setTextSize(2);
    display.print(txt4);
    display.display();
}
 
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val) {  return( (val/10*16) + (val%10) ); }
 
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val) {  return( (val/16*10) + (val%16) ); }
 
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, 
byte dayOfMonth, byte month, byte year) {
    // sets time and date data to DS3231
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set next input to start at the seconds register
    Wire.write(decToBcd(second)); // set seconds
    Wire.write(decToBcd(minute)); // set minutes
    Wire.write(decToBcd(hour)); // set hours
    Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
    Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
    Wire.write(decToBcd(month)); // set month
    Wire.write(decToBcd(year)); // set year (0 to 99)
    Wire.endTransmission();
}
// Zeit auslesen
void readDS3231time(byte *second, byte *minute, byte *hour,
        byte *dayOfWeek, byte *dayOfMonth, byte *month,byte *year) {
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
    // request seven bytes of data from DS3231 starting from register 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());
}
 
// Werte in Uhrzeit umformatieren (HH:MM:SS)
String getUhrzeit(byte second, byte minute, byte hour) {
    String h = String(hour);        if (hour<10)   h="0" + h;
    String m = String(minute);      if (minute<10) m="0" + m;
    String s = String(second);      if (second<10) s="0" + s;
    return h + ":" + m + ":" + s;
}
 
// Werte in Datum umformatieren (DD-MM-YYYY)
String getDatum(byte dayOfWeek, byte dayOfMonth, byte month, byte year) {
    String d = String(dayOfMonth);  if (dayOfMonth<10) d = "0" + d;
    String mo = String(month);      if (month<10) mo = "0" + mo;
    String y = String(year);        if (year<10) y = "0" + y;
    return d + "-" + mo + "-20" + y;
}
 
// Uhrzeit anzeigen
void displayTime() {
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    // retrieve data from DS3231
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,  &year);
    String uhrzeit = getUhrzeit(second, minute, hour);
    String datum = getDatum(dayOfWeek, dayOfMonth, month, year);
    String tag = getDayOfWeek(dayOfWeek);
    drawText(uhrzeit,"",tag,datum);
}
 
// Endlosschleife
void loop() {
    displayTime(); // display the real-time clock data on the Serial Monitor,
    delay(1000); // every second
}
ds3231.txt · Last modified: 2024/03/11 13:49 by walter