Project Timer with DS1307 - Array of TimeElements; - Is Possible ?

Using TimeAlarms you can set an alarm to trigger any date and time. When that alarm is triggered the the actions that you specify will be carried out. This could include setting the alarm to trigger again.

From the readme file

"If you want to trigger once at a specified date and time you can use the trigger Once() method:
Alarm. triggerOnce(time_t value, explicitAlarm); // value specifies a date and time
(See the makeTime() method in the Time library to convert dates and times into time_t)"

Thanks, if i not understood bad please correct me if i wrong

Alarm.timerOnce(time_t value, explicitAlarm);

time_t_value --> is my date 22/01/2013 12:23 --> using the excel conversion is in number 41296.52

well at this point should conver my date in number and how can i do for do it ?

Thanks,
gnux

I've looked into the library ...

but Im not able to use an a pratical example for doing the coversion ...

could you help kindly me ?

Thanks,
gnux

So i've did several try but i don't undestand boa use the function, can some Give me an example ... Kindly ? :slight_smile: thx gnux

Hi,
Could be something like that ?
for example : 22/01/2013 17:12:00

tm.Year = 2013;
tm.Month = 01;
tm.Day = 22;
tm.Hour = 17;
tm.Minute = 12;
tm.Second = 00;
Alarm.timerOnce(makeTime(tm), OnceOnly) ;

Thanks
Gnux

Yes you are almost there! :slight_smile:

In fact, instead of typing that into a forum post and hitting "Submit",

You could type it into an empty sketch (surrounded by setup(){...}) and hit "Verify". Any error messages might guide you the rest of the way.

It is often faster than the forum too! :slight_smile:

Cheers,
John

Yes, I'm completely agree with you :slight_smile: but today I was at work without time for try to do it :slight_smile: ...

and then I've Im waiting a input for start in right direction :wink: only that :slight_smile: ... in the meantime the unique things that I was able to do was looking inside the forum that was another similar topic ...

gnux

For example I've did this simply sketch:

#include <Time.h>
#include <TimeAlarms.h>

void setup()
{
  Serial.begin(9600);
  setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011

  tm.Year = 2011;
  tm.Month = 01;
  tm.Day = 01;
  tm.Hour = 8;
  tm.Minute = 31;
  tm.Second = 00;
  Alarm.timerOnce(makeTime(tm), OnceOnly) ;
 
  // Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
               // called once after 10 seconds 
}

void  loop(){  
  digitalClockDisplay();
  Alarm.delay(1000); // wait one second between clock display
}

// functions to be called when an alarm triggers:

void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

