chipKIT® Development Platform

Inspired by Arduino™

About IR libraries

Created Mon, 12 Sep 2011 15:02:06 +0000 by rebeN


rebeN

Mon, 12 Sep 2011 15:02:06 +0000

Hi, I would put my robot I'm doing with Chipkit UNO32 a transmitter and infrared receiver. I'm using the Arduino environment, 2 months ago I searched libraries to use these two components but found nothing. Do you know if there is already able to use libraries and copy the TV remote and generate power? thanks

I need something like this: http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html


milos.dzaleta

Thu, 29 Sep 2011 21:01:47 +0000

And I need help about IR libraries.

Please can someone help with this library (posted in post above this) because it can't compile in ChipKit MPIDE

Thanks


Addidis

Thu, 29 Mar 2012 01:03:06 +0000

Here is a little tutorial. opps http://www.ladyada.net/learn/sensors/ir.html I used the IR detector and an IR led from radioshack and a 220 ohm resistor, this gave me like 3 feet of distance. Make sure to power the detector from 3.3v and not 5v. Then use this code.

Here is the pin chart, that shows digital pin #2 = RD8 So PIND and 2 become PORTD and 8 even though it is still pin 2 with the IR detector on it. http://www.digilentinc.com/Data/Products/CHIPKIT-UNO32/chipKIT%20Uno32%20Pinout%20Table.xls

ReadIR

