Go Down

Topic: LED fade will not listen to IR input for interupt. (Read 3 times) previous topic - next topic

MrKovacic

I'll start by saying this, im pretty good with Autoit, but a baby when it comes to C++..

I have a decent script set up to blink LED's using an old blu-ray player remote. As it stands, the remote has numbered buttons, volume buttons etc.. It also has a red, green, blue and yellow button. I have it so if I push the R, G or B button, the LED of that color lights up. If I push Yellow, it shuts everything off. I am trying to incorperate fading into this, and while it will being and run the fade, it will no longer pay attention to the IR remote during the fade. I tried removing all delays, and even adding in some calls to read the IR, but no matter what I do, the Fade codes stay going until I reset the Arduino.

I have a simple blink on button 2, a fairly simple fade using cos on button  1, and a more advanced fade on button 7.

While any of the fades are going, I can't get Arduino to check the IR for changes.

here is the code:
Code: [Select]

// include some junk
#include <IRremote.h>


int RECV_PIN = 11;
int periode = 2000;
int displace = 500;
int testtime = 1000;
long time=0;
/*  FUTURE USE
int RED1 = 2;
int GREEN1 = 3;
int BLUE1 = 4;

int RED2 = 5;
int GREEN2 = 6;
int BLUE2 = 7;

int RED3 = 8;
int GREEN3 = 9;
int BLUE3 = 10;

int RED4 = 11;
int GREEN4 = 12;
int BLUE4 = 13;
*/
int redPin = 7;   // Red LED,   connected to digital pin 9
int grnPin = 6;  // Green LED, connected to digital pin 10
int bluPin = 8;  // Blue LED,  connected to digital pin 11

int value, value2, value3 ;

int RED = 7;
int GREEN = 6;
int BLUE = 8;

// Color arrays
int black[3]  = { 0, 0, 0 };
int white[3]  = { 100, 100, 100 };
int red[3]    = { 100, 0, 0 };
int green[3]  = { 0, 100, 0 };
int blue[3]   = { 0, 0, 100 };
int yellow[3] = { 100, 100, 0 };
int pink[3] = { 0, 100, 100 };
int magenta[3] = { 100, 0, 100 };

// etc.

// Set initial color
int redVal = black[0];
int grnVal = black[1];
int bluVal = black[2];


//int wait = 2;      // no longer used

int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;
IRrecv irrecv(RECV_PIN);
decode_results results;
long previousMillis = 0;   
long interval = 1000;
long chill = 2;

int ledState = LOW; // only for BLUE LED for now, will add more later, just want to blink blue for now
int blinkone = 0;
int blinktwo= 0;
int blinkthree = 0;
int blinkfour = 0;
int blinkfive = 0;
int blinksix = 0;
int blinkseven = 0;
int blinkeight = 0;
int blinknine = 0;


void setup() //Just some obvious crap
{
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  irrecv.enableIRIn(); // kick on the IR receiver
}



