ir remote & rgb led strip

hi guys first time writer , old reader of the forum
I made a little circuit to control an rgb led strip with my tv remote control.I want to mix colors by enabling-disabling ports ( works) and to make a swirl effect by pressing another button on my remote controller(does not work).
When i try to call the function swirl() , the loop is not endless (stops after a while) and the remote does not work in this period of time

the code im using :

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;
 
#define REDPIN 5
#define GREENPIN 6
#define BLUEPIN 3
 
#define FADESPEED 8     // make this higher to slow down
 
void setup() {
  pinMode(REDPIN, OUTPUT);
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
  
  
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}
 void swirl() {
       int r, g, b;
     // fade from blue to violet
  for (r = 0; r < 256; r++) { 
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  } 
  // fade from violet to red
  for (b = 255; b > 0; b--) { 
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  } 
  // fade from red to yellow
  for (g = 0; g < 256; g++) { 
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  } 
  // fade from yellow to green
  for (r = 255; r > 0; r--) { 
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  } 
  // fade from green to teal
  for (b = 0; b < 256; b++) { 
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  } 
  // fade from teal to blue
  for (g = 255; g > 0; g--) { 
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  }
    
    
    }
 
void loop() {
  
  
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX );
      switch (results.value){
    case 0x1FED827 : //red on
   digitalWrite(3,HIGH); 
    break;
   
  case 0x1FEF807 :  //red off
    digitalWrite(3,LOW);
   break;
   
   
    case 0x1FE9867 :  //green on
   digitalWrite(5,HIGH);
    break;
   
  case 0x1FEB847 :   // green off
    digitalWrite(5,LOW);
   break;
   
   
    case 0x1FE58A7 :   // blue on
   digitalWrite(6,HIGH);
    break;
   
  case 0x1FE7887 :  // blue off
    digitalWrite(6,LOW);
   break;


   case 0x1FE30CF :  //swirl
   swirl();
   break;



    }
    //delay(200); //A simple delay because it reads a lot of values in a press of a button
    irrecv.resume(); // Receive the next value
  }
}

When i try to call the function swirl() , the loop is not endless (stops after a while) and the remote does not work in this period of time

Nothing works, except interrupts, during a call to delay(). You need to stop using it. Look at the Blink Without Delay example, without delay.

hi thanks for the reply Can you help me a bit more? Im a rookie...

// set the brightness of pin 5: analogWrite(5, brightness);

// change the brightness for next time through the loop: brightness = brightness + fadeAmount;

// reverse the direction of the fading at the ends of the fade: if (brightness == 0 || brightness == 255) { fadeAmount = -fadeAmount ; } // wait for 30 milliseconds to see the dimming effect delay(30);

but it doesnt work either.. I think the problem has to do with the loops..

I think the problem has to do with the loops.

What loops? There are no loops in that code.

Where does this code snippet fit with the previous code you posted? What is the advantage of this code over that code, since it still uses the dreaded delay() function?

ok misunderstanding about the last snippet :blush:... it was the only example i found with fade... I cant think a possible solution without the delay...

the loops im talking about are swirl() and irrecv.resume() since i want them to run in a loop .The first one in an endless loop (if called) but with the possibility to interrupt it with an irrecv.resume() .

thank you about your patience..

Go back and look at your original code.

Inside the swirl() function, each call to delay() causes program execution to be delayed by only 8 milliseconds, but you do that 1533 times before leaving the function.

The result is that over 12 seconds elapse from the time you enter the swirl() function until the time that you leave it. Changing the way that the delay is implemented won’t fix that. Period. You will still have to wait 12+ seconds before it gets back to the place where it sees if anything has been received from the IR remote.

One fairly simple way, without major (structural) changes to your original code, is to put some instructions in each of the six loops in the swirl() function that detects when a new IR code has been received and return from the function if that happens. (There are certainly other ways; maybe even “better” ways, but I think it’s no big deal to make your original approach more workable.)

In IRremote.cpp there is a volatile variable (a struct) named irparams. This struct has a data member that is a state variable that keeps track of things being received by the interrupt-driven receiver program. It is declared extern in <IRremoteInt.h> (“Normally” you wouldn’t have to know anything about this, but in this case, it can help to look beneath the bonnet. The great thing about Open Source code—especially well-written code—is that you can see and do things that many people wouldn’t “normally” have to do.)

