mirror of
https://github.com/donl/IR-Commander.git
synced 2026-05-26 14:22:17 -06:00
185 lines
5.3 KiB
Text
185 lines
5.3 KiB
Text
/* 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 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 "ircodes.h"
|
|
|
|
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, ApplePlaySignal,sizeof(ApplePlaySignal)/4)) {
|
|
Serial.println("PLAY");
|
|
}
|
|
if (IRcompare(numberpulses, AppleRewindSignal,sizeof(AppleRewindSignal)/4)) {
|
|
Serial.println("REWIND");
|
|
}
|
|
if (IRcompare(numberpulses, AppleForwardSignal,sizeof(AppleForwardSignal)/4)) {
|
|
Serial.println("FORWARD");
|
|
}
|
|
delay(500);
|
|
}
|
|
|
|
//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};");
|
|
}
|
|
|