IR remote command is stuck in While loop ! help me plz

First of all, sorry for my bad English. I need to control lights using IR remote , my codes are done but except one thing. There are totally 12 led bulbs connected to Arduino, which are divided as 4 parts, like 4 buttons in IR remote. When I press the button in IR remote it works fine but if I press the button 1, it goes to switch case and finds my button code and run the codes which I have written inside the switch case but inside the switch case I have a while loop . I need to stop the while loop when the next button is pressed but I cannot stop the while loop. Help me to sort this problem. :disappointed_relieved: :cry:

Here i post my code

#include <IRremote.h>
#define PIN_RECEIVER A0

int Lane1[] = {13,12,11}; // Lane 1 Red, Yellow and Green
int Lane2[] = {10,9,8};// Lane 2 Red, Yellow and Green
int Lane3[] = {7,6,5};// Lane 3 Red, Yellow and Green
int Lane4[] = {4,3,2};// Lane 4 Red, Yellow and Green

IRrecv receiver(PIN_RECEIVER);
decode_results results;      

void setup() 
{
  receiver.enableIRIn();
  for (int i = 0; i < 3; i++)
  {
    pinMode(Lane1[i], OUTPUT); 
    pinMode(Lane2[i], OUTPUT);
    pinMode(Lane3[i], OUTPUT);
    pinMode(Lane4[i], OUTPUT);
  }
}