Here’s something to try. Go back to your original code. Then:

.
.
.
// your other stuff
.
.
.
// There is a volatile variable named irparams that is
// defined in IRremote.c  (And declared extern in
// IRremote.h)
//
// irparams is a struct that has a data member
// named rcvstate.
//
// This variable keeps track of what is happening in
// the interrupt-driven IR receiver state machine.
//
// This variable is set to STATE_IDLE when the receiver
// is enabled, and changes to other states as stuff
// is detected on Arduino's input pin connected to
// the IR receiver.
//
// The value of irparams.rcvstate will be equal to STATE_STOP only
// after a new code has been received from the IR Remote,
// and is reset to STATE_IDLE by a call to IRrecv::resume()
//
// davekw7x
//
#include <IRremoteInt.h>

void swirl()
{
    int r, g, b;
    // fade from blue to violet
    for (r = 0; r < 256; r++) {
        if (irparams.rcvstate == STATE_STOP) {
            return;
        }
        analogWrite(REDPIN, r);
        delay(FADESPEED);
    } 
    // fade from violet to red
    for (b = 255; b > 0; b--) { 
        if (irparams.rcvstate == STATE_STOP) {
            return;
        }
        analogWrite(BLUEPIN, b);
        delay(FADESPEED);
    } 
.
.   // Same for other loops in swirl()
.

Now, you might want to do a little cleanup (turn off the LEDs before returning, for example), but maybe the above suggestion will be a starting point.

Bottom line: If the code is inside swirl() when the receiver sees something new from the IR remote, it will bail out of the function after some few milliseconds so that the IR remote code can be decoded with no obvious delay from the user’s point of view.

Regards,

Dave

thanks Dave… but the code doesn’t work…
I dont know if i did anything wrong but i dont see any fade in-out…
I can see the ir codes when i call the swirl() so it works…
here is the code

#include <IRremote.h>
#include <IRremoteInt.h>
int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;
 
#define REDPIN 5
#define GREENPIN 6
#define BLUEPIN 3
 
#define FADESPEED 10     // make this higher to slow down
 
void setup() {
  pinMode(REDPIN, OUTPUT);
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
  
  
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}
 void swirl() {
       int r, g, b;
      // fade from blue to violet
    for (r = 0; r < 256; r++) {
        if (irparams.rcvstate == STATE_STOP) {
           return;
        }
        analogWrite(REDPIN, r);
        delay(FADESPEED);
    } 
    // fade from violet to red
    for (b = 255; b > 0; b--) { 
        if (irparams.rcvstate == STATE_STOP) {
            return;
        }
        analogWrite(BLUEPIN, b);
        delay(FADESPEED);
    }
   // fade from red to yellow
  for (g = 0; g < 256; g++) { 
     if (irparams.rcvstate == STATE_STOP) {
           return;
        }
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  } 
  // fade from yellow to green
  for (r = 255; r > 0; r--) { 
     if (irparams.rcvstate == STATE_STOP) {
            return;
        }
    analogWrite(REDPIN, r);
    delay(FADESPEED);
  } 
  // fade from green to teal
  for (b = 0; b < 256; b++) { 
     if (irparams.rcvstate == STATE_STOP) {
            return;
        }
    analogWrite(BLUEPIN, b);
    delay(FADESPEED);
  } 
  // fade from teal to blue
  for (g = 255; g > 0; g--) { 
     if (irparams.rcvstate == STATE_STOP) {
            return;
        }
    analogWrite(GREENPIN, g);
    delay(FADESPEED);
  } 
     
 }
 
void loop() {
  
  
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX );
      switch (results.value){
    case 0x1FED827 : 
   digitalWrite(3,HIGH);
    break;
   
  case 0x1FEF807 : 
    digitalWrite(3,LOW);
   break;
   
   
    case 0x1FE9867 : 
   digitalWrite(5,HIGH);
    break;
   
  case 0x1FEB847 : 
    digitalWrite(5,LOW);
   break;
   
   
    case 0x1FE58A7 : 
   digitalWrite(6,HIGH);
    break;
   
  case 0x1FE7887 : 
    digitalWrite(6,LOW);
   break;
   
    case 0x1FE30CF :  //swirl
   swirl();
   break;

   
    }
    delay(200); //A simple delay because it reads a lot of values in a press of a button
    irrecv.resume(); // Receive the next value
  }
}

