Go Down

Topic: Time Maths (Read 572 times) previous topic - next topic

jonwhitear

Hi,

I'm trying to set a timer - the time is displayed on an LCD screen, and I use push buttons to adjust the hours and minutes. Here's the function that's called by the screen display function:-

Code: [Select]
time_t ModifyScreenElementTime(time_t InputTime) {
 tmElements_t tmSet;
 breakTime(InputTime, tmSet);
 
//  byte YYYY = tmSet.Year;
//  byte MM = tmSet.Month;
 byte DD = tmSet.Day;
 byte hh = tmSet.Hour;
 byte mm = tmSet.Minute;
 //byte ss = tmSet.Second;
 
 if (ReadButton(LEFT) == BUTTON_PRESS) {
   mm++;
//    DebugMessage_P(PSTR("Screen element incremented by 1 min"));
 }
 if (ReadButton(RIGHT) == BUTTON_PRESS) {
   mm--;
//    DebugMessage_P(PSTR("Screen element decremented by 1 min"));
 }
 if (ReadButton(LEFT) == BUTTON_PRESS_HOLD) {
   hh++;
//    DebugMessage_P(PSTR("Screen element incremented by 1 hour"));
 }
 if (ReadButton(RIGHT) == BUTTON_PRESS_HOLD) {
   hh--;
//    DebugMessage_P(PSTR("Screen element decremented by 1 hour"));
 }
 
 if (mm > 59) {
   mm = 0;
   hh++;
 }
  if (hh > 23) {
   hh = 0;
   DD++;
 }
 //  byte YYYY = tmSet.Year;
//  byte MM = tmSet.Month;
 tmSet.Day = DD;
 tmSet.Hour = hh;
 tmSet.Minute = mm;
 tmSet.Second = 0;
 
 return makeTime(tmSet);
}


My trouble is with rollover from minutes to hours to days etc.. What I'd really like to do is convert from time_t to Unix time (i.e. seconds since 1/1/1970) so that I can manipulate the seconds value and then convert it back. I know of a function to convert to seconds (I think that's in the Time library) but I can't fine one to convert back i.e. form seconds to time_t.

I'd appreciate any help. I'm new with Arduino and programming in general, so if I've got the whole approach glaringly wrong, please advise how I should approach it.

Cheers,

Jon

MarkT

I note you don't test for variables underflowing.  The byte variables will wrap round to 255 if you decrement from 0.

You code will then think its overflowed!
[ I won't respond to messages, use the forum please ]

jonwhitear

Thanks. I'll put in checks to fix that. Does that have any other consequences other than I get a value of 255 when I decrement from 0?

guix


What I'd really like to do is convert from time_t to Unix time (i.e. seconds since 1/1/1970) so that I can manipulate the seconds value and then convert it back. I know of a function to convert to seconds (I think that's in the Time library) but I can't fine one to convert back i.e. form seconds to time_t.


Hello and welcome,

I'm not sure to understand, isn't a time_t already in seconds?

MarkT

At the moment the function will scan the buttons and make changes to mins and hours, but you don't seem
to have any way to prevent it then repeating those changes continually while the button is pressed - there
is no detection of button-down or button-up transistions (unless readButton() is doing that?)

We'd need to see more (all?) code to know if this is an issue.
[ I won't respond to messages, use the forum please ]

jonwhitear

#5
Nov 26, 2012, 03:48 am Last Edit: Nov 26, 2012, 10:23 am by jonwhitear Reason: 1
Thanks for the pointers folks.

time_t is indeed already in seconds When I first tried this, I got some unexpected results manipulating the time_t directly (e.g. adding 3600 seconds to it to increment the hour) so I thought there must be a reason why I couldn't do that. I've tried this again now and it's working as expected. Fortunately that means I don't need to check for overflows now.

My button read function does only register a button press once.

Edit: For the sake of completeness, here's the working function...

Code: [Select]
time_t ModifyScreenElementTime(time_t InputTime)

  if (ReadButton(LEFT) == BUTTON_PRESS) InputTime += 60;         // Increment Input time by 1 minute
  if (ReadButton(RIGHT) == BUTTON_PRESS) InputTime -= 60;        // Decrement Input time by 1 minute
  if (ReadButton(LEFT) == BUTTON_PRESS_HOLD) InputTime += 3600;  // Increment Input time by 1 hour
  if (ReadButton(RIGHT) == BUTTON_PRESS_HOLD) InputTime -= 3600; // Decrement Input time by 1 hour
 
  if (InputTime < now()) InputTime = now(); //Timer can't start before now
  return InputTime;
}


Cheers,

Jon

Go Up