How to stop or break the loop?

Hi,Guys.
I made a auto power on/off project.the main function is ready.but i'd like
to stop the loop when some situation was happened.like,

i want to set the overtime,when buttonState == HIGH or buttonState == LOW over 30seconds then to stop the loop or make the relayState to keeps LOW .etc.

#include <Four7Seg74hc595.h>
/*
* PRESS BUTTON COUNTER INCREMENT
*/
esl::Four7Seg74hc595 display( 10,9,8 );
// Pin connected to Pin 14 of 74HC595 (Data=DIO,arduino pin8)
// Pin connected to Pin 12 of 74HC595 (Latch=RCLK,arduino pin9)
// Pin connected to Pin 11 of 74HC595 (Clock=SCLK,arduino pin10)

char sbuf[5];
uint32_t  ts; 
const int buttonPin = 2;                 // (pushbutton)
const int relayPin = 13;                 // (Relay)
int buttonPushCounter = 0;   //counter for the number of button presses
int buttonState = 0 ;         //current state of the button
int lastButtonState = 0;     //previous state of the button
int relayState;
unsigned long previousMillis = 0;        // will store last time LED was updated
long OnTime = 15000;           // milliseconds of on-time
long OffTime = 1500;           // milliseconds of off-time

void setup()
 {
  Serial.begin(9600);                     //  Serial port, 9600 bps
  pinMode(buttonPin, INPUT);             // buttonPin setup to INPUT
  pinMode(relayPin, OUTPUT);             // relayPin setup to OUTPUT 
  for (uint8_t i=0; i < 100; i++) {
    display.setDigits( "----", 4 );
    display.update();
    delay(10);}
 
  delay(1000);
  buttonPushCounter = 0;
  sprintf( sbuf, "%04u", buttonPushCounter );
  display.setDigits( sbuf, 4 );
  display.update();
 }
void loop()
 {
  unsigned long currentMillis = millis();
       if ( currentMillis - ts >= 5 ) {
     display.setDigits( sbuf, 4 );
     display.update();
     ts += 5; // display-update interval = 5msec }

  buttonState = digitalRead(buttonPin);

  if (buttonState != lastButtonState) {    // Check the buttonstate (pressed)
  // if pressed then buttonState becomes to HIGH
     if (buttonState == HIGH){ 
        // if the current state is HIGH then the button
      // went from off to on:
      buttonPushCounter++;
      Serial.print("number of button pushesON:  ");
      Serial.println(buttonPushCounter,DEC);
      sprintf( sbuf, "%04u", buttonPushCounter );
     }
    else if (buttonState == LOW) {
      // if the current state is HIGH then the button
      // went from off to on:
      buttonPushCounter++;
      Serial.print("number of button pushesOFF:  ");
      Serial.println(buttonPushCounter,DEC);
      sprintf( sbuf, "%04u", buttonPushCounter );
     }
     }
lastButtonState = buttonState;  // save the current state as the last state, for next time through the loop

    if (buttonState == HIGH){
    if((relayState == LOW) && (currentMillis - previousMillis >= OnTime)){
    previousMillis = currentMillis;  // Remember the time
    relayState = HIGH;  // Turn it on
    digitalWrite(relayPin, relayState);  // Update the actual LED 
    }
    else if((relayState == HIGH) && (currentMillis - previousMillis >= OffTime)){
    relayState = LOW;  // turn it off
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(relayPin, relayState);}	  // Update the actual LED
    }

    else if (buttonState == LOW) {
    if(currentMillis - previousMillis >= OffTime) {
    previousMillis = currentMillis;   
    if (relayState == HIGH)
      relayState = LOW;
    else
      relayState = HIGH;
    digitalWrite(relayPin, relayState);
  }
  }
}

Please:

  1. Post your entire code so we can see what is really going on.

  2. Indent your code so we can read it. Like this:

  if (buttonState == HIGH) {
    if((relayState == LOW) && (currentMillis - previousMillis >= OnTime)){
      previousMillis = currentMillis;  // Remember the time
      relayState = HIGH;  // Turn it off
      digitalWrite(relayPin, relayState);  // Update the actual LED
    }
    else if((relayState == HIGH) && (currentMillis - previousMillis >= OffTime)){
      relayState = LOW;  // turn it on
      previousMillis = currentMillis;   // Remember the time
      digitalWrite(relayPin, relayState);	  // Update the actual LED
    }
    else if(currentMillis - previousMillis1 >= OverTime){
      relayState = LOW;  // turn it on
      previousMillis1 = currentMillis;   // Remember the time
      digitalWrite(relayPin, relayState);	  // Update the actual LED
    }
  }
  else if (buttonState == LOW) {
    if(currentMillis - previousMillis >= OffTime) {
      previousMillis = currentMillis;   
      if (relayState == HIGH) relayState = LOW;
      else relayState = HIGH;
    digitalWrite(relayPin, relayState);
    }
  }

If you want to check that a button is constantly LOW for an interval you need to reset the clock whenever it goes HIGH - something like this

buttonVal = digitalRead(buttonPin);
if (buttonVal == HIGH) { // assumes LOW whe button is pressed
   startMillis = millis();  // reset the timer
}
if (millis() - startMillis >= interval) {
   // do whatever 
}

...R

startMillis() = millis();  // reset the timer

There's a typo there.

Thank you for your quick reply.i have tried to modified the code with everybody provide.but it still goes back to the loop.i want to make the relay stop working after either buttonstate is HIGH or LOW over 30s ,how can i do?unless delay().Please help...

jonixchen:
Thank you for your quick reply.i have tried to modified the code with everybody provide.but it still goes back to the loop.i want to make the relay stop working after either buttonstate is HIGH or LOW over 30s ,how can i do?unless delay().Please help...

you can not stop the main loop and there's no reason to want to.

The question is what do you want to do after the button state has not changed for 30s(presume seconds?)

"stop relay working" means?

do you want the relay to stay in the same state that it is in after 30's or do you want it to go to a set state like on/off

some times in code you have to think a little backwards. Instead of "I want the relay to stop after 30's" maybe you should be looking at "I don't want this part of the code to work if the timer is higher than 30's" if you don't reset the timer then it will remain that way until I do something that will reset the timer.

odometer:

startMillis() = millis();  // reset the timer

There's a typo there.

Thanks for spotting that. I have removed to erroneous () in Reply #2

...R

jonixchen:
Thank you for your quick reply.i have tried to modified the code with everybody provide.but it still goes back to the loop.

If you want help please post your latest code in your next Post - do NOT update the code in an earlier post.

...R