pyrforos: thanks Dave.. but the code doesn't work......

Well, I guess there is a little more to be done.

In the first place, when you press a button on the remote, you already know that sometimes (depending on the remote control unit and the particular protocol) the code is sent more than once. So, as soon as you get into the swirl() function it may be that another copy of the same IR remote code is received soon enough that it bails out before you want it to.

One approach, which may be practical, is to simply wait for a couple of hundred milliseconds (or some heuristically-determined interval) after detecting the "swirl" command and then execute irrecv.resume() (to set the receiver back to its idle state) before calling swirl().

  case 0x1FE30CF :  //swirl
    delay(200);    // Wait a little while in case it's repeated
    irrecv.resume(); // Set recvstate to IDLE
    swirl();
    break;

A better way might be to make the conditional return statements inside swirl() perform a test (by decoding the received stuff while it's still inside swirl() and returning only if it is different from the swirl command).

Regards,

Dave

ok... the whole code has not the desired effect the irparams.rcvstate == STATE_STOP stuff works

Yes i had tested the fade stuff alone . If i replace my code with your code at the swirl function, with no input from the remote, it loops only one time for all the loops.This means fade from blue to violet-->fade from violet to red-->fade from red to yellow-->fade from yellow to green-->fade from green to teal-->fade from teal to blue and thats all stays at blue. What i need is the swirl function to run in infinite loop till i stop it. The visual effects they are not the same as with the stand-alone swirl() , at some point a blue flash appears and the fade is very quick.

edit: hugh ? the post disappeared?

thanks again Dave
I tried your code but… nothing
Anyway im too tired to continue now… maybe tomorrow :slight_smile:

I realized that I had accidentally hit the “Post” button prematurely and tried to delete my post before it got out. Sorry about the confusion.

Anyhow…

The stand-alone code calls the swirl() repeatedly. If this does what you want, then do something like the following:

void swirl()
{
    while(1) {

    // Everything that works will be repeated continuously until it receives
    // another code from the IR remote control causing it to return
   
    }
}

Now test that swirly stuff in something like the folowing:

#define REDPIN 5
#define GREENPIN 6
#define BLUEPIN 3

#define FADESPEED 10     // make this higher to slow down

void setup() {
    swirl();
    //Should never leave the new swirl()
}
void loop(){
}

void swirl()
{
    int i;
    
    while(1) {
        for (i = 0; i < 256; i++) {
            analogWrite(REDPIN, i);
            delay(FADESPEED);
        } 
        // fade from violet to red
        for (i = 255; i > 0; i--) { 
            analogWrite(BLUEPIN, i);
            delay(FADESPEED);
        }
        // fade from red to yellow
        for (i = 0; i < 256; i++) { 
            analogWrite(GREENPIN, i);
            delay(FADESPEED);
        } 
        // fade from yellow to green
        for (i = 255; i > 0; i--) { 
            analogWrite(REDPIN, i);
            delay(FADESPEED);
        } 
        // fade from green to teal
        for (i = 0; i < 256; i++) { 
            analogWrite(BLUEPIN, i);
            delay(FADESPEED);
        } 
        // fade from teal to blue
        for (i = 255; i > 0; i--) { 
            analogWrite(GREENPIN, i);
            delay(FADESPEED);
        } 
    }
}

If that looks OK, then put in the bail-out stuff in the loops and put it in your IR remote sketch

Regards,

Dave

The stand-alone code works , stand-alone code + swirl works ,with ir stuff it doesn’t

I’m completely lost in the code… too hard core for me… :astonished:

so a try to debug…

#include <IRremote.h>
#include <IRremoteInt.h>
int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;
 
#define REDPIN 5
#define GREENPIN 6
#define BLUEPIN 3
 
#define FADESPEED 5     // make this higher to slow down
 
void setup() {
  pinMode(REDPIN, OUTPUT);
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
  
  
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
//   swirl();
    //Should never leave the new swirl()
}

void loop() {
  
  
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX );
      switch (results.value){
    case 0x1FED827 : 
   digitalWrite(3,HIGH);
    break;
   
  case 0x1FEF807 : 
    digitalWrite(3,LOW);
   break;
   
   
    case 0x1FE9867 : 
   digitalWrite(5,HIGH);
    break;
   
  case 0x1FEB847 : 
    digitalWrite(5,LOW);
   break;
   
   
    case 0x1FE58A7 : 
   digitalWrite(6,HIGH);
    break;
   
  case 0x1FE7887 : 
    digitalWrite(6,LOW);
   break;
   
    case 0x1FE30CF :  //swirl
   //delay(200);    // Wait a little while in case it's repeated
    irrecv.resume(); // Set recvstate to IDLE
    swirl();
   break;

   
    }
    //delay(200); //A simple delay because it reads a lot of values in a press of a button
    irrecv.resume(); // Receive the next value
  }
}
    
  
void swirl()
{
    int i;
    
    while(1) {
        // fade from blue to violet
        for (i = 0; i < 256; i++) {
          Serial.println("1  fade from blue to violet");
          //if (irparams.rcvstate == STATE_STOP) {
//            Serial.println("******ABORT*****"); 
         //   return;
        //}
            analogWrite(REDPIN, i);
            delay(FADESPEED);
        } 
        // fade from violet to red
        for (i = 255; i > 0; i--) { 
          Serial.println("2 fade from violet to red");
          //if (irparams.rcvstate == STATE_STOP) {
//            Serial.println("******ABORT*****"); 
            //return;
        //}
            analogWrite(BLUEPIN, i);
            delay(FADESPEED);
        }
        // fade from red to yellow
        for (i = 0; i < 256; i++) { 
          Serial.println("3  fade from red to yellow");
         // if (irparams.rcvstate == STATE_STOP) {
//           Serial.println("******ABORT*****"); 
           // return;
        //}
            analogWrite(GREENPIN, i);
            delay(FADESPEED);
        } 
        // fade from yellow to green
        for (i = 255; i > 0; i--) { 
          Serial.println("4  fade from yellow to green");
         if (irparams.rcvstate == STATE_STOP) {
          Serial.println("******ABORT*****"); 
            return;
        }
            analogWrite(REDPIN, i);
            delay(FADESPEED);
        } 
        // fade from green to teal
        for (i = 0; i < 256; i++) { 
          Serial.println("5  fade from green to teal");
         // if (irparams.rcvstate == STATE_STOP) {
//           Serial.println("******ABORT*****"); 
           // return;
        //}
            analogWrite(BLUEPIN, i);
            delay(FADESPEED);
        } 
        // fade from teal to blue
        for (i = 255; i > 0; i--) {
          Serial.println("6  fade from teal to blue");
          //if (irparams.rcvstate == STATE_STOP) {
//            Serial.println("******ABORT*****"); 
            //return;
        //}
            analogWrite(GREENPIN, i);
            delay(FADESPEED);
        } 
    }
}

