RTC DS3231

Hi, I need help on how to set initial time on my rtc connected to arduino uno. I am in search of a complete walk through, Ive exhausted youtube and other forums and have had no success in getting the initial time date and day of week set. All help is appreciated. thank you

Are you using an Arduino RTC library? Which one? Have you looked at the examples that come with it?

Yes, I can not figure it out. Nor do I know which library I am using. I am at a complete loss

engr2017:
Yes, I can not figure it out. Nor do I know which library I am using. I am at a complete loss

What is the name of the RTC library that you are using ?
How did you install it ?

I do not think I have one. I have downloaded some.but I do not know how to install them

In any sketch :

In the Tools menu select Manage Libraries
Enter DS3231 into the search box
Find the library named DS3231RTC on the list and install it
Close the Library Manager

Now under File/Examples you will find DS3231RTC on the list, one of which is SetSerial which allows you to set the time on the RTC and display it

Note that many other libraries for the DS3231 are available some of which offer better features but this one will do what you want for now

Run this code to set the initial time. Then load your intended sketch.

/*
Test of RTC DS1307 via I2C.
 Counts 
 Seconds, 
 Minutes, 
 Hours, 
 Date of the Month, 
 Month, 
 Day of the week, and 
 Year with Leap-Year
 
 56 bytes battery backed RAM
 Square Wave Output
 
 11/17/2012- Updated for Wire.write & Wire.read commands
 1/18/13 - fixed unclear reference to 0x00
 */


/*
Modified to Run thru IDE Serial port
*/
#include <Wire.h>


//variables
byte zeroByte = 0;
byte seconds_address = 0x00;
byte seconds; // bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9


byte minutes_address = 0x01;
byte minutes;  // bits 6-5-4 = tens of minutes, bits 3-2-1-0 = units of minutes


byte hours_address = 0x02; 
byte hours;  // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)


byte day_week_address = 0x03; 
byte day_week = 0; // range 01-07


byte date_month_address = 0x04;
byte date_month = 0; // range 01-31


byte month_address = 0x05;
byte month = 0; // range 01-12


byte year_address = 0x06;
int year = 0; // upper byte 0-9, lower byte 0-9


byte square_address = 0x07;
byte sqwe = 0;  // square wave enable
// Out-0-0-Sqwe-0-0-RS1-RS0
// Out, Sqwe = 0/0 - Square wave output = 0
// Out, Sqwe = 1/0 - Square wave output = 1
// Out, Sqwe = 0/1 or 1/1 - Square wave output per RS1/RS0
// RS1/RS0 = 00 = 1 Hz
// RS1/RSo = 01 = 4 KHz
// RS1/RS0 = 10 = 8 KHz
// RS1/RS0 = 11 = 32 KHz


byte RTC_ram_address = 0x08; //range = 08-63, 0x08-0x3F


int RTC_address = 0x68; // 1101 000 


byte incomingCommand = 0;
byte RTC_write_command = 0;
byte RTC_read_command = 0;
byte RTC_ram_command = 0;


// use F0xx, F1xx,F2xx, F3xx, F4xx, F5xx, F6xx, F7xx
// to send one register write commands
// use E0xx to read registers back - not coded yet
// use C0xx to read RAM back - not coded yet


byte incomingRegister = 0;
byte RTC_register = 0;
byte incomingData1 = 0;
byte incomingData2 = 0;
byte new_data = 0;
byte outgoingData = 0;
int delay_time = 100;


unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long duration = 5000;


void setup() {
  Wire.begin(); // no address, we are master
  Serial.begin (57600);  
  Serial.flush();
  currentMillis = millis();  
}