void loop() {
  unsigned long currentMillis = millis(); // Start the arduino counting so it can keep time
  if (irrecv.decode(&results)) {
    if (results.value == 0x66B47) { // BLUE button on the remote
      digitalWrite(BLUE, HIGH);
    }
    else if (results.value == 0xE6B47) { // RED button on the remote
      digitalWrite(RED, HIGH);
    }   
   
        else if (results.value == 0x490) { // Vol Up button on the remote
      interval = interval - 50;
      if  (interval < 75) {
            interval =100;
                           }
    } 
   
        else if (results.value == 0xC90) { // Vol Down button on the remote
            interval = interval + 50;
    } 
   
            else if (results.value == 0x290) { // Vol Down button on the remote
            interval = 1000;
    } 
   
        else if (results.value == 0x16B47) { // GREEN button on the remote
      digitalWrite(GREEN, HIGH);
    }
   
        else if (results.value == 0xB47) { // 1 button on the remote
  while (results.value == 0xB47) {
  time = millis();
  value = 128+127*cos(2*PI/periode*time);
  value2 = 128+127*cos(2*PI/periode*(displace-time));
  value3 = 128+127*cos(2*PI/periode*(testtime-time));
  analogWrite(redPin, value);           // sets the value (range from 0 to 255)
  analogWrite(grnPin, value2);           // sets the value (range from 0 to 255)
  analogWrite(bluPin, value3);
  irrecv.resume();
        }}
       
       
        else if (results.value == 0x80B47) { // 2 button on the remote

blinkone = 1;
blinktwo= 0;
blinkthree = 0;
blinkfour = 0;
blinkfive = 0;
blinksix = 0;
blinkseven = 0;
blinkeight = 0;
blinknine = 0;
        }        else if (results.value == 0x40B47) { // 3 button on the remote

blinkone = 0;
blinktwo= 0;
blinkthree = 1;
blinkfour = 0;
blinkfive = 0;
blinksix = 0;
blinkseven = 0;
blinkeight = 0;
blinknine = 0;
        }        else if (results.value == 0xC0B47) { // 4 button on the remote

blinkone = 0;
blinktwo= 0;
blinkthree = 0;
blinkfour = 1;
blinkfive = 0;
blinksix = 0;
blinkseven = 0;
blinkeight = 0;
blinknine = 0;
        }        else if (results.value == 0x20B47) { // 5 button on the remote

blinkone = 0;
blinktwo= 0;
blinkthree = 0;
blinkfour = 0;
blinkfive = 1;
blinksix = 0;
blinkseven = 0;
blinkeight = 0;
blinknine = 0;
        }        else if (results.value == 0xA0B47) { // 6 button on the remote

blinkone = 0;
blinktwo= 0;
blinkthree = 0;
blinkfour = 0;
blinkfive = 0;
blinksix = 1;
blinkseven = 0;
blinkeight = 0;
blinknine = 0;
        }        else if (results.value == 0x60B47) { // 7 button on the remote
while (results.value == 0x60B47) {

  crossFade(red);
  crossFade(green);
  crossFade(blue);
  crossFade(yellow);
  crossFade(white);
  crossFade(pink);
  crossFade(magenta);
  }

        }        else if (results.value == 0xE0B47) { // 8 button on the remote

blinkone = 0;
blinktwo= 0;
blinkthree = 0;
blinkfour = 0;
blinkfive = 0;
blinksix = 0;
blinkseven = 0;
blinkeight = 1;
blinknine = 0;
        }        else if (results.value == 0x10B47) { // 9 button on the remote

blinkone = 0;
blinktwo= 0;
blinkthree = 0;
blinkfour = 0;
blinkfive = 0;
blinksix = 0;
blinkseven = 0;
blinkeight = 0;
blinknine = 1;
        }
       
       
       
       

        else if (results.value == 0x96B47  ) { // YELLOW - shut everything off. aka blackout
      digitalWrite(BLUE, LOW);
      digitalWrite(RED, LOW);
      digitalWrite(GREEN, LOW);
      blinkone = 0; // stops that pesky blue light from blinking like a little bitch

    }
    irrecv.resume(); //doesnt matter where you put this, it workd right here so I guess dont mess with it
  }
 
 
 
  if (blinkone == 1) {   // First flash pattern. On and off, bow to its awesomeness!
     
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    digitalWrite(BLUE, ledState);
      }   
     }   //include this
 
}


int calculateStep(int prevValue, int endValue) {
  int step = endValue - prevValue; // What's the overall gap?
  if (step) {                      // If its non-zero,
    step = 1020/step;              //   divide by 1020
  }
  return step;
}

int calculateVal(int step, int val, int i) {

  if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
    if (step > 0) {              //   increment the value if step is positive...
      val += 1;           
    }
    else if (step < 0) {         //   ...or decrement it if step is negative
      val -= 1;
    }
  }
  // Defensive driving: make sure val stays in the range 0-255
  if (val > 255) {
    val = 255;
  }
  else if (val < 0) {
    val = 0;
  }
  return val;
}




void crossFade(int color[3]) {
    unsigned long currentMillis = millis();
  // Convert to 0-255
  int R = (color[0] * 255) / 100;
  int G = (color[1] * 255) / 100;
  int B = (color[2] * 255) / 100;

  int stepR = calculateStep(prevR, R);
  int stepG = calculateStep(prevG, G);
  int stepB = calculateStep(prevB, B);

  for (int i = 0; i <= 1020; i++) {
    redVal = calculateVal(stepR, redVal, i);
    grnVal = calculateVal(stepG, grnVal, i);
    bluVal = calculateVal(stepB, bluVal, i);

    analogWrite(redPin, redVal);   // Write current values to LED pins
    analogWrite(grnPin, grnVal);     
    analogWrite(bluPin, bluVal);
   
int zag = 1;
do {
zag = zag + 1;
getIR();
} while (zag < 200);

     
     


  }
  // Update current values for next loop
  prevR = redVal;
  prevG = grnVal;
  prevB = bluVal;

}