i put the bail out in one loop only and i commented the others

i get :
blah blah blah
3 fade from red to yellow

3 fade from red to yellow

4 fade from yellow to green

*ABORT

Sorry guys but im reaaaaally a newbie in that …

pyrforos:
blah blah blah
3 fade from red to yellow

3 fade from red to yellow

4 fade from yellow to green

*ABORT

So there is something in the IR receive buffer. Try the following: Uncomment the delay() function call in the swirl case:

        case 0x1FE30CF :  //swirl
            delay(200);      // Wait a little while in case it's repeated <---Do this
            irrecv.resume(); // Set recvstate to IDLE
            swirl();
            // You may want to turn off all of the LEDs here to get back to a "clean slate"
            break;

Even if you jab the button very quickly, some remote control devicess will repeat the code (or in some cases will send a special “repeat” code). In your particular program the only place this causes a problem is in the swirl() function. (If you press and hold the “Red On” button, for example, it just goes back through the loop and turns it on again, so the repeated code doesn’t cause any effect that can be noticed by human users.)

There are more sophisticated ways to deal with this more reliably, but maybe this can get you down into the swirl() function with nothing in the IR receive buffer so that it can continue until you deliberately press a button.

Regards,

Dave

seems to be working! thanks a lot! :)

BUGS: to the change from violet to red appears a blue light flash for a msec....

