Setting RTC DS1307

Will this work to set a DS1307? It works for a DS3231.
You have to type the year, month, etc., manually into the code before you run it.

#include "Wire.h"

void setup() {
  Wire.begin();
  Serial.begin(9600);
  // program to precisely set Chronodot
  Wire.beginTransmission(0x68); // address DS3231
  Wire.write(0x00); // select register
  
  Wire.write(0x30); // seconds (BCD)
  Wire.write(0x43); // minutes (BCD)
  Wire.write(0x17); // hours (BCD)
  Wire.write(0x07); // day of week (I use Mon=1 .. Sun=7)
  Wire.write(0x15); // day of month (BCD)
  Wire.write(0x09); // month (BCD)
  Wire.write(0x13); // year (BCD, two digits)
  
  Wire.endTransmission();
}

void loop() {
  delay(500);  
}
1 Like

OP, FYI

byte decToBcd(byte val) 
{
  return ((val/10*16) + (val%10));
}

byte bcdToDec(byte val) 
{
  return ((val/16*10) + (val%16));
}

Please, tell me which of the following two RTC Modules you own. After that I will guide you using SSS (Start with Small Step) Methodoloy to make your clock working. At the same time, I will try to explain (to the best of my ability) the meanings/purposes of the codes.

image
Figure-1: RTC Module using DS1307 Chip

image
Figure-2: RTC Module using DS3231 Chip

1 Like

I have neither yet. I have sent away for the DS1307. As I have been told the DS3231 is better I will get that. I gather from figure 1, even though it is labelled '12C modules', that it has the DS1307 integrated on it?
Could you explain in regard to the DS3231 please.

Not sure how to manually enter year, month etc into the code. For example for year do I just put 2024 into the brackets after deleting the 0x13. can you tell me for all seconds to year please the specific way to enter everything. thanks.

  • If you have added the DS3231 Library to the IDE, there is an sketch named set_echo under the examples.
    You can use this sketch to set the DS3231 time and date.
  • You enter changes into the Serial Monitor with this:
    Format YYMMDDwhhmmssx
  Serial.println("Format YYMMDDwhhmmssx");
  Serial.println("Where YY = Year (ex. 20 for 2020)");
  Serial.println("      MM = Month (ex. 04 for April)");
  Serial.println("      DD = Day of month (ex. 09 for 9th)");
  Serial.println("      w  = Day of week from 1 to 7, 1 = Sunday (ex. 5 for Thursday)");
  Serial.println("      hh = hours in 24h format (ex. 09 for 9AM or 21 for 9PM)");
  Serial.println("      mm = minutes (ex. 02)");
  Serial.println("      ss = seconds (ex. 42)");
  Serial.println("Example for input : 2405154003600x");  //2024 May 15 Wed. 12AM 36 minutes 0 seconds

Sketch is included below:

/*

Sets the time from input and prints back time stamps for 5 seconds

Based on DS3231_set.pde
by Eric Ayars
4/11

Added printing back of time stamps and increased baud rate
(to better synchronize computer and RTC)
Andy Wickert
5/15/2011

Clean for SAMD arch, add explanation, respect code-style and
fix interpretation of Serial input if used more than once
Olivier Staquet
4/26/2020

*/

#include <DS3231.h>
#include <Wire.h>

DS3231 myRTC;

byte year;
byte month;
byte date;
byte dow;
byte hour;
byte minute;
byte second;

bool century = false;
bool h12Flag;
bool pmFlag;

/*****************************************************************************************************
 * Setup
 *  - Open Serial and Wire connection
 *  - Explain to the user how to use the program
 *****************************************************************************************************/
void setup() {
  // Start the serial port
  Serial.begin(57600);

  // Start the I2C interface
  Wire.begin();

  // Request the time correction on the Serial
  delay(4000);
  Serial.println("Format YYMMDDwhhmmssx");
  Serial.println("Where YY = Year (ex. 20 for 2020)");
  Serial.println("      MM = Month (ex. 04 for April)");
  Serial.println("      DD = Day of month (ex. 09 for 9th)");
  Serial.println("      w  = Day of week from 1 to 7, 1 = Sunday (ex. 5 for Thursday)");
  Serial.println("      hh = hours in 24h format (ex. 09 for 9AM or 21 for 9PM)");
  Serial.println("      mm = minutes (ex. 02)");
  Serial.println("      ss = seconds (ex. 42)");
  Serial.println("Example for input : 2405154003600x");
  Serial.println("-----------------------------------------------------------------------------");
  Serial.println("Please enter the current time to set on DS3231 ended by 'x':");
}

/*****************************************************************************************************
 * Loop
 *  - Each time we receive the time correction on the Serial
 *  - Set the clock of the DS3231
 *  - Echo the value from the DS3231 during 5 seconds
 *****************************************************************************************************/
void loop() {
  // If something is coming in on the serial line, it's
  // a time correction so set the clock accordingly.
  if (Serial.available()) {
    inputDateFromSerial();

    myRTC.setClockMode(false);  // set to 24h

    myRTC.setYear(year);
    myRTC.setMonth(month);
    myRTC.setDate(date);
    myRTC.setDoW(dow);
    myRTC.setHour(hour);
    myRTC.setMinute(minute);
    myRTC.setSecond(second);

    // Give time at next five seconds
    for (uint8_t i = 0; i < 5; i++){
        delay(1000);
        Serial.print(myRTC.getYear(), DEC);
        Serial.print("-");
        Serial.print(myRTC.getMonth(century), DEC);
        Serial.print("-");
        Serial.print(myRTC.getDate(), DEC);
        Serial.print(" ");
        Serial.print(myRTC.getHour(h12Flag, pmFlag), DEC); //24-hr
        Serial.print(":");
        Serial.print(myRTC.getMinute(), DEC);
        Serial.print(":");
        Serial.println(myRTC.getSecond(), DEC);
    }

    // Notify that we are ready for the next input
    Serial.println("Please enter the current time to set on DS3231 ended by 'x':");
  }
  delay(1000);
}

