cryeffect.net

DS1307 RTC programmieren

    Im heutigen Artikel geht es darum, wie man ein RTC (Real Time Clock) programmiert. Wenn wir einen frisch gekauften RTC anschließen, ist das Problem oft, dass dieser nicht korrekt eingestellt ist. Mit einen kleinen Sketch haben wir nun die Möglichkeit, über den “seriellen Monitor” das RTC Modul auf die korrekte Uhrzeit und Datum einzustellen. Hierfür verdrahten wir unseren Arduino Nano über den I2C Bus mit dem DS1307 Modul. Das ganze wird wie folgt verdrahtet.

    Haben wir die beiden miteinander verdrahtet, können wir auch schon mit dem Sketch starten. Dafür nutzen wir den Beispiel Sketch vom DS1307.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133

    // Sets the date/time of an DS1307 RTC module via serial monitor
    // (c) 2018 Christian Grieger
    // GNU GENERAL PUBLIC LICENSE

    // I²C Address for the RTC module
    #define DS1307_ADDRESS 0x68

    #include <Wire.h>

    void setup()
    {
    Wire.begin();
    Serial.begin(9600);
    while (!Serial); // wait for serial port to connect. Needed for native USB
    Serial.flush();

    printDateTime();

    Serial.println("Please change to newline ending the settings of the Serial Monitor");
    Serial.println("Would you like to set the date and time now? Y/N");

    while (!Serial.available()) delay(10);
    if (Serial.read() == 'y' Serial.read() == 'Y') {
    Serial.read();
    setDateTime();
    printDateTime();
    }
    }

    void loop()
    {
    }

    // Sets date/time of the RTC module via the serial monitor

    void setDateTime()
    {
    byte second = 0, minute = 0, hour = 0, weekday = 0, monthday = 0, month = 0, year = 0;

    Serial.print(F("Year (00-99): "));
    year = readByte();
    Serial.println(year);

    Serial.print(F("Month (1-12): "));
    month = readByte();
    Serial.println(month);

    Serial.print(F("Day of the month (1-31): "));
    monthday = readByte();
    Serial.println(monthday);

    Serial.print(F("Day of the week (1-7): "));
    weekday = readByte();
    Serial.println(weekday);

    Serial.print(F("Hour (0-23): "));
    hour = readByte();
    Serial.println(hour);

    Serial.print(F("Minute (0-59): "));
    minute = readByte();
    Serial.println(minute);

    second = 0;

    // The following codes transmits the data to the RTC
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.write(byte(0));
    Wire.write(decToBcd(second));
    Wire.write(decToBcd(minute));
    Wire.write(decToBcd(hour));
    Wire.write(decToBcd(weekday));
    Wire.write(decToBcd(monthday));
    Wire.write(decToBcd(month));
    Wire.write(decToBcd(year));
    Wire.write(byte(0));
    Wire.endTransmission();
    }

    byte readByte()
    {
    while (!Serial.available()) {
    delay(10);
    }
    byte reading = 0;
    byte incomingByte = Serial.read();
    while (incomingByte != '\n') {
    if (incomingByte >= '0' && incomingByte <= '9') {
    reading = reading * 10 + (incomingByte - '0');
    }
    incomingByte = Serial.read();
    }
    Serial.flush();
    return reading;
    }

    // Prints the current date/time set in the RTC module to the serial monitor

    void printDateTime()
    {
    Wire.beginTransmission(DS1307_ADDRESS);
    Wire.write(0x00);
    Wire.endTransmission();
    Wire.requestFrom(DS1307_ADDRESS, 7);

    byte nowSeconds = bcdToDec(Wire.read());
    byte nowMinute = bcdToDec(Wire.read());
    byte nowHour = bcdToDec(Wire.read() & 0b111111);
    byte nowWeekDay = bcdToDec(Wire.read());
    byte nowMonthDay = bcdToDec(Wire.read());
    byte nowMonth = bcdToDec(Wire.read());
    byte nowYear = bcdToDec(Wire.read());

    char data[20] = "";
    sprintf(data, "20%02d-%02d-%02d %02d:%02d:%02d", nowYear, nowMonth, nowMonthDay, nowHour, nowMinute, nowSeconds);
    Serial.print("Current datetime: ");
    Serial.println(data);
    }

    // Converts a decimal (Base-10) integer to BCD (Binary-coded decimal)

    int decToBcd(int value)
    {
    return ((value/10*16) + (value%10));
    }

    // Converts a BCD (Binary-coded decimal) to decimal (Base-10) integer

    int bcdToDec(int value)
    {
    return ((value/16*10) + (value%16));
    }

    Haben wir den Sketch hochgeladen, können wir uns mittels “Seriellen Monitor” und einer Baudrate von 9600 verbinden, um die aktuelle Zeit einzustellen. Durch die verbaute Batterie läuft der RTC auch ohne externen Strom weiter und speichert die Zeit. Wenn alles geklappt hat, gibt der RTC, über den I2C Bus, die aktuelle Zeit an unseren Arduino Nano weiter, was wir über den “Seriellen Monitor” sehen.