# Breaking out of a while loop using IR remote

**URL:** <https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232>\
**Category:** Programming\
**Created:** [May 1, 2022, 6:10pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232 "2022-05-01T18:10:10Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![sreksfionou](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sreksfionou](https://forum.arduino.cc/u/sreksfionou)\
**Post date:** [May 1, 2022, 6:10pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/1 "2022-05-01T18:10:10Z")

</div>

So I have this code to control my three leds using IR remote. With this code the while loop runs only once, does anybody knows how to make it run until I press any other button on the remote?

```cpp
#include <IRremote.h>
#include <Adafruit_NeoPixel.h>

int LEDP = 6;
int pocet = 3;
Adafruit_NeoPixel pixely(pocet, LEDP, NEO_GRB + NEO_KHZ800);
const int RECV_PIN = 3;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;

void setup(){
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv.blink13(true);
  pixely.begin();
}

void loop() {
    if (irrecv.decode(&results)) {
        if (results.value == 0xFFFFFFFF) {
            results.value = key_value;
        } // if
        
        switch (results.value) {
          case 0xFF6897:
          pixely.setPixelColor(0, pixely.Color(0,0,0));
          pixely.setPixelColor(1, pixely.Color(0,0,0));
          pixely.setPixelColor(2, pixely.Color(0,0,0));
          pixely.show();
          break;
                
          case 0xFF30CF:
          pixely.setPixelColor(0, pixely.Color(0,255,0));
          pixely.setPixelColor(1, pixely.Color(0,255,0));
          pixely.setPixelColor(2, pixely.Color(0,255,0));
          pixely.show();
          break;
                
          case 0xFF18E7:
          pixely.setPixelColor(0, pixely.Color(150,150,150));
          pixely.setPixelColor(1, pixely.Color(150,150,150));
          pixely.setPixelColor(2, pixely.Color(150,150,150));
          pixely.show();
          break;
                
          case 0xFF7A85:
          pixely.setPixelColor(0, pixely.Color(150,150,150));
          pixely.setPixelColor(1, pixely.Color(0,0,0));
          pixely.setPixelColor(2, pixely.Color(0,0,0));
          pixely.show();
          break;
                
          case 0xFF10EF:
          pixely.setPixelColor(0, pixely.Color(0,0,0));
          pixely.setPixelColor(1, pixely.Color(0,0,0));
          pixely.setPixelColor(2, pixely.Color(150,150,150));
          pixely.show();
          break;
                
          case 0xFF38C7:
          pixely.setPixelColor(0, pixely.Color(0,0,0));
          pixely.setPixelColor(1, pixely.Color(150,150,150));
          pixely.setPixelColor(2, pixely.Color(0,0,0));
          pixely.show();
          break;
                
          case 0xFF5AA5:
          
          irrecv.resume();
                
          while (0xFF5AA5 == results.value) {
          pixely.setPixelColor(0, pixely.Color(150,150,150));
          pixely.setPixelColor(1, pixely.Color(0,0,0));
          pixely.setPixelColor(2, pixely.Color(0,0,0));
          pixely.show();
          delay(1000);
          pixely.setPixelColor(0, pixely.Color(0,0,0));
          pixely.setPixelColor(1, pixely.Color(0,0,0));
          pixely.setPixelColor(2, pixely.Color(150,150,150));
          pixely.show();
          delay(1000);
          pixely.setPixelColor(0, pixely.Color(0,0,0));
          pixely.setPixelColor(1, pixely.Color(150,150,150));
          pixely.setPixelColor(2, pixely.Color(0,0,0));
          pixely.show();
          delay(1000);
          pixely.setPixelColor(0, pixely.Color(150,150,150));
          pixely.setPixelColor(1, pixely.Color(150,150,150));
          pixely.setPixelColor(2, pixely.Color(150,150,150));
          pixely.show();
                    delay(1000);
           
        if (irrecv.decode(&results)) {
                        break;
                    } // if
                } // while
                break;
        } // switch        
        key_value = results.value;
        irrecv.resume();
        
    } // if
} // loop()

```

---

<div class="post-metadata">

**Author:** ![xfpd](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/xfpd/32/1120236_2.png) [@xfpd](https://forum.arduino.cc/u/xfpd)\
**Post date:** [May 1, 2022, 6:19pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/2 "2022-05-01T18:19:36Z")

</div>

I like to put "halting" code in void setup(). When the looping code exits, the program ends (assuming void loop() is left empty). ~~This is because I am not a fan of break();~~

---

<div class="post-metadata">

**Author:** ![sreksfionou](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sreksfionou](https://forum.arduino.cc/u/sreksfionou)\
**Post date:** [May 1, 2022, 6:21pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/3 "2022-05-01T18:21:51Z")

</div>

Well, I am quite new to arduino and I do not know what that actually is, would it solve that my while loop inside void loop runs only once?

---

<div class="post-metadata">

**Author:** ![xfpd](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/xfpd/32/1120236_2.png) [@xfpd](https://forum.arduino.cc/u/xfpd)\
**Post date:** [May 1, 2022, 6:29pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/4 "2022-05-01T18:29:51Z")

</div>

All Arduino code have two functions:

```cpp
void setup()

```

and

```cpp
void loop()

```

Most Arduino programs use void setup() to "set things up" because it runs only once.  
Most Arduino programs use void loop() to "repeat these steps" because often, repetition is needed, and seldom do programs want to run once and end.

However; if you want a code that halts without having to make an infinite loop, move the code you have written inside the "void loop()" and paste it inside the "void setup()" to run your code once only. This means, if you want at least an initial loop, you will have to wrap your code in a loop that allows your code to repeat.

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [May 1, 2022, 6:40pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/5 "2022-05-01T18:40:00Z")

</div>

> [@sreksfionou](#):
>
> ` while (0xFF5AA5 == results.value) {`

I am sure I do not know what @xfpd is talking about or has in mind.

You could make the while condition just be 1,

```arduino
   while (1) {

```

making an infinite loop.

Within that loop, read the IR remote signal and if you get any, or an appropriate one, _break_ out of the _while_ loop.

But… the use of _dealy_() in your _while_ loop may mean non-responsiveness to the signals. I've never used that library, but it looks in any case like you'd usually be waiting some good time for a reaction to new IR signals. Or worse maybe have to stab the remote button during a brief and unknowable window of opportunity during the time it is running.

This kind of functionality really needs a different approach, expecially if you ever want to immediately suspender a running animation or long sequence of activites.

a7

---

<div class="post-metadata">

**Author:** ![sreksfionou](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sreksfionou](https://forum.arduino.cc/u/sreksfionou)\
**Post date:** [May 1, 2022, 7:13pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/6 "2022-05-01T19:13:06Z")

</div>

but what i want to do is that i want to press a button a start a loop that would go until i press another button

---

<div class="post-metadata">

**Author:** ![sreksfionou](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sreksfionou](https://forum.arduino.cc/u/sreksfionou)\
**Post date:** [May 1, 2022, 7:16pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/7 "2022-05-01T19:16:45Z")

</div>

well, first of all, thank you, however right now when i start the loop it goes forever until i press another button, so that works, but when i start the loop for the second time it runs only once, i have no clue why is that happening, do you have any idea?

---

<div class="post-metadata">

**Author:** ![xfpd](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/xfpd/32/1120236_2.png) [@xfpd](https://forum.arduino.cc/u/xfpd)\
**Post date:** [May 1, 2022, 7:30pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/8 "2022-05-01T19:30:14Z")

</div>

When you "start a second time"... how are you starting? Arduino reset button? IDE Upload? IRremote press? Also... maybe your switch/case: needs a "default:" if all other cases fail.

---

<div class="post-metadata">

**Author:** ![sreksfionou](https://avatars.discourse-cdn.com/v4/letter/s/ec9cab/32.png) [@sreksfionou](https://forum.arduino.cc/u/sreksfionou)\
**Post date:** [May 1, 2022, 7:34pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/9 "2022-05-01T19:34:14Z")

</div>

I start it for the second time by IR remote press, everything else works

---

<div class="post-metadata">

**Author:** ![cdr\_xavier](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cdr_xavier/32/543397_2.png) [@cdr\_xavier](https://forum.arduino.cc/u/cdr_xavier)\
**Post date:** [May 1, 2022, 8:27pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/10 "2022-05-01T20:27:42Z")

</div>

what you could do is do a "if ... else" statement inside "loop()".  
You would be checking the input (from the IR receiver) and keep the current state as a variable in memory. If the input is equal to 0x3A run the first if loop and if it is not run the second loop (or just stuff under "else" statements)

I would assume it's because this statement

```cpp
if (irrecv.decode(&results)) {
                        break;
                    } // if

```

evaluate to true.

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [May 1, 2022, 8:28pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/11 "2022-05-01T20:28:13Z")

</div>

> [@sreksfionou](#):
>
> I start it for the second time by IR remote press, everything else works

Weird. Did you retry changing it along the lines I suggested?

This is the entire case you working with, with all that stuff changed to just print.

```arduino
        while (0xFF5AA5 == results.value) {
             
                Serial.println("going to sleep for 4 seconds)";
          	delay(4000);
          	
	        if (irrecv.decode(&results)) 
                        break;
                
         } // while

        break;

```

You are saying that the fits time you hit "0xFF5AA5", you get a long string of activity, like in my reduction just printing the message over and over…

and when you hit another button, that stops…

and when you hit "0xFF5AA5" again, you get that message once only?

Have you tried... making the break in the _if_ act on one specific other code?

```arduino
        while (0xFF5AA5 == results.value) {
             
                Serial.println("going to sleep for 4 seconds)";
          	delay(4000);
          	
	        if (irrecv.decode(&results)) {
                       if (results.value == 0xFFFFFFFF) && key_value == SOME OTHER BUTTON CODE)
                             break;
             }
         } // while

        break;

```

The behaviour you describe is impossible, but if you are observing it, the only way to "see" what is going on is to add some print statments,some more print statEments.

I suggest you to use something like my modified case above, you could even turn the four second delay down massively, to see the effect of all that sleeping you doing. Try _delay_(50), yes it will spam your serial monitor but might shed some light.

@xfpd points out you don't have a default case, that will not change anything as far as I can tell.

I also recommend, since at the time of triggering the _while_ results.value IS 0xFF55AA55, you do what I said:

```arduino
        while (1) { // until we get signal (or a specifici signal in this version
             
                Serial.println("going to sleep for 4 seconds)";
          	delay(4000);
          	
	        if (irrecv.decode(&results)) {
                       if (results.value == 0xFFFFFFFF) && key_value == SOME OTHER BUTTON CODE)
                             break;
             }
         } // while

        break;

```

Are you 100 percent sure you've shared the code you running?

Obvsy replace "SOME OTHER BUTTON CODE" with another valid known IR code that you know you can reliably receive.

I'll need to go to considerably more trouble to actually run this thing, so it's on you for a bit Skippy!

HTH

a7

---

<div class="post-metadata">

**Author:** ![cdr\_xavier](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cdr_xavier/32/543397_2.png) [@cdr\_xavier](https://forum.arduino.cc/u/cdr_xavier)\
**Post date:** [May 1, 2022, 8:32pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/12 "2022-05-01T20:32:05Z")

</div>

> [@alto777](#):
>
> The behaviour you describe is impossible

It depend on how the sensor/input is implemented. Especially since there is such a large delay in between commands.  
Perhaps it's because he have one too many `irrcev.resume()`

Yes, one should not use (especially values that are so large) delays inside, well, any function. Try the example "blink without delay". Although it should not be a massive problem, but again, it depend on the input you are using. Some are quite nice while others are quite ugly.

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [May 1, 2022, 8:36pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/13 "2022-05-01T20:36:33Z")

</div>

> [@cdr\_xavier](#):
>
> It depend on how the sensor/input is implemented

You know more than I do if you aren't just guessing!

Do you think experiments as I coded examples of which in #11 will be useful?

a7

---

<div class="post-metadata">

**Author:** ![cdr\_xavier](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cdr_xavier/32/543397_2.png) [@cdr\_xavier](https://forum.arduino.cc/u/cdr_xavier)\
**Post date:** [May 1, 2022, 8:50pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/14 "2022-05-01T20:50:32Z")

</div>

> [@alto777](#):
>
> You know more than I do if you aren't just guessing!

~~Well, I would just assume it since sensors (especially cheap ones) that I have came across don't like delays. Others like delays.  
So yes, I am guessing, but it's based on stuff I have encountered (and knew). Which isn't that different.~~

~~For example. To take a measure with the cheap ultrasonic sensor in the robot car kit we have, you first send a "measure" command. Which is straightforward. However the sensor then turns off its I2C interface once it receives the measure command (and is measuring) so any commands from the host during this time will hang the host.  
In this case there is not much you can do but use a delay of _at least_ 100ms.~~

~~Whereas the compass module have a built-in microcontroller and initializes everything so it produce results every 33.3ms (and overwrites this with new data instantaneously) no matter if you need it or not.~~

~~The SHT30 temperature sensor from Sensirion have a "clock-stretching" mode that holds the clock line low until measurement is complete before sending back the data, which will also hang the processor. It also have a non-clock-stretching mode where the sensor immediately respond NACK (not acknowledge) and so there will be no hangs/pause.~~

~~I have not encountered any hang caused by buffer overflow (usually incoming buffers), but it does not mean there is any, especially with UART (serial).~~

~~In his sketch for example if the IR receiver is .. The time between his `irrecv.resume()` and `irrecv.decode()` is 4 seconds. What happens between the 4 seconds, I don't know. Maybe the IR receiver is constantly clocking in new data and when he checks, the new data might not be immediately available (causing it to return gibberish, which is not 0), or that the receiver have waited for too long and decided to do other things (low power sleep?) that might require another command and thus `decode` will not work.~~

~~It's best to avoid `delay`, (of any length), and _ **read the datasheet** _.~~

~~My implementation of my SHT30 sketch involves a menu (on a screen) that allow the user to input various different commands (e.g. continuous, single-shot, soft reset, heater, repeatability, sleep) to the temperature sensor, while the "unofficial library" support just a few, with great limitations (e.g. clock stretching).~~

~~One of the obvious downsides (of writing every code you need yourself) is massive headache and time spent. Which is understandable. But at least read the datasheet.~~

* * *

(let's get back)

Yes. Your code is a very simple structure that can test if the library/sensor can "deal with" the program structure.

You can see that in his code he is trying to pause the sketch into displaying perhaps some colored LED sequence until it receives any other data, which exits the while loop and go back to the main loop.

> [@sreksfionou](#):
>
> right now when i start the loop it goes forever until i press another button, so that works

Yes.

> [@sreksfionou](#):
>
> but when i start the loop for the second time it runs only once

So the second time you tried to pause it it will only run once.

Have you tested with other cases (e.g., do some non-loop cases like `0xFF30CF`)?

Also. Your `switch` loop is lacking a "default". This might cause problems.

---

<div class="post-metadata">

**Author:** ![johnwasser](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/johnwasser/32/214270_2.png) [@johnwasser](https://forum.arduino.cc/u/johnwasser)\
**Post date:** [May 1, 2022, 9:05pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/15 "2022-05-01T21:05:44Z")

</div>

Just remember the last key received and repeat that. If you don't want to repeat an action, set 'key\_value' back to 0.

```cpp
void loop()
{
  if (irrecv.decode(&results))
  {
    if (results.value != 0xFFFFFFFF)
    {
      // Not q repeat code so remember the code:
      key_value = results.value;
    } // if
  } // if

  // Repeat key_value until it is changed
  switch (key_value)
  {
    case 0xFF6897:
      pixely.setPixelColor(0, pixely.Color(0, 0, 0));
      pixely.setPixelColor(1, pixely.Color(0, 0, 0));
      pixely.setPixelColor(2, pixely.Color(0, 0, 0));
      pixely.show();
      break;

    case 0xFF30CF:
      pixely.setPixelColor(0, pixely.Color(0, 255, 0));
      pixely.setPixelColor(1, pixely.Color(0, 255, 0));
      pixely.setPixelColor(2, pixely.Color(0, 255, 0));
      pixely.show();
      break;

    case 0xFF18E7:
      pixely.setPixelColor(0, pixely.Color(150, 150, 150));
      pixely.setPixelColor(1, pixely.Color(150, 150, 150));
      pixely.setPixelColor(2, pixely.Color(150, 150, 150));
      pixely.show();
      break;

    case 0xFF7A85:
      pixely.setPixelColor(0, pixely.Color(150, 150, 150));
      pixely.setPixelColor(1, pixely.Color(0, 0, 0));
      pixely.setPixelColor(2, pixely.Color(0, 0, 0));
      pixely.show();
      break;

    case 0xFF10EF:
      pixely.setPixelColor(0, pixely.Color(0, 0, 0));
      pixely.setPixelColor(1, pixely.Color(0, 0, 0));
      pixely.setPixelColor(2, pixely.Color(150, 150, 150));
      pixely.show();
      break;

    case 0xFF38C7:
      pixely.setPixelColor(0, pixely.Color(0, 0, 0));
      pixely.setPixelColor(1, pixely.Color(150, 150, 150));
      pixely.setPixelColor(2, pixely.Color(0, 0, 0));
      pixely.show();
      break;

    case 0xFF5AA5:
      pixely.setPixelColor(0, pixely.Color(150, 150, 150));
      pixely.setPixelColor(1, pixely.Color(0, 0, 0));
      pixely.setPixelColor(2, pixely.Color(0, 0, 0));
      pixely.show();
      delay(1000);
      pixely.setPixelColor(0, pixely.Color(0, 0, 0));
      pixely.setPixelColor(1, pixely.Color(0, 0, 0));
      pixely.setPixelColor(2, pixely.Color(150, 150, 150));
      pixely.show();
      delay(1000);
      pixely.setPixelColor(0, pixely.Color(0, 0, 0));
      pixely.setPixelColor(1, pixely.Color(150, 150, 150));
      pixely.setPixelColor(2, pixely.Color(0, 0, 0));
      pixely.show();
      delay(1000);
      pixely.setPixelColor(0, pixely.Color(150, 150, 150));
      pixely.setPixelColor(1, pixely.Color(150, 150, 150));
      pixely.setPixelColor(2, pixely.Color(150, 150, 150));
      pixely.show();
      delay(1000);
      break;
  } // switch

  irrecv.resume();
  
} // loop()

```

---

<div class="post-metadata">

**Author:** ![xfpd](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/xfpd/32/1120236_2.png) [@xfpd](https://forum.arduino.cc/u/xfpd)\
**Post date:** [May 1, 2022, 9:19pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/16 "2022-05-01T21:19:20Z")

</div>

~~[quote="johnwasser, post:15, topic:987232"]  
'key\_value' back to 0.  
[/quote]~~

 

~~Sorta like switch() {default: key\_value = 0}; except altoid777 says that is useless code.~~

---

<div class="post-metadata">

**Author:** ![alto777](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/alto777/32/317385_2.png) [@alto777](https://forum.arduino.cc/u/alto777)\
**Post date:** [May 1, 2022, 11:36pm UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/17 "2022-05-01T23:36:56Z")

</div>

> [@cdr\_xavier](#):
>
> Also. Your `switch` loop is lacking a "default". This might cause problems.

If it does, what code would you put in the default case that you think might avoid those problems?

A default case with no code is as good as not having one…

a7

---

<div class="post-metadata">

**Author:** ![cdr\_xavier](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cdr_xavier/32/543397_2.png) [@cdr\_xavier](https://forum.arduino.cc/u/cdr_xavier)\
**Post date:** [May 2, 2022, 12:14am UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/18 "2022-05-02T00:14:54Z")

</div>

> [@alto777](#):
>
> what code would you put in the default case that you think might avoid those problems?

put anything. Like, say, a dummy `irrecv.decode()` to flush the library buffers, if they did implement one. Before or after a `irrecv.resome()`

Now that we mentioned the library for the 100th time, maybe I should look into what is the library (what does it do, etc). Sounds interesting since I have some useless remotes laying around.

And yes, if default is not written then it just won't do anything.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/system/32/1140315_2.png) [@system](https://forum.arduino.cc/u/system)\
**Post date:** [October 29, 2022, 12:14am UTC](https://forum.arduino.cc/t/breaking-out-of-a-while-loop-using-ir-remote/987232/19 "2022-10-29T00:14:59Z")

</div>

Closed on October 29, 2022, 12:14am UTC

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
