IR detector Make remote controls and listeners

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
dleec45
 
Posts: 18
Joined: Tue Jun 26, 2012 3:26 pm

IR detector Make remote controls and listeners

Post by dleec45 »

Would welcome some insight on what might be going on in the project here... http://www.ladyada.net/learn/sensors/ir.html
I'm playing with the code at the bottom of the page which deals with decoding the apple remote....what I'm doing is trying to map a product like this one... https://www.adafruit.com/products/389 ....so that I can control the menu in BeerTroller instead of the knob that is currently used..the program I have is written to display what key is pressed but it only works for the first 6 buttons and I'm thinking that even though the program loads....there may be a memory issue but I don't get any errors on loading....any ideas on how i can debut this problem, not been playing with this environment that long....thanks

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: IR detector Make remote controls and listeners

Post by adafruit_support_bill »

the program I have is written to display what key is pressed but it only works for the first 6 buttons
How exactly does it fail? Does it crash completely, or does it continue to recognize only those 6?

The IR detector is somewhat noise sensitive. If you are doing this circuit on a breadboard, be sure to keep the jumpers as short as possible.

dleec45
 
Posts: 18
Joined: Tue Jun 26, 2012 3:26 pm

Re: IR detector Make remote controls and listeners

Post by dleec45 »

Well it doesn't exactly fail in the sense of crashing....there i a line of code what when every thing is initialized you see "Ready to decode IR!" in the Serial Monitor......if I don't have any of the if statements commented out and I'm trying to test the entire number of buttons on the transmitter....it just never displays that ready statement, but if I comment out everything except the first 6 it works as it should....here is a bit of the code...
See NOTE: below....that is the limit in which the program will work....any more if statements and it looks like it never initializes and displays the Ready statement...

______________________________________

[Edit - moderator - use 'code' button when submitting code]

Code: Select all

void setup(void) {
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");
}

