IR Commander Code Issue

Hey Guys,

I am following this Sensor tutorials - IR remote receiver/decoder tutorial tutorial and I have been able to detect all the apple remote buttons and print to the serial to confirm :slight_smile:

However, on adding a second remote (for a bose sounddock) I’m having issues. I have managed to get one button working but not a second, something strange is happening in my code and was wondering if the same thing has happened to anyone else…

The code is below, and works like a charm when:

//  if (IRcompare(numberpulses, BoseSDVolDown, sizeof(BoseSDVolDown)/4)) {
 //  Serial.println("BOSE Vol Down");
//  }

is commented out; i can communicate with the board via Serial and detect IR signals. However, when I try and add that BoseSDVolDown comparison it all goes Pete Tong…I can no longer connect via Serial as i’m faced with just a white box most of the time and sometimes the setup initialises but then the board constantly resets when it first calls the loop. Commenting the 1st (and obviously 3rd) lines brings it back to life!

I can’t see what the problem is, it is the same logic/code for all the other IR signal but this one gives me trouble! I would appreciate any advice or pointers why this doesn’t work.

Main

// #define DEBUG

#define IRpin_PIN      PIND
#define IRpin          2

// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 65000
#define NUMPULSES 50

#define RESOLUTION 20 

// What percent we will allow in variation to match the same code
#define FUZZINESS 10

// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[NUMPULSES][2];  // pair is high and low pulse 
uint8_t currentpulse = 0; // index for pulses we're storing

 #include "ircodes.h" // list of remote codes



void setup(void) {
 
  Serial.begin(9600);
  Serial.println("Ready and Waiting...");
}

void loop(void) {
  
  
  int numberpulses;
    
  numberpulses = listenForIR();
  
   
  Serial.print("Heard ");
  Serial.print(numberpulses);
  Serial.println("-pulse long IR signal");
  
  printpulses();
  
  if (IRcompare(numberpulses, AppleMenuSignal,sizeof(AppleMenuSignal)/4)) {
    Serial.println("APPLE MENU");
  }
  
   if (IRcompare(numberpulses, ApplePlaySignal,sizeof(ApplePlaySignal)/4)) {
    Serial.println("APPLE PLAY / PAUSE");
   }
     if (IRcompare(numberpulses, AppleLeftSignal,sizeof(AppleLeftSignal)/4)) {
   Serial.println("APPLE LEFT");
   }
   
  if (IRcompare(numberpulses, AppleRightSignal,sizeof(AppleRightSignal)/4)) {
    Serial.println("APPLE RIGHT");
    
  } 
      if (IRcompare(numberpulses, AppleUpSignal,sizeof(AppleUpSignal)/4)) {
    Serial.println("APPLE UP");
      
  } 
      if (IRcompare(numberpulses, AppleDownSignal,sizeof(AppleDownSignal)/4)) {
   Serial.println("APPLE DOWN");
   
  } 
      if (IRcompare(numberpulses, AppleCentreSignal,sizeof(AppleCentreSignal)/4)) {
    Serial.println("APPLE CENTRE");
   } 
  
   if (IRcompare(numberpulses, BoseSoundDockOff, sizeof(BoseSoundDockOff)/4)) {
    Serial.println("BOSE OFF");
  }
  
 //  if (IRcompare(numberpulses, BoseSDVolDown, sizeof(BoseSDVolDown)/4)) {
 //  Serial.println("BOSE Vol Down");
//  }

  
  delay(500);
  
}

//-IR COMPARE -//

boolean IRcompare(int numpulses, int Signal[], int refsize) {
  
  int count = min(numpulses , refsize); 
  
 
  for (int i=0; i< count-1; i++) {
    int oncode = pulses[i][1] * RESOLUTION / 10;
    int offcode = pulses[i+1][0] * RESOLUTION / 10;
    
#ifdef DEBUG    
    Serial.print(oncode); // the ON signal we heard
    Serial.print(" - ");
    Serial.print(Signal[i*2 + 0]); // the ON signal we want 
#endif   
    
    // check to make sure the error is less than FUZZINESS percent
    if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
#ifdef DEBUG
      Serial.print(" (ok)");
#endif
    } else {
#ifdef DEBUG
      Serial.print(" (x)");
#endif
      // we didn't match perfectly, return a false match
       
      return false;}
     
    

    
    if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
   } else {
     // we didn't match perfectly, return a false match
            return false;
    }
    
 }
  // Everything matched!
  return true;
}

//-LISTEN FOR IR-//

int listenForIR(void) {
  currentpulse = 0;
  
  while (1) {
    uint16_t highpulse, lowpulse;  // temporary storage timing
    highpulse = lowpulse = 0; // start out with no pulse length
  
//  while (digitalRead(IRpin)) { // this is too slow!
    while (IRpin_PIN & (1 << IRpin)) {
       // pin is still HIGH

       // count off another few microseconds
       highpulse++;
       delayMicroseconds(RESOLUTION);

       // If the pulse is too long, we 'timed out' - either nothing
       // was received or the code is finished, so print what
       // we've grabbed so far, and then reset
       
       // KGO: Added check for end of receive buffer
       if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
         return currentpulse;
       }
    }
    // we didn't time out so lets stash the reading
    pulses[currentpulse][0] = highpulse;
  
    // same as above
    while (! (IRpin_PIN & _BV(IRpin))) {
       // pin is still LOW
       lowpulse++;
       delayMicroseconds(RESOLUTION);
        // KGO: Added check for end of receive buffer
        if (((lowpulse >= MAXPULSE)  && (currentpulse != 0))|| currentpulse == NUMPULSES) {
         return currentpulse;
       }
    }
    pulses[currentpulse][1] = lowpulse;

    // we read one high-low pulse successfully, continue!
    currentpulse++;
  }
}

