Looping switch case functions whilst allowing for interruptions

Dear all,

I have a question regarding a project that I build with a combination of Arduino and Adafruit/brandless products, using the Arduino IDE. The project in short consists of an IR sensor and remote, an Adafruit Trinket (or Arduino Uno, I also tried with that...) and a LED ring with four different light settings, linked to specific sensor values from the remote control.

Now the issue is that I want all of the functions to loop infinitely, whilst allowing me to change to another function if I press a different button on the remote.

Right now it works as following; if I press "1" it repeats the program infinitely with an unwanted delay between the repeats, but if I press another button while the program runs it doesn't react. Only when I press exactly after one cycle of the first program I am able to switch it. Can somebody help me with how I can achieve this? Is it in the break part of the switchcase function?

/* This is a sketch for the belt project, used on 24/11/2015 on the Adafruit Trinket
ATTiny85 based mini microcontroller and a PNA4602 or TSOP38238 to
read an IR code and perform a function.  

This program includes modes that are IR controlled for a NeoPixel ring. The individual modes are explained in the code. 

*/

#include <Adafruit_NeoPixel.h>
 
// We need to use the 'raw' pin reading methods because timing is very important here 
// and the digitalRead() procedure is slower!
#define IRpin_PIN  PINB // ATTiny85 had Port B pins
#define IRpin      2    // IR sensor - TSOP38238 on Pin GPIO #2 / D2
#define RingPin   1 // DConnects to Adafruit Neopixel Ring

#define MAXPULSE    5000  // the maximum pulse we'll listen for - 5 milliseconds 
#define NUMPULSES    100  // max IR pulse pairs to sample
#define RESOLUTION     2  // // time between IR measurements
#define NumPixels        24 // number of pixels 
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, 1, NEO_GRB + NEO_KHZ800);
 
// we will store up to 40 pulse pairs (reduce if needed)
uint16_t pulses[40][2];   // pair is high and low pulse
uint16_t currentpulse = 0; // index for pulses we're storing
uint32_t irCode = 0;
uint16_t n;
uint32_t irCodeRead;
 
void setup() {
  pinMode(IRpin, INPUT);       // Listen to IR receiver on Trinket pin D2
  pinMode(RingPin, OUTPUT); // Output tones on Trinket pin D1
  strip.begin();
    cli();  // disables interrupts
    strip.show();  // generates the NeoPixel control signals
    sei();  // re-enables interrupts; // Initialize all pixels to 'off'
}
 
void loop() {
  
  irCode=listenForIR(); // Wait for an IR Code
 
  // Process the pulses to get our code
  for (int i = 0; i < 32; i++) {
    irCode=irCode<<1;
    if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) {
      irCode|=0; 
    } else {
      irCode|=1;
      int rccode = irCode;
    }
  

  }
  switch (irCode) {{
  //ACTION ONE: TURNING WHITE AROUND THE CIRCLE, "STARTING ENERGY BELT"
  //PRESS BUTTON "1" *Note: white color updated to softer
  case(0xC03FDA25)  : {      // "1" on my remote
   colorWipe(strip.Color(225, 250, 180), 60); // White
   colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
   colorWipe(strip.Color(225, 250, 180), 60); // White
   colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
   break;
   strip.show();
  }
   //ACTION TWO: SKIN COLOR "CHARGING"
   //PRESS BUTTON "2"
   //IMPORTANT: to change speed, change max int i value in code since i increases at constant rate
  case(0xC03FE619) : {      // "2" on my remote
      for (int i = 0 ; i < 51; i++)  {    
      colorWipe(strip.Color((5*i), (1.96078431*i), (0.39215686*i)), 1); // Skin Color
     }

    break; 
  } 
    //ACTION THREE: FADING RED, "RUNNING OUT OF BODY FAT"
   //PRESS BUTTON "3"
   //IMPORTANT: to change speed, change max int i value in code since i increases at constant rate
  case(0xC03FEC13) : {      // "3" on my remote
    for (int i = 0 ; i < 51; i++)  {    
      colorWipe(strip.Color((5*i), (0.1*i), (0)), 1); // Full red
     }
    for (int i = 51 ; i >-1; i--)  {
      colorWipe(strip.Color((5*i), (0.1*i), (0)), 1);
     }
         delay(30);
    for (int i = 0 ; i < 51; i++)  {    
      colorWipe(strip.Color((5*i), (0.1*i), (0)), 1); // Full red
     }
    for (int i = 51 ; i >-1; i--)  {
      colorWipe(strip.Color((5*i), (0.1*i), (0)), 1);
     }}
     break;
  }  
 
  
 
 }}


