Go Down

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

UKHeliBob


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.  :~

As they say at the Pantomime "Oh yes it is !"

What have you tried whilst working on this ?  Have you added some code to look for IR signals whilst the fade is going on ?  The getIR function in your code looks handy judging by its name whereas the irrecv.resume doesn't, at least for getting an IR signal.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

AWOL

Topics merged - please don't start a new thread on a still-active topic.
"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]
 if (irrecv.decode(&results)) {
   while (results.value == 0x66B47) { // BLUE button on the remote
     digitalWrite(BLUE, HIGH);
   }

You are STILL mixing GETTING a value (irrecv.decode()) with USING the value. You absolutely, positively MUST stop doing that.

Code: [Select]
 // GET a value
 if(irrecv.decode(&results))
 {
    IRVal = results.value;
 }

  // USE the value
 if(IRVal == 0x66B47) // Blue
 { // Down here where it belong
     digitalWrite(BLUE, HIGH);
 }
 // The rest of the cases


Declare IRVal as a long, global variable.

Pay attention to when it is appropriate to use if versus while. Almost all of your while statements should be if statements.

MrKovacic



Pay attention to when it is appropriate to use if versus while. Almost all of your while statements should be if statements.


The funny part is, the original code was using IF statements.

this was the original 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;
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)) {
    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);
       
      }
     
   // }


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

      blinkone = 1;

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


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


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


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


    }       
    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


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


    }


    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

    }
    irrecv.resume();
    }



  if (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 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.  :~

As they say at the Pantomime "Oh yes it is !"

What have you tried whilst working on this ?  Have you added some code to look for IR signals whilst the fade is going on ?  The getIR function in your code looks handy judging by its name whereas the irrecv.resume doesn't, at least for getting an IR signal.


I did try, but it seems like te piece of code actually doing the math acts like a delay, so the Ir rec pin will ignore what it sees. I am hoping to use the yellow button as a 'stop all' type feature. Using the blink without delay, I can interupt a standard blink, but I cant seems to slide a chunk of code into that fade. It seems like the fade either wont loop (runs through one cycle), or it will not run at all, Or.. it will continue to run ignoring any other button press I do.

UKHeliBob

If you don't insert the code to look for an IR signal the loop is not going to exit, is it ?

As a matter of interest, why all the maths ?  Will statements like these always give a result between 0 an 255 ?
Code: [Select]
        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));   
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Nick Gammon

You've ignored my comment about getIR not doing anything useful. It's nice to format the code, but don't overlook the comments about the code itself.

It looks to me like you are calling getIR inside the loop which fades LEDs, so having it work properly would be helpful.
Please post technical questions on the forum, not by personal message. Thanks!

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

MrKovacic


You've ignored my comment about getIR not doing anything useful. It's nice to format the code, but don't overlook the comments about the code itself.

It looks to me like you are calling getIR inside the loop which fades LEDs, so having it work properly would be helpful.


I'm not ignoring the comments, I was just mentioning that I was going back and forth between using IF statements and While statements. Doesn't seem to be much difference, except the IF statements work better. I can try to move the detection portion of the code to a function, then just call that function. The only thing I am having trouble with is, when I press a button on the remote, it seems like it continues with the fade math. Almost like by the time the entire code from the remote has been transmitted, the Arduino is already past the function to look for code, and is back handling math for the fade. I am wondering if it is possible at all to have it fade some LEDs and at the same time, keep an eye on the IR_RCV pin waiting for a button press.

MrKovacic


If you don't insert the code to look for an IR signal the loop is not going to exit, is it ?

As a matter of interest, why all the maths ?  Will statements like these always give a result between 0 an 255 ?
Code: [Select]
        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));   


To be honest, i am not 100% sure. I know it is a small fader for the LEDs. I have 2 faders, one I can customize nicely, and this one.

In the future, I hope to make a few scripts to blink LEDs to react to sound, but different settings.

UKHeliBob

It seems to me that one of the problems for you and those trying to help is that the current sketch is complicated to understand in its own right without trying to shoehorn reading the IR into it.  There is a lot going on in the sketch and I for one cannot see the wood for the trees.  For instance, the crossFade function is called with a parameter of color[3] but the color array is not defined in the sketch nor is there any attempt to use the value of color[3] in the function.  Needless to say the sketch will not compile.

I would suggest that you start with a much simpler sketch, get it working then add to it.  How about a sketch to respond to button presses to turn on or off a single LED ?  In my experience there is a world of difference between trying to understand and modify a program written by someone else and writing one yourself.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

MrKovacic


It seems to me that one of the problems for you and those trying to help is that the current sketch is complicated to understand in its own right without trying to shoehorn reading the IR into it.  There is a lot going on in the sketch and I for one cannot see the wood for the trees.  For instance, the crossFade function is called with a parameter of color[3] but the color array is not defined in the sketch nor is there any attempt to use the value of color[3] in the function.  Needless to say the sketch will not compile.

I would suggest that you start with a much simpler sketch, get it working then add to it.  How about a sketch to respond to button presses to turn on or off a single LED ?  In my experience there is a world of difference between trying to understand and modify a program written by someone else and writing one yourself.


This script is more of a Frankenstein. Parts of it were inspired from other code. I am going to explore using a pin change interrupter to do the dirty work of the yellow button which is, for the time being, my all stop button. Because I have no formal or book training, I write code based on my thought pattern which is much like RAM on any computer, all over the place.

