0

I am trying to set the time on my DS3231, then read that time on my arduino nano. This is for a digital clock project. I am using DS3232 library by JChristensen.

He has an example that can set the DS3231 time through the serial monitor, and it works great, but I don't understand how to implement it into my sketch.

I can confirm that once the external RTC is set using said example, I can then upload my code, and the clock holds time when unplugged. It's setting the time within my sketch that I can't figure out. I've been at it for about 8 hours today and read through the github resources.

Here's my code. Towards the top you can see my attempt to set the system time, then set it to the RTC.

 #include "SevSeg.h"; 
    #include <DS3232RTC.h>; //Jack Christensen 
    https://github.com/JChristensen/DS3232RTC
    #include <Streaming.h>; //Mikal Hart https://github.com/janelia- 
     arduino/Streaming
    //Also requires time library https://github.com/PaulStoffregen/Time 

    SevSeg sevseg; 



    void setup() {
    // put your setup code here, to run once:


    //Serial.begin(9600);

    setSyncProvider(RTC.get);// the function to get the time from the RTC
    setTime(8,0,0,20,1,2020);
    time_t t = now();
    RTC.set(now());         


     byte numDigits = 4;
     byte digitPins[] = {2, 3, 4, 5};
     byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12};
     bool resistorsOnSegments = false; // 'false' means resistors are on digit 
     pins
     byte hardwareConfig = COMMON_CATHODE; // See README.md for options
     bool updateWithDelays = false; // Default 'false' is Recommended
     bool leadingZeros = false; // Use 'true' if you'd like to keep the leading 
     zeros
     bool disableDecPoint = true; // Use 'true' if your decimal point doesn't 
     exist or isn't connected. Then, you only need to specify 7 segmentPins[]




     sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, 
      resistorsOnSegments,
       updateWithDelays, leadingZeros, disableDecPoint);



    }


     void loop() {



    sevseg.setChars("hola");
    sevseg.refreshDisplay();



     if(millis()>6000) {

    int adj = 0;
    int timenumber; 
    int hr = hourFormat12();
    int Min = minute();



    timenumber = (hr*100) + Min; //converts time into a number for the seven 
    segment display






   sevseg.setNumber(timenumber);
   sevseg.refreshDisplay();
    } 

    }

And JChristensen's Example Code:

// Arduino DS3232RTC Library
// https://github.com/JChristensen/DS3232RTC
// Copyright (C) 2018 by Jack Christensen and licensed under
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
//
// Example sketch to display the date and time from a DS3231
// or DS3232 RTC every second. Display the temperature once per
// minute. (The DS3231 does a temperature conversion once every
// 64 seconds. This is also the default for the DS3232.)
//
// Set the date and time by entering the following on the Arduino
// serial monitor:
//  year,month,day,hour,minute,second,
//
// Where
//  year can be two or four digits,
//  month is 1-12,
//  day is 1-31,
//  hour is 0-23, and
//  minute and second are 0-59.
//
// Entering the final comma delimiter (after "second") will avoid a
// one-second timeout and will allow the RTC to be set more accurately.
//
// No validity checking is done, invalid values or incomplete syntax
// in the input will result in an incorrect RTC setting.
//
// Jack Christensen 08Aug2013

#include <DS3232RTC.h>      // https://github.com/JChristensen/DS3232RTC
#include <Streaming.h>      // http://arduiniana.org/libraries/streaming/

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

    // setSyncProvider() causes the Time library to synchronize with the
    // external RTC by calling RTC.get() every five minutes by default.
    setSyncProvider(RTC.get);
    Serial << F("RTC Sync");
    if (timeStatus() != timeSet) Serial << F(" FAIL!");
    Serial << endl;
}