void printpulses(void) {
  
  // print it in a 'array' format
  Serial.println("Recieved Following IR");
  Serial.println("int IRsignal[] = {");
  Serial.println("// ON, OFF (in 10's of microseconds)");
  for (uint8_t i = 0; i < currentpulse-1; i++) {
    Serial.print("\t"); // tab
    Serial.print(pulses[i][1] * RESOLUTION / 10, DEC);
    Serial.print(", ");
    Serial.print(pulses[i+1][0] * RESOLUTION / 10, DEC);
    Serial.println(",");
  }
  Serial.print("\t"); // tab
  Serial.print(pulses[currentpulse-1][1] * RESOLUTION / 10, DEC);
  Serial.print(", 0};");
  Serial.println("");
}

ircodes.h

int AppleMenuSignal[] = {

// ON, OFF (in 10's of microseconds)

	896, 436,
	58, 52,
	60, 160,
	58, 160,
	58, 160,
	60, 52,
	58, 160,
	58, 160,
	60, 158,
	60, 160,
	58, 160,
	58, 162,
	58, 52,
	58, 52,
	58, 52,
	58, 52,
	58, 160,
	60, 160,
	58, 160,
	58, 52,
	58, 52,
	60, 50,
	60, 50,
	60, 50,
	60, 50,
	60, 52,
	58, 160,
	58, 52,
	58, 52,
	58, 52,
	60, 158,
	60, 160,
	58, 54,
	58, 0};

int ApplePlaySignal[] = {

// ON, OFF (in 10's of microseconds)

	898, 436,
	58, 52,
	58, 160,
	58, 162,
	58, 160,
	58, 52,
	58, 160,
	60, 160,
	58, 160,
	58, 160,
	60, 160,
	58, 160,
	58, 52,
	58, 52,
	56, 54,
	58, 52,
	58, 162,
	58, 160,
	58, 160,
	60, 160,
	56, 162,
	58, 162,
	58, 52,
	54, 164,
	58, 52,
	58, 52,
	60, 158,
	60, 50,
	60, 52,
	58, 52,
	58, 160,
	58, 160,
	60, 52,
	56, 3562,
	892, 438,
	58, 52,
	58, 160,
	58, 160,
	60, 160,
	58, 52,
	58, 160,
	60, 160,
	58, 160,
	58, 162,
	58, 160,
	58, 160,
	60, 50,
	60, 50,
	60, 50,
	60, 52,
	58, 160,
	58, 160,
	58, 54,
	58, 160,
	58, 52,
	56, 54,
	58, 52,
	58, 52,
	56, 54,
	60, 50,
	56, 164,
	58, 52,
	58, 52,
	58, 52,
	58, 160,
	60, 160,
	58, 54,
	58, 0};

// other apple ones excluded to save space


int BoseSoundDockOff[] = {
// ON, OFF (in 10's of microseconds)

	104, 138,
	56, 40,
	56, 40,
	56, 138,
	54, 138,
	56, 40,
	56, 40,
	56, 138,
	54, 42,
	54, 138,
	56, 138,
	56, 40,
	54, 42,
	54, 138,
	56, 138,
	54, 42,
	54, 138,
	56, 4884};

int BoseSDVolDown[] = {
// ON, OFF (in 10's of microseconds)

	101, 134,
	54, 40,
	54, 134,
	54, 40,
	53, 41,
	53, 40,
	53, 41,
	53, 40,
	54, 40,
	53, 135,
	53, 40,
	54, 135,
	53, 135,
	53, 135,
	54, 134,
	54, 135,
        54, 133,
	54, 4768};

Here is an example of the output in the serial monitor when it’s behaving…

Ready and Waiting...
Heard 36-pulse long IR signal
Recieved Following IR
int IRsignal[] = {
// ON, OFF (in 10's of microseconds)
	884, 430,
	58, 52,
	56, 160,
	56, 160,
	56, 158,
	58, 52,
	58, 158,
	58, 156,
	60, 158,
	56, 158,
	58, 158,
	58, 158,
	58, 52,
	58, 50,
	58, 50,
	58, 52,
	56, 160,
	58, 156,
	58, 52,
	58, 50,
	58, 158,
	58, 52,
	56, 52,
	58, 50,
	58, 52,
	56, 52,
	58, 158,
	58, 50,
	58, 52,
	58, 50,
	58, 158,
	58, 158,
	58, 52,
	58, 3934,
	880, 214,
	58, 0};
APPLE LEFT

I suspect you are running out of memory. Without seeing all the codes it is hard to be certain, but I count up 120 bytes for just the first one, and you have quite a few. You only have 2048 bytes of RAM.

I suggest you look up PROGMEM and make those arrays PROGMEM ones, that saves them having to be copied into RAM.

http://arduino.cc/en/Reference/PROGMEM