void getIR() {
IRrecv irrecv(RECV_PIN);
decode_results nresults;
}


Any help would be very appreciated! :smiley-eek:

Nick Gammon

This function doesn't seem to do anything useful:

Code: [Select]
void getIR() {
  IRrecv irrecv(RECV_PIN);
  decode_results nresults;
}


You also have near the top of your sketch:

Code: [Select]
IRrecv irrecv(RECV_PIN);
decode_results results;
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

UKHeliBob

Does that code compile for you ?

Will this and similar 'while' loops ever exit ?

Code: [Select]
        else if (results.value == 0xB47)
    {                                           // 1 button on the remote
      while (results.value == 0xB47)
      {
        time = millis();
        value = 128+127*cos(2*PI/periode*time);
        value2 = 128+127*cos(2*PI/periode*(displace-time));
        value3 = 128+127*cos(2*PI/periode*(testtime-time));
        analogWrite(redPin, value);           // sets the value (range from 0 to 255)
        analogWrite(grnPin, value2);           // sets the value (range from 0 to 255)
        analogWrite(bluPin, value3);
        irrecv.resume();
      }
    }


NOTE - I have tidied up the layout a bit to make it easier to read.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

AWOL

The IDE has a useful auto-format feature (ctrl-T).
Please try to use it before posting.
Code: [Select]
/*  FUTURE USE
int RED1 = 2;
int GREEN1 = 3;
int BLUE1 = 4;

int RED2 = 5;
int GREEN2 = 6;
int BLUE2 = 7;

int RED3 = 8;
int GREEN3 = 9;
int BLUE3 = 10;

int RED4 = 11;
int GREEN4 = 12;
int BLUE4 = 13;
*/
int redPin = 7;   // Red LED,   connected to digital pin 9
int grnPin = 6;  // Green LED, connected to digital pin 10
int bluPin = 8;  

Please, get these into arrays before your code gets too unwieldy.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

bot-thoughts

Not trying to be pedantic; I'm actually posting in hopes that it helps you down the road. If you haven't looked at coding style, it's worth it. It'll pay off by making it easier to debug your code later -- whether by yourself or by folks on a forum.  I think K&R and Allman are both good choices likely to be readable to the vast majority of programmers. Anyway I hope this helps.
http://www.bot-thoughts.com/

MrKovacic

Thank you for the info so far, and I will fix those. Being a beginner, I code in the only way I know how, but am slowly learning.

Any thoughts into the original issue I was having? Trying to get arduino to check for input during any one of those fades?

PaulS

Quote
Trying to get arduino to check for input during any one of those fades?

Strip out all the modes that work fine. Post just the one part that does not work.

The IR signal is received using interrupts, so that is not the problem. The problem is see if there is a new value to use. Clearly, you aren't doing that. Equally clearly, it is hard to tell you where to add that in all that randomly arranged code.

MrKovacic

Breaking it down in its simplest form...

Code: [Select]


  time = millis();
  value = 128+127*cos(2*PI/periode*time);
  value2 = 128+127*cos(2*PI/periode*(displace-time));
  value3 = 128+127*cos(2*PI/periode*(testtime-time));
  analogWrite(redPin, value);           // sets the value (range from 0 to 255)
  analogWrite(grnPin, value2);           // sets the value (range from 0 to 255)
  analogWrite(bluPin, value3);
  irrecv.resume();


While this fade is taking place, I need it to continually check for IR input. The code above in a loop causes all 3 LEDs to fade back and forth. Looking for any thoughts on how to slide an interrupt in there. I have already stripped away the delays.

Any thoughts?

AWOL

I think that consistent indentation helps make code more readable, and can sometimes highlight logical mistakes.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

Code: [Select]
  irrecv.resume();
That just tells it to go get ready to receive another input. It does not determine whether any input was received, nor does it decode the results.

I think you would be far ahead if you separated the "get a value" code from the "use a value" code.

Create functions for each of the "use a value" cases. Call them when the appropriate value is present.

If you don't want to redo the function if a new value has not arrived (as in it is unlikely that "go faster" should be repeated), then, in that case, set the last value received to a do nothing value, like 0.

MrKovacic


I think that consistent indentation helps make code more readable, and can sometimes highlight logical mistakes.


Im actually pretty happy you guys told me about Ctrl + T because I didn't know about it. I code in Autoit at work, and we have a separate Tidy and Cleanup program that removes all comments, fixes indentation and removes empty lines which helps in the space of the code. I'm thinking of adapting it for Arduino, because it would be easy to do. I would call it a pre compiler ;)

