I HATE C!!!! - DaysBetween

[quote]
#include <SPI.h>        //SPI.h must be included as DMD is written by SPI (the IDE complains otherwise)
#include <DMD.h>        //
#include <TimerOne.h>   //
#include "SystemFont5x7.h"
#include "Arial_black_16.h"
#include <Wire.h>
#include <DS1307.h>

//Fire up the DMD library as dmd
#define DISPLAYS_ACROSS 1
#define DISPLAYS_DOWN 1
DMD dmd(DISPLAYS_ACROSS, DISPLAYS_DOWN);
#define SECONDSINDAY 86400
#define SECONDSINHOUR 3600
#define SECONDSINMINUTE 60


// Put your target date here. 
int targetYear = 14; 
byte targetMonth = 12;
byte targetDay = 25;
byte targetHour = 0;
byte targetMinute = 0;
byte targetSecond = 0;



unsigned int monthdays[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};

bool century, h24, ampm;
unsigned long targetDate;
unsigned long Now, dT;



/*--------------------------------------------------------------------------------------
  Interrupt handler for Timer1 (TimerOne) driven DMD refresh scanning, this gets
  called at the period set in Timer1.initialize();
--------------------------------------------------------------------------------------*/
void ScanDMD()
{ 
  dmd.scanDisplayBySPI();
}





void setup(void)
{

   //initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
   Timer1.initialize( 5000 );           //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
   Timer1.attachInterrupt( ScanDMD );   //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI()
   Serial.begin(9600);

   //clear/init the DMD pixels held in RAM
   dmd.clearScreen( true );   //true is normal (all pixels off), false is negative (all pixels on)
 
}

int strLength(char *buffer){
  int i = 0, length =0;
  while (buffer != '\0'){  
    if (buffer[i+1] == '\0') {
    length = i+1;
    return length;
    }
    i++;
  }
}


void ScrollText()
{
     long start=millis();
   long timer=start;
   boolean ret=false;
   while(!ret){
     if ((timer+55) < millis()) {
       ret=dmd.stepMarquee(-1,0);
       timer=millis();
     }
   }

}

//code directly from a C snippet... 

/* time_t timeFromDate( int year, int month, int day ) { 
     time_t rawtime; 
     struct tm * my_time; 
  
     // Create a filled in time structure 
     time( &rawtime ); 
     my_time = localtime( &rawtime ); 
      
     // Reassign our date 
     my_time->tm_year     = year - 1900; // Different sources say 1900 and 1970? 
     my_time->tm_mon        = month - 1;    // tm uses uses january + months [0..11]  
     my_time->tm_mday     = day; 
  
     // Return it as seconds since epoch 
     return( mktime( my_time ) ); 
 } */ 
  

unsigned long secondsSince2000(unsigned long year, byte month, byte day, byte hour, byte minute, byte second)
{
	// This code stolen from someene else's DS1337 library. It was called 
	// "date_to_epoch_seconds()" there, but it didn't do epoch seconds,
	// just seconds since 2000. That's fine in this case, since seconds
	// since 2000 is sufficient for this purpose.
  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;

  return sse;
}


