Relay blinking without delay

Everyone's seen the common LED blink without delay method using Millis commands, but how would i get a relay to go HIGH and LOW on continuous loop in the same way when I flip a switch and then turn off the relay when the switch is turned off?

Exactly the same way you do it with the LED. There's nothing special about the fact that BWoD uses an LED. You could have any code there that you want to run periodically. It's the concept of keeping track of what time it was the last time you did something and comparing to the current time (using subtraction) to determine if it is time to do it again.

Add code to BWD so the switch becomes an enabling variable.
When high and it's time, toggle the relay.
Else turn off the relay.

Show us the sketch you have so far.

Use a 'flag' to keep track of what's going. This might be called a simple example of a state machine. One state is the relay is on and time is passing checking for the turn off time. The other state is looking for a turn on event to occur.

void loop(){
currentTime = millis();
  if (switchState == 1 && (currentTime - turnOnTime >= onDuration){
  // been on long enough, turn off
  switchState = 0;
  digitalWrite (relayPin, LOW); // assume LOW = off
  }
  else {
  // check switch for a turn on if not already on, other just keep waiting for onDuration to pass
  if ((switchState == 0) && digitalRead(flipSwitchPin) == LOW){ // pin with internal pullup, Connect to GND for a start
  switchState = 1;
  digitalWrite (relayPin, HIGH); // assume LOW = off
  turnOnTime = currentTime; // capture turn-on time
  }
// do other stuff  for a bit while time passes

} // end loop
1 Like

switchState is redundant - could do a bitRead of the relayPin as a test of it being on/off also.

I have a VERY long and complex code I am trying to add this function too, so I'd rather not post the whole thing just to avoid confusion. What I'm looking for is a complete example code like the "Blink Without Delay" example code that I can use as my example for how to add it to my current project.

CrossRoads, your example code is helpful, but I can't get it to compile in my program because of things not being declared. I could try and get it to work on my own after going through my code for a while, but if you have a short full and complete version of that code that you could copy and paste for me to use as an example, that's exactly what I need :slight_smile:

What I‚Äôm looking for is a complete example code like the ‚ÄúBlink Without Delay‚ÄĚ example code that I can use as my example for how to add it to my current project.

//BWD example

unsigned long FlashTime;
unsigned long currentmillis; 

void setup()
{
  pinMode(13, OUTPUT);
  FlashTime = millis();

} //  >>>>>>>>>>>>>> E N D   O F   s e t u p ( ) <<<<<<<<<<<<<<<<<


void loop()
{
  //leave this line of code at the top
  currentmillis  = millis();

  //***************************
   if (CheckTime(FlashTime, 100UL))
  {
    digitalWrite(13,!digitalRead(13));
  }
  //***************************

  //Put your non-blocking regular stuff here



} //   >>>>>>>>>>>>>> E N D  O F  l o o p ( ) <<<<<<<<<<<<<<<<<


//======================================================================
//                       F U N C T I O N S
//======================================================================

//***************************
//Delay time expired function
boolean CheckTime(unsigned long &lastMillis, unsigned long wait) 
{
  //is the time up for this task?
  if (currentmillis - lastMillis >= wait) 
  {
    lastMillis += wait;  //get ready for the next iteration

    return true;
  }

  return false;
} //END of CheckTime()

//***************************

//======================================================================
//                       E N D   O F   C O D E
//======================================================================

I think that's all I needed LarryD! works just fine as an example code, hopefully I can add it to my project without any bugs.

Next Step:
How could I get the relay to flash in different patterns? Such as flash of and on 10 times fast, then 10 times slowly, then 10 times fast again?

How could I get the relay to flash in different patterns? Such as flash of and on 10 times fast, then 10 times slowly, then 10 times fast again?

Larry's example uses a variable named wait. Since it's a variable you can change it (or rather your program can change it) while the program is running. Or, you can use a WaitLong and WaitShort variable.

If you want 10 loops, use a [u]for-loop[/u] that loops 10 times with one wait variable/value followed by another for-loop that uses a different wait variable/value.

Or, use the same 10-count for-loop and toggle between the two different values each time.

...The two most important concepts in programming are conditional execution (if-statements) and loops (doing something over-and-over, usually until some condition is reached). Once you understand those two concepts you can begin to understand how programming "works".

Once you understand those two concepts you can begin to understand how programming "works".

Very true DVDdoug! I'm still pretty new to Arduino, but I know it well enough to know how important that understanding is. Sometimes commands that I thought would work just don't tho, but that's what these lovely forums are for! Thanks for the info everyone! I think I have everything I need now to complete my project, I just need the time to put it all together with my current project code. So much to do, so little time! :astonished:

Now that I have some time to play with the code, I'm not sure I know how to set my values for the long wait and short wait times for flash rates like this...

longWait = 10000;
shortWait = 10;

How do I set this up in the code?

//BWD example
unsigned long FlashTime = millis(); 
unsigned long RelayTime = millis();
unsigned long WaitTime = 200;
unsigned long currentmillis = millis(); 
byte x = 0;

void setup()
{
  pinMode(13, OUTPUT); //connect to LED
  pinMode(12, OUTPUT); //connect to relay driver
  
  x = 0;
  RelayTime = millis();
  FlashTime = millis();

} //  >>>>>>>>>>>>>> E N D   O F   s e t u p ( ) <<<<<<<<<<<<<<<<<


void loop()
{
  //leave this line of code at the top
  currentmillis  = millis();

  //***************************
  //just some code to see if the sketch is blocking
  if (CheckTime(FlashTime, 50UL))
  {
    digitalWrite(13,!digitalRead(13)); //toggle LED
  }
  //***************************
  if (CheckTime(RelayTime, WaitTime))
  {
    if(x < 20)
    {
      WaitTime = 200; //Fast
    }
    else
    {
      WaitTime = 400; //Slow
    }

    digitalWrite(12,!digitalRead(12)); //toggle relay
    x++;
    if(x > 39)
      {
        x = 0; 
      }
    //RelayTime = millis();  //this is not needed
  }
  //***************************

  //Put your non-blocking regular stuff here



} //   >>>>>>>>>>>>>> E N D  O F  l o o p ( ) <<<<<<<<<<<<<<<<<


//======================================================================
//                       F U N C T I O N S
//======================================================================

//***************************
//Delay time expired function
boolean CheckTime(unsigned long &lastMillis, unsigned long wait) 
{
  //is the time up for this task?
  if (currentmillis - lastMillis >= wait) 
  {
    lastMillis += wait;  //get ready for the next iteration

    return true;
  }

  return false;
} //END of CheckTime()

//***************************

//======================================================================
//                       E N D   O F   C O D E
//======================================================================

Edit:
Rearranged sketch

Why does the LED (13) keep flashing when the Relay (12) is toggling?

Edit:
You do not need to have //RelayTime = millis(); in the sketch above

LarryD How do I adjust light flash speeds using your code? I've changed all the numbers to greater values to slow the flash speed down and no matter what I do, one relay always stays on while the other always flashes quickly

Change the last parameter in the ‚Äúcall‚ÄĚ xxxx to what ever you desire.
if (CheckTime(FlashTime, xxxx))

Or

Change the value of WaitTime
if (CheckTime(RelayTime, WaitTime))
.
.
.

if(x < 20)
{
WaitTime = 200; //Fast. In this case change 200 to a different number that you want let’s say 100, goes faster
}
else
{
WaitTime = 400; //Slow. Also you can change 400 to a different number let’s say 1000, goes slower
}

.

Adjusting these numbers has absolutely no effect on my end

if(x < 20)
{
WaitTime = 200; //Fast. In this case change 200 to a different number that you want let’s say 100, goes faster
}
else
{
WaitTime = 400; //Slow. Also you can change 400 to a different number let’s say 1000, goes slower
}

Show me your sketch and I will try it here.

My version works OK.

I have changed nothing except the pins for my relays on my board and the 200 wait time to 2000

//BWD example
unsigned long FlashTime = millis();
unsigned long RelayTime = millis();
unsigned long WaitTime = 200;
unsigned long currentmillis = millis();
byte x = 0;

void setup()
{
pinMode(8, OUTPUT); //connect to LED channel 1
pinMode(9, OUTPUT); //connect to relay driver channel 2

x = 0;
RelayTime = millis();
FlashTime = millis();

} // >>>>>>>>>>>>>> E N D O F s e t u p ( ) <<<<<<<<<<<<<<<<<

void loop()
{
//leave this line of code at the top
currentmillis = millis();

//***************************
//just some code to see if the sketch is blocking
if (CheckTime(FlashTime, 50UL))
{
digitalWrite(8,!digitalRead(8)); //toggle LED
}
//***************************
if (CheckTime(RelayTime, WaitTime))
{
if(x < 20)
{
WaitTime = 2000; //Fast was 200
}
else
{
WaitTime = 400; //Slow
}

digitalWrite(8,!digitalRead(8)); //toggle relay
x++;
if(x > 39)
{
x = 0;
}
//RelayTime = millis(); //this is not needed
}
//***************************

//Put your non-blocking regular stuff here

} // >>>>>>>>>>>>>> E N D O F l o o p ( ) <<<<<<<<<<<<<<<<<

//======================================================================
// F U N C T I O N S
//======================================================================

//***************************
//Delay time expired function
boolean CheckTime(unsigned long &lastMillis, unsigned long wait)
{
//is the time up for this task?
if (currentmillis - lastMillis >= wait)
{
lastMillis += wait; //get ready for the next iteration

return true;
}

return false;
} //END of CheckTime()

//***************************

//======================================================================
// E N D O F C O D E
//======================================================================

Change your last line to 9 :
if (CheckTime(RelayTime, WaitTime))
{
if(x < 20)
{
WaitTime = 2000; //Fast was 200
}
else
{
WaitTime = 400; //Slow
}

// digitalWrite(8,!digitalRead( 8 )); //toggle relay

digitalWrite(9,!digitalRead(9)); //toggle relay <---------------<<<< Change to 9 :wink:

Oops... I really need to start color coding my wires... :o lol now how do I set the speed of the flashing for pin 8? pin 8 relay just keeps fast