As for the actual code, my overall goal is to make an LED sequencer which will eventually include various other blink patterns that listen to sound. If I am having this much trouble with this simple fade issue, I am getting scared to go into sound. I finished an amazing huge project at work with over 1700 lines of code, so I got gitty thinking I could jump into C++ and do the same thing.

I was hoping some good examples already existed out there, but after doing some searching, I had no luck.

MrKovacic


Code: [Select]
  irrecv.resume();
That just tells it to go get ready to receive another input. It does not determine whether any input was received, nor does it decode the results.

I think you would be far ahead if you separated the "get a value" code from the "use a value" code.

Create functions for each of the "use a value" cases. Call them when the appropriate value is present.

If you don't want to redo the function if a new value has not arrived (as in it is unlikely that "go faster" should be repeated), then, in that case, set the last value received to a do nothing value, like 0.



I will give that a try.. I guess I can separate the two, and try to call the read function separately through the code. I just have to figure out how to make the code say ' While running this fade, using the least amount of time, check the IR Rec pin and see if any of the pre-defined values have been seen, and run the loop if they have to execute the proper function'.

MrKovacic

I am off to work so I may not reply for a bit..

MrKovacic

I have been working on this and no luck..

All I need is for this script to be able to pick up an IR signal and change whats its doing while its in the middle of fading..

I'm thinking its not possible.  :~

MrKovacic

I posted this another time but no one could help due to the formatting of the code..

I have a decent script set up to blink LED's using an old blu-ray player remote. As it stands, the remote has numbered buttons, volume buttons etc.. It also has a red, green, blue and yellow button. I have it so if I push the R, G or B button, the LED of that color lights up. If I push Yellow, it shuts everything off. I am trying to incorporate fading into this, and while it will being and run the fade, it will no longer pay attention to the IR remote during the fade. I tried removing all delays, and even adding in some calls to read the IR, but no matter what I do, the Fade codes stay going until I reset the Arduino.

While any of the fades are going, I can't get Arduino to check the IR for changes.

I have 2 versions of the code, I would love for either one to work. One uses IF statements, the other uses WHILE statements:

Code: [Select]

// include
#include <IRremote.h>


int RECV_PIN = 11;
int periode = 2000;
int displace = 500;
int testtime = 1000;
long time=0;
/*  FUTURE USE
int RED1 = 2;
int GREEN1 = 3;
int BLUE1 = 4;

int RED2 = 5;
int GREEN2 = 6;
int BLUE2 = 7;

int RED3 = 8;
int GREEN3 = 9;
int BLUE3 = 10;

int RED4 = 11;
int GREEN4 = 12;
int BLUE4 = 13;
*/
int redPin = 7;   // Red LED,   connected to digital pin 9
int grnPin = 6;  // Green LED, connected to digital pin 10
int bluPin = 8;  // Blue LED,  connected to digital pin 11

int value, value2, value3 ;

int RED = 7;
int GREEN = 6;
int BLUE = 8;

// Color arrays
int black[3]  = {
 0, 0, 0 };
int white[3]  = {
 100, 100, 100 };
int red[3]    = {
 100, 0, 0 };
int green[3]  = {
 0, 100, 0 };
int blue[3]   = {
 0, 0, 100 };
int yellow[3] = {
 100, 100, 0 };
int pink[3] = {
 0, 100, 100 };
int magenta[3] = {
 100, 0, 100 };

// etc.

// Set initial color
int redVal = black[0];
int grnVal = black[1];
int bluVal = black[2];


//int wait = 2;      // no longer used

int prevR = redVal;
int prevG = grnVal;
int prevB = bluVal;
IRrecv irrecv(RECV_PIN);
decode_results results;
long previousMillis = 0;  
long interval = 1000;
long chill = 2;

int ledState = LOW; // only for BLUE LED for now, will add more later, just want to blink blue for now
int blinkone = 0;
int blinktwo= 0;
int blinkthree = 0;
int blinkfour = 0;
int blinkfive = 0;
int blinksix = 0;
int blinkseven = 0;
int blinkeight = 0;
int blinknine = 0;
int val;