/* Raw IR decoder sketch!
 
 This sketch/program uses the Arduno and a PNA4602 to 
 decode IR received. This can be used to make a IR receiver
 (by looking for a particular code)
 or transmitter (by pulsing an IR LED at ~38KHz for the
 durations detected 
 
 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      PORTD
#define IRpin          8

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

// 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

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

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

void loop(void) {
  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
     if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  // 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);
     if ((lowpulse >= MAXPULSE)  && (currentpulse != 0)) {
       printpulses();
       currentpulse=0;
       return;
     }
  }
  pulses[currentpulse][1] = lowpulse;

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

void printpulses(void) {
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
  for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.print(" usec, ");
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
    Serial.println(" usec");
  }
  
  // print it in a 'array' format
  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};");
}

You can copy the print out from above into the .h file below and run the code below to turn your tv on/off. Just read the IR code, put it in the header file, and run the code.

SendIR

// This sketch will send out a Nikon D50 trigger signal (probably works with most Nikons)
// See the full tutorial at http://www.ladyada.net/learn/sensors/ir.html
// this code is public domain, please enjoy!
#include <ircodes.h> 
int IRledPin =  7;    // LED connected to digital pin 13
 
// The setup() method runs once, when the sketch starts
 
void setup()   {                
  // initialize the IR digital pin as an output:
  pinMode(IRledPin, OUTPUT);      
 pinMode(2,INPUT);  //I have a detector plugged in here. 
  Serial.begin(9600);
}
 
void loop()                     
{
  

  Serial.println("Sending IR signal");
  SendIr(IRsignal, sizeof(IRsignal)/sizeof(int));
  delay(5*1000);  // wait 15 seconds (15 seconds * 1000 milliseconds)
  SendIr(IRsignal, sizeof(IRsignal)/sizeof(int));
  Serial.println("DONE");
  while(1){};
  
}
 
// This procedure sends a 38KHz pulse to the IRledPin 
// for a certain # of microseconds. We'll use this whenever we need to send codes
void pulseIR(long microsecs) {
  // we'll count down from the number of microseconds we are told to wait
 unsigned int x;
 unsigned int status;
 
  //cli();  // this turns off any background interrupts
 status = INTDisableInterrupts();
 
  while (microsecs > 0) {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
  // digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
    PORTDbits.RD9 = 1;
   delayMicroseconds(13);         // hang out for 10 microseconds

    PORTDbits.RD9 = 0;
 //  digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
   delayMicroseconds(13);         // hang out for 10 microseconds

   // so 26 microseconds altogether
   microsecs -= 26;
  }
 
  //sei();  // this turns them back on
  status = INTEnableInterrupts();
}


 void SendIr(const int *msg, int len){
    int x;   

    for (x = 0; x < len; x+=2){
      pulseIR(msg[x]*10);
      delayMicroseconds(msg[x+1]*10);
      }
   }

This is ircodes.h Stick it in the sketch folder for sendIR

int IRsignal[] = {
// ON, OFF
	2380, 580,

	1220, 540,

	620, 580,

	1220, 540,

	640, 560,

	1180, 580,

	640, 540,

	640, 540,

	1240, 540,

	640, 540,

	620, 560,

	640, 540,

	640, 25940,

	2360, 580,

	1220, 540,

	640, 560,

	1200, 580,

	620, 560,

	1180, 580,

	600, 580,

	640, 540,

	1180, 580,

	640, 540,

	640, 540,

	620, 580,

	600, 26000,

	2400, 540,

	1180, 580,

	640, 540,

	1200, 580,

	600, 580,

	1220, 560,

	600, 560,

	640, 540,

	1240, 540,

	600, 580,

	640, 540,

	640, 540,

	600, 26000,

	2380, 560,

	1240, 540,

	600, 580,

	1220, 560,

	640, 540,

	1200, 580,

	620, 560,

	600, 580,

	1220, 560,

	620, 560,

	600, 560,

	640, 560,

	620, 0};

I made a little improvement to how you send the codes but for the most part you should be able to follow the examples. Some remotes will not work, that was made for sony remotes.

CompareIR to stored command

/* Raw IR 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      PORTD
#define IRpin          8
#define DEBUG
// 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 "ircodes.h"

int IRledPin =  7;    // LED connected to digital pin 13


void setup(void) {
  pinMode(IRledPin, OUTPUT);
  pinMode(SW1, INPUT);
  Serial.begin(9600);
  Serial.println("Ready to decode IR!");
}

void loop(void) {
  int numberpulses;
  int x;
  numberpulses = listenForIR();
  

 
  Serial.print("Heard ");
  Serial.print(numberpulses);
  Serial.println("-pulse long IR signal");
  if (IRcompare(numberpulses, IRsignal,sizeof(IRsignal)/4)) {
    Serial.println("Detected the button you learned");
  }

 
  delay(500);
}

void pulseIR(long microsecs) {
  // we'll count down from the number of microseconds we are told to wait
 unsigned int x;
 unsigned int status;
 
  //cli();  // this turns off any background interrupts
 status = INTDisableInterrupts();
 
  while (microsecs > 0) {
    // 38 kHz is about 13 microseconds high and 13 microseconds low
  // digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
    PORTDbits.RD9 = 1;
   delayMicroseconds(13);         // hang out for 10 microseconds

    PORTDbits.RD9 = 0;
 //  digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
   delayMicroseconds(13);         // hang out for 10 microseconds

   // so 26 microseconds altogether
   microsecs -= 26;
  }
 
  //sei();  // this turns them back on
  status = INTEnableInterrupts();
}
//KGO: added size of compare sample. Only compare the minimum of the two
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(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;
    }
    
    
#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;
}

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) {
  Serial.println("\n\r\n\rReceived: \n\rOFF \tON");
  for (uint8_t i = 0; i < currentpulse; i++) {
    Serial.print(pulses[i][0] * RESOLUTION, DEC);
    Serial.print(" usec, ");
    Serial.print(pulses[i][1] * RESOLUTION, DEC);
    Serial.println(" usec");
  }
  
  // print it in a 'array' format
  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};");
}

You need a .h file in the same folder as the compare sketch too. Let me know if you have any problem I had to switch something to get the compare sketch to work proper. But I tried these as I posted them they work.


acmilangr

Mon, 09 Apr 2012 22:09:45 +0000

hi all

today i succed to make a function that dont need to loop in void loop all time

i found an old code on arduino's forum and i modified it to work as i wanted.

int getIRKey() {
  int total_length=10000;
  int header_length=7000;
  int check_on_high=3000; 
  int check_on_low=1000;
  int ir_data[12];
  int ir_result[12];
  long pulselow;

  for (int i=0;i<total_length;i++){//give time to check all pulses. becouse we dont know where the header low bit is  
        delayMicroseconds(1);
        if (digitalRead(ir_pin)==LOW){ //if you found low signal        
            pulselow=pulseIn(ir_pin,LOW);//then store in pulselow the length of pulse
            //======pulseIn can be replaced with that code>  
            //      while(digitalRead(ir_pin)==LOW){ //then store in pulselow the length of pulse
            //          pulselow++;         
            //          delayMicroseconds(1); 
            //     }
            //====================================================================           
            //if (pulselow/57>header_length){ //use this if you will dont use the pulseIn code adove
            if (pulselow>header_length){ //if this is the header pulse
                    pulselow=0;
                    for (int j=0;j<12;j++){
                       ir_data[j] = pulseIn(ir_pin, LOW);      //Start measuring bits, I only want low pulses
                    }
                    for(int i=0;i<12;i++) {		  //Parse them
                        if(ir_data[i]>check_on_high) {		  //is it a 1?
                    	ir_result[i] = 1;
                        }  else {
                        	if(ir_data[i]>check_on_low) {		//is it a 0?
                        	    ir_result[i] = 0;
                        	} else {
                        	   ir_result[i] = 2;			  //Flag the data as invalid; I don't know what it is!
                        	}
                        }
                    }
                    for(int i=0;i<12;i++) {		  //Pre-check data for errors
                        if(ir_result[i] > 1) {
                         	return -1;			     //Return -1 on invalid data
                        }
                   }
                   int result = 0;
                   int seed = 1;
                   for(int i=0;i<12;i++) {		  //Convert bits to integer
                        if(ir_result[i] == 1) {
                    	  result += seed;
                        }
                        seed = seed * 2;
                   }
                   return result;		
            }
    }
    }
}