void loop(void) {
  int numberpulses;
  
  numberpulses = listenForIR();
  
  Serial.print("Heard ");
  Serial.print(numberpulses);
  Serial.println("-pulse long IR signal");
  if (IRcompare(numberpulses, CarMP3PREV,sizeof(CarMP3PREV)/4)) {
    Serial.println("PREV");
  }
    if (IRcompare(numberpulses, CarMP3NEXT,sizeof(CarMP3NEXT)/4)) {
    Serial.println("NEXT");
  }
    if (IRcompare(numberpulses, CarMP3PLAYPAUSE,sizeof(CarMP3PLAYPAUSE)/4)) {
    Serial.println("PLAY/PAUSE");
  }
    if (IRcompare(numberpulses, CarMP3VOLmin,sizeof(CarMP3VOLmin)/4)) {
    Serial.println("VOLmin");
  }
    if (IRcompare(numberpulses, CarMP3VOLplus,sizeof(CarMP3VOLplus)/4)) {
    Serial.println("VOLplus");
  }
    if (IRcompare(numberpulses, CarMP3BEGIN,sizeof(CarMP3BEGIN)/4)) {
    Serial.println("BEGIN");  //[b] ** NOTE:  this is as far as it will work,[/b]
  }
    if (IRcompare(numberpulses, CarMP3MINUS,sizeof(CarMP3MINUS)/4)) {
    Serial.println("MINUS");
  }
    if (IRcompare(numberpulses, CarMP3PLUS,sizeof(CarMP3PLUS)/4)) {
    Serial.println("PLUS");
  }
___________________________


Regards, Lee

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: IR detector Make remote controls and listeners

Post by adafruit_support_bill »

Sounds like a memory problem. Possibly running out of RAM. You can free up some by telling the compiler to keep all your strings in Flash. This is easy in Arduino 1.0 and later using the "F()" macro as in"

Code: Select all

Serial.println(F("-pulse long IR signal"));

dleec45
 
Posts: 18
Joined: Tue Jun 26, 2012 3:26 pm

Re: IR detector Make remote controls and listeners

Post by dleec45 »

Thanks for the replies.....Inserted the code mentioned but didn't seem to change anything....the compiler gives me this info...Binary sketch size: 7,622 bytes (of a 32,256 byte maximum) to I think we have room.....here's the output from the first 7 and as you can see, only the first six give the correct reply....
Heard 34-pulse long IR signal
count set to: 34
PREV
count set to: 34
count set to: 34
count set to: 34
count set to: 34
count set to: 34
Heard 34-pulse long IR signal
count set to: 34
count set to: 34
NEXT
count set to: 34
count set to: 34
count set to: 34
count set to: 34
Heard 36-pulse long IR signal
count set to: 36
count set to: 36
count set to: 36
PLAY/PAUSE
count set to: 36
count set to: 36
count set to: 36
Heard 34-pulse long IR signal
count set to: 34
count set to: 34
count set to: 34
count set to: 34
VOLmin
count set to: 34
count set to: 34
Heard 36-pulse long IR signal
count set to: 36
count set to: 36
count set to: 36
count set to: 36
count set to: 36
VOLplus
count set to: 36
Heard 36-pulse long IR signal
count set to: 36
count set to: 36
count set to: 36
count set to: 36
count set to: 36
count set to: 36
BEGIN
Heard 36-pulse long IR signal
count set to: 36
count set to: 36
count set to: 36
count set to: 36
count set to: 36
count set to: 36

This one should have printed MINUS but none of the rest give any indication of what is being printed....maybe I should redo all the collection of data after the first six and see if that makes a different.....sound reasonable? thanks again

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: IR detector Make remote controls and listeners

Post by adafruit_support_rick »

Inserted the code mentioned but didn't seem to change anything....the compiler gives me this info...Binary sketch size: 7,622 bytes (of a 32,256 byte maximum) to I think we have room.
adafruit_support was referring to RAM, not flash. The 7,622-byte sketch is written into flash, and there are 32Kbytes of that available. However, the arduino only has 2K bytes of RAM. The strings in all of your print statements are stored in RAM, unless you use the F("…") syntax, which tells the compiler to store the string in flash.

Since you have a long set of if() statements which are all pretty much the same, and your program works with a few of them, but stops working with more of them, a RAM limitation is a reasonable conclusion.

Are you certain you modified ALL of your literal strings (i.e., anything between quote marks) to the F(" ") format?

Here's another thing to try. Pick a different six if() statements, and see if it works with those six. That will tell you if it's a problem with the code or not.

dleec45
 
Posts: 18
Joined: Tue Jun 26, 2012 3:26 pm

Re: IR detector Make remote controls and listeners

Post by dleec45 »

I didn't initially understand that you wanted all println modified but they are now....didn't make a differenc as I also check the code by commenting out everything except the last 6 and they work when depressed in any order.....but when more that 6 have been added to the if statement, the first one will work but then nothing else will happen, ie; no further response shows in the monitor...was wondering if another kind of logic would work but couldn't think of anything at the moment.....

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: IR detector Make remote controls and listeners

Post by adafruit_support_bill »

All but the first 'if' should probably be changed to 'else if'. But that wouldn't keep you from getting more than 6 cases to work.

dleec45
 
Posts: 18
Joined: Tue Jun 26, 2012 3:26 pm

Re: IR detector Make remote controls and listeners

Post by dleec45 »

Thanks again for the suggestion....did that and yes, didn't make any difference.....when nothing commented out, doesn't even give first message Serial.println(F("Ready to decode IR!")); which I find odd that it doesn't even get that far in the execution.....not being that familiar with the IDE is there a way to trace through code and see where it gets too and what is happening?

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: IR detector Make remote controls and listeners

Post by adafruit_support_rick »

It shouldn't be getting worse. Post your complete code again (use the "code" tags).

dleec45
 
Posts: 18
Joined: Tue Jun 26, 2012 3:26 pm

Re: IR detector Make remote controls and listeners

Post by dleec45 »

Here's the code.... and at the end is the .h file also is at the end....thanks

Code: Select all

/* Raw IR Car commander
 
 This sketch/program uses the Arduno and a PNA4602 to 
 decode IR received.  It then attempts to match it to a previously
 recorded IR signal
 
 Code is public domain, check out www.ladyada.net and adafruit.com
 for more tutorials! 
 */


// We need to use the 'raw' pin reading methods
// because timing is very important here and the digitalRead()
// procedure is slower!
// uint8_t IRpin = 2;
// Digital pin #2 is the same as Pin D2 see
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#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

// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 20 

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

// 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 "carmp3codes.h"

void setup(void) {
  Serial.begin(9600);
  Serial.println(F("Ready to decode IR!"));
}

void loop(void) {
  int numberpulses;
  
  numberpulses = listenForIR();
  
  Serial.print("Heard ");
  Serial.print(numberpulses);
  Serial.println(F("-pulse long IR signal")); 
  
  if (IRcompare(numberpulses, CarMP3PREV,sizeof(CarMP3PREV)/4)) {
    Serial.println(F("PREV"));
  }
    else if (IRcompare(numberpulses, CarMP3NEXT,sizeof(CarMP3NEXT)/4)) {
    Serial.println(F("NEXT"));
  }
    else if (IRcompare(numberpulses, CarMP3PLAYPAUSE,sizeof(CarMP3PLAYPAUSE)/4)) {
    Serial.println(F("PLAY/PAUSE"));
  }
    else if (IRcompare(numberpulses, CarMP3VOLmin,sizeof(CarMP3VOLmin)/4)) {
    Serial.println(F("VOLmin"));
  }
    else if (IRcompare(numberpulses, CarMP3VOLplus,sizeof(CarMP3VOLplus)/4)) {
    Serial.println(F("VOLplus"));
  }
    else if (IRcompare(numberpulses, CarMP3BEGIN,sizeof(CarMP3BEGIN)/4)) {
    Serial.println(F("BEGIN"));
  }
    else if (IRcompare(numberpulses, CarMP3MINUS,sizeof(CarMP3MINUS)/4)) {
    Serial.println(F("MINUS"));
  }
    else if (IRcompare(numberpulses, CarMP3PLUS,sizeof(CarMP3PLUS)/4)) {
    Serial.println(F("PLUS"));
  }
    else if (IRcompare(numberpulses, CarMP3EQ,sizeof(CarMP3EQ)/4)) {
    Serial.println(F("EQ"));
  }
    else if (IRcompare(numberpulses, CarMP3ZERO,sizeof(CarMP3ZERO)/4)) {
    Serial.println(F("ZERO"));
  }
    else if (IRcompare(numberpulses, CarMP3100plus,sizeof(CarMP3100plus)/4)) {
    Serial.println(F("100plus"));
  }
    else if (IRcompare(numberpulses, CarMP3200plus,sizeof(CarMP3200plus)/4)) {
    Serial.println(F("200plus"));
  }
    else if (IRcompare(numberpulses, CarMP3ONE,sizeof(CarMP3ONE)/4)) {
    Serial.println(F("ONE"));
  }
    else if (IRcompare(numberpulses, CarMP3TWO,sizeof(CarMP3TWO)/4)) {
    Serial.println(F("TWO"));
  }
    else if (IRcompare(numberpulses, CarMP3THREE,sizeof(CarMP3THREE)/4)) {
    Serial.println(F("THREE"));
  }
    else if (IRcompare(numberpulses, CarMP3FOUR,sizeof(CarMP3FOUR)/4)) {
    Serial.println(F("FOUR"));
  }
    else if (IRcompare(numberpulses, CarMP3FIVE,sizeof(CarMP3FIVE)/4)) {
    Serial.println(F("FIVE"));
  }
    else if (IRcompare(numberpulses, CarMP3SIX,sizeof(CarMP3SIX)/4)) {
    Serial.println(F("SIX"));
  }
    else if (IRcompare(numberpulses, CarMP3SEVEN,sizeof(CarMP3SEVEN)/4)) {
    Serial.println(F("SEVEN"));
  }
    else if (IRcompare(numberpulses, CarMP3EIGHT,sizeof(CarMP3EIGHT)/4)) {
    Serial.println(F("EIGHT"));
  }
    else if (IRcompare(numberpulses, CarMP3NINE,sizeof(CarMP3NINE)/4)) {
    Serial.println(F("NINE"));
  }

  delay(500);
}



Code: Select all

/******************* Car MP3 codes ************/

int CarMP3PREV[] = {
// ON, OFF (in 10's of microseconds)
	878, 436,
	56, 54,
	58, 52,
	50, 56,
	56, 54,
	58, 52,
	52, 56,
	56, 54,
	58, 52,
	50, 166,
	60, 158,
	56, 164,
	52, 166,
	58, 160,
	56, 164,
	52, 166,
	58, 160,
	56, 164,
	52, 56,
	56, 164,
	50, 58,
	56, 52,
	58, 52,
	52, 166,
	56, 54,
	52, 56,
	54, 166,
	50, 58,
	52, 168,
	50, 166,
	56, 162,
	56, 54,
	56, 162,
	54, 3890,
	874, 222,
	54, 0};

int CarMP3NEXT[] = {
	882, 432,
	60, 50,
	56, 54,
	56, 52,
	58, 52,
	54, 54,
	58, 50,
	60, 50,
	58, 52,
	56, 162,
	56, 162,
	58, 162,
	54, 164,
	56, 162,
	58, 162,
	52, 166,
	56, 160,
	60, 50,
	56, 162,
	60, 160,
	54, 54,
	58, 52,
	58, 52,
	56, 162,
	54, 54,
	54, 164,
	56, 54,
	54, 54,
	58, 162,
	52, 166,
	54, 164,
	58, 50,
	56, 162,
	60, 3884,
	882, 214,
	58, 2808,
	882, 214,
	56, 2812,
	880, 214,
	56, 0};
	
int CarMP3PLAYPAUSE[] = {
	880, 434,
	60, 50,
	56, 54,
	56, 52,
	58, 52,
	54, 56,
	56, 50,
	60, 50,
	56, 54,
	56, 162,
	56, 162,
	58, 162,
	56, 162,
	54, 164,
	58, 162,
	56, 160,
	56, 162,
	60, 160,
	56, 162,
	56, 162,
	60, 50,
	56, 54,
	54, 54,
	58, 162,
	50, 58,
	58, 50,
	56, 54,
	54, 54,
	58, 162,
	54, 164,
	56, 162,
	58, 52,
	54, 164,
	58, 3884,
	882, 214,
	58, 2808,
	882, 214,
	58, 2808,
	882, 214,
	58, 2808,
	882, 214,
	56, 0};


int CarMP3NINE[] = {
	880, 434,
	58, 50,
	56, 54,
	58, 50,
	60, 50,
	58, 52,
	56, 52,
	58, 52,
	56, 54,
	56, 160,
	56, 162,
	60, 160,
	58, 160,
	56, 162,
	60, 160,
	56, 162,
	56, 162,
	60, 50,
	56, 162,
	58, 50,
	56, 162,
	60, 50,
	56, 54,
	56, 162,
	58, 52,
	56, 162,
	56, 54,
	56, 162,
	56, 54,
	56, 160,
	56, 162,
	60, 50,
	56, 162,
	60, 3884,
	880, 216,
	56, 2810,
	880, 216,
	58, 2808,
	880, 216,
	60, 0};
Last edited by dleec45 on Sun Jul 01, 2012 11:39 am, edited 1 time in total.

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: IR detector Make remote controls and listeners

Post by adafruit_support_bill »

You probably want to put all those arrays in PROGMEM. There really isn't a lot of RAM to work with in the Arduino.
http://itp.nyu.edu/~gpv206/2008/04/maki ... o_mem.html
http://arduino.cc/en/Reference/PROGMEM

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: IR detector Make remote controls and listeners

Post by adafruit_support_rick »

Oh, yeah. That's where all your RAM is going. The reason it works with <= six commands is that the linker is smart enough to ignore the command arrays that you don't refer to. adafruit_support has it right - you need to stick all of those into PROGMEM.
PROGMEM is the flash memory on the chip. By default, all data declarations, even constants like your arrays, and even things explicity declared CONST, go into RAM. The F("…") syntax you used on the literal strings is a shortcut for declaring the strings as PROGMEM.

So, you're making something that will drive an IR-remote-controlled car?

dleec45
 
Posts: 18
Joined: Tue Jun 26, 2012 3:26 pm

Re: IR detector Make remote controls and listeners

Post by dleec45 »

Thanks a lot for your help....I'll give this a try and see how it works

dleec45
 
Posts: 18
Joined: Tue Jun 26, 2012 3:26 pm

Re: IR detector Make remote controls and listeners

Post by dleec45 »

Well after looking at the examples of how to use PROGMEM in the above examples and thinking about how to fix my problem and changing the code to read from that space, I have come to realize that I don't really have any ideas on were to start or how to deal with arrays from the set of instructions (functions) you use to deal with data in this space...after looking at the code the modification seems to only be needed in this one subroutine as follows:

Code: Select all

boolean IRcompare(int numpulses, int Signal[], int refsize) {
int count = min(numpulses,refsize);
Serial.print("count set to: ");
Serial.println(count);
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(pgm_read_word_near(Signal[i*2 + 0])_; // the ON signal we want 
	#endif   
    
    // check to make sure the error is less than FUZZINESS percent
    if ( abs(oncode - pgm_read_word_near(Signal[i*2 + 0])+ <= pgm_read_word_near((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;
    }
    
#ifdef DEBUG
    Serial.print("  \t"); // tab
    Serial.print(offcode); // the OFF signal we heard
    Serial.print(" - ");
    Serial.print(Signal[i*2 + 1]); // the OFF signal we want 
#endif    
    
if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * 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;
    	}
    
	#ifdef DEBUG
   		Serial.println();
	#endif
	}
// Everything matched!
return true;
}
for when this is called from one of the if statements as here:
if (IRcompare(numberpulses, &CarMP3PREV,sizeof(&CarMP3PREV)/4))
{
Serial.println(F("PREV"));
}
all the work is done in the IRcompare routine.....any suggestions appreciated....and as always thanks again

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”