Created Mon, 12 Sep 2011 15:02:06 +0000 by 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
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
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.
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;
}
}
}
}