uint16_t listenForIR() {  // IR receive code
  currentpulse = 0;
  while (1) {
   unsigned int highpulse, lowpulse;  // temporary storage timing
   highpulse = lowpulse = 0; // start out with no pulse length 
  
   while (IRpin_PIN & _BV(IRpin)) { // got a high pulse
      highpulse++; 
      delayMicroseconds(RESOLUTION);
      if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
        return currentpulse; 
      }
   }
   pulses[currentpulse][0] = highpulse;
 
   while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse
      lowpulse++; 
      delayMicroseconds(RESOLUTION);
      if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
        return currentpulse; 
      }
   }
   pulses[currentpulse][1] = lowpulse;
   currentpulse++;
  }
}

void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}

Walburvis:
Is it in the break part of the switchcase function?

No.

But, your code has a bunch of problems.

Here's your code reformatted to make it easier for us to read:

/* This is a sketch for the belt project, used on 24/11/2015 on the Adafruit Trinket
ATTiny85 based mini microcontroller and a PNA4602 or TSOP38238 to
read an IR code and perform a function. 

This program includes modes that are IR controlled for a NeoPixel ring. The individual modes are explained in the code.

*/

#include <Adafruit_NeoPixel.h>

// We need to use the 'raw' pin reading methods because timing is very important here
// and the digitalRead() procedure is slower!
#define IRpin_PIN  PINB // ATTiny85 had Port B pins
#define IRpin      2    // IR sensor - TSOP38238 on Pin GPIO #2 / D2
#define RingPin   1 // DConnects to Adafruit Neopixel Ring

#define MAXPULSE    5000  // the maximum pulse we'll listen for - 5 milliseconds
#define NUMPULSES    100  // max IR pulse pairs to sample
#define RESOLUTION     2  // // time between IR measurements
#define NumPixels        24 // number of pixels

Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, 1, NEO_GRB + NEO_KHZ800);

// we will store up to 40 pulse pairs (reduce if needed)
uint16_t pulses[40][2];   // pair is high and low pulse
uint16_t currentpulse = 0; // index for pulses we're storing
uint32_t irCode = 0;
uint16_t n;
uint32_t irCodeRead;

void setup() 
{
    pinMode(IRpin, INPUT);       // Listen to IR receiver on Trinket pin D2
    pinMode(RingPin, OUTPUT); // Output tones on Trinket pin D1
    strip.begin();
    cli();  // disables interrupts
    strip.show();  // generates the NeoPixel control signals
    sei();  // re-enables interrupts; // Initialize all pixels to 'off'
}

void loop() 
{
    irCode=listenForIR(); // Wait for an IR Code

    // Process the pulses to get our code
    for (int i = 0; i < 32; i++) 
    {
        irCode=irCode << 1;
        if (pulses[i][0] * RESOLUTION > 0 && pulses[i][0] * RESOLUTION < 500) 
        {
            irCode |= 0;
        } 
        else
        {
            irCode |= 1;
            int rccode = irCode;
        }
    }
    
    switch (irCode) 
    {
        {
            //ACTION ONE: TURNING WHITE AROUND THE CIRCLE, "STARTING ENERGY BELT"
            //PRESS BUTTON "1" *Note: white color updated to softer
            case(0xC03FDA25)  :
            {      // "1" on my remote
                colorWipe(strip.Color(225, 250, 180), 60); // White
                colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
                colorWipe(strip.Color(225, 250, 180), 60); // White
                colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
                break;
                strip.show();
            }
            //ACTION TWO: SKIN COLOR "CHARGING"
            //PRESS BUTTON "2"
            //IMPORTANT: to change speed, change max int i value in code since i increases at constant rate
            case(0xC03FE619) : 
            {      // "2" on my remote
                for (int i = 0 ; i < 51; i++) 
                {   
                    colorWipe(strip.Color((5*i), (1.96078431*i), (0.39215686*i)), 1); // Skin Color
                }

                break;
            }
            //ACTION THREE: FADING RED, "RUNNING OUT OF BODY FAT"
            //PRESS BUTTON "3"
            //IMPORTANT: to change speed, change max int i value in code since i increases at constant rate
            case(0xC03FEC13) : 
            {      // "3" on my remote
                for (int i = 0 ; i < 51; i++) 
                {   
                    colorWipe(strip.Color((5*i), (0.1*i), (0)), 1); // Full red
                }
                for (int i = 51 ; i >-1; i--)  
                {
                    colorWipe(strip.Color((5*i), (0.1*i), (0)), 1);
                }
                delay(30);
                for (int i = 0 ; i < 51; i++) 
                {   
                    colorWipe(strip.Color((5*i), (0.1*i), (0)), 1); // Full red
                }
                for (int i = 51 ; i >-1; i--)  
                {
                    colorWipe(strip.Color((5*i), (0.1*i), (0)), 1);
                }
            }
            break;
        }
    }
}


