Using the delay vs millis to sequence relays

Need help with code

I'm new at Arduino and am trying to write a sketch so that when a button is pressed, after a certain amount of time, relays begin turning on. Each in sequence after a delay. They stay on while the button is pressed (5v to pin 2). After the button is released, the relays turn off in reverse order after a delay. Currently, I've written the program using delay()...can this be done better using the millis command? If so, how?. Is there a better way? As written, after pin 2 goes low, there is a long delay before the relays start turning off. Prolly because it is going through all the delays of the loop. I'll eventually be triggering with a photocell, so any help there would be appreciated too. Again, I'm new to this so go easy on me. See below. Thanx! Scott

/* Written by Scott Robinson - November 2017. Bible opens and several lights trigger in sequence */

/* Bible light trigger for photo resistor or switch. Turns on relays when PR goes low. 2 sec delay between each. Turns off relays when PR goes high.
UNO Pin Setup
Pin 2 - switch
Pin 6 - Relay 1 (IN1)
Pin 7 - Relay 2 (IN2)
Pin 8 - Relay 3 (IN3)
Pin 9 - Relay 4 (IN4)
Pin 10 - Relay 5 (IN5)
Pin 13 - Power on/off LED

*/

#define RELAY1 6
#define RELAY2 7
#define RELAY3 8
#define RELAY4 9
#define RELAY5 10

int ledPin = 13 ; // setup pin 13 for power on LED

void setup()

{

pinMode(ledPin, OUTPUT) ; //Turn on LED pin 13
digitalWrite (ledPin, HIGH) ;

pinMode(2, INPUT); //setup pin 2 input for switch
digitalWrite (2, LOW); // default low or 0

// Initialise the Arduino data pins for OUTPUT
pinMode(RELAY1, OUTPUT);
pinMode(RELAY2, OUTPUT);
pinMode(RELAY3, OUTPUT);
pinMode(RELAY4, OUTPUT);
pinMode(RELAY5, OUTPUT);

delay(500); //Wait chip initialization is complete

// Setup - Turn off all relays to start
digitalWrite(RELAY1,HIGH); // Turns Relay Off
digitalWrite(RELAY2,HIGH); // Turns Relay Off
digitalWrite(RELAY3,HIGH); // Turns Relay Off
digitalWrite(RELAY4,HIGH); // Turns Relay Off
digitalWrite(RELAY5,HIGH); // Turns Relay Off

}

void loop()

{

int reading2 = digitalRead(2); // check pin 2 for +5v if switch is used
if (reading2 == 1) // read pin 2 if +5v then
{
delay(2000); // Initial wait

digitalWrite(RELAY1,LOW); // Turns ON Relays 1
delay(1000); // Wait

digitalWrite(RELAY2,LOW); // Turns ON Relay 2
delay(1000); // Wait

digitalWrite(RELAY3,LOW); // Turns ON Relay 3
delay(1000); // Wait

digitalWrite(RELAY4,LOW); // Turns ON Relay 4
delay(1000); // Wait

digitalWrite(RELAY5,LOW); // Turns ON Relay 5

}

else
{ //If pin 2 is low

digitalWrite(RELAY5,HIGH); // Turns OFF Relay 5
delay(1000); // wait

digitalWrite(RELAY4,HIGH); // Turns OFF Relay 4
delay(1000); // wait

digitalWrite(RELAY3,HIGH); // Turns OFF Relay 3
delay(1000); // wait

digitalWrite(RELAY2,HIGH); // Turns OFF Relay 2
delay(1000); // wait

digitalWrite(RELAY1,HIGH); // Turns OFF Relay 1
}
}

can this be done better using the millis command?

Absolutely. What you need to do is record when the switch becomes pressed. Periodically, you see if it has been long enough that it is now time to turn the relay on.

You need to record when the switch becomes released, so that you can see when it has been released long enough so that you need to turn the relay off.

The state change detection and the blink without delay examples have all the clues you need.

I hope this helps.

// Turn 5 relays on and off in sequence

/*
UNO Pin Setup
Pin 2 - Switch
Pin 6 - Relay 1 (IN1)
Pin 7 - Relay 2 (IN2)
Pin 8 - Relay 3 (IN3)
Pin 9 - Relay 4 (IN4)
Pin 10 - Relay 5 (IN5)
Pin 13 - Power on/off LED
*/

unsigned int Led13 = 13 ; // setup pin 13 for LED indicates button is active
unsigned int PRbutton2 = 2 ; // Setup pin 2 for PhotoResistor Button
unsigned int ButtonState = 0; // Value for Button State on pin 2
unsigned int RelaysOnState = 0; // Value for Relays On State
unsigned int PinArray = {6,7,8,9,10}; // PinArray for Relays
int x = 0; // Counter used in for loops
unsigned int DelayTime = 1000; // Time to delay while turning on Relays

void setup(){

pinMode(Led13, OUTPUT) ; //Turn off LED pin 13
digitalWrite (Led13, LOW) ;

pinMode(PRbutton2, INPUT); //setup pin 2 input for switch
digitalWrite (PRbutton2, LOW); // default low or 0

for (x=0;x<5;x++) { // Make all the declarations at once
pinMode(PinArray, OUTPUT);
} // End of For Loop
} // End of Setup Loop

