-
Notifications
You must be signed in to change notification settings - Fork 2
/
IR_Decoder.pde
137 lines (111 loc) · 3.62 KB
/
IR_Decoder.pde
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* 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
This code is based on https://raw.github.com/adafruit/Raw-IR-decoder-for-Arduino
Modified by: Filipe Mondaini
Github: github.com/fmondaini
*/
#include <LiquidCrystal.h>
#include "ircodes.h"
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// http://arduino.cc/en/Hacking/PinMapping168 for the 'raw' pin mapping
#define IRpin_PIN PIND
#define IRpin 6
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAX_PULSE_TIME 65000
// Maximum number of pulses to be storaged in the array.
#define MAX_PULSES 34
// 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
#define ERROR_MARGIN 20
// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[MAX_PULSES][2]; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
void setup(void) {
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Decodificador IR");
lcd.setCursor(0,1);
}
void loop(void) {
int numberpulses;
numberpulses = listenForIR();
lcd.setCursor(0,1);
//TODO: Find a better solution for cleaning up the 2nd line of the lcd display
lcd.print(" ");
lcd.setCursor(0,1);
if (IRcompare(numberpulses, IRPlay)) {
lcd.print("PLAY");
}
if (IRcompare(numberpulses, IRBackward)) {
lcd.print("REWIND");
}
if (IRcompare(numberpulses, IRForward)) {
lcd.print("FORWARD");
}
if (IRcompare(numberpulses, IRVolumePlus)) {
lcd.print("VOLUME +");
}
if (IRcompare(numberpulses, IRVolumeMinus)) {
lcd.print("VOLUME -");
}
if (IRcompare(numberpulses, IRPower)) {
lcd.print("POWER");
}
}
int listenForIR(void) {
currentpulse = 0;
while (1) {
uint16_t highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
// pin is still HIGH
while (IRpin_PIN & (1 << IRpin)) {
// 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 >= MAX_PULSE_TIME) && (currentpulse != 0)) {
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);
if ((lowpulse >= MAX_PULSE_TIME) && (currentpulse != 0)) {
return currentpulse;
}
}
pulses[currentpulse][1] = lowpulse;
// we read one high-low pulse successfully, continue!
currentpulse++;
if (currentpulse >= MAX_PULSES){
return currentpulse;
}
}
}
boolean IRcompare(int numpulses, int Signal[]) {
for (int i=0; i< numpulses-1; i++) {
int oncode = pulses[i][1] * RESOLUTION / 10;
int offcode = pulses[i+1][0] * RESOLUTION / 10;
// check to make sure the error is less than ERROR_MARGIN percent
if (!(abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * ERROR_MARGIN / 100))) {
return false;
}
if (!(abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * ERROR_MARGIN / 100))) {
return false;
}
}
// Everything matched!
return true;
}