void GetAndDrawTime()
{
   byte h,m,s, d;
   int y;
   char TimeStr[30];
 
//  DisplayCountDown();
  
  //This code below WAS in displayCountDown();
  
  long targetDate =secondsSince2000(targetYear, targetMonth, targetDay, targetHour, targetMinute, targetSecond);

  Serial.println(targetDate);
//  Serial.println(RTC.now);
  
  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print(" ");                 // some space for a more happy life
  Serial.print(RTC.get(DS1307_DOW,false));
  Serial.print(" ");
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.println(RTC.get(DS1307_YR,false)); //read 


int year = RTC.get(DS1307_YR,false);
int month = RTC.get(DS1307_MTH,false);
if (century) year += 100;
int day = RTC.get(DS1307_DATE,false);
int hour = RTC.get(DS1307_HR,true);

if ((h24) && (ampm)) hour += 12;
int minute = RTC.get(DS1307_MIN,false);
int second = RTC.get(DS1307_SEC,false);

   //    Serial.println("year: "+year);
   //    Serial.println("month: "+month);
   //    Serial.println("day: "+day); 
   //    Serial.println("hour: "+hour);
   //    Serial.println("minute: "+minute);
   //    Serial.println("second: "+second);

 	Now = secondsSince2000(year, month, day, hour, minute, second);
 
    
	// Are we past the countdown?
	if (Now >= targetDate) {
		//celebrate();
	}

	// Here's the time remaining.
	dT = targetDate - Now;

	// Figure out whole days remaining
	int remDays = dT/SECONDSINDAY;

	// Here's the leftover HMS
	int remSeconds = dT%SECONDSINDAY;
	
	// Figure out the whole hours remaining
	int remHours = remSeconds/SECONDSINHOUR;

	// Here's the leftover MS
//	 remSeconds = remSeconds%SECONDSINHOUR;

	// Figure out the whole minutes remaining
//	 int remMinutes = remSeconds/SECONDSINMINUTE;

	// Here's the leftover S
//	 remSeconds = remSeconds%SECONDSINMINUTE;


   sprintf(TimeStr,"%d days until Christmas!",remDays);
      
   Serial.println(TimeStr);

   dmd.clearScreen( true ); 
   dmd.drawMarquee(TimeStr,strLength(TimeStr),(32*DISPLAYS_ACROSS)-1,0);      


   boolean ret=false;
   long timer = 0;
   while(!ret){
     if ((timer+95) < millis()) {
       ret=dmd.stepMarquee(-1,0);
       timer=millis();
     }
   }
   
  dmd.clearScreen( true ); 
  
  
   
   h = RTC.get(DS1307_HR,true);
   m = RTC.get(DS1307_MIN,true);
   s = RTC.get(DS1307_SEC,true);
   if (h>=12) 
      sprintf(TimeStr,"Time: %d:%dpm",h,m);
       else
      sprintf(TimeStr,"Time: %d:%dam",h,m);
      
   Serial.println(TimeStr);
   dmd.clearScreen( true ); 
  
     
   dmd.drawMarquee(TimeStr,strLength(TimeStr),(32*DISPLAYS_ACROSS)-1,0);      
   long start=millis();
   timer=start;
   ret=false;
   while(!ret){
     if ((timer+95) < millis()) {
       ret=dmd.stepMarquee(-1,0);
       timer=millis();
     }
   }
   
  dmd.clearScreen( true ); 
  Serial.println(TimeStr);


    d = RTC.get(DS1307_DATE,true);
    m = RTC.get(DS1307_MTH,true);
    y = RTC.get(DS1307_YR,true);

    sprintf(TimeStr,"Date: %d/%d/%d",d,m,y);
      
   Serial.println(TimeStr);

   dmd.clearScreen( true ); 
   dmd.drawMarquee(TimeStr,strLength(TimeStr),(32*DISPLAYS_ACROSS)-1,0);      


   ret=false;
   while(!ret){
     if ((timer+95) < millis()) {
       ret=dmd.stepMarquee(-1,0);
       timer=millis();
     }
   }
   
  dmd.clearScreen( true ); 

  
 

}





void prettystuff()
{
//     half the pixels on
   dmd.drawTestPattern( PATTERN_ALT_0 );
   delay( 1000 );

   // the other half on
   dmd.drawTestPattern( PATTERN_ALT_1 );
   delay( 1000 );
 
}

void loop(void)
{
   byte b;
   
   // 10 x 14 font clock, including demo of OR and NOR modes for pixels so that the flashing colon can be overlayed
   dmd.clearScreen( true );
   dmd.selectFont(Arial_Black_16);

   GetAndDrawTime();
/*	  Serial.print("\nActual time : ")
	  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true//
	  Serial.print(":");
	  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
	  Serial.print(":");
	  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
	  Serial.print(" ");                 // some space for a more happy life
	  Serial.print(RTC.get(DS1307_DOW,false));
	  Serial.print(" ");
	  Serial.print(RTC.get(DS1307_DATE,false));//read date
	  Serial.print("/");
	  Serial.print(RTC.get(DS1307_MTH,false));//read month
	  Serial.print("/");
	  Serial.println(RTC.get(DS1307_YR,false)); //read year
*/
 
}

here's the Serial Debug Dump...

472780800
16:32:40 4 17/9/2014
15252 days until Christmas!
Time: 16:33pm
Time: 16:33pm
Date: 17/9/2014
472780800
16:33:37 4 17/9/2014
15252 days until Christmas!

it's more like 98 days to Christmas.... I also don't really understand why the code i stole calculates the date from 2000, surely the date and time stamp NOW - EncodedDate(Christmas) = Seconds between/days/hours etc... why is calculating the date from 2000 required?

link

http://physics.csuchico.edu/~eayars/code/countdown.pde.html

Anyone know how to simply Encode the time stamp as of NOW (Time now) deduct from CalculatedTimeStamp? (future Date) thanks!

Segment of Code not working

