Maybe it's me, but I have found it unreasonably difficult and confusing to get a basic clock running off the square wave output from the DS3231 module. I don't understand why this isn't more common - it's just one more wire, after all.
I think I have a result at last, which others may find useful.
I take no great credit, I just adapted the standard clock I have used for years, and that was done largely by blunder.
The code is for Mega, using interrupt 4, being pin 19, which is right next to the I2C bus. using interrupt 0, pin 2, would work for both Mega and Uno. I guess it will work without change on a DS1307.
#include "Wire.h"
#define DS3231_ADDRESS 0x68
volatile bool ledstate = 0;
volatile bool interrupt = 1;
void setup(){
Wire.begin();
Serial.begin(9600);
pinMode(13, OUTPUT);//Led
Wire.beginTransmission(0x68); //DS3231 address
Wire.write(0x0E); //ADDRESS The configuration register
Wire.write(0); // DATA To enable the interrupt at 1Hz
Wire.endTransmission();
attachInterrupt(4, rtc_interrupt, FALLING);// pin 19 Mega
//attachInterrupt(0, rtc_interrupt, FALLING); pin 2 Uno OR Mega
}
void loop(){
if (interrupt)
{
digitalWrite(13, ledstate);
//DO STUFF HERE
interrupt = 0;
printDate();// possibly redundant
}
}
byte bcdToDec(byte val)
{
// Convert binary coded decimal to normal decimal numbers
return ( (val/16*10) + (val%16) );
}
void printDate(){
// Reset the register pointer
Wire.beginTransmission(DS3231_ADDRESS);
byte zero = 0x00;
Wire.write(zero);
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 7);
int second = bcdToDec(Wire.read());
int minute = bcdToDec(Wire.read());
int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time
int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
int monthDay = bcdToDec(Wire.read());
int month = bcdToDec(Wire.read());
int year = bcdToDec(Wire.read());
Serial.print(month);
Serial.print("/");
Serial.print(monthDay);
Serial.print("/");
Serial.print(year);
Serial.print(" ");
Serial.print(hour);
Serial.print(":");
Serial.print(minute);
Serial.print(":");
Serial.println(second);
}
void rtc_interrupt()
{
ledstate = !ledstate;
interrupt = 1;
}