Go Down

### Topic: Blink without delay, extended to more complex switch patterns (Read 2711 times)previous topic - next topic

#### beperron

##### Dec 04, 2012, 07:23 pm
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

#### robtillaart

#1
##### Dec 04, 2012, 07:39 pm
you need to make an array of ON and OFF intervals and take after every time the next interval

Code: [Select]
`if (millis() - lasttime > interval[idx]){   lasttime += interval[idx];   idx++;   if (idx == idxmax) idx = 0;   blink = ! blink;   digitalWrite(13, blink);}`
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

#### beperron

#2
##### Dec 04, 2012, 07:52 pm
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

#### nickgammon

#3
##### Dec 04, 2012, 08:19 pm
Please post technical questions on the forum, not by personal message. Thanks!

#### Arrch

#4
##### Dec 04, 2012, 10:10 pm
You need a Finite State Machine.

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

#### marco_c

#5
##### Dec 05, 2012, 08:13 am
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.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

#### beperron

#6
##### Dec 06, 2012, 02:30 am
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?

#### nickgammon

#7
##### Dec 06, 2012, 03:59 am
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.
Please post technical questions on the forum, not by personal message. Thanks!

#### UKHeliBob

#8
##### Jan 31, 2015, 09:53 am
Code: [Select]
`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() ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

#### UKHeliBob

#9
##### Jan 31, 2015, 10:03 am
Quote
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.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

#### jurs

#10
##### Jan 31, 2015, 10:18 am
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.

Code: [Select]
`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)  {    if (!digitalRead(LED))    {      Serial.print(millis());      Serial.println("\tHIGH");    }    digitalWrite(LED,HIGH);  }  else  {    if (digitalRead(LED))    {      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);  }}`

#### jurs

#11
##### Jan 31, 2015, 10:31 am
I think we can stop discussing in this thread, as the thread starter might not read it.

It was "amvsadnik" who woke up this two year old thread today, just to promote his library.

The thread and question is very old.

#### Robin2

#12
##### Jan 31, 2015, 02:10 pm
Have you looked at several things at a time which is an extended demo of BWoD?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

#### TVA_VAE

#13
##### Jan 31, 2015, 02:47 pm
Interrupt? Calculate clock speed and how long ea step takes and make loops, then you can use the delay of the component with its steps self? I don't know if this is a great idea but i think it is possible .

Go Up