How to Exit a nested loop after an elapsed period of times or no. loops

I’ve created a nested loop and I want it to break that loop once 10 minutes has elapsed or after 10 loops!
I’m new to Arduino and would really appreciate some help on this.
Here is my code:

int temp; //A0 producing 4V
#define start_button 2 // #define any text saying start_button will be replaced with (port)2
#define LED1 3 // #define any text saying LED1 will be replaced with (port)3
#define heater_element 4 // #define any text saying heater_element will be replaced with (port)4
#define LED2 5 // #define any text saying LED2 will be replaced with (port)5
#define LED3 6 // #define any text saying LED3 will be replaced with (port)6
#define piezo_buzzer 7 // #define any text saying piezo_buzzer will be replaced with (port)7

void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  // initialize pins:
  pinMode(LED1,OUTPUT);                       
  pinMode(heater_element,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  pinMode(piezo_buzzer,OUTPUT);
}

void loop()
{
   if (digitalRead(start_button)==HIGH)                      //starting machine
 {
   digitalWrite (LED1,HIGH);                     //turning on 'started' LED
   Serial.println("Started cooking process");
   delay(5000);                                   //delay for 5 seconds 
  }
   if (analogRead(temp)<=4.5)
   {
   digitalWrite (heater_element,HIGH);           //turing on heater
   digitalWrite (LED2,HIGH);                     //turning on 'Boiling' LED
   Serial.println("Started to boil");
   delay(5000);                               
   }
   while (analogRead(temp)>4.5)
   {
   digitalWrite (heater_element,LOW);                     //turning off heating element
   Serial.println("Water Boiled");                                                     
   }
   do 
   {
    if (analogRead(temp)>4.5)
    {
      break;
    }
    else
    {
    digitalWrite (heater_element,HIGH);
    delay(10000); 
    digitalWrite (heater_element,LOW);
    delay(50000);
    }
   }
   while(delay(600000));

}

You could rethink your code as a state machine and manage time and temperature as events to change state

If you were to describe in plain English what you want, how would it look like and what would be the state of the Heater element at each state

For example

state IDLE heater is off
State COOKING heater is on

Now define how you get from on state to the other

If state is IDLE and you press the button go to COOKING state (and thus set jester accordingly)
If state is COOKING and you press the button go to the IDLE state (and thus set jester accordingly)
If state is cooking and 10 minutes are up, go to the IDLE state (and thus set jester accordingly)

You might need other states to describe specifics. Like you have a BOILING state. What's the heater in that state?

Etc

surely there is a way I can do it using this code

Hi wpage97!

  1. The break operator leaves 1 nested level where it is.

  2. while (delay... The while loop runs while the condition is true, but the delay function doesn't return value.

  3. I can't see any nested loop in your sketch (not to mention you loops inside the loop function ).

What you need, IMHO, is to exit loop function if the time hasn't come yet and accumulate some time counter.

For example:

long _10m_delay=millis(); // get the start time moment
int _10timesy=0;
bool time_has_come=false;

loop() {
  if ((millis - _10m_delay) >  1000*60*10)    // 1000ms = 1 second
  {
    time_has_come=true;
    _10m_delay=millis();
  }
  if ( _10times_delay > 9) {
    _10times_delay = 0;
    time_has_come=true;
  }
  if (time_has_come) {
    time_has_come=false;
    ... do you want to do here ...
  }

  ... if the time  _10times_delay++;

}

BTW, to exit function immediately you need issue the return operator.

If you had nested loops - Sure you could use a goto... that's considered ugly practice in general unless it's really really needed and your code will soon become spaghetti code... hard to maintain... your call of course.

On the other hand, Understanding how to build a state machine will help you for many many other programs

And more…

As far as I understand the cooking process is 10 minutes long. After you press “Start” button you get the the start time, and then all you need is keep the temperature near 4.5 until 10 min has gone.
I’ve kept all minor things like LEDs in this code for your attention.

long ctime=0; // if ctime > 0 then cooking is started
const byte pinTEMP=A0; // don't forget to initialize variables or make constants

void loop()
{
  if (digitalRead(start_button)==HIGH && ctime ==0)         //starting machine
  {
     digitalWrite (LED1,HIGH);                     // turning on 'started' LED
     Serial.println("Cooking...");
     ctime=millis();                                     // get the cooking start time
  }

  if ((ctime>0) && (millis()-ctime) > 1000*60*10 )
  {
     ctime=0;
     digitalWrite (heater_element,LOW);
     Serial.println("Done!");
  }

  if (analogRead(pinTEMP)>4.5)
  {
    digitalWrite (heater_element,LOW);  //turning off heating element
    if(ctime > 0) Serial.println("Cooking...                 "); // erase "warming up"
  }

  // start warmin up if temperature is low and cooking in progress.
  if (analogRead(pinTEMP)<=4.5 && (ctime>0))
  {
    digitalWrite (heater_element,HIGH);           //turing on heater
    digitalWrite (LED2,HIGH);                     //turning on 'Boiling' LED
    Serial.println("Cooking...  warming up");
  }
}

@Andri what happens if you press again the button? (And ctime would be better as being the same type millis() returns)

I agree with J-M-L, state machines are a great tool to have, and the way forward for this problem.

@J-M-L:
I didn't want to introduce another bool to be cooking_in_progress flag, so ctime>0 condition is the flag. It becomes 0 only when device is powered on or the current task is done (10 minutes' gone).
So if button pressed when current cooking in progress then ctime>0 and condition
(digitalRead(start_button)==HIGH && ctime ==0)
returns false and nothing happens until task is finished and ctime accept value of 0.

My sketch is just an example to understand how it could be arranged.

P.S. we could add "Stop" button to set ctime=0 to interrupt current cooking or simple reset device. It depends on how smart the device's going to be.

OK you risk a bug every 50 days if you are unlucky :slight_smile:

I'd be more worried about the 1000*60*10