void loop() 
{  
  
  if (receiver.decode()) 
  {
      translateIR();
      receiver.resume();  // Receive the next value
  }  
}
void algorithm()
{ 
  int n=0;
  while(n==0){
    digitalWrite(Lane1[2], HIGH); //lane 1-Green
    digitalWrite(Lane3[0], HIGH); 
    digitalWrite(Lane4[0], HIGH);
    digitalWrite(Lane2[0], HIGH);
    receiver.resume();
    delay(7000);
    digitalWrite(Lane1[2], LOW); 	
    digitalWrite(Lane3[0], LOW);	
    digitalWrite(Lane1[1], HIGH);	//lane 1-Yellow
    digitalWrite(Lane3[1], HIGH);	//lane 3-Yellow
    receiver.resume();
    delay(3000);
    digitalWrite(Lane1[1], LOW);
    digitalWrite(Lane3[1], LOW);
    digitalWrite(Lane1[0], HIGH); //lane 1-Red
    digitalWrite(Lane3[2], HIGH); //lane 3-Green
    receiver.resume();
    delay(7000);
    digitalWrite(Lane3[2], LOW);
    digitalWrite(Lane4[0], LOW);
    digitalWrite(Lane3[1], HIGH);  //lane 3-Yellow
    digitalWrite(Lane4[1], HIGH);  //lane 4-Yellow
    receiver.resume(); 
    delay(3000);
    digitalWrite(Lane3[1], LOW);
    digitalWrite(Lane4[1], LOW);
    digitalWrite(Lane3[0], HIGH);	//lane 3-Red
    digitalWrite(Lane4[2], HIGH);	//lane 4-Green
    receiver.resume();
    delay(7000);
    digitalWrite(Lane4[2], LOW);
    digitalWrite(Lane2[0], LOW);
    digitalWrite(Lane4[1], HIGH);  //lane 4-Yellow
    digitalWrite(Lane2[1], HIGH);  //lane 2-Yellow
    receiver.resume();
    delay(3000);
    digitalWrite(Lane4[1], LOW);
    digitalWrite(Lane2[1], LOW);
    digitalWrite(Lane4[0], HIGH);  //lane 4-Red
    digitalWrite(Lane2[2], HIGH);  //lane 2-Green
    receiver.resume();
    delay(7000);
    digitalWrite(Lane1[0], LOW);
    digitalWrite(Lane2[2], LOW);
    digitalWrite(Lane1[1], HIGH);  //lane 1-Yellow
    digitalWrite(Lane2[1], HIGH);  //lane 2-Yellow
    receiver.resume();
    delay(3000);
    digitalWrite(Lane1[1], LOW);
    digitalWrite(Lane2[1], LOW);
  }
  
}
void translateIR()
{
  // Takes command based on IR code received
  switch (receiver.decodedIRData.command) {
    case 168:
    // All Lane goes OFF
      digitalWrite(Lane1[0], LOW);
	    digitalWrite(Lane1[2], LOW);
	    digitalWrite(Lane1[1], LOW); 
	    digitalWrite(Lane3[1], LOW);
	    digitalWrite(Lane3[2], LOW);
  	  digitalWrite(Lane3[0], LOW); 
	    digitalWrite(Lane4[1], LOW);
	    digitalWrite(Lane4[2], LOW); 
  	  digitalWrite(Lane4[0], LOW); 
      digitalWrite(Lane2[1], LOW);
	    digitalWrite(Lane2[2], LOW);
  	  digitalWrite(Lane2[0], LOW); 
      break;
    case 48:
    //Keypad button "1"     
         //Lane 1 - Green
      digitalWrite(Lane1[0], LOW);
	    digitalWrite(Lane1[2], LOW);
	    digitalWrite(Lane1[1], HIGH); //lane 1-Yellow
	    digitalWrite(Lane3[1], LOW);
	    digitalWrite(Lane3[2], LOW);
  	  digitalWrite(Lane3[0], HIGH); //lane 3-Red
	    digitalWrite(Lane4[1], LOW);
	    digitalWrite(Lane4[2], LOW); 
  	  digitalWrite(Lane4[0], HIGH); //lane 4-Red
	    digitalWrite(Lane2[1], LOW);
	    digitalWrite(Lane2[2], LOW);
  	  digitalWrite(Lane2[0], HIGH); //lane 2-red
	    delay(3000);
	    digitalWrite(Lane1[1], LOW);
	    digitalWrite(Lane1[2], HIGH); //lane 1-Green
      break; 
    case 24:
      //Keypad button "2"     
         //Lane 3 - Green
	    digitalWrite(Lane4[1], LOW);
	    digitalWrite(Lane4[2], LOW); 
  	  digitalWrite(Lane4[0], HIGH);  //lane 4-Red
	    digitalWrite(Lane2[1], LOW);
	    digitalWrite(Lane2[2], LOW);
  	  digitalWrite(Lane2[0], HIGH);  //lane 2-Red   
      digitalWrite(Lane1[2], LOW);
	    digitalWrite(Lane1[1], LOW);
	    digitalWrite(Lane1[0], HIGH); 	//lane 1-Red	
	    digitalWrite(Lane3[0], LOW);
	    digitalWrite(Lane3[2], LOW);	
  	  digitalWrite(Lane3[1], HIGH);	//lane 3-Yellow
  	  delay(3000);
  	  digitalWrite(Lane3[1], LOW);
  	  digitalWrite(Lane3[2], HIGH); //lane 3-Green   
      break; 
    case 122:
      //Keypad button "3"     
          //Lane 4 - Green
	    digitalWrite(Lane4[2], LOW); 
  	  digitalWrite(Lane4[0], LOW);
	    digitalWrite(Lane4[1], HIGH);  //lane 4-Yellow
	    digitalWrite(Lane2[1], LOW);
	    digitalWrite(Lane2[2], LOW);
  	  digitalWrite(Lane2[0], HIGH);  //lane 2-Red   
      digitalWrite(Lane1[2], LOW);
	    digitalWrite(Lane1[1], LOW);
	    digitalWrite(Lane1[0], HIGH); 	//lane 1-Red	
	    digitalWrite(Lane3[1], LOW);
	    digitalWrite(Lane3[2], LOW);	
  	  digitalWrite(Lane3[0], HIGH);	//lane 3-Red
  	  delay(3000);
  	  digitalWrite(Lane4[1], LOW);
  	  digitalWrite(Lane4[2], HIGH); //lane 4-Green     
      break;  
    case 16:
       //Keypad button "4"     
         //Lane 2 - green     
      digitalWrite(Lane4[2], LOW); 
  	  digitalWrite(Lane4[1], LOW);
	    digitalWrite(Lane4[0], HIGH);  //lane 4-Red
	    digitalWrite(Lane2[0], LOW);
	    digitalWrite(Lane2[2], LOW);
  	  digitalWrite(Lane2[1], HIGH);  //lane 2-Yellow   
      digitalWrite(Lane1[2], LOW);
	    digitalWrite(Lane1[1], LOW);
	    digitalWrite(Lane1[0], HIGH); 	//lane 1-Red	
	    digitalWrite(Lane3[1], LOW);
	    digitalWrite(Lane3[2], LOW);	
  	  digitalWrite(Lane3[0], HIGH);	//lane 3-Red
  	  delay(3000);
  	  digitalWrite(Lane2[1], LOW);
  	  digitalWrite(Lane2[2], HIGH); //lane 2-Green     
      break; 
    case 194:
      algorithm();
      break; 
      receiver.resume();
 }
}

@krishvvip Installation and Troubleshooting is for Problems with the Arduino itself NOT your project. It says so in the description of the section. Therefore I have moved your post here. Please be more careful where you post in future.

You may want to read this before you proceed:-
how to get the best out of this forum

You need to post your code along with a schematic of how things are wired up. Hand drawn is fine, Fritzing is not.

@Grumpy_Mike Now i have edited my post and added my code.. plz help me

General advise: don't use a while-loop for these things and don't use delay.

A simple solution might be to

  1. get rid of delay
  2. make the variable n a global variable and if another key is pressed, change n from 0 to 1 and test in algoritm.

