Date/Time for RTC as seconds since 1/1/2000

Hi,

I have been using the nice DS3231 RTC along with this library Modified DS3231 library for compatibility with Arduino 1.0 · GitHub

I would like to be able to set the alarm interupt with the number of seconds since 1/1/2000, ie the starting date for this RTC as reported by this function: Serial.print(now.get(),DEC);

The Alarm is currently set by this function which uses hours, minutes and seconds: RTC.enableInterrupts(18,4,16); //ie 18:04:16

Is there a clever coder out there who may guide me on how to write a function that uses Seconds since 1/1/2000 to set the alarm? This would very simply allow me to query the current time with now.get and then add a number of seconds and set the alarm - the nice thing about this would be that all the roller-overs of minutes and hours would be taken care of :slight_smile:

The RTC.enableInterrupts(18,4,0); code from the library that I would like to change to RTC.enableInterrupts(440003968);

//Enable HH/MM/SS interrupt on /INTA pin. All interrupts works like single-shot counter
void DS3231::enableInterrupts(uint8_t hh24, uint8_t mm, uint8_t ss)
{
unsigned char ctReg=0;
ctReg |= 0b00011101;
writeRegister(DS3231_CONTROL_REG, ctReg); //CONTROL Register Address
 
writeRegister(DS3231_AL1SEC_REG, 0b00000000 | bin2bcd(ss) ); //Clr AM1
writeRegister(DS3231_AL1MIN_REG, 0b00000000 | bin2bcd(mm)); //Clr AM2
writeRegister(DS3231_AL1HOUR_REG, (0b00000000 | (bin2bcd(hh24) & 0b10111111))); //Clr AM3
writeRegister(DS3231_AL1WDAY_REG, 0b10000000 ); //set AM4
}

There are (365.25 days/year * 24 hrs/day * 60 min/hr * 60 sec/min) = 31,557,600 sec/year taking into account leap years (but not leap seconds). From 2001 to 2012, there has thus been 378,691,200 seconds elapsed. Why not use that as a starting point instead? Then you only have to account for 1 years worth of time, going on two, as time passes.

Hi Crossroads,

Thanks, I will look at that. Also, looking at the datasheets it looks as if there are some alarm modes which are not implemented in the Library such as ‘When Minutes Match’ & ‘When Minutes and Seconds Match’ - this would suffice as I could just increment minutes and seconds and not worry about what happens to hours, day, months etc - So if I understand right I have modified bit 7 in the registers below to enable ‘When Minutes and Seconds Match’ - might be a bit of a rough code edit but it could work :slight_smile:

//Enable HH/MM/SS interrupt on /INTA pin. All interrupts works like single-shot counter
void DS3231::enableInterrupts(uint8_t hh24, uint8_t mm, uint8_t ss)
{
    unsigned char ctReg=0;
    ctReg |= 0b00011101; 
    writeRegister(DS3231_CONTROL_REG, ctReg);     //CONTROL Register Address

    writeRegister(DS3231_AL1SEC_REG,  0b00000000 | bin2bcd(ss) ); //Clr AM1
    writeRegister(DS3231_AL1MIN_REG,  0b00000000 | bin2bcd(mm)); //Clr AM2
    writeRegister(DS3231_AL1HOUR_REG, (0b10000000 | (bin2bcd(hh24) & 0b10111111))); //Clr AM3
    writeRegister(DS3231_AL1WDAY_REG, 0b10000000 ); //set AM4
}

I suppose.
I wouldn’t have bothered with a library myself; just access the registers directly & do whatever. Then there is no guessing as to what is going on. But I think I am far in the minority on that.

Well I think your right, hacking the Library like this will trip me up in the future - I would prefer to set those register bits from the sketch but really not sure how to do that?

Its just I2C commands. Define some register/address names to make the code easier to follow, then just need a couple lines to write to a register:

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);

Attached is my test code for a DS1307. DS3231 is similar. All the register addresses are right in the datasheet.

RTC_I2C_test__IDE_Serial.ino (8.07 KB)