uint16_t listenForIR() 
{  // IR receive code
    currentpulse = 0;
    while (1) 
    {
        unsigned int highpulse, lowpulse;  // temporary storage timing
        highpulse = lowpulse = 0; // start out with no pulse length

        while (IRpin_PIN & _BV(IRpin)) 
        { // got a high pulse
            highpulse++;
            delayMicroseconds(RESOLUTION);
            if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) 
            {
                return currentpulse;
            }
        }
        pulses[currentpulse][0] = highpulse;

        while (! (IRpin_PIN & _BV(IRpin)))
        { // got a low pulse
            lowpulse++;
            delayMicroseconds(RESOLUTION);
            if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) 
            {
                return currentpulse;
            }
        }
        pulses[currentpulse][1] = lowpulse;
        currentpulse++;
    }
}

void colorWipe(uint32_t c, uint8_t wait)
{
    for(uint16_t i=0; i<strip.numPixels(); i++)
    {
        strip.setPixelColor(i, c);
        strip.show();
        delay(wait);
    }
}

Initial Problems:

  1. This line:
            irCode |= 0;

does nothing. What did you want it to do?

  1. The strip.show() here is unreachable code, since it is after a break.
            case(0xC03FDA25)  :
            {      // "1" on my remote
                colorWipe(strip.Color(225, 250, 180), 60); // White
                colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
                colorWipe(strip.Color(225, 250, 180), 60); // White
                colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
                break;
                strip.show();
            }
  1. This code does not need the extra braces:
    switch (irCode) 
    {
        {
            //ACTION ONE: TURNING WHITE AROUND THE CIRCLE, "STARTING ENERGY BELT"
            //PRESS BUTTON "1" *Note: white color updated to softer
            case(0xC03FDA25)  :
  1. I don't see why it would repeat. It looks like the listenForIR should block waiting for a button to be pressed. Is this not the case?

Thank you for your quick reply!

  1. I must say that I have very basic code knowledge, so the IR part is something that I got from a tutorial but I do not understand it very clearly... but as far as I know the IR part of it works well, since I tested it with serial reading and the values were received accurately and there were no problems there as far as I know.

  2. I have now removed the strip.show() after the break, and it seems to still work the same.

  3. I tested it again and it didn't repeat, it ran every program that was initiated once and then stopped and I was able to change it do a different mode. But now that I am typing this (one minute later without any buttons pressed/light modes running) it started by itself doing mode 3 again (and it is still repeating now two minutes later)... If I press any other button now it does not react. That was all with the initial code. And when I unplugged it and tried again and mode 1 was the last mode used it acts the same... stays in the end setting for mode 1 (dim white light) and after a while starts looping it. The only way to let it do something else is to press another button exactly the moment when one cycle is over.

You need to post the latest version of your program to allow us to keep up with you.

...R

BTW,

this line:

            int rccode = irCode;

also does nothing.

please post links to where you are getting the IR code from.

This code in your main loop is wrong in many, many ways, so I can't work out what it's trying to do:

    irCode=listenForIR(); // Wait for an IR Code

    // Process the pulses to get our code
    for (int i = 0; i < 32; i++) 
    {
        irCode=irCode << 1;
        if (pulses[i][0] * RESOLUTION > 0 && pulses[i][0] * RESOLUTION < 500) 
        {
            irCode |= 0;
        } 
        else
        {
            irCode |= 1;
            int rccode = irCode;
        }
    }

This is my most recent code:

/* This is a sketch for the belt project, used on 24/11/2015 on the Adafruit Trinket
ATTiny85 based mini microcontroller and a PNA4602 or TSOP38238 to
read an IR code and perform a function. 

This program includes modes that are IR controlled for a NeoPixel ring. The individual modes are explained in the code.

*/

#include <Adafruit_NeoPixel.h>

// We need to use the 'raw' pin reading methods because timing is very important here
// and the digitalRead() procedure is slower!
#define IRpin_PIN  PINB // ATTiny85 had Port B pins
#define IRpin      2    // IR sensor - TSOP38238 on Pin GPIO #2 / D2
#define RingPin   1 // DConnects to Adafruit Neopixel Ring

#define MAXPULSE    5000  // the maximum pulse we'll listen for - 5 milliseconds
#define NUMPULSES    100  // max IR pulse pairs to sample
#define RESOLUTION     2  // // time between IR measurements
#define NumPixels        24 // number of pixels

Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, 1, NEO_GRB + NEO_KHZ800);

// we will store up to 40 pulse pairs (reduce if needed)
uint16_t pulses[40][2];   // pair is high and low pulse
uint16_t currentpulse = 0; // index for pulses we're storing
uint32_t irCode = 0;
uint16_t n;
uint32_t irCodeRead;

void setup() 
{
    pinMode(IRpin, INPUT);       // Listen to IR receiver on Trinket pin D2
    pinMode(RingPin, OUTPUT); // Output tones on Trinket pin D1
    strip.begin();
    cli();  // disables interrupts
    strip.show();  // generates the NeoPixel control signals
    sei();  // re-enables interrupts; // Initialize all pixels to 'off'
}

void loop() 
{
    irCode=listenForIR(); // Wait for an IR Code

    // Process the pulses to get our code
    for (int i = 0; i < 32; i++) 
    {
        irCode=irCode << 1;
        if (pulses[i][0] * RESOLUTION > 0 && pulses[i][0] * RESOLUTION < 500) 
        {
            irCode |= 0;
        } 
        else
        {
            irCode |= 1;
            int rccode = irCode;
        }
    }
    
    switch (irCode) 
    {
        {
            //ACTION ONE: TURNING WHITE AROUND THE CIRCLE, "STARTING ENERGY BELT"
            //PRESS BUTTON "1" *Note: white color updated to softer
            case(0xC03FDA25)  :
            {      // "1" on my remote
                colorWipe(strip.Color(225, 250, 180), 60); // White
                colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
                colorWipe(strip.Color(225, 250, 180), 60); // White
                colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
                break;
            }
            //ACTION TWO: SKIN COLOR "CHARGING"
            //PRESS BUTTON "2"
            //IMPORTANT: to change speed, change max int i value in code since i increases at constant rate
            case(0xC03FE619) : 
            {      // "2" on my remote
                for (int i = 0 ; i < 51; i++) 
                {   
                    colorWipe(strip.Color((5*i), (1.96078431*i), (0.39215686*i)), 1); // Skin Color
                }

                break;
            }
            //ACTION THREE: FADING RED, "RUNNING OUT OF BODY FAT"
            //PRESS BUTTON "3"
            //IMPORTANT: to change speed, change max int i value in code since i increases at constant rate
            case(0xC03FEC13) : 
            {      // "3" on my remote
                for (int i = 0 ; i < 51; i++) 
                {   
                    colorWipe(strip.Color((5*i), (0.1*i), (0)), 1); // Full red
                }
                for (int i = 51 ; i >-1; i--)  
                {
                    colorWipe(strip.Color((5*i), (0.1*i), (0)), 1);
                }
                delay(30);
                for (int i = 0 ; i < 51; i++) 
                {   
                    colorWipe(strip.Color((5*i), (0.1*i), (0)), 1); // Full red
                }
                for (int i = 51 ; i >-1; i--)  
                {
                    colorWipe(strip.Color((5*i), (0.1*i), (0)), 1);
                }
            }
            break;
        }
    }
}


uint16_t listenForIR() 
{  // IR receive code
    currentpulse = 0;
    while (1) 
    {
        unsigned int highpulse, lowpulse;  // temporary storage timing
        highpulse = lowpulse = 0; // start out with no pulse length

        while (IRpin_PIN & _BV(IRpin)) 
        { // got a high pulse
            highpulse++;
            delayMicroseconds(RESOLUTION);
            if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) 
            {
                return currentpulse;
            }
        }
        pulses[currentpulse][0] = highpulse;

        while (! (IRpin_PIN & _BV(IRpin)))
        { // got a low pulse
            lowpulse++;
            delayMicroseconds(RESOLUTION);
            if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) 
            {
                return currentpulse;
            }
        }
        pulses[currentpulse][1] = lowpulse;
        currentpulse++;
    }
}