void loop()
{
    static time_t tLast;
    time_t t;
    tmElements_t tm;

    // check for input to set the RTC, minimum length is 12, i.e. yy,m,d,h,m,s
    if (Serial.available() >= 12) {
        // note that the tmElements_t Year member is an offset from 1970,
        // but the RTC wants the last two digits of the calendar year.
        // use the convenience macros from the Time Library to do the conversions.
        int y = Serial.parseInt();
        if (y >= 100 && y < 1000)
            Serial << F("Error: Year must be two digits or four digits!") << endl;
        else {
            if (y >= 1000)
                tm.Year = CalendarYrToTm(y);
            else    // (y < 100)
                tm.Year = y2kYearToTm(y);
            tm.Month = Serial.parseInt();
            tm.Day = Serial.parseInt();
            tm.Hour = Serial.parseInt();
            tm.Minute = Serial.parseInt();
            tm.Second = Serial.parseInt();
            t = makeTime(tm);
            RTC.set(t);        // use the time_t value to ensure correct weekday is set
            setTime(t);
            Serial << F("RTC set to: ");
            printDateTime(t);
            Serial << endl;
            // dump any extraneous input
            while (Serial.available() > 0) Serial.read();
        }
    }

    t = now();
    if (t != tLast) {
        tLast = t;
        printDateTime(t);
        if (second(t) == 0) {
            float c = RTC.temperature() / 4.;
            float f = c * 9. / 5. + 32.;
            Serial << F("  ") << c << F(" C  ") << f << F(" F");
        }
        Serial << endl;
    }
}

// print date and time to Serial
void printDateTime(time_t t)
{
    printDate(t);
    Serial << ' ';
    printTime(t);
}

// print time to Serial
void printTime(time_t t)
{
    printI00(hour(t), ':');
    printI00(minute(t), ':');
    printI00(second(t), ' ');
}

// print date to Serial
void printDate(time_t t)
{
    printI00(day(t), 0);
    Serial << monthShortStr(month(t)) << _DEC(year(t));
}

// Print an integer in "00" format (with leading zero),
// followed by a delimiter character to Serial.
// Input value assumed to be between 0 and 99.
void printI00(int val, char delim)
{
    if (val < 10) Serial << '0';
    Serial << _DEC(val);
    if (delim > 0) Serial << delim;
    return;
}
  • Can you format your code a little bit? It is impossible to read it in this way... With wrong tabs and a lot of line feeds. An error is this: if(millis()>6000). This means that your loop will not do anything for 6 seconds and then it will refresh the display so fast as possible... If you just want update your clock, you can do it 1 time every second with a delay, or better, update the display only if the second value changed. – Adriano Jan 21 at 12:03
  • Do you understand, how the example sketch is setting the time? If yes, what exactly is your problem in implementing it? – chrisl Jan 21 at 14:45
  • It’s set through the serial monitor. So I need to make a function to send input to the serial. I haven’t yet figured out how the example code it able to do this – StrugglingStudent117 Jan 21 at 16:20
0

I figured it out. You must first set the built in arduino RTC using the time library, then set the DS3232 from there. It did not work for my code before because it has to be called outside of the setup function.

For instance, I made a function that adjusts the hour:

void adjHr() { //hour adjustment function

if(millis() >= time_now + period){
        time_now += period;
        time_now = millis();
        setTime(hour()+1,minute(),second(),day(),month(),year());
        RTC.set(now());
    }

My setup function also includes:

setSyncProvider(RTC.get);

Allows the code to get time from the DS3232.

| improve this answer | |
  • it is not the best way – Juraj Jan 27 at 18:50
  • It is “a” way. But if you have a better way, do share and i’ll mark your’s as the answer – StrugglingStudent117 Jan 28 at 1:45
  • you have a better way in the code in question. tmElements_t – Juraj Jan 28 at 5:59
  • I assume you’re referring to using the serial monitor to set the time. That seems like a very straightforward way to do it, but I have yet to figure that out. For now, setting the time with my alternate method is good enough. – StrugglingStudent117 Jan 29 at 19:05
  • it has nothing to do with Serial. in the example the values are read from Serial (read by parseInt) and are set into the tmElements_t structure. but you can use the variables to set the elements of date and time. Then the makeTime from TimeLib function calculates the 'epoch' value and it is set to RTC. the way in your answer will have a problem, because the time runs in TimeLib – Juraj Jan 29 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.