I will explore other options and start a new thread with simpler easier to understand code if I get stuck.  Thanks!

Nick Gammon

Code: [Select]

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);

  }


There is nothing in that loop (from 0 to 1020) that leaves the loop early (if you press a button on the remote or for any other reason). You need to address that first.




Code: [Select]
    int zag = 1;
    do {
      zag = zag + 1;
      getIR();
    }
    while (zag < 200);


What does that do? It gets the IR remote value 199 times. Why? Why not once?




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


You are making a second instance of irrecv (the first being global) which is then immediately destroyed. The value nresults is not used anywhere.
Please post technical questions on the forum, not by personal message. Thanks!

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

MrKovacic

Since I don't know or dont fully understand how to get it to check for that push in t he middle of a fade. I decided to try an interupt, which did not help. Here is the new code, and I cleaned it up using AutoIT Cleaner:

Any thoughts would be greatly appreciated

Code: [Select]

#include <IRremote.h>
int pbIn                    = 0;
volatile int state          = LOW;
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;
int grnPin                  = 6;
int bluPin                  = 8;
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 prevR                   = redVal;
int prevG                   = grnVal;
int prevB                   = bluVal;
long previousMillis         = 0;
long interval               = 1000;
long chill                  = 2;
int ledState                = LOW;
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;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup(){
attachInterrupt(pbIn, CheckYellow, HIGH);
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
pinMode(6, OUTPUT);
irrecv.enableIRIn();
}
void loop() {
unsigned long currentMillis = millis();
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);
analogWrite(grnPin, value2);
analogWrite(bluPin, value3);
}
}
else if (results.value      == 0x80B47) { // 2 button on the remote
blinkone                    = 1;
}
else if (results.value      == 0x40B47) { // 3 button on the remote
}
else if (results.value      == 0xC0B47) { // 4 button on the remote
}
else if (results.value      == 0x20B47) { // 5 button on the remote
}
else if (results.value      == 0xA0B47) { // 6 button on the remote
}
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
}
else if (results.value      == 0x10B47) { // 9 button on the remote
}
else if (results.value      == 0x96B47 ) { // YELLOW - shut everything off. aka blackout
digitalWrite(BLUE, LOW);
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
blinkone                    = 0;
}
if (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;
if (step) { // If its non-zero,
step                        = 1020/step;
}
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 CheckYellow() {
if (results.value           == 0x96B47 ) {
loop();
}
}

void crossFade(int color[3]) {
  // 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);
}
}

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

MrKovacic

I have also tried setting the function like this:

Code: [Select]

void getIR() {
IRrecv irrecv(RECV_PIN);
if (irrecv.decode(&results)){

  loop();

}}


and tried

Code: [Select]

void getIR() {
IRrecv irrecv(RECV_PIN);
if (irrecv.decode(&results)){
if (results.value == 0x96B47  ) {
  loop();
}
}}


and putting

Code: [Select]

getIR();


in various places in the fade function. The only 2 things that happen are either the fade doesnt work at all, or it works fine but refuses to stop for the yellow button.

michinyon

you got the part in there  which says

if ( ir value ==  some value )
{
     while (ir value == some value)
     {
          // doing something here

     }

}


and that is not going to work  unless sometime is updating the value of "ir value"
You either need an interrupt code which is going to possible change this while the  while() loop is running,
or else you need so code inside the while() loop  which might change that ir value variable.

If it is there, I don't see it.   Which could explain why that bit keeps on running indefinitely.







UKHeliBob

If I am reading your code right you have

Code: [Select]
attachInterrupt(pbIn, CheckYellow, HIGH);

pbIn is set to 0 so I interpret that as "call the CheckYellow function when the pin associated with interrupt 0 is HIGH"
Although I freely admit that I am not familiar with interrupts, reading the reference pages I see that interrupt 0 is associated with pin 2 and that the possible values of the third parameter of attachInterrupt() are LOW, CHANGE, RISING OR FALLING.

Have you got anything attached to pin 2 ?
What will happen with the parameter set to HIGH ?

If the interrupt ever causes the CheckYellow function to be called

Code: [Select]
void CheckYellow() {
  if (results.value           == 0x96B47 ) {
    loop();
  }
}

This calls the loop() function.  What is that all about ?

Your code won't compile for me because I don't have the library but there are also other errors reported

Code: [Select]
sketch_jan16a:69: error: 'IRrecv' does not name a type
sketch_jan16a:70: error: 'decode_results' does not name a type
sketch_jan16a.ino: In function 'void setup()':
sketch_jan16a:76: error: 'irrecv' was not declared in this scope
sketch_jan16a.ino: In function 'void loop()':
sketch_jan16a:80: error: 'irrecv' was not declared in this scope
sketch_jan16a:80: error: 'results' was not declared in this scope
sketch_jan16a.ino: In function 'void CheckYellow()':
sketch_jan16a:184: error: 'results' was not declared in this scope
sketch_jan16a.ino: In function 'void getIR()':
sketch_jan16a:211: error: 'IRrecv' was not declared in this scope
sketch_jan16a:211: error: expected `;' before 'irrecv'
sketch_jan16a:212: error: 'decode_results' was not declared in this scope
sketch_jan16a:212: error: expected `;' before 'nresults'


Your code has got so mangled through attempts to fix problems that it is practically unreadable.  Can I suggest that you create an example of what you want to do, keeping it as simple as possible as I for one cannot see the wood for the trees.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Go Up