problem with RTC DS1337 and unix time

i try to see the unix time from a ds1337 RTC.

i tried this code:

#include <DS1337.h>
#include <Wire.h>


DS1337 RTC = DS1337();
int i=0;
long c;
void setup() {
   Serial.begin(115200);
   RTC.start();
}

void loop(){
 i++;
 Serial.print(i);
 RTC.readTime();
 Serial.print("  ");
 Serial.println(byte(RTC.readTime()));
 delay(1000);
}

but it does not compile... the problem is located in this line:

Serial.println(byte(RTC.readTime()));

and the error message from Arduino IDE is:

error: void value not ignored as it ought to be

I am not sure now, but i was sure to use this code some time ago without problems...

I am using Arduino IDE 022.

Any idea? Thanks!

It sounds as if RTC.readTime() returns void, not the actual time. I don't think there's "a" RTC library -- googling finds several libraries -- so you'll have to specify which one you're using. Or just look up readTime() in the header file. (At least my copy of Arduino 022 doesn't have a DS1337.h header file -- where did you get it from?)

My guess is that the library wants you to first call readTime() to read the time into the RTC variable, and then ask the RTC variable for the time it last read using some other function.

Thanks jwatte,

I said "a" exactly because there is not the unique library.... otherwise i could wrote "the". But you are right! I should be more clear when asking, sorry.

I do not remember from where i obtained the library, because i tested all the available for this RTC. Then, i post here the library (if someone knows the author, please, let me know):

DS1337.h

/*
  DS1337.h - library for DS1337 rtc
*/

// ensure this library description is only included once
#ifndef DS1337_h
#define DS1337_h

// include types & constants of Wiring core API
#include <WProgram.h>
#include <WConstants.h>

// include types & constants of Wire ic2 lib
#include <Wire.h>

// indices within the rtc_bcd[] buffer
#define DS1337_SEC	0
#define DS1337_MIN	1
#define DS1337_HR	2
#define DS1337_DOW	3
#define DS1337_DATE     4
#define DS1337_MTH	5
#define DS1337_YR	6

#define DS1337_BASE_YR		2000

#define DS1337_CTRL_ID		B1101000

 // Define register bit masks
#define DS1337_CLOCKHALT	B10000000

#define DS1337_LO_BCD		B00001111
#define DS1337_HI_BCD		B11110000

#define DS1337_HI_SEC		B01110000
#define DS1337_HI_MIN		B01110000
#define DS1337_HI_HR		B00110000
#define DS1337_LO_DOW		B00000111
#define DS1337_HI_DATE		B00110000
#define DS1337_HI_MTH		B00110000
#define DS1337_HI_YR		B11110000

#define DS1337_ARLM1		0x07
#define DS1337_ARLM1_LO_SEC	B00001111
#define DS1337_ARLM1_HI_SEC	B01110000
#define DS1337_ARLM1_LO_MIN	B01110000
#define DS1337_ARLM1_HI_MIN	B00001111

#define DS1337_SP			0x0E
#define	DS1337_SP_EOSC		B10000000
#define	DS1337_SP_RS2		B00010000
#define	DS1337_SP_RS1		B00001000
#define	DS1337_SP_INTCN		B00000100
#define	DS1337_SP_A2IE		B00000010
#define	DS1337_SP_A1IE		B00000001

#define DS1337_STATUS		0x0F
#define DS1337_STATUS_OSF	B10000000
#define DS1337_STATUS_A2F	B00000010
#define DS1337_STATUS_A1F	B00000001

/* Definitions for alarm repeat */
/* The private variable alarm_repeat holds the user's alarm repeat preference. However, the DS1337 encodes these in the topmost bit(s) of the 4 alarm registers. */
/* Splattering these bits across the alarm regs is handled in the writeAlarm() function. */
/* If DY/DT is set, the day field is interpreted as a DayOfWeek (1 ~ 7), else it is interpreted as a DayOfMonth.*/

/* user alarm_repeat bit mask:
       7   6   5    4       3      2       1     0
      [x   x   x   A1M4   DY/DT   A1M3   A1M2   A1M1]
*/

#define EVERY_SECOND       B00010111
#define EVERY_MINUTE       B00010110
#define EVERY_HOUR         B00010100
#define EVERY_DAY          B00010000
#define EVERY_WEEK         B00001000
#define EVERY_MONTH        B00000000


/* typedef struct {
  unsigned int year;
  unsigned char month;
  unsigned char day;
  unsigned char dayOfWeek;
  unsigned char hour;
  unsigned char minute;
  unsigned char second;
} TIME; */


// library interface description
class DS1337
{
	// user-accessible "public" interface
	public:
		DS1337();

		unsigned char time_is_set();
		unsigned char alarm_is_set();
		//unsigned char time_is_valid();

		unsigned char enable_interrupt();
		unsigned char disable_interrupt();
		unsigned char clear_interrupt();

		void    readTime();
		void    readAlarm();
		void    writeTime();
                void    writeTime(unsigned long);
		void    writeAlarm();
                void    writeAlarm(unsigned long);
                void    setAlarmRepeat(byte repeat);


		void	getTime(int *);
                unsigned char getSeconds();
                unsigned char getMinutes();
                unsigned char getHours();
                unsigned char getDays();
                unsigned char getDayOfWeek();
                unsigned char getMonths();
                unsigned int getYears();
                unsigned long date_to_epoch_seconds(unsigned int year, byte month, byte day, byte hour, byte minute, byte second);
                unsigned long date_to_epoch_seconds();
                void epoch_seconds_to_date(unsigned long);
                //void snooze(unsigned long secondsToSnooze);
                //unsigned long date2seconds();

                //void writeTime(int *);

                void setSeconds(unsigned char);
                void setMinutes(unsigned char);
                void setHours(unsigned char);
                void setDays(unsigned char);
                void setDayOfWeek(unsigned char);
                void setMonths(unsigned char);
                void setYears(unsigned int);


		void	start(void);
		void	stop(void);
		unsigned char getRegister(unsigned char registerNumber);
		void	setRegister(unsigned char registerNumber, unsigned char registerValue);
		//void	unsetRegister(unsigned char registerNumber, unsigned char registerMask);

	// library-accessible "private" interface
	private:
	        byte    time_set;
	        byte alarm_repeat;
		byte	rtc_bcd[7]; // used prior to read/set DS1337 registers;
		void	read(void);
		void	save(void);
		byte bcd2bin(byte);
		byte bin2bcd(byte);
};

//extern DS1337 RTC;

#endif

and here the next file:

DS1337.ccp

extern "C" {
//	#include <Wire/Wire.h>
	#include <Wire.h>
	#include <avr/pgmspace.h>
}

#include "DS1337.h"
//#include "programStrings.h"

// NOTE: To keep the math from getting even more lengthy/annoying than it already is, the following constraints are imposed:
//   1) All times are in 24-hour format (military time)
//   2) DayOfWeek field is not used internally or checked for validity. Alarm functions may optionally set alarms repeating on DayOfWeek, but this feature has not been tested yet.
//   3) This library's buffer stores all times in raw BCD format, just as it is sent from the RTC.
//      It is not converted to/from 'real' (binary) values until needed via get...() and set...() functions.
//      In other words, don't go hacking around and reading from the rtc_bcd[] buffer directly, unless you want the raw BCD results.

// Cumulative number of days elapsed at the start of each month, assuming a normal (non-leap) year.
unsigned int monthdays[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};

DS1337::DS1337() {
   wire.begin();
}

// Aquire data from the RTC chip in BCD format
// refresh the buffer
void DS1337::readTime(void)
{
// use the Wire lib to connect to tho rtc
// reset the register pointer to zero
	Wire.beginTransmission(DS1337_CTRL_ID);
	Wire.send(0x00);
	Wire.endTransmission();

// request the 7 bytes of data    (secs, min, hr, dow, date. mth, yr)
	Wire.requestFrom(DS1337_CTRL_ID, 7);
	for(int i=0; i<7; i++)
	{
	// store data in raw bcd format
		if (Wire.available())
			rtc_bcd[i]=Wire.receive();
	}
}

// Read the current alarm value. Note that the repeat flags and DY/DT are removed from the result.
void DS1337::readAlarm(void)
{
        //alarm_repeat = 0;
        byte temp;
// use the Wire lib to connect to tho rtc
// point to start of Alarm1 registers
	Wire.beginTransmission(DS1337_CTRL_ID);
	Wire.send(DS1337_ARLM1);
	Wire.endTransmission();

// request the *4* bytes of data (secs, min, hr, dow/date). Note the format is nearly identical, except for the choice of dayOfWeek vs. date,
// and that the topmost bit of each helps determine if/how the alarm repeats.
	Wire.requestFrom(DS1337_CTRL_ID, 4);
	for(int i=0; i<4; i++)
	{
                // store data in raw bcd format
		if (Wire.available())
                        temp = Wire.receive();
                        rtc_bcd[i] = temp & B01111111;
	}

	// 4th byte read may contain either a date or DayOfWeek, depending on the value of the DY/DT flag.
	// For laziness sake we read it into the DayOfWeek field regardless (rtc_bcd[3]). Correct as needed...
        if(rtc_bcd[3] & B01000000) // DY/DT set: DayOfWeek
        {
           rtc_bcd[3] &= B10111111; // clear DY/DT flag
           rtc_bcd[4] = 0; // alarm *date* undefined
        }
        else
        {
            rtc_bcd[4] = rtc_bcd[3];
            rtc_bcd[3] = 0; // alarm dayOfWeek undefined
        }
}

// update the data on the IC from the bcd formatted data in the buffer

void DS1337::writeTime(void)
{
        //byte temp;
	Wire.beginTransmission(DS1337_CTRL_ID);
	Wire.send(0x00); // reset register pointer
	for(int i=0; i<7; i++)
	{
		Wire.send(rtc_bcd[i]);
	}
	Wire.endTransmission();

	// clear the Oscillator Stop Flag
        setRegister(DS1337_STATUS, getRegister(DS1337_STATUS) & !DS1337_STATUS_OSF);
        //temp = getRegister(DS1337_STATUS);
        //temp &= (!DS1337_STATUS_OSF);
        //setRegister(DS1337_STATUS, temp);
}

void DS1337::writeTime(unsigned long sse)
{
        epoch_seconds_to_date(sse);
        writeTime();
}

// FIXME: automatically set alarm interrupt after writing new alarm? Nah...

// Write the BCD alarm value in the buffer to the alarm registers.
// If an alarm repeat mode has been specified, poke those bytes into the buffer before sending.
void DS1337::writeAlarm(void)
{
	Wire.beginTransmission(DS1337_CTRL_ID);
	Wire.send(DS1337_ARLM1); // set register pointer

        Wire.send(rtc_bcd[DS1337_SEC] | ((alarm_repeat & B00000001 ) << 7)); // A1M1
        Wire.send(rtc_bcd[DS1337_MIN] | ((alarm_repeat & B00000010 ) << 6)); // A1M2
        Wire.send(rtc_bcd[DS1337_HR] | ((alarm_repeat & B00000100 ) << 5)); // A1M3

        // Check if we are using date or DayOfWeek and send the appropriate value
        if(alarm_repeat & B00001000) // DayOfWeek
        {
            // send DOW as 4th alarm reg byte
            Wire.send(rtc_bcd[DS1337_DOW] | ((alarm_repeat & B00011000 ) << 3)); // A1M4 and DY/DT
        }
        else // date
        {
            // send date as 4th alarm reg byte
            Wire.send(rtc_bcd[DS1337_DATE] | ((alarm_repeat & B00011000 ) << 3)); // A1M4 and DY/DT
        }

	Wire.endTransmission();
}


void DS1337::writeAlarm(unsigned long sse)
{
        epoch_seconds_to_date(sse);
        writeAlarm();
}

void DS1337::setAlarmRepeat(byte repeat)
{
        alarm_repeat = repeat;
}


// Decided to let the user implement any needed snooze function, since we don't know in advance if they are currently handling the interrupt,
// and if we optionally handle it ourselves, switching around pointers between member and user functions here will get messy...

/* void DS1337::snooze(unsigned long secondsToSnooze)
{
...
} */


unsigned char DS1337::getRegister(unsigned char registerNumber)
{
	Wire.beginTransmission(DS1337_CTRL_ID);
	Wire.send(registerNumber);
	Wire.endTransmission();

	Wire.requestFrom(DS1337_CTRL_ID, 1);

	return Wire.receive();
}

void DS1337::setRegister(unsigned char registerNumber, unsigned char value)
{
	Wire.beginTransmission(DS1337_CTRL_ID);
	Wire.send(registerNumber); // set register pointer

	Wire.send(value);

	Wire.endTransmission();
}

unsigned char DS1337::time_is_set()
{
  // Return TRUE if Oscillator Stop Flag is clear (osc. not stopped since last time setting), FALSE otherwise
  byte asdf = ((getRegister(DS1337_STATUS) & DS1337_STATUS_OSF) == 0);
  return asdf;
}
unsigned char DS1337::alarm_is_set()
{
  // Return TRUE if the alarm interrupt flag is enabled.
  byte asdf = (getRegister(DS1337_SP) & DS1337_SP_A1IE);
  return asdf;
}

unsigned char DS1337::enable_interrupt()
{
   clear_interrupt();
   setRegister(DS1337_SP, getRegister(DS1337_SP) | DS1337_SP_INTCN | DS1337_SP_A1IE); // map alarm interrupt to INT1 and enable interrupt
}

unsigned char DS1337::disable_interrupt()
{
   setRegister(DS1337_SP, getRegister(DS1337_SP) & !DS1337_SP_A1IE);
}

unsigned char DS1337::clear_interrupt()
{
   setRegister(DS1337_STATUS, getRegister(DS1337_STATUS) & !DS1337_STATUS_A1F);
}

unsigned char DS1337::getSeconds()
{
    return bcd2bin(rtc_bcd[DS1337_SEC]);
}

unsigned char DS1337::getMinutes()
{
    return bcd2bin(rtc_bcd[DS1337_MIN]);
}
unsigned char DS1337::getHours()
{
    return bcd2bin(rtc_bcd[DS1337_HR]);
}
unsigned char DS1337::getDays()
{
    return bcd2bin(rtc_bcd[DS1337_DATE]);
}
unsigned char DS1337::getDayOfWeek()
{
    return bcd2bin(rtc_bcd[DS1337_DOW]);
}
unsigned char DS1337::getMonths()
{
    return bcd2bin(rtc_bcd[DS1337_MTH]);
}
unsigned int DS1337::getYears()
{
    return 2000 + bcd2bin(rtc_bcd[DS1337_YR]);
}

and follows here:

unsigned long DS1337::date_to_epoch_seconds(unsigned int year, byte month, byte day, byte hour, byte minute, byte second)
{

  //gracefully handle 2- and 4-digit year formats
  if (year > 1999)
  {
     year -= 2000;
  }


// Between year 2000 and 2100, a leap year occurs in every year divisible by 4.

//   sse_y = (((unsigned long)year)*365*24*60*60);
//   sse_ly = ((((unsigned long)year+3)>>2) + ((unsigned long)year%4==0 && (unsigned long)month>2))*24*60*60;
//   sse_d = ((unsigned long)monthdays[month-1] + (unsigned long)day-1) *24*60*60;
//   sse_h = ((unsigned long)hour*60*60);
//   sse_m = ((unsigned long)minute*60);
//   sse_s = (unsigned long)second;
//
//   sse = sse_y + sse_ly + sse_d + sse_h + sse_m + sse_s;



// NB: The multiplication-by-constants below is intentionally left expanded for readability; GCC is smart and will optimize them to single constants during compilation.


  //         Whole year seconds                      Cumulative total of seconds contributed by elapsed leap year days
  unsigned long sse = (((unsigned long)year)*365*24*60*60)   +   ((((unsigned long)year+3)>>2) + ((unsigned long)year%4==0 && (unsigned long)month>2))*24*60*60   +   \
         ((unsigned long)monthdays[month-1] + (unsigned long)day-1) *24*60*60   +   ((unsigned long)hour*60*60)   +   ((unsigned long)minute*60)   + (unsigned long)second;
         // Seconds in days since start of year                      hours                      minutes           sec

  return sse;
}

unsigned long DS1337::date_to_epoch_seconds()
{
     unsigned long asdf = date_to_epoch_seconds(int(bcd2bin(rtc_bcd[DS1337_YR])), bcd2bin(rtc_bcd[DS1337_MTH]), bcd2bin(rtc_bcd[DS1337_DATE]), bcd2bin(rtc_bcd[DS1337_HR]), bcd2bin(rtc_bcd[DS1337_MIN]), bcd2bin(rtc_bcd[DS1337_SEC]));
     return asdf;
}


void DS1337::epoch_seconds_to_date(unsigned long binary)
{
   // This routine taken from Dallas/Maxim application note 517
   // http://www.maxim-ic.com/app-notes/index.mvp/id/517
   // Arn't the fastest thing, but it produces correct results.
   // Slightly modified for epoch date of 1/1/2000.

   // TODO: Optimize (especially eliminate/fake as much sluggish long-division as possible); eliminate redundant variables

   unsigned long hour;
   unsigned long day;
   unsigned long minute;
   unsigned long second;
   unsigned long month;
   unsigned long year;

   unsigned long whole_minutes;
   unsigned long whole_hours;
   unsigned long whole_days;
   unsigned long whole_days_since_1968;
   unsigned long leap_year_periods;
   unsigned long days_since_current_lyear;
   unsigned long whole_years;
   unsigned long days_since_first_of_year;
   unsigned long days_to_month;
   unsigned long day_of_week;

   whole_minutes = binary / 60;
   second = binary - (60 * whole_minutes);                 // leftover seconds

   whole_hours  = whole_minutes / 60;
   minute = whole_minutes - (60 * whole_hours);            // leftover minutes

   whole_days   = whole_hours / 24;
   hour         = whole_hours - (24 * whole_days);         // leftover hours

   whole_days_since_1968 = whole_days;// + 365 + 366;
   leap_year_periods = whole_days_since_1968 / ((4 * 365) + 1);

   days_since_current_lyear = whole_days_since_1968 % ((4 * 365) + 1);

   // if days are after a current leap year then add a leap year period
   if ((days_since_current_lyear >= (31 + 29))) {
      leap_year_periods++;
   }
   whole_years = (whole_days_since_1968 - leap_year_periods) / 365;
   days_since_first_of_year = whole_days_since_1968 - (whole_years * 365) - leap_year_periods;

   if ((days_since_current_lyear <= 365) && (days_since_current_lyear >= 60)) {
      days_since_first_of_year++;
   }
   year = whole_years;// + 68;

   // walk across monthdays[] to find what month it is based on how many days have passed
   //   within the current year
   month = 13;
   days_to_month = 366;
   while (days_since_first_of_year < days_to_month) {
       month--;
       days_to_month = monthdays[month-1];
       if ((month > 2) && ((year % 4) == 0)) {
           days_to_month++;
        }
   }
   day = days_since_first_of_year - days_to_month + 1;

   day_of_week = (whole_days  + 4) % 7;


   rtc_bcd[DS1337_SEC] = bin2bcd(second);
   rtc_bcd[DS1337_MIN] = bin2bcd(minute);
   rtc_bcd[DS1337_HR] = bin2bcd(hour);
   rtc_bcd[DS1337_DATE] = bin2bcd(day);
   rtc_bcd[DS1337_DOW] = bin2bcd(day_of_week);
   rtc_bcd[DS1337_MTH] = bin2bcd(month);
   rtc_bcd[DS1337_YR] = bin2bcd(year);
}


void DS1337::setSeconds(unsigned char v)
{
    rtc_bcd[DS1337_SEC] = bin2bcd(v);

}
void DS1337::setMinutes(unsigned char v)
{
    rtc_bcd[DS1337_MIN] = bin2bcd(v);

}
void DS1337::setHours(unsigned char v)
{
    rtc_bcd[DS1337_HR] = bin2bcd(v);

}
void DS1337::setDays(unsigned char v)
{
    rtc_bcd[DS1337_DATE] = bin2bcd(v);

}
void DS1337::setDayOfWeek(unsigned char v)
{
    rtc_bcd[DS1337_DOW] = bin2bcd(v);

}
void DS1337::setMonths(unsigned char v)
{
    rtc_bcd[DS1337_MTH] = bin2bcd(v);

}
void DS1337::setYears(unsigned int v)
{
    if (v>1999)
    {
        v -= 2000;
    }
    rtc_bcd[DS1337_YR] = bin2bcd(v);

}

byte DS1337::bcd2bin(byte v)
{
   return (v&0x0F) + ((v>>4)*10);
}

byte DS1337::bin2bcd(byte v)
{
   return ((v / 10)<<4) + (v % 10);
}

void DS1337::stop(void)
{
	setRegister(DS1337_SP, getRegister(DS1337_SP) | DS1337_SP_EOSC);
}

void DS1337::start(void)
{
	setRegister(DS1337_SP, getRegister(DS1337_SP) & !DS1337_SP_EOSC);
}

and now the example:

#include <DS1337.h>
#include <Wire.h>
#include <avr/power.h>
#include <avr/sleep.h>

/*
  DS1337 RTC Example
  Tests and examples for common RTC library features.
  This shows the basic functions (reading and setting time/alarm values), converting back and forth between epoch seconds and calendar dates,
  and using alarm interrupts.

  Don't let the 'Binary sketch size' throw you; this example file and all its print statements add a lot of overhead.
 
 */

int ledPin =  27;    // LED connected to digital pin 13
int INT_PIN = 24; // INTerrupt pin from the RTC. On Mosquino boards, RTC is tied to INT2
int int_number = 2;

DS1337 RTC = DS1337();

void setup()   {                
//  
//    // 25: SCL
//    //26: SDA
//
//pinMode(25, INPUT);
//pinMode(26, INPUT);
  
  pinMode(INT_PIN, INPUT);
  digitalWrite(INT_PIN, HIGH);
  
  pinMode(ledPin, OUTPUT);    
  digitalWrite(ledPin, LOW);

  // enable deep sleeping
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();

  Serial.begin(9600);

  RTC.start(); // ensure RTC oscillator is running, if not already
  
  if(!RTC.time_is_set()) // set a time, if none set already...
  {
    Serial.println("Clock not set, setting to epoch (1/1/2000).");
    // set initially to epoch
    RTC.setSeconds(0);
    RTC.setMinutes(0);
    RTC.setHours(0);
    RTC.setDays(1);
    RTC.setMonths(1);
    RTC.setYears(2000);
    RTC.writeTime();
  }
  
  // If the oscillator is borked (or not really talking to the RTC), try to warn about it
  if(!RTC.time_is_set())
  {
    Serial.println("Clock did not set, wtf? Check that its oscillator is working.");
  }
}

void nap()
{
  // Dummy function. We don't actually want to do anything here, just use an interrupt to wake up.
  //RTC.clear_interrupt();
  // For some reason, sending commands to clear the interrupt on the RTC here does not work. Maybe Wire uses interrupts itself?
}

void loop()                     
{
  Serial.flush();
  Serial.println ("\nRTC Library Tests \n 1) Basic (read and write time) \n 2) Alarm interrupts/wakeup \n 3) date <--> epoch seconds validation \n ");

  while(!Serial.available()){}
  
  switch(Serial.read())
  {
    case '1':
      test_basic();
      break;
    case '2':
      test_interrupts();
      break;      
    case '3':
      test_epoch_seconds();
      break;   
    default:
      break; 
  }
}

void test_basic()
{
  // Test basic functions (time read and write)
  Serial.print ("The current time is ");
  RTC.readTime(); // update RTC library's buffers from chip
  printTime(0);
  Serial.println("\nSetting times using direct method: 1/31/07 12:34:56");
    RTC.setSeconds(56);
    RTC.setMinutes(34);
    RTC.setHours(12);
    RTC.setDays(31);
    RTC.setMonths(1);
    RTC.setYears(2007); // 2-digit or 4-digit years are supported
    RTC.writeTime();
    delay(500);  // This is not needed; just making it more clear that we are reading a new result
    RTC.readTime();
    Serial.print("Read back: ");
    printTime(0);
    Serial.println("  (we'll never forget)");
    Serial.println("Setting time using epoch seconds: 2024784000 (midnight on 2/29/2064)");
    RTC.writeTime(2024784000);
    delay(500);  
    RTC.readTime();    
    Serial.print("Read back: ");
    printTime(0);
    Serial.println("  (Happy 21st birthday Carlotta) ");    
    Serial.println("Writing alarm: 8:00am on the 15th of the month.");
    RTC.setSeconds(0);
    RTC.setMinutes(0);
    RTC.setHours(8);
    RTC.setDays(15);
    RTC.setAlarmRepeat(EVERY_MONTH); // There is no DS1337 setting for 'alarm once' - user must shut off the alarm after it goes off.
    RTC.writeAlarm();
    delay(500);
    RTC.readAlarm();
    Serial.print("Read back: ");
    printTime(1);    
    Serial.println("\nWriting alarm: 2:31:05 pm on the 3rd day of the week.");
    RTC.setSeconds(5);
    RTC.setMinutes(31);
    RTC.setHours(14);
    RTC.setDayOfWeek(3);
    RTC.setAlarmRepeat(EVERY_WEEK); // to alarm on matching day-of-week instead of date
    RTC.writeAlarm();
    delay(500);
    RTC.readAlarm();
    Serial.print("Read back: ");
    printTime(1);
    Serial.println("\n");
 }

and finally the second part of the example:

void test_interrupts()
{
  Serial.println("Setting a 1Hz periodic alarm interrupt to sleep in between. Watchen das blinkenlights...");
  // Steps to use an alarm interrupt:
  // 1) attach an interrupt handler (it can be blank if you just want to wake)
  // 2) enable alarm interrupt from RTC using RTC.enable_interrupt();
  // 3) set and write the alarm time
  // 4) sleep! ...zzz...
  // 5) clear the interrupt from RTC using RTC.clear_interrupt();
  // ...
  // 6) If no further alarms desired, disable the RTC alarm interrupt using RTC.disable_interrupt();
  attachInterrupt(int_number, nap, FALLING);
  RTC.enable_interrupt();
  RTC.setAlarmRepeat(EVERY_SECOND); // if alarming every second, time registers larger than 1 second (hour, etc.) are don't-care
  RTC.writeAlarm();
  for(byte i = 0; i<3; i++)
  {
    digitalWrite(ledPin, HIGH);
    delay(3); // wait >2 byte times for any pending Tx bytes to finish writing
    sleep_cpu(); // sleep. Will we waked by next alarm interrupt
    RTC.clear_interrupt();
    digitalWrite(ledPin, LOW);
    delay(3); // wait >2 byte times for any pending Tx bytes to finish writing
    sleep_cpu(); // sleep. Will we waked by next alarm interrupt
    RTC.clear_interrupt();
  }
  RTC.disable_interrupt(); // ensure we stop receiving interrupts
  detachInterrupt(int_number);
  Serial.println("Going to snooze for 5 seconds...");
  snooze(5);
  Serial.println("...and wake up again.");  
}

byte test_epoch_seconds()
{
  // Output the time calculated in epoch seconds at midnight for every day between 1/1/2000 and 12/31/2099.
  // Also, convert the result back to a date/time and make sure it matches the original value.
  // To ensure we are getting clean values to start with, no calculation results are written back to
  // the RTC. Instead, we use the alarm to wake up when it rolls over midnight, then advance the clock
  // to 23:59:59 of that same day. This way one 'day' passes per second, and a century's worth of tests
  // will complete in ~10 hours.

  unsigned char second;
  unsigned char minute;
  unsigned char hour;
  unsigned char month;
  unsigned char day;
  unsigned int year;
  unsigned long old_epoch_seconds = 0;
  unsigned long new_epoch_seconds = 1;
  Serial.println("Going to output and check epoch seconds at midnight on every day \n  from 1/1/2000 to 12/31/2099. This will take a long time! (overnight)\n  You probably want to capture the output to a file (e.g. hyperterminal). \n  Press SPACE to continue or any other key to skip.\n");
  Serial.flush();
  while(!Serial.available()){}
  if(Serial.read() == ' ')
  {
    Serial.println("Date, Seconds Since Epoch, Consistency Check Date, Consistency Check Result");
   RTC.writeTime(0); // reset time to epoch
    RTC.setAlarmRepeat(EVERY_DAY);
    RTC.writeAlarm(0); // ensure alarm starts at a valid value too
    RTC.enable_interrupt(); // make RTC generate a pulse every time one 'day' passes
    while(new_epoch_seconds > old_epoch_seconds) // keep going until date rolls over to 1/1/2000 again
    {
        // fastforward to the end of the day. The math for converting hours/min to seconds is trivial; 
        // this test is mainly concerned with ensuring stuff like days-in-a-month and leap years are handled correctly.
        RTC.readTime();  // restore known-good copy of date/time from chip to library's buffer
        RTC.setHours(23);
        RTC.setMinutes(59);
        RTC.setSeconds(59);
        RTC.writeTime(); // note: writing a new time resets the RTC's oscillator count ("milliseconds") to 0, so we have a full second until the next interrupt happens.
      while(digitalRead(INT_PIN) != 0) {}  // wait for 'day' to rollover. Pin 24 = INT2
        RTC.readTime();
        //store a copy of the original values
        second = RTC.getSeconds();
        minute = RTC.getMinutes();
        hour = RTC.getHours();        
        day = RTC.getDays();
        month = RTC.getMonths();        
        year = RTC.getYears();        
        printTime(0);
        old_epoch_seconds = new_epoch_seconds;
        new_epoch_seconds = RTC.date_to_epoch_seconds();
        Serial.print(" , ");
        Serial.print(new_epoch_seconds);
        Serial.print(" , ");
        // ensure that the result converted back to date matches the original value.
        // Remember that this function will update the contents of the RTC library's buffer, NOT on the chip.
        RTC.epoch_seconds_to_date(new_epoch_seconds);
        printTime(0);
        
        if( second == RTC.getSeconds() && minute == RTC.getMinutes() && hour == RTC.getHours() && day == RTC.getDays() && month == RTC.getMonths() && year == RTC.getYears() )
        {
          Serial.println(", Pass");
        }
        else
        {
          Serial.println(", FAIL!");
        }
        
    }
    Serial.println("\n\nDone!");
    RTC.disable_interrupt();
  }
}

void snooze(unsigned long secondsToSnooze)
{ 
  // Given a value in secondsToSnooze, set an alarm for that many seconds into the future and go to sleep.
  // The alarm can be set for a maximum of 28-31 days into the future - it doesn't have settings for months or years.
  
  RTC.readTime(); // update RTC library's buffers to contain the current time.
                  // Remember most functions (including epoch seconds stuff) work on what's in the buffer, not what's in the chip.

  
  RTC.setAlarmRepeat(EVERY_MONTH); // There is no DS1337 setting for 'alarm once' - once in a month is the most restrictive it gets.

  RTC.writeAlarm(RTC.date_to_epoch_seconds() + secondsToSnooze);
 
  attachInterrupt(int_number, nap, FALLING);
  RTC.enable_interrupt();
  
  delay(3); // wait >2 byte times for any pending Tx bytes to finish writing
  
  sleep_cpu(); // sleep. Will we waked by next alarm interrupt
 
  RTC.clear_interrupt(); // tell RTC to clear its interrupt flag and drop the INT line
  RTC.disable_interrupt(); // ensure we stop receiving interrupts
  detachInterrupt(int_number); // disconnect INT2 from the current interrupt handler.
  
}

void printTime(byte type)
{
  // Print a formatted string of the current date and time.
  // If 'type' is non-zero, print as an alarm value (seconds thru DOW/month only)
  // This function assumes the desired time values are already present in the RTC library buffer (e.g. readTime() has been called recently)

  if(!type)
  {
    Serial.print(int(RTC.getMonths()));
    Serial.print("/");  
    Serial.print(int(RTC.getDays()));
    Serial.print("/");  
    Serial.print(RTC.getYears());
  }
  else
  {
    //if(RTC.getDays() == 0) // Day-Of-Week repeating alarm will have DayOfWeek *instead* of date, so print that.
    {
      Serial.print(int(RTC.getDayOfWeek()));
      Serial.print("th day of week, ");
    }
    //else
    {
      Serial.print(int(RTC.getDays()));
      Serial.print("th day of month, ");      
    }
  }
  
  Serial.print("  ");
  Serial.print(int(RTC.getHours()));
  Serial.print(":");
  Serial.print(int(RTC.getMinutes()));
  Serial.print(":");
  Serial.print(int(RTC.getSeconds()));  
}

Thanks for your help.

You are right. It looks like the command readTime() reads the time and "save" it into a buffer in RTC,, and later you can obtain the different components from it (seconds, minutes, hour,...). However, i just want the value contained in this buffer as it is.

Thanks!

Any idea about how could i obtain the unix time from this library?

Normally, what i do is:

RTC.readTime() it update the library's buffer from the DS1337
RTC.getHour() it returns the hours (and the same for minutes, seconds, day, etc.) from the buffer.

I want to obtain the value contained in the buffer such as it is, not the values for day,hour, minute...

I tried:

RTC.readTime();
Serial.print(byte(RTC.readTime()));

But it returns this error:

void value not ignored as it ought to be

Could someone help me? Thanks!

madepablo:
Serial.print(byte(RTC.readTime()));

Your own post says that RTC.readTime() update's the library's buffer. So if you want to read the time, you need to read the library's buffer!

Again your own post gives what you need to do: RTC.getHour(), RTC.getMinutes()... etc.

so:

  Serial.print(int(RTC.getHours()));
  Serial.print(":");
  Serial.print(int(RTC.getMinutes()));
  Serial.print(":");
  Serial.print(int(RTC.getSeconds()));

Would print the current time.

The function "unsigned long DS1337::date_to_epoch_seconds(unsigned int year, byte month, byte day, byte hour, byte minute, byte second)" has the math (or you could just call this function) to calculate the UNIX time.

Thanks James C4S,

I know how to read the time from the library buffer using the commands that you propose. This is what i normally use. But, i want the Unix time, what it is what the RTC directly returns.

What you propose is a solution, but is the long and dirty way :wink:
I was looking for the direct way to read the seven bytes contained in the buffer...

Thanks!

madepablo:
I know how to read the time from the library buffer using the commands that you propose. This is what i normally use.

Okay, so now we finally understand what your real question actually is.

madepablo:
But, i want the Unix time, what it is what the RTC directly returns.

The DS1337 you are using does not just return the # of seconds since epoch. As its data sheet says, "The clock/calendar provides seconds, minutes, hours, day, date, month, and year information."

Look at the Table 2, Timekeeper Register for the DS1337 (http://datasheets.maxim-ic.com/en/ds/DS1337-DS1337C.pdf). There is no register for UNIX time.

So the only way for the library you've posted to determine the UNIX time is to calculate it, which I referenced in my previous reply. There isn't a register in the DS1337 that you can read to get this information. Instead, you need to retrieve the year, month, day, hours, and seconds to calculate it.

unsigned long sse = (((unsigned long)year)*365*24*60*60)   +   ((((unsigned long)year+3)>>2) + ((unsigned long)year%4==0 && (unsigned long)month>2))*24*60*60   +   \
         ((unsigned long)monthdays[month-1] + (unsigned long)day-1) *24*60*60   +   ((unsigned long)hour*60*60)   +   ((unsigned long)minute*60)   + (unsigned long)second;

You might be interested in this thread:
http://arduino.cc/forum/index.php/topic,74828.0.html

I think you used a different RTC library in the past.

Thanks James C4S,

You are right. I was worng about what return the RTC. So, i must convert the numbers os seconds, minutes, hours,... to unix time by myself.

And you were also right about i used other libraries in the pas... i used all the available libraries for DS1337, because ones are good for ones thngs but bad for others.... so i readed something about unix time in other library and i was confuse. Thanks a lot for your comments!
I appreciate it a lot. Thanks!

madepablo,

You asked if anybody knew who the author of the library you posted is. The library is from Yet-Another DS1337 RTC library by Drmn4ea.

Cheers.