Using a timer to trigger for certain periods between intervals

Hi all,

Say I want to switch a light on and off for a period of time at designated intervals without using delays and I would also like to change this interval later on.

I am checking out the TimeAlarms “Alarm.timerRepeat” function but it has two problems:

  1. it seems to need to be placed into void setup with the interval already hard-coded and I can’t use a global variable. (i.e. Alarm.timerRepeat(my_variable,my_function) does not seem to work)

  2. it only calls the function once and then waits until the next interval. My light blinks but doesn’t stay on for the period required.

Grateful for any ideas…

Look at the demo several things at a time which illustrates how to use millis() to manage time. Much easier than trying to figure out alarm libraries.

...R

unsigned long pulseLength=500;
unsigned long lastChange=0;
bool lightState=0;

void loop()
{
unsigned long t=millis();

if ( (t-lastChange) >= pulseLength)
  {
   lightState = !lightState;
   digitalWrite(lightPin, lightState);
   lastChange=t;
  }
  
if(someCondition)
  {
   pulseLength=somethingElse;
  }

}

I am checking out the TimeAlarms "Alarm.timerRepeat" function but it has two problems:

  1. it seems to need to be placed into void setup with the interval already hard-coded

No it doesn't. You can set up an alarm from inside any function in the program.

and I can't use a global variable. (i.e. Alarm.timerRepeat(my_variable,my_function) does not seem to work)

True, but why do you want to do this ?

  1. it only calls the function once and then waits until the next interval.

True. When triggered the alarm waits for the next interval. That is what it is meant to do.

My light blinks but doesn't stay on for the period required.

What it does when triggered is up to you. If the callback function turns off the light then that is what it will do.

KenF:

unsigned long pulseLength=500;

unsigned long lastChange=0;
bool lightState=0;

void loop()
{
unsigned long t=millis();

if ( (t-lastChange) >= pulseLength)
  {
  lightState = !lightState;
  digitalWrite(lightPin, lightState);
  lastChange=t;
  }
 
if(someCondition)
  {
  pulseLength=somethingElse;
  }

}

Thanks for this code. I had something similar but it doesn’t seem to work when the main loop is cycling more quickly than the blink period and doing something else. For example:

void loop{
do A;
do B;
Alarm.repeatTime(interval, my_function);
}
void my_function{
light stays on if millis()<my_period;
}

When Alarm.repeatTime is triggered it doesn’t wait until millis()==my_period before exiting the function and moving onto ‘do A’. That’s why my light doesn’t seem to stay on.

}

UKHeliBob:
No it doesn't. You can set up an alarm from inside any function in the program.

oh! Great! thanks!

UKHeliBob:
True, but why do you want to do this?

Because I wanna have some buttons to allow the user to change this period.

UKHeliBob:
When triggered the alarm waits for the next interval. That is what it is meant to do.What it does when triggered is up to you. If the callback function turns off the light then that is what it will do.

See my response to KenF above. The callback function doesn't turn off the light. It just stops sending a signal after the function is triggered and doesn't wait for the requisite period required by the function because the main loop is telling it to move on. I'm not a programmer so that's just my lay person's explanation of what seems to be going on. Most likely I am missing something :-(. How loop within loops are managed are a bit of a mystery to me.

Robin2:
Look at the demo several things at a time which illustrates how to use millis() to manage time. Much easier than trying to figure out alarm libraries.

...R

Thanks! I will check this out. I am using now() because I hated dealing in millis.. but I will take a look. :slight_smile:

skreech:
Thanks for this code. I had something similar but it doesn’t seem to work when the main loop is cycling more quickly than the blink period and doing something else. For example:

void loop{
do A;
do B;
Alarm.repeatTime(interval, my_function);
}
void my_function{
light stays on if millis()<my_period;
}

When Alarm.repeatTime is triggered it doesn’t wait until millis()==my_period before exiting the function and moving onto ‘do A’. That’s why my light doesn’t seem to stay on.

}

Your “something similar” is quite deeply flawed.

KenF:
Your "something similar" is quite deeply flawed.

so you're saying the main loop should wait for the called function to complete before moving on?

skreech:
so you're saying the main loop should wait for the called function to complete before moving on?

That's the usual way loop and functions work.
If you want a function to end before it has completed then use:

if (condition){ 
return;
}

Henry_Best:
That's the usual way loop and functions work.
If you want a function to end before it has completed then use:

if (condition){ 

return;
}

Yea I think I managed to figure it out using conditional ifs and current_time-previous_time>my_period statements.

phew I'm glad I don't have to mess with the alarm timers anymore.

Thanks for all your help!

Because I wanna have some buttons to allow the user to change this period.

You will probably need to disable the current alarm and create another one as I don't think that there is a method of changing the alarm parameters once set.

The callback function doesn't turn off the light. It just stops sending a signal after the function is triggered and doesn't wait for the requisite period required by the function because the main loop is telling it to move on.

The main loop does nothing of the kind. Please post the full program code that you are using.