Run Millis loop for x amount of time

Hi Ive managed to get this to run the relays the way I need were Relay0 loops on off and the others stay on. what I need to do is get the hole thing to shut off after X amount of seconds.

I'll be using a input trigger to turn it on but have not set that up yet.

  • Relays 0,1,2 & 3 are connected to the Arduino digital pins 2,3,9 & 7 respectively.
  • Relays can be 'ON' or 'OFF' by setting High/Low to the associated digital IO's.
    */

const int relaypin0 = 2;
const int relaypin1 = 3;
const int relaypin2 = 9;
const int relaypin3 = 7;
int relayState0 = LOW;
int relayState1 = LOW;
int relayState2 = LOW;
int relayState3 = LOW;
long previousMillis = 0;
long interval = 100000;

void setup()
{
pinMode(relaypin0, OUTPUT);
pinMode(relaypin1, OUTPUT);
pinMode(relaypin2, OUTPUT);
pinMode(relaypin3, OUTPUT);
}

void loop()
{

unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:

if (relayState0 == LOW)
relayState0 = HIGH;

else
relayState0 = LOW;

if (relayState1 == LOW)
relayState1 = HIGH;
else
relayState1 = HIGH;

if (relayState2 == LOW)
relayState2 = HIGH;
else
relayState2 = HIGH;

if (relayState3 == LOW)
relayState3 = HIGH;
else
relayState3 = HIGH;

digitalWrite(relaypin0,relayState0 );
digitalWrite(relaypin1,relayState1 );
digitalWrite(relaypin2,relayState2 );
digitalWrite(relaypin3,relayState3 );
}

}

You know how to measure the passage of time - when the time span is up, simply enter an infinite loop doing nothing.

Please use code tags when posting code.

I have no Idea I rewrote this from the blink without delay code.
I've never used this forum before and have never used the arduino board before. and I don't know what a code tag is sorry.

Code tag is the # icon above the :wink: :sweat_smile: icons. Select the code when you paste it, and hit that #....

Then
{
your code
}
will be
easy to read;
like this

The first three posts at the top of this Forum will help you understand the Rules for posting on the Forum, especially the two by Nick Gammon. The rules make it easier for the rest of us to help you with your problem.

CBottcher:
I have no Idea I rewrote this from the blink without delay code.

So what do you think this line does?

   if(currentMillis - previousMillis > interval) {

Really, you are so close to just knowing what you ask for.

There is a trick you can use to change each relay pin without needing to know the state. But get your other parts right first.

But more important is that you learn about arrays and loops. You IDE has Examples in section 5.Control deal with them. Those relay pins can be in an array that a loop can index through, treating all the same with one code instead of code lines for each named pin. This is a very fundamental part of programming that saves you time and typing.

PS -- also --

long previousMillis = 0;
long interval = 100000;

Make all your time variables unsigned long. Yes, you can use long which is 32-bit signed and get away with it in this and many cases but it's a bad habit that can bite you, mixing signed and unsigned variables in operations.

long interval = 100000;

Won't work because the compiler will try and make 100000 into an int before assigning and get it wrong.

long interval = 100000L; // the L is to tell the compiler to make the value signed 32 bit.
unsigned long previousMillis = 0UL;
unsigned long interval = 100000UL; // the UL is to tell the compiler to make the value unsigned 32 bit.

Now if only there were variables to keep track of how long the lights have been blinking, you could code for when they should stop. But where would they come from?

CBottcher:
and I don't know what a code tag is sorry.

. . . which is why we posted this at the top of nearly every section of the forum

When you are in the form where you are posting your answer to this, you’ll notice there are buttons above the textarea. One of them is marked with the #symbol. If you click this you will have the “code tags” inserted into the text area. This is where you should paste your code.

Anyhow, this will probably do something approaching what you’re after.

int relayPins[4]={2,3,9,7};
int triggerPin=8;
//time that relays stay on after being triggered
unsigned long activityPeriod=10000;//10 seconds

//if you want relay 0 to stay on for 1/2 second in every 2
//you would make pulseLength=500 pulsePeriod=2000;
unsigned long pulseLength=500;
unsigned long pulsePeriod=2000;

void setup()
{
int n;
for (n=0;n<4;n++)
  {digitalWrite(relayPins[n],LOW);
   pinMode(relayPins[n],OUTPUT);
   pinMode(triggerPin,INPUT_PULLUP);
  }
}


int relaysActive=0;
unsigned long triggerTime;//time user triggered
unsigned long lastPulse=0;//time relay 0 was last toggled

void loop()
{
int n;
unsigned long currentTime=millis();
switch(relaysActive)
  {case 0://nothing going on yet
    if (digitalRead(triggerPin)==LOW)
      {for(n=0;n<4;n++)
           digitalWrite(relayPins[n],HIGH);
       triggerTime=currentTime;
       lastPulse=currentTime;
       relaysActive=true;
       maintainRelay0();
       }
      break;
   case 1:maintainRelay0();
           if ((currentTime-triggerTime)>activityPeriod)
             {for(n=0;n<4;n++)
                digitalWrite(relayPins[n],LOW);
             relaysActive=0;
             }          
  } 
}

void maintainRelay0()
{
unsigned long currentTime=millis();
if((currentTime-lastPulse)>pulsePeriod)
  lastPulse=currentTime;
bool newState=((currentTime-lastPulse)<pulseLength);
if (newState==1)
   Serial.println("it's HIGH");
digitalWrite(relayPins[0],newState);  
}

Thanks everyone for Helping. Ive been playing and have setup the following.

const int buttonPin = 5;     // the number of the pushbutton pin
const int relaypin0 =  2;
const int relaypin1 =  3;
const int relaypin2 =  9;
const int relaypin3 =  7;
long previousMillis = 0;
long interval = 1000;

// variables will change:
int buttonState = 0;        
int relayState0 = 0;
void setup() {
  
  
  
pinMode(relaypin0, OUTPUT);
pinMode(relaypin1, OUTPUT);
pinMode(relaypin2, OUTPUT);
pinMode(relaypin3, OUTPUT);

  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);    
}

