# Blink without delay, extended to more complex switch patterns

Greetings:

I am currently working on a timer that will operate a switch at fixed intervals. While that switch is operating, I would also like to take sensor readings that will operate a separate set of switches. Given that I want to perform other tasks while the timer is performing other functions, it is pretty clear I need to avoid the delay function. Right now, I have been examining the "Blink without Delay" code and seem to understand how that is operating. However, I am having a difficult time extending this example to other intervals. My hope is that I can get a few suggestions to help sort out this problem.

So, right now I am looking at the standard 'Blink Without Delay' code that is timing the LED to go on and off at 1 second intervals. What should I be doing to make the light operate as follows:

Step 1: On for 5 seconds, off for 10 seconds
Step 2: On for 2 seconds, off for 5 seconds
Step 3: On for 7 seconds, off for 2 seconds

Those are just arbitrary values, but if I get the general concept with these values, I can easily adapt the code to my needs -- right now, I just can't seem to get the logic for establishing these intervals! Ok, if that makes sense, a critical next step is to be able to perform simultaneous readings of a sensor that operates a different switch independent of this timer. I don't have to solve this issue now, but I want to ensure that the code I write can incorporate this independent task.

I hope this makes sense. Any bit of guidance you can offer at this point would be GREATLY appreciated.

Brian

you need to make an array of ON and OFF intervals and take after every time the next interval

``````if (millis() - lasttime > interval[idx])
{
lasttime += interval[idx];
idx++;
if (idx == idxmax) idx = 0;
}
``````

Ok, I will take a look into the array, although I admit that I don't fully understand it at this point. If there is any further sample code that anybody has to guide me, that will be useful. During the interim, I will be studying the array function and the snippet provided.

Thanks!
Brian

You need a Finite State Machine.

In the example, state 0 would contain an interval value of 5, state 1 would be 10, etc.

My Multiblink example in the Playground uses a finite state machine and arrays of structures to keep track of multiple blink rates and timers. Not beginners code, but I am happy to help if you need it.

Thanks for these suggestions. I am looking at the examples provided and will work toward a workable solution -- indeed, your help is appreciated. Just curious, do you think that a real time clock (rtc) is an option?

You could use a RTC, but for "on for 10 seconds, off for 5 seconds" sort of stuff, using millis() in an appropriate way is all you need.

``````void loop(){
//...
WATER_PUMP.startsstimer();
LIGHTHING.startsstimer();
//..
}
``````

Do you really mean to start the timers each time through loop() or should this be in setup() ?

this function inside the loop only check if the timer needs to be turn ON or OFF continuously,

Then startsstimer is surely a silly name for the function. updatesstimer or checksstimer might have been a better choice.

beperron:
So, right now I am looking at the standard ‘Blink Without Delay’ code that is timing the LED to go on and off at 1 second intervals. What should I be doing to make the light operate as follows:

Step 1: On for 5 seconds, off for 10 seconds
Step 2: On for 2 seconds, off for 5 seconds
Step 3: On for 7 seconds, off for 2 seconds

Those are just arbitrary values, but if I get the general concept with these values, I can easily adapt the code to my needs – right now, I just can’t seem to get the logic for establishing these intervals!

I have worked out some demonstration code for you.

Debug messages on Serial included, so that you can see the millis() when the actual switching occurs.

``````struct timer_t {int timeON; int timeCycle;};

timer_t timers[]={
{5, 15}, // on for 5 seconds, total cycle 15 seconds
{2, 7 }, //  on for 2 seconds, total cycle 7 seconds
{7, 9 },//  on for 7 seconds, total cycle 9 seconds
};

#define LED 13

#define NUMTIMERS (sizeof(timers)/sizeof(timers[0]))

void setup() {
Serial.begin(9600);
Serial.println("Start!");
pinMode(LED, OUTPUT);
}

void loop()
{
static unsigned long lastCycleStartTime;
static int timerActive;
unsigned long seconds=millis()/1000; // bad solution, just for a quick demonstration
if (seconds-lastCycleStartTime < timers[timerActive].timeON)
{
{
Serial.print(millis());
Serial.println("\tHIGH");
}
digitalWrite(LED,HIGH);
}
else
{
{
Serial.print(millis());
Serial.println("\tLOW");
}
digitalWrite(LED,LOW);
}
if (seconds-lastCycleStartTime>= timers[timerActive].timeCycle)
{ // if timeCycle is over, switch to next
timerActive++;
lastCycleStartTime=seconds;
if (timerActive>=NUMTIMERS) timerActive=0;
Serial.print("Active Timer: ");
Serial.println(timerActive);
}
}
``````