To get rid of delay, you will have to implement algorithm as a finite state machine.

Your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advise on) your project :wink: See About the IDE 1.x category.

Either don't use while or check for new IR button pressed in the while loop.

Skickat från Outlook

But no schematic yet. Code can't be verified without knowing what it is going to control.

I can see nothing in your algorithm function that would change the value of n so once your code is in that function it can not get out of it.

@sterretje I can remove delay but i need to turn on the led for 3 seconds then i need to move to next led.
if i remove delay how i can stop 3 seconds ?. can u plz change and rewrite any one of the switch case in my code?

@Railroader I keep on searching that in google for a week i can't get rid my problem :face_holding_back_tears: :pleading_face:

@Grumpy_Mike you can understand all my stuff ir-receiver.ino - Wokwi Arduino and ESP32 Simulator use this link . you can edit the code and just click save option there.. so I can view it through the same link or else post the code here.

Use a finite state machine. You can implement that using a switch/case. And use millis() for the timing.

I am new to Arduino i know millis() function, but i don't know how to use it

Maybe those will help

  1. Using millis() for timing. A beginners guide
  2. Demonstration code for several things at the same time

Sorry I don't do simulators. You still can't get out of the algorithm function though.

There is no ready code to find anyware. You need to make it Yourself.

you can understand all my stuff ir-receiver.ino - Wokwi Arduino and ESP32 Simulator soprapk use this link

yes, because i can't understand what actually millis() function do :cold_sweat: :disappointed_relieved: :cry: :sob: ... plz can u change one swtich case to millis() function. so i can understand the code and change my whole code.

The millis() function simply returns the number of milliseconds since the processor was powered up.

You use that function to implement a state machine.

A state machine is simply a task or sequence of tasks that the processor will do. The task should be quick and use no delays. At the end of that task it can set a time when that task will be done again. It is a whole new way of writing code and is a step up in code sophistication from what you are doing now.

You just can not convert one of your switch statements into a task, but you can use a switch statement to enable a task. This is why in reply #12 you were given two links to help you try and understand this new way of programming.
This is my take on how to do it
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html

So take your case 48

That would be the same down to the delay but remove everything else.
Then at the delay you would enable a task to do the

       digitalWrite(Lane1[1], LOW);
       digitalWrite(Lane1[2], HIGH); //lane 1-Green

in three seconds time. So write these lines as a function call it say "task48a"
You need a boolean variable to say if this task is enabled call it "task48aEnable" and a variable that has the time this task has to run.
so you would have

void task48a(){
       digitalWrite(Lane1[1], LOW);
       digitalWrite(Lane1[2], HIGH); //lane 1-Green
          task48aEnable = false;  // do not run this task again until enabled
}

Now replace the delay(3000) with

task48aEnable = true; // this is a global boolean variable.
runTask48a = millis() + 3000; // this is a global unsigned long int

Now your loop function should consist of a loop that looks at the time given by millis() and sees if it is time to run your task. If it is it then runs it.

void loop() {
if( task48aEnable == true and millis() > runTask48a) task48a();
// check here for other tasks and look at the incoming IR
}

The thing is you have to eliminate all delays like this, and the time for the loop function to go round needs to be very short, preferably less than one millisecond, but in your application this is not so important as the time delay is not too critical.

I know that some people will object to my clumsy use of millis() here and say there might be an error after it is running for 45 or so days continuously, but I think it is simpler to understand it this way.

The trick in developing code is to do it one small piece at a time, and test it. Slowly build it up towards you final function, testing at each step.

@Grumpy_Mike thank you so much.. now I understand the code and concept of millis().. the function millis() uses the run time of the compiler, but I got a another problem that when I press the button 1 and pressing the button 2 immediately
void loop() { if( task48aEnable == true and millis() > runTask48a) task48a(); }
this above line becomes true because when I press button 1 it executes the code in friction of second. so it task48aEnable becomes ture and runTask48a also initialized so after 3 seconds inside the void loop() the if condition i mentioned above becomes true so at the same time the other if condition i have created after understanding your code also becomes true so two green leds where glowing at the same time..

So basically when you are looking at the IR input you capture the information but you do not action it until all the pending functions have been compleared. You do this by looking at all the task enabled flags. If there are some that are true you do not action the IR input. Only when they are all false do you go on to take the action caused by the received IR.

@Grumpy_Mike Thank you for your reply :heart:. i found a way by adding another if condition inside the if condition like nested if.

if( task48aEnable == true and millis() > runTask48a)
  {
    if(receiver.decodedIRData.command==48)
    {
      task48a();
    }
  } 

i have finished coding for 4 buttons. now I am trying to LOOP this all buttons in single button.. so if press the button 5 (actually it is a loop button) so I need to loop the BUTTONS 1,2,3,4 in button 5.
Any idea how can i do that ?