void colorWipe(uint32_t c, uint8_t wait)
{
    for(uint16_t i=0; i<strip.numPixels(); i++)
    {
        strip.setPixelColor(i, c);
        strip.show();
        delay(wait);
    }
}

And I got the IR part from here: https://learn.adafruit.com/trinket-gemma-ir-remote-control/using-ir-codes-1

Here's his link:

Wow, well this code from that link:

  irCode=listenForIR(); // Wait for an IR Code
 
  // Process the pulses to get our code
  for (int i = 0; i < 32; i++) {
    irCode=irCode<<1;
    if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) {
      irCode|=0; 
    } else {
      irCode|=1;
    }
  }

is a complete disaster. I have no idea what they think they are doing there, but it's almost certainly not what they thought they were doing.

Do you maybe have suggestions on what I could do? I tried to avoid building it up from scratch, but if that's the best way now maybe I should look into it?

Walburvis:
Do you maybe have suggestions on what I could do? I tried to avoid building it up from scratch, but if that's the best way now maybe I should look into it?

Unfortunately, I have not worked with IRs, but I am sure somebody here has and will be able to make a suggestion for you. There are a bunch of ways you could do it, but I don't know what the experienced people would suggest as the best.

But regardless of the IR part (since I guess it works quite fine..?) can you maybe give me advice on how to achieve the switch case part?