void loop(){
  
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {    
     
       unsigned long currentMillis = millis();
        previousMillis = currentMillis;
        digitalWrite(relaypin0, HIGH); 
      if (relayState0 == HIGH)
      relayState0 = LOW;

    else
      relayState0 = HIGH;

    
      
      
   digitalWrite(relaypin1, HIGH);
  digitalWrite(relaypin2, HIGH);
 digitalWrite(relaypin3, HIGH);  
 delay(5000); 
  }
  else {
    // turn LED off:
    digitalWrite(relaypin0, LOW); 
    digitalWrite(relaypin1, LOW);
    digitalWrite(relaypin2, LOW);
    digitalWrite(relaypin3, LOW);
  }
}

I cant seem to get the millis funtion associate with relat0 after digitalWrite (relaypin0, HIGH);
is there a way to get it to turn on/off within the delay time of the other relays

cheers

Where you have a delay() in your code, execution stays at that command until it is done. Period.

So what do you think this line does?

   if(currentMillis - previousMillis > interval) {

I asked that for a reason. If you take the time to answer you might see why.

CBottcher:
Thanks everyone for Helping. Ive been playing and have setup the following.

I cant seem to get the millis funtion associate with relat0 after digitalWrite (relaypin0, HIGH);
is there a way to get it to turn on/off within the delay time of the other relays

cheers

try something like this. Connect your PushButton to pin5 and ground, no resistor (you will use the internal pull-up resistor)

Arduino will start up, start toggling relay0 every second, and turn on all of the other relays. After 60seconds, they all turn off. If you push the button… it starts over.

compiled but not tested…

const int buttonPin = 5;
const int relaypin0 =  2;
const int relaypin1 =  3;
const int relaypin2 =  9;
const int relaypin3 =  7;
unsigned long startTime;
unsigned long interval = 1000UL;
unsigned long timeOut = 60000UL;

int lastButtonState;        
boolean active = true;
int relays = 0;
void setup() 
{
  Serial.begin(115200);
  pinMode(relaypin0, OUTPUT);
  pinMode(relaypin1, OUTPUT);
  pinMode(relaypin2, OUTPUT);
  pinMode(relaypin3, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);    
}

void loop()
{
  int buttonState = digitalRead(buttonPin);
  if (buttonState == LOW && lastButtonState == HIGH) 
  {
    active = true;
    startTime = millis();
    Serial.println(F("Button Pressed"));
  }
  lastButtonState = buttonState;
  
  if (active && millis() - startTime < timeOut)
  {
    toggleRelay(relaypin0);
    if (relays == 0)
    {
      relaysOn();
    }
  }
  else
  {
    if (relays == 1)
    {
      relaysOff();
    }
  }
}

void toggleRelay(int relay)
{
  static unsigned long lastToggleTime;
  if (millis() - lastToggleTime >= interval)
  {
    digitalWrite(relay, !digitalRead(relay));
    lastToggleTime += interval;
    Serial.print(F("Toggle Relay is ")); Serial.println(digitalRead(relaypin0)? F("HIGH") : F("LOW"));
  }
}
void relaysOn()
{
  digitalWrite(relaypin1, HIGH);
  digitalWrite(relaypin2, HIGH);
  digitalWrite(relaypin3, HIGH); 
  relays = 1; 
  Serial.println(F("All other relays HIGH"));
}

void relaysOff()
{
  digitalWrite(relaypin0, LOW); 
  digitalWrite(relaypin1, LOW);
  digitalWrite(relaypin2, LOW);
  digitalWrite(relaypin3, LOW);
  relays = 0;
  Serial.println(F("All relays LOW"));
}

It looks like it will work. It runs once after power up and them after when button press.

thanks

You can toggle any Port pin by writing 1 to the corresponding PIN register bit, same one you read the pin with.