void loop() {


  if (Serial.available() >3){
    incomingCommand = Serial.read();
    incomingRegister = Serial.read();
    incomingData1 = Serial.read();
    incomingData1 = incomingData1 - 0x30; // convert ASCII to HEX
    incomingData2 = Serial.read();
    incomingData2 = incomingData2 - 0x30;  // convert ASCII to HEX
    new_data = (incomingData1 << 4) + incomingData2;  // put the Upper/Lower nibbles together
    Serial.print ("command ");
    Serial.println (incomingCommand);
    Serial.print ("register ");
    Serial.println(incomingRegister);
    Serial.print ("data1 ");
    Serial.println (incomingData1, HEX);
    Serial.print ("data2 ");
    Serial.println (incomingData2, HEX);
    Serial.print ("combined data ");    
    Serial.println (new_data, HEX);
    
  }
  // *******************************************
//  RTC_write_command = incomingCommand & 0xF0;  // mask off high byte
//  if (RTC_write_command == 0xF0){  // check for Write command
if ((incomingCommand == 'F') | (incomingCommand == 'f')){
  incomingCommand = 0;  // reset for next pass
//    RTC_register = incomingCommand & 0x0F;  // mask off low btye
//    incomingCommand = 0;
//    new_data = incomingData;
    Serial.println (" Sending a command ");
//    switch (RTC_register){
switch (incomingRegister){
  case '0': // write seconds
        Serial.println ("Seconds ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(seconds_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
      delay (delay_time);
      break;
    case '1': // write minutes
    Serial.println ("Minutes ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(minutes_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
      delay (delay_time);
      break;
    case '2': // write hours
        Serial.println ("Hours ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(hours_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '3': // write day
        Serial.println ("Day ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(day_week_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '4': // write date of month
        Serial.println ("Day of Month ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(date_month_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '5': // write month
        Serial.println ("Month ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(month_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '6': // write year
        Serial.println ("Year ");
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(year_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '7': // write square wave
        Serial.println ("Square Wave ");
    Serial.println (RTC_register, HEX);
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(square_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
    case '8': // write RAM
        Serial.print ("RAM ");
    Serial.println (RTC_register, HEX);
      Wire.beginTransmission(RTC_address); // select device
      Wire.write(RTC_ram_address);          // queue the register
      Wire.write(new_data);                  // queue data
      Wire.endTransmission();            // send it
     delay (delay_time);
      break;
      // all others,do nothing
      Serial.println ("Invalid command ");
    }  // end Switch
  } // end if command == 'F'
  // ************************************


  currentMillis = millis();
  if ( (currentMillis - previousMillis) >= duration){
    previousMillis = currentMillis;  
    // Reset the register pointer  
    Wire.beginTransmission(RTC_address);  
    Wire.write(zeroByte);  
    Wire.endTransmission();   


    Wire.requestFrom(RTC_address,8 );  
    seconds = Wire.read();  
    minutes = Wire.read();  
    hours = Wire.read();  
    day_week = Wire.read();  
    date_month = Wire.read();  
    month = Wire.read();  
    year = Wire.read();  
    sqwe = Wire.read();


    // Seconds 
    // bit 7 = Clock Halt, Enabled = 0, Halt = 1
    // bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9 


    // Hours
    // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
    // bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
    // bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)


    Serial.print ("Hrs " );
    Serial.print (hours, HEX);
    Serial.print (" Mins ");
    Serial.print (minutes, HEX);
    Serial.print (" Secs ");
    Serial.print (seconds, HEX);
    Serial.print (" Day ");
    Serial.print (day_week, HEX);
    Serial.print (" Date ");
    Serial.print (date_month, HEX);
    Serial.print (" Month ");
    Serial.print (month, HEX);
    Serial.print (" Year 20");
    Serial.print (year, HEX);
    Serial.print (" Square Wave ");
    Serial.println (sqwe, HEX);


  }
}

I successfully got this done now I found this code on the internet and experimented with it. how could this code be modified to to trigger the relay at specific times at specific days of the week?

// include all the libraries
#include <Wire.h> // Required by RTClib
#include <LiquidCrystal.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <TimeAlarms.h>
// set up the LCD pins
LiquidCrystal lcd(9, 8, 4, 5, 6, 7);
void setup() {

pinMode(10, OUTPUT);
lcd.begin (16, 2); // for 16 x 2 LCD module
lcd.clear();
lcd.setCursor(0, 0);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if (timeStatus() != timeSet)
lcd.print("Unable to sync with the RTC");
else
lcd.print("RTC has set the system time");
delay(1500);
lcd.clear();
// Set the allram times to go off
Alarm.alarmRepeat(17, 38 , 0, morningbegin); // 09:58am every day
Alarm.alarmRepeat(17, 39, 0, morningstart); // 09:58am every day
Alarm.alarmRepeat(17, 40, 0, morningfinish); // 10:30Am every day
Alarm.alarmRepeat(12, 41, 0, dinnerstart); // 12:58PM every day
Alarm.alarmRepeat(13, 42, 0, dinnerfinish); // 1:30Pm every day
Alarm.alarmRepeat(17, 43, 0, hometime); // 5:25pm every day
}

void loop() {
digitalClockDisplay(); //Display the data
Alarm.delay(1000); // wait one second between clock display(could be removed)
}
// Display the time and date
void digitalClockDisplay() {
lcd.setCursor(3, 0);
printDigits(day());
lcd.print(day());
lcd.print("/");
printDigits(month());
lcd.print(month());
lcd.print("/");
lcd.print(year());
lcd.setCursor(4, 1);
printDigits(hour());
lcd.print(hour());
lcd.print(":");
printDigits(minute());
lcd.print(minute());
lcd.print(":");
printDigits(second());
lcd.print(second());
}

void printDigits(int digits) {
if (digits < 10)
lcd.print('0');
}
void morningbegin() {
digitalWrite(10, HIGH); // turn the relay on (HIGH is the voltage level)
Alarm.delay(4000); // wait for Sound bell for 4 seconds
digitalWrite(10, LOW); // turn the relay off by making the voltage LOW
}

void morningstart() {
digitalWrite(10, HIGH); // turn the relay on (HIGH is the voltage level)
Alarm.delay(4000); // wait for Sound bell for 4 seconds
digitalWrite(10, LOW); // turn the relay off by making the voltage LOW
}
void morningfinish() {
digitalWrite(10, HIGH); // turn the relay on (HIGH is the voltage level)
Alarm.delay(4000); // wait for Sound bell for 4 seconds
digitalWrite(10, LOW); // turn the relay off by making the voltage LOW
}
void dinnerstart() {
digitalWrite(10, HIGH); // turn the relay on (HIGH is the voltage level)
Alarm.delay(4000); // wait for Sound bell for 4 seconds
digitalWrite(10, LOW); // turn the relay off by making the voltage LOW
}
void dinnerfinish() {
digitalWrite(10, HIGH); // turn the relay on (HIGH is the voltage level)
Alarm.delay(4000); // wait for Sound bell for 4 seconds
digitalWrite(10, LOW); // turn the relay off by making the voltage LOW
}
void hometime() {
digitalWrite(10, HIGH); // turn the relay on (HIGH is the voltage level)
Alarm.delay(4000); // wait for Sound bell for 4 seconds
digitalWrite(10, LOW); // turn the relay off by making the voltage LOW

Please follow the advice on posting code given in posting code

In particular note the advice to Auto format code in the IDE and to use code tags when posting code here as it prevents some combinations of characters in code being interpreted as HTML commands such as italics, bold or a smiley character, all of which render the code useless

how could this code be modified to to trigger the relay at specific times at specific days of the week?

See the documentation on the alarm calls available with the TimeAlarms.h
https://www.pjrc.com/teensy/td_libs_TimeAlarms.html

Read in the current RTC data.

if (dayNow == alarmDay){
   if (hourNow == alarmHour){
     if (minuteNow == alarmMinute){
        if (secondNow == secondAlarm){
           // do your action
        }
     }
   }
}

**1. **Let us follow this tutorial to operate DS3231 RTC Module based on RTClib.h Library (Jeelab's fantastic RTC library); where, we will --
(1) Set initial time of the day either manually or auto update from Computer.
(2) The time of the day (HRS:MIN:SEC) will be shown on Serial Monitor at 1-sec interval using delay() function. (In reality, the 1-sec time interval will be coming from the internal 1-sec elapse time of RTC fro which we have to write extra codes.)

2. Let us connect DS3231 RTC Module with UNO as per following diagram (Fig-1).
RTCSM.png
Figure-1:

3. Upload the following sketch and check that the Serial Monitor shows time of the day.

#include<Wire.h>
#include<RTClib.h>  //Jeelab's fantastic RTC library from GitHub
RTC_DS3231 rtc;

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  rtc.begin();
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));//auto update from computer time
  rtc.adjust(DateTime(2021, 1, 31, 12, 8, 57));//set date-time manualy:yr,mo,dy,hr,mn,sec
  
  //--checking if DS3231 is present-----------------
  Wire.beginTransmission(0x68);
  byte busStatus = Wire.endTransmission();
  if (busStatus != 0)
  {
    Serial.print("DS3231 RTC is not found...!");
    while(1); //wait for ever
  }
  Serial.println("DS3231 RTC found...!");
}

void loop()
{
  //--- show Time in this format HRS:MIN:SEC
  DateTime nowDT = rtc.now(); //now() method returns current date and time (DT)
  Serial.print(nowDT.hour()); Serial.print(':');
  Serial.print(nowDT.minute()); Serial.print(':');
  Serial.println(nowDT.second());
  //-----------------------------------------------
  delay(1000);  //this delay should be taken from RTC's 1-sec elapse time with extra codes
}

4. Alternate codes where 1-sec time delay is offered by the RTC itself.

#include <Wire.h>
#include "RTClib.h"
byte prSec = 0;
RTC_DS3231 rtc;

void setup ()
{
  Serial.begin(9600);
  rtc.begin();
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //Date and Time are taken from Computer
  rtc.adjust(DateTime(2021, 12, 31, 11, 59, 57));//set date-time manualy:yr,mo,dy,hr,mn,sec
}

void loop ()
{
  showTime();
  timeDelay();
}
//===================================================
void showTime()
{
  DateTime nowDT = rtc.now();
  Serial.print(nowDT.hour(), DEC); Serial.print(':');
  //-------------------------------------------------
  byte myMin = nowDT.minute();
  if (myMin < 10)
  {
    Serial.print('0');
  }
  Serial.print(nowDT.minute(), DEC); Serial.print(':');
  //--------------------------------------------------
  byte mySec = nowDT.second();
  if (mySec < 10)
  {
    Serial.print('0');
  }
  Serial.println(nowDT.second(), DEC);
}
//---------------------------------------------
void timeDelay()
{
  prSec = bcdSecond();   //current second of RTC
  while (bcdSecond() - prSec != 1)
  {
    ;
  }
  prSec = bcdSecond(); //delay(1000);
}

byte bcdSecond()
{
  DateTime nowTime = rtc.now();
  if (nowTime.second() == 0 )
  {
    prSec = 0;
    return prSec;
  }
  else
  {
    DateTime nowTime = rtc.now();
    return nowTime.second();
  }
}
//==========================================

Note: There are many libraries under this name: "RTClib.h" of which I prefer to use "Jeelab's fantastic RTC library". The procedure to include this library in the IDE are:
Sketch ---> Include Library ----> Add .ZIP... Library and follow the menu.

RTCSM.png

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.