Essentially what I want to achieve is the following:

  1. Trinket listens for IR code
  2. Trinket receives a code, processes it, gives specific directions to LED ring
  3. Trinket keeps listening for IR code and aborts process if another button pressed is detected
  4. Trinket then switches to different light mode

I thought about creating a variable that is the latest received value from the remote control. It does not give a zero value, just sends out a hexadecimal value once a button is pressed (and when continuously pressed it gives a few of the same value out per second). But how can I do this then, and is this an option?

  1. Trinket listens for IR code
  • do this in loop() but do not block the free running of the loop() function
  1. Trinket receives a code, processes it, gives specific directions to LED ring
  • use switch/case to activate appropriate code. DO NOT use delay() in that code. Instead use millis() for timing. Save the millis() value at the time that the start action happens. Then, each time through loop() in the case being used, check whether the required wait period has elapsed by subtracting the start time from the millis() value now. If the period has elapsed then act accordingly, turn on the next LED, for example, and maybe save the start time for the next activity. If not, then go round loop() again, taking other actions and/or reading inputs, but don't block the free running of loop().
  1. Trinket keeps listening for IR code and aborts process if another button pressed is detected
  • same as 1 above
  1. Trinket then switches to different light mode
  • same as 2 above

Walburvis:
But regardless of the IR part (since I guess it works quite fine..?) can you maybe give me advice on how to achieve the switch case part?

Essentially what I want to achieve is the following:

  1. Trinket listens for IR code
  2. Trinket receives a code, processes it, gives specific directions to LED ring
  3. Trinket keeps listening for IR code and aborts process if another button pressed is detected
  4. Trinket then switches to different light mode

I thought about creating a variable that is the latest received value from the remote control. It does not give a zero value, just sends out a hexadecimal value once a button is pressed (and when continuously pressed it gives a few of the same value out per second). But how can I do this then, and is this an option?

So, yes, you can do it as you suggest.

The loop code would essentially be:

unsigned long lastIRCode;

void loop()
{
    if (newIRCodeAvailable())
    {
        lastIRCode = getNewIRCode();
    }

    switch (lastIRCode)
    {
        case(0xC03FDA25)  :
              colorWipe(strip.Color(225, 250, 180), 60); // White
              colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
              colorWipe(strip.Color(225, 250, 180), 60); // White
              colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
              break;
        case(0xC03FE619) :
              for (int i = 0 ; i < 51; i++)
              {   
                  colorWipe(strip.Color((5*i), (1.96078431*i), (0.39215686*i)), 1); // Skin Color
              }
              break;
        case(0xC03FEC13) :
              for (int i = 0 ; i < 51; i++)
              {   
                  colorWipe(strip.Color((5*i), (0.1*i), (0)), 1); // Full red
              }
              for (int i = 51 ; i >-1; i--) 
              {
                  colorWipe(strip.Color((5*i), (0.1*i), (0)), 1);
              }
              delay(30);
              for (int i = 0 ; i < 51; i++)
              {   
                  colorWipe(strip.Color((5*i), (0.1*i), (0)), 1); // Full red
              }
              for (int i = 51 ; i >-1; i--) 
              {
                  colorWipe(strip.Color((5*i), (0.1*i), (0)), 1);
              }
              break;
        default:
            break;   
    }
}