void setup()
{
 pinMode(8, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(6, OUTPUT);
 irrecv.enableIRIn(); // kick on the IR receiver
}



void loop() {
 unsigned long currentMillis = millis(); // Start the arduino counting so it can keep time

 if (irrecv.decode(&results)) {
   while (results.value == 0x66B47) { // BLUE button on the remote
     digitalWrite(BLUE, HIGH);
   }
   while (results.value == 0xE6B47) { // RED button on the remote
     digitalWrite(RED, HIGH);
   }  

   while (results.value == 0x490) { // Vol Up button on the remote
     interval = interval - 50;
     if  (interval < 75) {
       interval =100;
     }
   }  

   while (results.value == 0xC90) { // Vol Down button on the remote
     interval = interval + 50;
   }  

   while (results.value == 0x290) { // Vol Down button on the remote
     interval = 1000;
   }  

   while (results.value == 0x16B47) { // GREEN button on the remote
     digitalWrite(GREEN, HIGH);
   }

   // else if (results.value == 0xB47) { // 1 button on the remote

   while (results.value == 0xB47) {
     time = millis();
     value = 128+127*cos(2*PI/periode*time);
     value2 = 128+127*cos(2*PI/periode*(displace-time));
     value3 = 128+127*cos(2*PI/periode*(testtime-time));  
     analogWrite(redPin, value);    
     analogWrite(grnPin, value2);        
     analogWrite(bluPin, value3);
     loop();
   }
   // }


   while(results.value == 0x80B47) { // 2 button on the remote

     blinkone = 1;

   }        
   while (results.value == 0x40B47) { // 3 button on the remote


   }        
   while (results.value == 0xC0B47) { // 4 button on the remote


   }        
   while (results.value == 0x20B47) { // 5 button on the remote


   }        
   while (results.value == 0xA0B47) { // 6 button on the remote


   }        
   while (results.value == 0x60B47) { // 7 button on the remote


     crossFade(red);
     crossFade(green);
     crossFade(blue);
     crossFade(yellow);
     crossFade(white);
     crossFade(pink);
     crossFade(magenta);
   }


   while (results.value == 0xE0B47) { // 8 button on the remote


   }        
   while (results.value == 0x10B47) { // 9 button on the remote


   }


   while (results.value == 0x96B47  ) { // YELLOW - shut everything off. aka blackout
     digitalWrite(BLUE, LOW);
     digitalWrite(RED, LOW);
     digitalWrite(GREEN, LOW);
     blinkone = 0;

   }
   irrecv.resume();
 }



 while (blinkone == 1) {   // First flash pattern. On and off

   if(currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;  
     if (ledState == LOW)
       ledState = HIGH;
     else
       ledState = LOW;

     digitalWrite(BLUE, ledState);
   }  
 }   //include this

}


int calculateStep(int prevValue, int endValue) {
 int step = endValue - prevValue; // What's the overall gap?
 if (step) {                      // If its non-zero,
   step = 1020/step;              //   divide by 1020
 }
 return step;
}

int calculateVal(int step, int val, int i) {

 if ((step) && i % step == 0) { // If step is non-zero and its time to change a value,
   if (step > 0) {              //   increment the value if step is positive...
     val += 1;          
   }
   else if (step < 0) {         //   ...or decrement it if step is negative
     val -= 1;
   }
 }
 // Defensive driving: make sure val stays in the range 0-255
 if (val > 255) {
   val = 255;
 }
 else if (val < 0) {
   val = 0;
 }
 return val;
}


void crossFade(int color[3]) {
 unsigned long currentMillis = millis();
 // Convert to 0-255
 int R = (color[0] * 255) / 100;
 int G = (color[1] * 255) / 100;
 int B = (color[2] * 255) / 100;

 int stepR = calculateStep(prevR, R);
 int stepG = calculateStep(prevG, G);
 int stepB = calculateStep(prevB, B);

 for (int i = 0; i <= 1020; i++) {
   redVal = calculateVal(stepR, redVal, i);
   grnVal = calculateVal(stepG, grnVal, i);
   bluVal = calculateVal(stepB, bluVal, i);

   analogWrite(redPin, redVal);   // Write current values to LED pins
   analogWrite(grnPin, grnVal);      
   analogWrite(bluPin, bluVal);

   int zag = 1;
   do {
     zag = zag + 1;
     getIR();
   }
   while (zag < 200);

 }
 // Update current values for next loop
 prevR = redVal;
 prevG = grnVal;
 prevB = bluVal;

}

void getIR() {
 IRrecv irrecv(RECV_PIN);
 decode_results nresults;
}





I am at a dead stop. I just need it to be able to switch to different modes, even while a fade is running.

Thanks in advance!

Go Up