Go Down

Topic: DS3231 will not change date (Read 395 times) previous topic - next topic

DRE50

I can set the day of the week as well as time no problem but it will not set the current date? any ideas? im using an arduino MEGA.
Code: [Select]
// DS3231_Serial_Easy
// Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
// web: http://www.RinkyDinkElectronics.com/
//
// A quick demo of how to use my DS3231-library to
// quickly send time and date information over a serial link
//
// To use the hardware I2C (TWI) interface of the chipKit you must connect
// the pins as follows:
//
// chipKit Uno32/uC32:
// ----------------------
// DS3231:  SDA pin   -> Analog 4
//          SCL pin   -> Analog 5
// *** Please note that JP6 and JP8 must be in the I2C position (closest to the analog pins)
//
// chipKit Max32:
// ----------------------
// DS3231:  SDA pin   -> Digital 20 (the pin labeled SDA)
//          SCL pin   -> Digital 21 (the pin labeled SCL)
//
// The chipKit boards does not have pull-up resistors on the hardware I2C interface
// so external pull-up resistors on the data and clock signals are required.
//
// You can connect the DS3231 to any available pin but if you use any
// other than what is described above the library will fall back to
// a software-based, TWI-like protocol which will require exclusive access
// to the pins used.
//

#include <DS3231.h>

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(115200);
 
  // Initialize the rtc object
  rtc.begin();
 
  // The following lines can be uncommented to set the date and time
  rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  rtc.setTime(19,45, 0);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(3, 25, 2020);   // Set the date to January 1st, 2014
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
 
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());
 
  // Wait one second before repeating :)
  delay (1000);
}

thanks

Koepel

You are using a library that is not on Github. That is problem number one, since users can not report a problem.
In the page of the Rinky-Dink DS3231 library is a note that has not be fully tested. That's problem number two.
The library can use its own software I2C or the Arduino Wire library. That software I2C is problem number three.
You are not the only one that has problems with that library. That is problem number four.
That library is from 2015, and the Arduino code improves and moves on. Maybe it is no longer 100% compatible.

First of all, you should test if the Arduino board can communicate over the I2C bus with the DS3231. Use a I2C Scanner for that.
When that is okay, find a better library.

floresta

The example code offered by the author:

Code: [Select]
 //rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014

   is not particularly helpful since it is impossible to determine which '1' represents the date and which '1' represnts the month.


Try changing your code to:

Code: [Select]
 rtc.setDate(25, 3, 2020);   // Set the date to 25 March 2020

  which is the format used in much of the civilized world.

Don

DRE50

Is there a Library you guys would recommend?

Koepel

For time, the most often used libraries are: the Adafruit RTClib and the TimeLib.

This library supports the DS3231 for the TimeLib: https://github.com/JChristensen/DS3232RTC.

floresta

I have successfully used the Christensen library mentioned in the previous post.

I am currently just using the wire library to deal with the RTC registers directly.  The DS3231 is fairly easy to deal with and the register access is straightforward once you get the hang of it.

Don


Nick_Pyner

If you just want to tell the time
http://bildr.org/2011/03/ds1307-arduino/
no library needed,and works fine with DS3231

Koepel

@Nick_Pyner, thanks, thas is a really short and nice example.

@floresta, if that short example is all that you need, then you can use that. At least put a link to that short example in your sketch. Then you have something to fall back to in case a library causes problems.


floresta

#8
Today at 05:15 pm Last Edit: Today at 05:35 pm by floresta
The example posted by Nick is essentially the same as the code that I first came up with and is all you really need.  

Subsequently I made some changes in how the month and year are dealt with in order to make the RTC data more compatible with the time.h (lower case 't') library.  By doing this I could use strftime() to easily display the results.

Code:
Code: [Select]
// read data from a DS3231RTC chip without using a dedicated RTC library

// Program information
char programName[] = "DS3231_Basic_20A.ino";

/* Program notes
    - Assumes that the clock has previously been set
 - Uses 24 hour clock format
 - Displays date and time in ISO8601 format (YYYY-MM-DD HH:MM:SS)
 - Does not display day-of-week information
 - Does not have provisions to set or adjust the clock data
 - Does not use any of the alarm functions
*/

/*  Differences between time.h and RTC values
  int tm_year;                  // time.h: Years since 1900
                                // RTC:    Years since 2000
                                
  int tm_mon;                   // time.h: Months numbered 0-11
                                // RTC:    Months numbered 1-12
*/

// Hardware connections
/*              ESP8266                       DS3231 Module
               (NodeMCU etc)                     (ZS-042)
             ---------------                   -----------
            |               |                 |           |
            |       (GPIO 5)|D1 ------------> | SCL       |
            |       (GPIO 4)|D2 <-----------> | SDA       |
            |               |3V3 -----------> | VCC       |
            |               |GND -----------> | GND       |
            |               |                 |           |
             ---------------                   -----------
*/

// Required libraries
#include <Wire.h>
//#include <time.h>             // seems to work without this declaration??

#define addr_DS3231 0x68 // I2C address

struct tm timeinfo;             // timeinfo structure (defined in time.h)
  
// ....................................................................................  
void setup()
{
  Serial.begin(115200);
  
  // display sign-on message - useful to determine exactly which version is running
  Serial.println();
  Serial.println();  
  Serial.print(programName);

  Serial.println();

  Wire.begin(); // enable I2C communications
  setupRtc();                           // get the clock into a known state
}      

// ....................................................................................  
void loop()
{
  // get RTC data, strip extraneous bits, and convert BCD to decimal
  getRtcData();
  
  // display the date and time in ISO8601 format
  displayRtcData();
  
  // delay
  delay(10000);
}

// ....................................................................................  
void setupRtc()
{
  //  get the clock into a known state
  //    turn off any Alarms that may be left over from a previous use
  //    disable interrupts from the clock
  //    make sure the clock is running
/*  
        0 0 0 0 0 0 0 0
        | | | | | | | |_____ (A1IE)  - disable Alarm 1 interrupt
        | | | | | | |_______ (A2IE)  - disable Alarm 2 interrupt
        | | | | | |_________ (INTCN) - disable interrupts from alarms
        | | | | |___________ (RS1)   - 1 Hz square wave (if enabled)
        | | | |_____________ (RS2)   -
        | | |_______________ (CONV)  - do not read chip temperature
        | |_________________ (BBSQW) - disable square wave output
        |___________________ (EOSC)  - enable oscillator (low turns clock on)
*/

  Wire.beginTransmission(addr_DS3231); // communicate with the RTC via I2C
  Wire.write(0x0E); // Control register
  Wire.write(B00000000); // write register bitmap
  Wire.endTransmission();  
}

// .......................................................................
void getRtcData()
{
  // request seven bytes of data from DS3231 starting with register 00h
  Wire.beginTransmission(addr_DS3231);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(addr_DS3231, 7);  

  // strip out extraneous bits used by the RTC chip and convert BCD to Decimal
  timeinfo.tm_sec  = bcdToDec(Wire.read() & 0x7F);
  timeinfo.tm_min  = bcdToDec(Wire.read() & 0x7F);
  timeinfo.tm_hour = bcdToDec(Wire.read() & 0x3F);
  timeinfo.tm_wday = bcdToDec(Wire.read() & 0x03);
  timeinfo.tm_mday = bcdToDec(Wire.read() & 0x3F);
  timeinfo.tm_mon  = bcdToDec(Wire.read() & 0x1F);
  timeinfo.tm_year = bcdToDec(Wire.read());
  
  // adjust month and year values to agree with time.h format
  timeinfo.tm_mon = timeinfo.tm_mon - 1;    
  timeinfo.tm_year = timeinfo.tm_year + 100;  
}

// .......................................................................
uint8_t bcdToDec(uint8_t val)
// Convert binary coded decimal to normal decimal numbers
{
  return ( (val/16*10) + (val%16) );
}

// .......................................................................
void displayRtcData()
{
  // display the date and time in this form --> 2020-03-21 12:34:56
  struct tm *timeinfoPtr = &timeinfo;       // pointer to timeinfo structure
  char strfBuf[30];                         // buffer used by strftime()
  
  Serial.print("\nThe present date and time is:  ");  
  strftime(strfBuf, sizeof(strfBuf), "%F %T", timeinfoPtr);  
  Serial.print(strfBuf);    
}




Output:
Code: [Select]
DS3231_Basic_20A.ino

The present date and time is:  2020-04-01 11:07:42
The present date and time is:  2020-04-01 11:07:52


Don

EDIT:  I just realized that this is running on an ESP8266.  I'll dig up an Arduino and check it out.

EDIT2:  It's working fine on a UNO type board.  The only change is that it does require the declaration for the time.h library.

Go Up