Okay, so I tried your suggestions.

  1. Firstly, I removed all delay functions, but I suspect there are some still in the colorWipe function itself maybe, since when I did that it was not possible to interrupt a program. The timing was changed (I tried with the two modes shown below and the first one went extremely fast while the second one went just as normal but did not allow for interruption. It repeated itself with about a sec in between repeatings). This was the code:
#include <Adafruit_NeoPixel.h>
 
// We need to use the 'raw' pin reading methods because timing is very important here 
// and the digitalRead() procedure is slower!
#define IRpin_PIN  PINB // ATTiny85 had Port B pins
#define IRpin      2    // IR sensor - TSOP38238 on Pin GPIO #2 / D2
#define RingPin   1 // DConnects to Adafruit Neopixel Ring

#define MAXPULSE    5000  // the maximum pulse we'll listen for - 5 milliseconds 
#define NUMPULSES    100  // max IR pulse pairs to sample
#define RESOLUTION     2  // // time between IR measurements
#define NumPixels        24 // number of pixels 
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, 1, NEO_GRB + NEO_KHZ800);
 
// we will store up to 40 pulse pairs (reduce if needed)
uint16_t pulses[40][2];   // pair is high and low pulse
uint16_t currentpulse = 0; // index for pulses we're storing
uint32_t irCode = 0;
uint16_t n;
uint32_t irCodeRead;
 
void setup() {
 pinMode(IRpin, INPUT);       // Listen to IR receiver on Trinket pin D2
 pinMode(RingPin, OUTPUT); // Output tones on Trinket pin D1
   strip.begin();
   cli();  // disables interrupts
     strip.show();  // generates the NeoPixel control signals
   sei();  // re-enables interrupts; // Initialize all pixels to 'off'
}
 
void loop() {
  
 irCode=listenForIR(); // Wait for an IR Code
 // Process the pulses to get our code
   for (int i = 0; i < 32; i++) {
   irCode=irCode<<1;
   if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) {
       irCode|=0; 
     } else {
     irCode|=1;
     int rccode = irCode;
     }
 }
   switch (irCode) {
   //ACTION ONE: TURNING WHITE AROUND THE CIRCLE, "STARTING ENERGY BELT"
   //PRESS BUTTON "1" *Note: white color updated to softer
   case(0xC03FDA25)  : {      // "1" on my remote
   colorWipe(strip.Color(225, 250, 180), 60); // White
   colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
   colorWipe(strip.Color(225, 250, 180), 60); // White
   colorWipe(strip.Color(56.25, 56.25, 45), 60); // White
   break;
 }
   //ACTION TWO: SKIN COLOR "CHARGING"
   //PRESS BUTTON "2"
   //IMPORTANT: to change speed, change max int i value in code since i increases at constant rate
   case(0xC03FE619) : {      // "2" on my remote
       for (int i = 0 ; i < 51; i++)  {    
       colorWipe(strip.Color((5*i), (1.96078431*i), (0.39215686*i)), 1); // Skin Color
     }
       for (int i = 51 ; i > 0; i--)  {    
       colorWipe(strip.Color((5*i), (1.96078431*i), (0.39215686*i)), 1); // Skin Color
     }
     break; 
}


uint16_t listenForIR() {  // IR receive code
 currentpulse = 0;
   while (1) {
   unsigned int highpulse, lowpulse;  // temporary storage timing
   highpulse = lowpulse = 0; // start out with no pulse length 
   while (IRpin_PIN & _BV(IRpin)) { // got a high pulse
     highpulse++; 
       delayMicroseconds(RESOLUTION);
       if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
         return currentpulse; 
     }
 }
   pulses[currentpulse][0] = highpulse;
 while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse
       lowpulse++; 
       delayMicroseconds(RESOLUTION);
     if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
         return currentpulse; 
     }
   }
   pulses[currentpulse][1] = lowpulse;
   currentpulse++;
 }
}