void GetAndDrawTime()
{
   byte h,m,s, d;
   int y;
   char TimeStr[30];
 
//  DisplayCountDown();
  
  //This code below WAS in displayCountDown();
  
  long targetDate =secondsSince2000(targetYear, targetMonth, targetDay, targetHour, targetMinute, targetSecond);

  Serial.println(targetDate);
//  Serial.println(RTC.now);
  
  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print(" ");                 // some space for a more happy life
  Serial.print(RTC.get(DS1307_DOW,false));
  Serial.print(" ");
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.println(RTC.get(DS1307_YR,false)); //read 


int year = RTC.get(DS1307_YR,false);
int month = RTC.get(DS1307_MTH,false);
if (century) year += 100;
int day = RTC.get(DS1307_DATE,false);
int hour = RTC.get(DS1307_HR,true);

if ((h24) && (ampm)) hour += 12;
int minute = RTC.get(DS1307_MIN,false);
int second = RTC.get(DS1307_SEC,false);

   //    Serial.println("year: "+year);
   //    Serial.println("month: "+month);
   //    Serial.println("day: "+day); 
   //    Serial.println("hour: "+hour);
   //    Serial.println("minute: "+minute);
   //    Serial.println("second: "+second);

 	Now = secondsSince2000(year, month, day, hour, minute, second);
 
    
	// Are we past the countdown?
	if (Now >= targetDate) {
		//celebrate();
	}

	// Here's the time remaining.
	dT = targetDate - Now;

	// Figure out whole days remaining
	int remDays = dT/SECONDSINDAY;

	// Here's the leftover HMS
	int remSeconds = dT%SECONDSINDAY;
	
	// Figure out the whole hours remaining
	int remHours = remSeconds/SECONDSINHOUR;

	// Here's the leftover MS
//	 remSeconds = remSeconds%SECONDSINHOUR;

	// Figure out the whole minutes remaining
//	 int remMinutes = remSeconds/SECONDSINMINUTE;

	// Here's the leftover S
//	 remSeconds = remSeconds%SECONDSINMINUTE;


   sprintf(TimeStr,"%d days until Christmas!",remDays);
      
   Serial.println(TimeStr);

shakes head... pours a glass of wine.

#define SECONDSINDAY 86400

BZZZZT

  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print(" ");                 // some space for a more happy life
  Serial.print(RTC.get(DS1307_DOW,false));
  Serial.print(" ");
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.println(RTC.get(DS1307_YR,false)); //read

Why do you get and print the values, and then turn around and get and use the same values all over again? Wouldn't it be sufficient to get them ONCE and then print and use the same set of values?

Why do you have two variables called targetDate, with different types?

BZZZZT

I'm not seeing the problem, there.

int remDays = dT/SECONDSINDAY;

Divide by 86400, or divide by 20864?

AWOL:

int remDays = dT/SECONDSINDAY;

Divide by 86400, or divide by 20864?

Nice, didn't think of that either.

#define SECONDSINDAY 86400L

Screw it, I'll start again regarding the countdown..

Anyone seen, come across code to simply get the number of seconds between two time stamps?

Anyone seen, come across code to simply get the number of seconds between two time stamps?

Between two time stamps? Or between two times?

I believe that the Time library has a method to convert a time/date to a time_t, which is the number of seconds since 1/1/1970.

With two time_t's, the number of seconds between them is s simple subtract operation.

#define SECONDS_IN_MINUTE 60UL
#define MINUTES_IN_HOUR   60UL
#define HOURS_IN_DAY      24UL
#define DAYS_IN_YEAR     365UL
#define SECONDS_IN_HOUR (SECONDS_IN_MINUTE * MINUTES_IN_HOUR)
#define SECONDS_IN_DAY  (SECONDS_IN_HOUR * HOURS_IN_DAY)

// Put your target date here. 
const int targetYear    = 14; 
const byte targetMonth  = 12;
const byte targetDay    = 25;
const byte targetHour   = 0;
const byte targetMinute = 0;
const byte targetSecond = 0;

const unsigned int monthdays[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};

unsigned long targetDate = secondsSince2000(targetYear, targetMonth, targetDay, targetHour, targetMinute, targetSecond);

void setup(void)
{
   Serial.begin(9600);
   timeToTarget();
}

unsigned long secondsSince2000(unsigned long year, byte month, byte day, byte hour, byte minute, byte second)
{
  return (((unsigned long)year) * DAYS_IN_YEAR * SECONDS_IN_DAY) +   
         ((((unsigned long)year + 3) / 4) + ((unsigned long)year % 4 == 0 && (unsigned long)month > 2)) * SECONDS_IN_HOUR +
         ((unsigned long)monthdays [month - 1] + (unsigned long)day - 1) * SECONDS_IN_DAY +
         ((unsigned long)hour * SECONDS_IN_HOUR)     +   
         ((unsigned long)minute * SECONDS_IN_MINUTE) + 
          (unsigned long)second;
}

void timeToTarget ()
{
  char timeStr[80]; // old habits die hard
  // I don't have an RTC, so fake it.
  unsigned long now = secondsSince2000(14, 9, 17, 12, 0, 0);
  unsigned long	dT = targetDate - now;
  int remDays = dT / SECONDS_IN_DAY;

  sprintf(timeStr,"%d days until Christmas!",remDays);
      
  Serial.println(timeStr);
}

void loop ()
{
}

98 days.
Yikes!

Thank you.