void digitalClockDisplay()
{
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

I received back the error : 'Tm was not declare in this scope' ... Then I've declared the type of variable looking the library ... but understanding was that tm should be a method of timer library correct and is not necessary to declare but just call ...

So declaring the variable

static tmElements_t tm;

the error during the compile is disappeared but the condition is never verified ...

where i wrong ?

I come back after 10 hours of work thanks for to be patient ...

thx to all for the support,
gnux

gnusso:
For example I've did this simply sketch:
...
I received back the error : 'Tm was not declare in this scope' ...
...

This is excellent. The message is telling you very specifically, that you are trying to use a variable which has not been declared, or at least not declared in an appropriate place. "Declared" means like this:

int g;   // variable g is declared here

void loop(){
  int loc;  //variable loc is declared here

  g = g + 1;  // variable g is used here

  loc = 7;  // variable loc is used here
  int i=43;  // variable i is both declared and used here
  i= i - 1;   //
}

So what your message is saying is that you're trying to use a variable called "tm" and there is none. For your code it is very simple to fix:

    ...
    TimeElements tm;    // declare variable tm here
    tm.Year = 2011;      // begin using variable tm here
    tm.Month = 01;
    ...

Than i shouldn't received this kind of issues. ...
where i wrong ?

I can't say that that is the only problem with your sketch, but its a start...

Cheers,
John

Ho thx for the advise :slight_smile: so i ve see that was miss the declaration infact i ve tried to declare in this way

static tmElements_t tm;

And the compile was ok

But the conditi in was never verified , so ill try your suggest and ill let you know thanks gnux

So, also changing the the declaration now i didn't have the errors from the compiler ...

but the condition is never true ...

and I don't understand why ... I've also did a Serial.println of makeTime(tm) but the number that I've tell me nothing if didn't have another function that convert back the value ...

:frowning: so now I'll let's go to bed because I'm completely fuse ...

thanks for the support,
gnux

Schermata 2013-01-22 a 21.45.08.png

gnusso:
tm.Year = 2011;
tm.Month = 01;
tm.Day = 01;
tm.Hour = 8;
tm.Minute = 31;
tm.Second = 00;
Alarm.timerOnce(makeTime(tm), OnceOnly) ;

... the condition is never verified ...

Maybe the alarm actually triggered-- where were you at 8:31am on 1/1/2011?

Just kidding.

As UkHeliBob pointed out you should be using Alarm.triggerOnce() instead of timerOnce(). The documentation doesn't seem to describe this. But you can get really good information about the TimeAlarms library by finding your Arduino/libraries/Timealarms/ directory and looking at readme.txt and TimeAlarms.h. It is very well documented there as are many/most ARduino libraries:

  (TimeAlarms.h)
  AlarmID_t triggerOnce(time_t value, OnTick_t onTickHandler);   // trigger once at the given time_t
  AlarmID_t timerOnce(time_t value, OnTick_t onTickHandler);   // trigger once after the given number of seconds

Also I noticed in Time.h that it is expecting a year in the form of "years since 1970", so you should put in some reasonable values like:

  static tmElements_t tm; // this is fine static is ok here but not necessary
  tm.Year = 2013 - 1970;  // this would be year 2013
  tm.Month = 01;
  tm.Day = 22;
  tm.Hour = 15;
  tm.Minute = 01;
  tm.Second = 00;
  Alarm.triggerOnce(makeTime(tm), OnceOnly) ;

HTH,
John

From the readme :

"Low level functions to convert between system time and individual time elements are provided:
breakTime( time, &tm); // break time_t into elements stored in tm struct
makeTime( &tm); // return time_t from elements stored in tm struct "

So you can convert both ways.

Hi Guys,
really thanks I've understood now ... so thanks for the very great support !!! I've adjust my sketch and now it's working ... so this morning I will try to play well with this :wink: thanks again,

warm regards,
Gnux

Good Morning,

I've note using the TimerAlarmExample:

#include <Time.h>
#include <TimeAlarms.h>

void setup()
{
  Serial.begin(9600);
  setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011
  // create the alarms 
  Alarm.alarmRepeat(8,30,0, MorningAlarm);  // 8:30am every day
  Alarm.alarmRepeat(17,45,0,EveningAlarm);  // 5:45pm every day 
  Alarm.alarmRepeat(dowSaturday,8,30,30,WeeklyAlarm);  // 8:30:30 every Saturday 

 
  Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 
}

void  loop(){  
  //digitalClockDisplay();
 
   
   Alarm.delay(1000); // wait one second between clock display
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");    
}

void EveningAlarm(){
  Serial.println("Alarm: - turn lights on");           
}

void WeeklyAlarm(){
  Serial.println("Alarm: - its Monday Morning");      
}

void ExplicitAlarm(){
  Serial.println("Alarm: - this triggers only at the given date and time");       
}

void Repeats(){
  Serial.println("15 second timer");         
}

void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

void digitalClockDisplay()
{
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

If I didn't put

 Alarm.delay(1000);

the timer doesn't work ...

My understanding is that the timer should work in background without block the cpu each time for a second ...

is there a way to change it ?

thx
gnux

The documentation for TimeAlarms specifically says that you must use Alarm.delay() for it to work otherwise it cannot check for alarms. There is no reason why you should not use Alarm.delay(1) if you want it not to block for 1 second. You could also arrange to call Alarm.delay() at less frequent intervals using millis() as your own non blocking timer and only calling it when the delay will not affect your program.

Thanks for information,
so then Alarm.delay(); is mandatory for start timer ...

into Example there is Alarm.delay(1000); just for see the time that change each 1 seconds...

correct ?

Also another curiosity ... if I use Alarm.triggerOnce(); into setup of course is used one time only , if call Alarm.triggerOnce() into loop after the first time that alarm is triggered each time is call the function ... due the fact the condition is always verify ...

Is there the possibility to Triggered off the alarm just after that is verify ? in this way I can pass several arguments to the triggeronce into the loop and i will able to change my timer ...

Make sense the questions ?

thanks
gnux

Post you whole code that is not working properly so that we can see how it is written and give advice.

I am sorry but I cannot make sense of your questions. Can you please rephrase them ?

If you are asking if you can disable an alarm once it is set then, yes you can. There is a limit to how many alarms can be set, normally 6 but the limit can be increased up to a limit of 255.

Hi, here you are the code ...
for sure the value into the ram are correct ... due the fact if i call the routine

Alarm.triggerOnce(makeTime(tm0stop), StopTimer0);

into the loop it's work ...

the code for the sketch :

void FaiTempo0()
{
   // make time stop timer 1
 TimerWakeup0 = memoria[0];
 tm0start.Hour =   memoria[2];  
 tm0start.Minute = memoria[3];
 tm0start.Second = 00;
 tm0start.Day =   memoria[4];
 tm0start.Month = memoria[5];
 tm0start.Year = (memoria[6]+2000) - 1970;
 StartTimer0 = memoria[7];
 
 // make time stop timer 0 
 tm0stop.Hour =   memoria[8];
 tm0stop.Minute = memoria[8];
 tm0stop.Second = 00;
 tm0stop.Day =   memoria[10];
 tm0stop.Month = memoria[11];
 tm0stop.Year = (memoria[12]+2000) - 1970;
 StopTimer0 = memoria[13];
}

void Timer()
{
   
     FaiTempo0();
      Alarm.triggerOnce(makeTime(tm0start), FunctionStartTimer0);
     if (TimerWakeup0 == 1) 
      {
        if (StartTimer0 == 0)
         {
          Alarm.triggerOnce(makeTime(tm0start), FunctionStartTimer0); 
          memoria[7] = 1;
          EEPROM.write(7, memoria[7]);
          
         }
         else
          {    
             if (StopTimer0 == 0);
              {
                Alarm.triggerOnce(makeTime(tm0stop), FunctionStopTimer0); 
                
                memoria[13] = 1;
                memoria[0] = 0;
               
                EEPROM.write(13, memoria[13]);
                EEPROM.write(0, memoria[0]);
                }   
            }  
       
           }
}

void loop() {
    Timer();
  m2.checkKey();
  m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();
  Alarm.delay(1);
}

of course there is all variable declared ...and memoria red value from eeprom correctly at the setup()

my purpose when will be ok is change from a menu value timer (date start and time start,devstart etc etc)

this was the scope of my question ... if is possible call triggerOnce ... into the loop and stop it after will be excute ... but I don't know how ...

thanks for the support,
gnux

We need to see the whole sketch to understand what you are doing