void colorWipe(uint32_t c, uint8_t wait) {
 for(uint16_t i=0; i<strip.numPixels(); i++) {
 strip.setPixelColor(i, c);
       strip.show();
 }
}

Could this be because of uint8_t wait in void colorWipe...?

  1. Secondly, as I did not manage to figure out this issue, I tried to build the switch case structure that you mentioned. Meaning there is firstly a switch case where the IR code is written to a variable (int knopSoort), and then secondly one where this variable leads to different light scenario's. Unfortunately, when I uploaded it, there was no reaction from the LEDs when I pressed a button... This was the code used:
#include <Adafruit_NeoPixel.h>
 
// We need to use the 'raw' pin reading methods because timing is very important here 
// and the digitalRead() procedure is slower!
#define IRpin_PIN  PINB // ATTiny85 had Port B pins
#define IRpin      2    // IR sensor - TSOP38238 on Pin GPIO #2 / D2
#define RingPin   1 // DConnects to Adafruit Neopixel Ring

#define MAXPULSE    5000  // the maximum pulse we'll listen for - 5 milliseconds 
#define NUMPULSES    100  // max IR pulse pairs to sample
#define RESOLUTION     2  // // time between IR measurements
#define NumPixels        24 // number of pixels 
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, 1, NEO_GRB + NEO_KHZ800);
 
// we will store up to 40 pulse pairs (reduce if needed)
uint16_t pulses[40][2];   // pair is high and low pulse
uint16_t currentpulse = 0; // index for pulses we're storing
uint32_t irCode = 0;
uint16_t n;
uint32_t irCodeRead;
int knopSoort = 0;
unsigned long previousMillis = 0; //will store last LED update time moment
const long interval = 300; // constant interval at which to "blink"

 
void setup() {
 pinMode(IRpin, INPUT);       // Listen to IR receiver on Trinket pin D2
   pinMode(RingPin, OUTPUT); // Output tones on Trinket pin D1
   strip.begin();
     cli();  // disables interrupts
     strip.show();  // generates the NeoPixel control signals
     sei();  // re-enables interrupts; // Initialize all pixels to 'off'
}
 
void loop() {
  
 irCode=listenForIR(); // Wait for an IR Code
 
   // Process the pulses to get our code
   for (int i = 0; i < 32; i++) {
     irCode=irCode<<1;
   if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) {
       irCode|=0; 
     } else {
       irCode|=1;
       int rccode = irCode;
     }
 }
   switch (irCode) {
   //PRESS BUTTON "1" *Note: white color updated to softer
     case(0xC03FDA25)  : {      // "1" on my remote
     int knopSoort = 1;
     break;
     }
   //PRESS BUTTON "2"
   case(0xC03FE619) : {      // "2" on my remote
     int knopSoort = 2;
     break; 
   } 
   }  
   switch (knopSoort) {
       case (1) : {
       for (int i = 0 ; i < 51; i++)  {    
       colorWipe(strip.Color((5*i), (4.65*i), (3.8*i)), 1);
       break;
     }
 }
       case (2) : {
         for (int i = 0 ; i < 51; i++)  {    
         colorWipe(strip.Color((5*i), (1.96078431*i), (0.39215686*i)), 1); // Skin Color
     }
     for (int i = 51 ; i >-1; i--)  {
       colorWipe(strip.Color((5*i), (1.96078431*i), (0.39215686*i)), 1);
     break;
 }
       }
 }
}

uint16_t listenForIR() {  // IR receive code
 currentpulse = 0;
   while (1) {
   unsigned int highpulse, lowpulse;  // temporary storage timing
   highpulse = lowpulse = 0; // start out with no pulse length 
  
   while (IRpin_PIN & _BV(IRpin)) { // got a high pulse
       highpulse++; 
       delayMicroseconds(RESOLUTION);
       if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
         return currentpulse; 
     }
   }
   pulses[currentpulse][0] = highpulse;
 
   while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse
       lowpulse++; 
     delayMicroseconds(RESOLUTION);
       if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
         return currentpulse; 
       }
   }
   pulses[currentpulse][1] = lowpulse;
   currentpulse++;
   }
}

void colorWipe(uint32_t c, uint8_t interval) {
 listenForIR();
   for(uint16_t i=0; i<strip.numPixels(); i++) {
       strip.setPixelColor(i, c);
       strip.show();
   }
}

Why doesn't it do anything anymore? It should receive the values and act from the variable knopSoort right?

@Arduinodlb I am going to try your suggestion!