Looping until a button is pressed

I have two programs, changeLights and yellowFlash. When i press a button on the IR remote i start changeLights, when i press another button i start yellowFlash. Once they've gone through the code once they stop, but i want them to loop until i press one of the two buttons again which would stop the current loop and start either the same or the other program loop.

This is what i've got so far:

#include <IRremote.h>

const int red = 10; // red led pin 10
const int yellow = 9; // yellow led pin 9
const int green = 8; // green led pin 8
const int receiver = 6; // Infrared receiver output pin( TSOP4838 )

int IRstate;
int lastIRstate;

IRrecv irrecv(receiver);
decode_results results;

void setup() {
  Serial.begin(9600);
  Serial.println("Traffic Lights - Initializing...");
  irrecv.enableIRIn();
  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(IRstate, INPUT);

  digitalWrite(red, HIGH);
  delay(1000);
  digitalWrite(red, LOW);
  digitalWrite(yellow, HIGH);
  delay(1000);
  digitalWrite(yellow, LOW);
  digitalWrite(green, HIGH);
  delay(1000);
  digitalWrite(green, LOW);
  delay(1000);
  Serial.println("Traffic Lights - Initialized!");
  Serial.println("Waiting for remote input...");
}

void loop() {
  
  IRstate = digitalRead(receiver);

  if (IRstate != lastIRstate) {
    
    if (irrecv.decode(&results)) {
         switch(results.value) {

            case 0x77E14033: // MENU
                Serial.println("MENU button pressed");
                yellowFlash();
            break;
            
            case 0x77E12033: // PLAY/PAUSE
                Serial.println("PLAY/PAUSE button pressed");
                changeLights();
            break;  
        }
        delay(10);
        irrecv.resume();
    }
  }
lastIRstate = IRstate;
}
void changeLights() { // I want this to loop until i press a button on the remote
 
    digitalWrite(green, LOW);
    digitalWrite(yellow, HIGH);
    delay(3000);

    digitalWrite(yellow, LOW);
    digitalWrite(red, HIGH);
    delay(5000);

    digitalWrite(yellow, HIGH);
    delay(2000);

    digitalWrite(yellow, LOW);
    digitalWrite(red, LOW);
    digitalWrite(green, HIGH);
    delay(5000); 
}
void yellowFlash() { // I want this to loop until i press a button on the remote
    
    digitalWrite(green, LOW);
    digitalWrite(red, LOW);
    digitalWrite(yellow, HIGH);
    delay(1000);
    digitalWrite(yellow, LOW);
    delay(1000);
    digitalWrite(yellow, HIGH);
    delay(1000);
    digitalWrite(yellow, LOW);   
}
if (IRstate != lastIRstate) {
cases
}
lastIRstate = IRstate;

you dont need this. because the moment it ends the loop and begins again.
the if statement will be false.

TheTonyy:
but i want them to loop until i press one of the two buttons again which would stop the current loop and start either the same or the other program loop.

I think the very few changes I have made in this version will do what you want.

#include <IRremote.h>

const int red = 10; // red led pin 10
const int yellow = 9; // yellow led pin 9
const int green = 8; // green led pin 8
const int receiver = 6; // Infrared receiver output pin( TSOP4838 )

boolean yellowFlashRun = false;  // NEW
boolean changeLightsRun = false;  // NEW

int IRstate;
int lastIRstate;

IRrecv irrecv(receiver);
decode_results results;

void setup() {
    Serial.begin(9600);
    Serial.println("Traffic Lights - Initializing...");
    irrecv.enableIRIn();
    pinMode(red, OUTPUT);
    pinMode(yellow, OUTPUT);
    pinMode(green, OUTPUT);
    pinMode(IRstate, INPUT);

    digitalWrite(red, HIGH);
    delay(1000);
    digitalWrite(red, LOW);
    digitalWrite(yellow, HIGH);
    delay(1000);
    digitalWrite(yellow, LOW);
    digitalWrite(green, HIGH);
    delay(1000);
    digitalWrite(green, LOW);
    delay(1000);
    Serial.println("Traffic Lights - Initialized!");
    Serial.println("Waiting for remote input...");
}

void loop() {
 
    IRstate = digitalRead(receiver);

    if (IRstate != lastIRstate) {
    
        if (irrecv.decode(&results)) {
             switch(results.value) {

                case 0x77E14033: // MENU
                    Serial.println("MENU button pressed");
                    yellowFlashRun = true; // NEW
                    changeLightsRun = false; // NEW
                break;
                
                case 0x77E12033: // PLAY/PAUSE
                    Serial.println("PLAY/PAUSE button pressed");
                    yellowFlashRun = false;  // NEW
                    changeLightsRun = true;  // NEW
                break; 
            }
            delay(10);
            irrecv.resume();
        }
    }
    lastIRstate = IRstate;
    changeLights();  // NEW
    yellowFlash();  // NEW
}
void changeLights() { // I want this to loop until i press a button on the remote

    if (changeLightsRun == true) { // new
        digitalWrite(green, LOW);
        digitalWrite(yellow, HIGH);
        delay(3000);

        digitalWrite(yellow, LOW);
        digitalWrite(red, HIGH);
        delay(5000);

        digitalWrite(yellow, HIGH);
        delay(2000);

        digitalWrite(yellow, LOW);
        digitalWrite(red, LOW);
        digitalWrite(green, HIGH);
        delay(5000);
    }
}
void yellowFlash() { // I want this to loop until i press a button on the remote
    
    if (yelloFlashRun == true) { // new
        digitalWrite(green, LOW);
        digitalWrite(red, LOW);
        digitalWrite(yellow, HIGH);
        delay(1000);
        digitalWrite(yellow, LOW);
        delay(1000);
        digitalWrite(yellow, HIGH);
        delay(1000);
        digitalWrite(yellow, LOW);   
    }
}

I think I have marked all the changes I made

Note how I have made the IR buttons set the value of variables rather than call the function directly. In effect the variable remember the button press.

...R

Thankyou for the answers. The code you posted does do what i want it to do. Is there a way to start the other loop at any time ? Currently i can start the other loop when the current one ends.

For that you need to get rid of all the delay()s and use millis() to manage the timing without blocking as illustrated in Several Things at a Time

...R