Help with IR Remote code, Mega2560-TLC5940-RBGs

Hello and thank you for your time,

I need a little help/direction with my IR remote code. I made a simplified working sketch of what I am trying to do. In the included sketch there are two functions that I would like to call by using an IR remote. The functions work well on their own but when I put them into a switch case statement for the IR remote it only runs the first millisecond (or so) of the function and stops. If I keep pushing the button it will run a little more with each button push. I need a way to write the sketch so it will loop the function while also check for additional IR button presses.

#include "Tlc5940.h" 
#include <IRremote.h>

int RECV_PIN = 46;
IRrecv irrecv(RECV_PIN);
decode_results results;


unsigned long previousMillis1 = 0;        
unsigned long interval1 = 10;                  
int fadeValue1 = 0;

int redfadeValue1 = 0;
int greenfadeValue1 = 0;
int bluefadeValue1 = 0;

int led1State = 0;
boolean next1 = false;




void setup(){
  
  Serial.begin(9600);
  irrecv.enableIRIn();
  Tlc.init();         
  led1State = 0;

}


void loop()   
{


  if (irrecv.decode(&results)) {

    switch(results.value) {
    case 0xFF6897: 
      Serial.println("1");  
      test1(); 
      break; 
    case 0xFF9867: 
      Serial.println("2");  
      test2(); 
      break; 

    }

    irrecv.resume(); 
  }

}




void test1(){ 

  switch (led1State) {
  case 0: 
    {    
      interval1 = 4;          
      magentaOn1();
      if (next1){
        next1 = false;
        led1State = 1;
      }
      break; 
    }



  case 1: 
    {    
      interval1 = 6;          
      magentaOff1();
      if (next1){
        next1 = false;
        led1State = 2;
      }
      break; 
    }



  case 2: 
    {    
      interval1 = 7;          
      blueOn1();
      if (next1){
        next1 = false;
        led1State = 3;
      }
      break; 
    }



  case 3: 
    {    
      interval1 = 6;          
      blueOff1();
      if (next1){
        next1 = false;
        led1State = 0;
      }
      break; 
    }

  }
}


void test2(){

  switch (led1State) {


  case 0: 
    {
      interval1 = 2;          
      whiteOn1();
      if (next1){
        next1 = false;
        led1State = 1;
      }
      break; 
    }


  case 1: 
    {
      interval1 = 8;          
      whiteOff1();
      if (next1){
        next1 = false;
        led1State = 2;
      }
      break; 
    }

  case 2: 
    {
      interval1 = 4;          
      blueOn1();
      if (next1){
        next1 = false;
        led1State = 3;
      }
      break; 
    }


  case 3: 
    {
      interval1 = 8;          
      blueOff1();
      if (next1){
        next1 = false;
        led1State = 0;
      }
      break; 
    }
  }
}



void blueOn1(){  
  unsigned long currentMillis1 = millis();                      
  if(currentMillis1 - previousMillis1 > interval1) { 
    previousMillis1 = currentMillis1;   
    if(bluefadeValue1 <= 4000, bluefadeValue1 +=5) {

      Tlc.set(2, bluefadeValue1);                

    }
    Tlc.update(); 
  }
  if(bluefadeValue1 >= 4000){
    next1 = true;
  }  
}




void blueOff1(){ 
  unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > interval1) { 
    previousMillis1 = currentMillis1;
    if(bluefadeValue1 >=0, bluefadeValue1 -=5){

      Tlc.set(2, bluefadeValue1);              

    }
    Tlc.update();
  } 
  if(bluefadeValue1 <= 0){
    next1 = true;
  }
}


void whiteOn1(){  
  unsigned long currentMillis1 = millis();                      
  if(currentMillis1 - previousMillis1 > interval1) { 
    previousMillis1 = currentMillis1;   
    if(redfadeValue1 <= 2000, redfadeValue1 +=5, greenfadeValue1 <= 2000, greenfadeValue1 +=5, bluefadeValue1 <= 2000, bluefadeValue1 +=5) {

      Tlc.set(0, redfadeValue1);                
      Tlc.set(1, greenfadeValue1);
      Tlc.set(2, bluefadeValue1); 

    }
    Tlc.update(); 
  }
  if(redfadeValue1 >= 2000){
    next1 = true;
  }  
}




void whiteOff1(){ 
  unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > interval1) { 
    previousMillis1 = currentMillis1;
    if(redfadeValue1 >=0, redfadeValue1 -=5, greenfadeValue1 >=0, greenfadeValue1 -=5, bluefadeValue1 >=0, bluefadeValue1 -=5){

      Tlc.set(0, redfadeValue1);              
      Tlc.set(1, greenfadeValue1); 
      Tlc.set(2, bluefadeValue1);

    }
    Tlc.update();
  } 
  if(redfadeValue1 <= 0){
    next1 = true;
  }
}



void magentaOn1(){  
  unsigned long currentMillis1 = millis();                      
  if(currentMillis1 - previousMillis1 > interval1) { 
    previousMillis1 = currentMillis1;   
    if(redfadeValue1 <= 4000, redfadeValue1 +=5, bluefadeValue1 <= 4000, bluefadeValue1 +=5) {

      Tlc.set(0, redfadeValue1);                
      Tlc.set(2, bluefadeValue1); 


    }
    Tlc.update(); 
  }
  if(bluefadeValue1 >= 4000){
    next1 = true;
  }  
}




void magentaOff1(){ 
  unsigned long currentMillis1 = millis();
  if(currentMillis1 - previousMillis1 > interval1) { 
    previousMillis1 = currentMillis1;
    if(redfadeValue1 >=0, redfadeValue1 -=5, bluefadeValue1 >=0, bluefadeValue1 -=5){

      Tlc.set(0, redfadeValue1);              
      Tlc.set(2, bluefadeValue1); 

    }
    Tlc.update();
  } 
  if(bluefadeValue1 <= 0){
    next1 = true;
  }
}

I was reading your code until the WTF light came on:

    if(redfadeValue1 <= 4000, redfadeValue1 +=5, bluefadeValue1 <= 4000, bluefadeValue1 +=5) {

This is nonsense.

PaulS,

How is it nonsense? It is used to manually fade my TLC5940. It is pretty similar to the arduino pwm fading example. And it works for what I need. If you have a better way to fade 10 RGBs at the same time with different intervals and without using tlc_addFade I'd be curious to see it.

http://arduino.cc/en/tutorial/fading

But anyways, I still need help. I have spent ~100 hours just getting to this point in my project and I am pretty stuck and can not figure out a way to call a function with an IR remote and have it run while still checking for additional IR inputs.

Any help at all is much appreciated.

How is it nonsense?

Perhaps it isn't. Perhaps it's simply lucky that it does what you expect, and doesn't cause detectable side effects. But, I'd never write code like that, because I know what the comma operator does, and doesn't do.

What do you think the statement is doing? And, as importantly, why not use a more conventional structure?

I am still pretty new to arduino and definitely new to C.

But as I read it, it says something like:

If redValue PWM is less or equal to 4000, increment it by 5 until it is 4000
and
If blueValue PWM is less or equal to 4000, increment it by 5 until it is 4000

I am too green and not clever enough to find a better way to write it. It has taken me forever to get to this point. It does work though. In my current sketch (~60,000 bytes) there are 10 RGBs, each has its own switch case to fade it in and out of different colors (similar to test1(); and test2(); in the sketch above) at different intervals and each switch case has 23 cases, so 10 RGBs x 23 cases = 230 cases for a function and everything does what I want.

The problem is I want to have more than one 230 caser to choose from with my IR remote.

Using the code from below, (and this is obvious) if I were to take out irrecv.resume(); I would be able to push a button and run/loop the entire associated function but (obvious part) I am not able to call the next function with the IR remote. Now if I put the irrecv.resume(); back in to the sketch and push a button it runs the first case and holds. I need a way to call a function with the IR remote, let that function loop until another function is called with the remote.

If redValue PWM is less or equal to 4000, increment it by 5 until it is 4000

No. Only a for loop or a while statement iterates until some condition is met/no longer met.

If you don't mind the fact that the IR sensor is not read often, leave the code the way it is. If the infrequent reads means that you miss a remote switch press (and they do), then you need to do something different. Typically, that means that you separate the reading of the IR data from doing something based on the IR data read AND that something is NOT blocking.

You need a state machine, to call the appropriate function, AND you need state machines in each function to determine what to do on any given iteration of the function.

Paul,

Thank you.

That is curious that arduino would use an if statement to

iterates until some condition is met/no longer met

in the http://arduino.cc/en/tutorial/fading pwm fade example.

I appreciate the direction. I will get back at it after work.

God bless the Northwest!

That is curious that arduino would use an if statement to

Need glasses? There is not an if statement anywhere in that code.