// * * * * * * * * Start of Main Loop * * * * * * * * *
void loop() {
digitalWrite (Led13, HIGH) ; // Led13 is On when Button is active
ButtonState = digitalRead(PRbutton2); // Button Pushed
if (ButtonState == (1) && RelaysOnState == (0)); // Button Pushed and Relays off
{
OffToOn();
}
if (ButtonState == (1) && RelaysOnState == (1)); // Button Pushed and Relays on
{
OnToOff();
}

} // End of Main Loop

// * * * * * Subroutines * * * * *

void OffToOn()
{ // Start OffToOn Function
digitalWrite (Led13, LOW) ; // Turn Led off to indicate button is inactive
RelaysOnState = (1); // Set RelaysOnState to 1 to indicate Relays are in fact ON
for (x=0;x<5;x++) {
digitalWrite(PinArray, HIGH); // Turn on all relays with a one second delay in between
delay(DelayTime);
} // End OffToOn Function
}

void OnToOff()
{ // Start OnToOff Function
digitalWrite (Led13, LOW) ; // Turn Led off to indicate button is inactive
RelaysOnState = (0); // Set RelaysOnState to 0 to indicate Relays are in fact OFF
for (x=4;x>=0;x–) {
digitalWrite(PinArray, LOW); // Turn off all relays with a one second delay in between
delay(DelayTime);
}
} // End OnToOff Function

RWFiveRelayOnOff.ino (2.35 KB)

If this is all the sketch does, there is really no reason to use millis(). You need to use millis() instead of delay() if you want to do something else useful while you're waiting. As you have explained it, there isn't anything useful to do once the bible has been opened until after all the lights light up, and then it only waits until the bible closes. Unless you want to interrupt the light-up sequence if the bible closes before all the lights get lit, or some other fancy thing like that.

It looks like it almost works as written. I think the delay after you let off the button is because it started the loop() function at the top again, and since the button was still pressed, it's lighting up the lights again. Except you don't see that it's lighting them up because they're already lit up. You could fix that by putting in a spin wait loop after the light-up sequence, and just loop until the button is released.

Try this:

/* Written by Scott Robinson - November 2017.  Bible opens and several lights trigger in sequence */

/* Bible light trigger for photo resistor or switch.  Turns on relays when PR goes low.  2 sec delay between each.  Turns off relays when PR goes high.
 UNO Pin Setup
 Pin 2 - switch
 Pin 6 - Relay 1 (IN1)
 Pin 7 - Relay 2 (IN2)
 Pin 8 - Relay 3 (IN3)
 Pin 9 - Relay 4 (IN4)
 Pin 10 - Relay 5 (IN5)
 Pin 13 - Power on/off LED


 */

#define RELAY1  6
#define RELAY2  7
#define RELAY3  8
#define RELAY4  9
#define RELAY5  10

int ledPin = 13 ;  // setup pin 13 for power on LED

void setup()

{

  pinMode(ledPin, OUTPUT) ;  //Turn on LED pin 13
  digitalWrite (ledPin, HIGH) ;

  pinMode(2, INPUT);  //setup pin 2 input for switch
  digitalWrite (2, LOW);  // default low or 0


  // Initialise the Arduino data pins for OUTPUT
  pinMode(RELAY1, OUTPUT);
  pinMode(RELAY2, OUTPUT);
  pinMode(RELAY3, OUTPUT);
  pinMode(RELAY4, OUTPUT);
  pinMode(RELAY5, OUTPUT);

  delay(500);  //Wait chip initialization is complete


  // Setup - Turn off all relays to start
  digitalWrite(RELAY1, HIGH);         // Turns Relay Off
  digitalWrite(RELAY2, HIGH);         // Turns Relay Off
  digitalWrite(RELAY3, HIGH);         // Turns Relay Off
  digitalWrite(RELAY4, HIGH);         // Turns Relay Off
  digitalWrite(RELAY5, HIGH);         // Turns Relay Off

}



void loop()

{

  int reading2 = digitalRead(2);  // check pin 2 for +5v if switch is used
  if (reading2 == 1)  // read pin 2 if +5v then
  {
    delay(2000);                                        // Initial wait

    digitalWrite(RELAY1, LOW);          // Turns ON Relays 1
    delay(1000);                                      // Wait


    digitalWrite(RELAY2, LOW);          // Turns ON Relay 2
    delay(1000);                                      // Wait


    digitalWrite(RELAY3, LOW);          // Turns ON Relay 3
    delay(1000);                                      // Wait


    digitalWrite(RELAY4, LOW);          // Turns ON Relay 4
    delay(1000);                                      // Wait


    digitalWrite(RELAY5, LOW);          // Turns ON Relay 5

  }

  while (digitalRead(2) == HIGH);      // Spin wait here until the button is released

  delay(1000);                         // "after a delay"?

  digitalWrite(RELAY5, HIGH);          // Turns OFF Relay 5
  delay(1000);                                        // wait

  digitalWrite(RELAY4, HIGH);          // Turns OFF Relay 4
  delay(1000);                                        // wait

  digitalWrite(RELAY3, HIGH);          // Turns OFF Relay 3
  delay(1000);                                        // wait

  digitalWrite(RELAY2, HIGH);          // Turns OFF Relay 2
  delay(1000);                                        // wait

  digitalWrite(RELAY1, HIGH);          // Turns OFF Relay 1
}