2 * IRrecord: record and play back IR signals as a minimal
3 * An IR detector/demodulator must be connected to the input RECV_PIN.
4 * An IR LED must be connected to the output PWM pin 3.
5 * A button must be connected to the input BUTTON_PIN; this is the
7 * A visible LED can be connected to STATUS_PIN to provide status.
10 * If the button is pressed, send the IR code.
11 * If an IR code is received, record it.
13 * Version 0.11 September, 2009
14 * Copyright 2009 Ken Shirriff
24 IRrecv irrecv(RECV_PIN);
27 decode_results results;
32 irrecv.enableIRIn(); // Start the receiver
33 pinMode(BUTTON_PIN, INPUT);
34 pinMode(STATUS_PIN, OUTPUT);
37 // Storage for the recorded code
38 int codeType = -1; // The type of code
39 unsigned long codeValue; // The code value if not raw
40 unsigned int rawCodes[RAWBUF]; // The durations if raw
41 int codeLen; // The length of the code
42 int toggle = 0; // The RC5/6 toggle state
44 // Stores the code for later playback
45 // Most of this code is just logging
46 void storeCode(decode_results *results) {
47 codeType = results->decode_type;
48 int count = results->rawlen;
49 if (codeType == UNKNOWN) {
50 Serial.println("Received unknown code, saving as raw");
51 codeLen = results->rawlen - 1;
52 // To store raw codes:
53 // Drop first value (gap)
54 // Convert from ticks to microseconds
55 // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
56 for (int i = 1; i <= codeLen; i++) {
59 rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
64 rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
67 Serial.print(rawCodes[i - 1], DEC);
72 if (codeType == NEC) {
73 Serial.print("Received NEC: ");
74 if (results->value == REPEAT) {
75 // Don't record a NEC repeat value as that's useless.
76 Serial.println("repeat; ignoring.");
80 else if (codeType == SONY) {
81 Serial.print("Received SONY: ");
83 else if (codeType == RC5) {
84 Serial.print("Received RC5: ");
86 else if (codeType == RC6) {
87 Serial.print("Received RC6: ");
90 Serial.print("Unexpected codeType ");
91 Serial.print(codeType, DEC);
94 Serial.println(results->value, HEX);
95 codeValue = results->value;
96 codeLen = results->bits;
100 void sendCode(int repeat) {
101 if (codeType == NEC) {
103 irsend.sendNEC(REPEAT, codeLen);
104 Serial.println("Sent NEC repeat");
107 irsend.sendNEC(codeValue, codeLen);
108 Serial.print("Sent NEC ");
109 Serial.println(codeValue, HEX);
112 else if (codeType == SONY) {
113 irsend.sendSony(codeValue, codeLen);
114 Serial.print("Sent Sony ");
115 Serial.println(codeValue, HEX);
117 else if (codeType == RC5 || codeType == RC6) {
119 // Flip the toggle bit for a new button press
122 // Put the toggle bit into the code to send
123 codeValue = codeValue & ~(1 << (codeLen - 1));
124 codeValue = codeValue | (toggle << (codeLen - 1));
125 if (codeType == RC5) {
126 Serial.print("Sent RC5 ");
127 Serial.println(codeValue, HEX);
128 irsend.sendRC5(codeValue, codeLen);
131 irsend.sendRC6(codeValue, codeLen);
132 Serial.print("Sent RC6 ");
133 Serial.println(codeValue, HEX);
136 else if (codeType == UNKNOWN /* i.e. raw */) {
138 irsend.sendRaw(rawCodes, codeLen, 38);
139 Serial.println("Sent raw");
146 // If button pressed, send the code.
147 int buttonState = digitalRead(BUTTON_PIN);
148 if (lastButtonState == HIGH && buttonState == LOW) {
149 Serial.println("Released");
150 irrecv.enableIRIn(); // Re-enable receiver
154 Serial.println("Pressed, sending");
155 digitalWrite(STATUS_PIN, HIGH);
156 sendCode(lastButtonState == buttonState);
157 digitalWrite(STATUS_PIN, LOW);
158 delay(50); // Wait a bit between retransmissions
160 else if (irrecv.decode(&results)) {
161 digitalWrite(STATUS_PIN, HIGH);
163 irrecv.resume(); // resume receiver
164 digitalWrite(STATUS_PIN, LOW);
166 lastButtonState = buttonState;