/*****************************************************************************************************
 * inputDateFromSerial
 *  - Read and interpret the data from the Serial input
 *  - Store the data in global variables
 *****************************************************************************************************/
void inputDateFromSerial() {
	// Call this if you notice something coming in on
	// the serial port. The stuff coming in should be in
	// the order YYMMDDwHHMMSS, with an 'x' at the end.
	boolean isStrComplete = false;
	char inputChar;
	byte temp1, temp2;
	char inputStr[20];

	uint8_t currentPos = 0;
	while (!isStrComplete) {
		if (Serial.available()) {
			inputChar = Serial.read();
			inputStr[currentPos] = inputChar;
			currentPos += 1;

      // Check if string complete (end with "x")
			if (inputChar == 'x') {
				isStrComplete = true;
			}
		}
	}
	Serial.println(inputStr);

  // Find the end of char "x"
  int posX = -1;
  for(uint8_t i = 0; i < 20; i++) {
    if(inputStr[i] == 'x') {
      posX = i;
      break;
    }
  }

  // Consider 0 character in ASCII
  uint8_t zeroAscii = '0';

	// Read Year first
	temp1 = (byte)inputStr[posX - 13] - zeroAscii;
	temp2 = (byte)inputStr[posX - 12] - zeroAscii;
	year = temp1 * 10 + temp2;

	// now month
	temp1 = (byte)inputStr[posX - 11] - zeroAscii;
	temp2 = (byte)inputStr[posX - 10] - zeroAscii;
	month = temp1 * 10 + temp2;

	// now date
	temp1 = (byte)inputStr[posX - 9] - zeroAscii;
	temp2 = (byte)inputStr[posX - 8] - zeroAscii;
	date = temp1 * 10 + temp2;

	// now Day of Week
	dow = (byte)inputStr[posX - 7] - zeroAscii;

	// now Hour
	temp1 = (byte)inputStr[posX - 6] - zeroAscii;
	temp2 = (byte)inputStr[posX - 5] - zeroAscii;
	hour = temp1 * 10 + temp2;

	// now Minute
	temp1 = (byte)inputStr[posX - 4] - zeroAscii;
	temp2 = (byte)inputStr[posX - 3] - zeroAscii;
	minute = temp1 * 10 + temp2;

	// now Second
	temp1 = (byte)inputStr[posX - 2] - zeroAscii;
	temp2 = (byte)inputStr[posX - 1] - zeroAscii;
	second = temp1 * 10 + temp2;
}

This code is in arduino for setting the time on the ds 1307 real time clock.

#include <time.h>
#include <DS1307 RTC.h>
#include <Wire.h>
set time(hr,min,sec,day,month,yr);
RTC. set(now());

Does anyone know the data that should be entered here. should hour be a number 1-24, minute 0-60, sec 0-60, day 1 -7 (sunday day 1 e.g), month 1-12(january =1?, year 24?
Somebody on this forum should know this. This is much simpler than any other code people have proposed on this forum. I presume the last 2 lines should be in set up and void loop would be left blank. Then load will set the clock on the ds1307.

The name of the library in the code snippet that you posted is obviously wrong. Does whatever library you are really using not come with some examples ?

It would be even easier to open the library and look at an example than to ask on the forum.

In answer to your question, the answerer will do exactly that - open the library and look at the example. So why do you force someone else to do it instead of doing it yourself?

If you use the TimeLib, then here is explanation: https://www.pjrc.com/teensy/td_libs_Time.html

If you use the Adafruit RTClib, then here is a tutorial: https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit

The Arduino IDE has a "Library Manager". Here is a list of timing libraries that can be selected in the Library Manager: https://www.arduinolibraries.info/categories/timing

Arduino has "time" libraries for some of the Arduino boards. The "time" library of the 'C' language can be used. Github has hundreds of "time" libraries.

If you want to know the values for the registers of the DS1307, then you can read the datasheet of the DS1307.

Can you tell what your project is for ? Which Arduino board do you use ? Which RTC module have you bought ?

Here is an example from the IDE

  //                  YYYY  MM  DD  HH  MM  SS
  rtc.adjust(DateTime(2024, 05, 15, 00, 00, 00));
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup ()
{
  while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(115200);
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning())
  {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    //                    YYYY MM DD HH MM SS
    //rtc.adjust(DateTime(2024,05,15,00,00,00));
  }
  
  //                  YYYY  MM  DD  HH  MM  SS
  rtc.adjust(DateTime(2024, 05, 15, 00, 00, 00));
}

void loop ()
{
  DateTime now = rtc.now();

  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(") ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

  delay(3000);
}

@petercl14
Why did you open a new thread about the 1307 RTC?
Please keep your discussion inside the single topic.
Duplicate threads is violation of the forum rules.

@petercl14 , please do not waste people's time. I've merged your other topic with this one.

2 Likes

Please, get one whichever you like. You can buy both if you like as a hobbyist who keeps many things in his store.

It is his style - to waste the other's time rather than make a smallest effort from his side.
@petercl14 - 4 years on forum, 87 started thread - and still asking an absolute beginner questions... like an argument's format of settime() function

That looks about right Larry for the data input. The Arduino coding is this way around;
setTime(hr,min,sec,day,month,yr) Only way to know for sure is when I get the hardware DS1307.

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