loop from green to teal is instant like it skips it. The fade code alone works perfectly

pyrforos:

BUGS: to the change from violet to red appears a blue light flash for a msec…

loop from green to teal is instant like it skips it. …

What were the last r, g, b values written before the flash?

Use print statements to make sure you know where (in the code) things are happening. Slow it down and see where the flash occurs and where it seems to be skipping stuff (you can even print value of millis() before and after each loop if you want to see whether it’s doing something other than you expected.

Bottom line: If you can’t see (by looking at the program) what’s misbehaving, try to make the program tell you.

void swirl()
{
    int i;

    while(1) {
        // fade from blue to violet
        Serial.println("1 Writing REDPIN 0-255  : fade from blue to violet");
        for (i = 0; i < 256; i++) {
            if (irparams.rcvstate == STATE_STOP) {
                Serial.println("******ABORT1*****"); 
                return;
            }
            analogWrite(REDPIN, i);
            delay(FADESPEED);
        } 

        // fade from violet to red
        Serial.println("2 Writing BLUEPIN 255-1 : fade from violet to red");
        for (i = 255; i > 0; i--) { 
            if (irparams.rcvstate == STATE_STOP) {
                Serial.println("******ABORT2*****"); 
                return;
            }
            analogWrite(BLUEPIN, i);
            delay(FADESPEED);
        }

        // fade from red to yellow
        Serial.println("3 Writing GREENPIN 0-255: fade from red to yellow");
        for (i = 0; i < 256; i++) { 
            if (irparams.rcvstate == STATE_STOP) {
                Serial.println("******ABORT3*****"); 
                return;
            }
            analogWrite(GREENPIN, i);
            delay(FADESPEED);
        }

        // fade from yellow to green
        Serial.println("4 Writing REDPIN 255-1  : fade from yellow to green"); 
        for (i = 255; i > 0; i--) { 
            if (irparams.rcvstate == STATE_STOP) {
                Serial.println("******ABORT4*****"); 
                return;
            }
            analogWrite(REDPIN, i);
            delay(FADESPEED);
        }

        // fade from green to teal
        Serial.println("5 Writing GREENPIN 0-255: fade from green to teal"); 
        for (i = 0; i < 256; i++) { 
            if (irparams.rcvstate == STATE_STOP) {
                Serial.println("******ABORT5*****"); 
                return;
            }
            analogWrite(BLUEPIN, i);
            delay(FADESPEED);
        }

        // fade from teal to blue
        Serial.println("6 Writing GREENPIN 255-1: fade from teal to blue");
        for (i = 255; i > 0; i--) {
            if (irparams.rcvstate == STATE_STOP) {
                Serial.println("******ABORT6*****"); 
                return;
            }
            analogWrite(GREENPIN, i);
            delay(FADESPEED);
        }
    }
    Serial.println();
}

Or some such thing.

Regards,

Dave

Footnote:
As I mentioned in a comment in a previous code snippet, I think it would be a Good Idea to write known values into the LEDs after returning from swirl() (I would probably turn them all off.)

Back in loop(), I suggest that you set LED values to whatever initial state you need them to be in order to see what you want before calling swirl() again. (Blue high , Red and Green, low, right?) Then when you begin a new odyssey to the land of swirl, the first time through the loop will be what you need in order to get some continuity as the loop repeats itself.

OMG OMG OMG!!!!! I just realized why all the "abort" stuff keeps on messing with my nerves... it's because of THE FRICKIN LAMP!!!! CAN YOU IMAGINE THIS STUFF? My desk is near the window and light variations is a very common thing because of the street lamp outside and the desk lamp .. As we know heat emits ir light... so my irparams.rcvstate == STATE_STOP sees that , since it doesnt seek for a certain ir value, just a variation of it, and bails out of the code... :fearful: :fearful: :fearful: :astonished: