]> git.piffa.net Git - arduino/blob - books/pdummies/Libraries/IRremote/examples/IRtest2/IRtest2.ino
first commit
[arduino] / books / pdummies / Libraries / IRremote / examples / IRtest2 / IRtest2.ino
1 /*
2  * Test send/receive functions of IRremote, using a pair of Arduinos.
3  *
4  * Arduino #1 should have an IR LED connected to the send pin (3).
5  * Arduino #2 should have an IR detector/demodulator connected to the
6  * receive pin (11) and a visible LED connected to pin 3.
7  *
8  * The cycle:
9  *  Arduino #1 will wait 2 seconds, then run through the tests.
10  *  It repeats this forever.
11  *  Arduino #2 will wait for at least one second of no signal
12  *  (to synchronize with #1).  It will then wait for the same test
13  *  signals.  It will log all the status to the serial port.  It will
14  *  also indicate status through the LED, which will flash each time a test
15  *  is completed.  If there is an error, it will light up for 5 seconds.
16  *
17  * The test passes if the LED flashes 19 times, pauses, and then repeats.
18  * The test fails if the LED lights for 5 seconds.
19  *
20  * The test software automatically decides which board is the sender and which is
21  * the receiver by looking for an input on the send pin, which will indicate
22  * the sender.  You should hook the serial port to the receiver for debugging.
23  *  
24  * Copyright 2010 Ken Shirriff
25  * http://arcfn.com
26  */
27
28 #include <IRremote.h>
29
30 int RECV_PIN = 11;
31 int LED_PIN = 3;
32
33 IRrecv irrecv(RECV_PIN);
34 IRsend irsend;
35
36 decode_results results;
37
38 #define RECEIVER 1
39 #define SENDER 2
40 #define ERROR 3
41
42 int mode;
43
44 void setup()
45 {
46   Serial.begin(9600);
47   // Check RECV_PIN to decide if we're RECEIVER or SENDER
48   if (digitalRead(RECV_PIN) == HIGH) {
49     mode = RECEIVER;
50     irrecv.enableIRIn();
51     pinMode(LED_PIN, OUTPUT);
52     digitalWrite(LED_PIN, LOW);
53     Serial.println("Receiver mode");
54   } 
55   else {
56     mode = SENDER;
57     Serial.println("Sender mode");
58   }
59 }
60
61 // Wait for the gap between tests, to synchronize with
62 // the sender.
63 // Specifically, wait for a signal followed by a gap of at last gap ms.
64 void waitForGap(int gap) {
65   Serial.println("Waiting for gap");
66   while (1) {
67     while (digitalRead(RECV_PIN) == LOW) { 
68     }
69     unsigned long time = millis();
70     while (digitalRead(RECV_PIN) == HIGH) {
71       if (millis() - time > gap) {
72         return;
73       }
74     }
75   }
76 }
77
78 // Dumps out the decode_results structure.
79 // Call this after IRrecv::decode()
80 void dump(decode_results *results) {
81   int count = results->rawlen;
82   if (results->decode_type == UNKNOWN) {
83     Serial.println("Could not decode message");
84   } 
85   else {
86     if (results->decode_type == NEC) {
87       Serial.print("Decoded NEC: ");
88     } 
89     else if (results->decode_type == SONY) {
90       Serial.print("Decoded SONY: ");
91     } 
92     else if (results->decode_type == RC5) {
93       Serial.print("Decoded RC5: ");
94     } 
95     else if (results->decode_type == RC6) {
96       Serial.print("Decoded RC6: ");
97     }
98     Serial.print(results->value, HEX);
99     Serial.print(" (");
100     Serial.print(results->bits, DEC);
101     Serial.println(" bits)");
102   }
103   Serial.print("Raw (");
104   Serial.print(count, DEC);
105   Serial.print("): ");
106
107   for (int i = 0; i < count; i++) {
108     if ((i % 2) == 1) {
109       Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
110     } 
111     else {
112       Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
113     }
114     Serial.print(" ");
115   }
116   Serial.println("");
117 }
118
119
120 // Test send or receive.
121 // If mode is SENDER, send a code of the specified type, value, and bits
122 // If mode is RECEIVER, receive a code and verify that it is of the
123 // specified type, value, and bits.  For success, the LED is flashed;
124 // for failure, the mode is set to ERROR.
125 // The motivation behind this method is that the sender and the receiver
126 // can do the same test calls, and the mode variable indicates whether
127 // to send or receive.
128 void test(char *label, int type, unsigned long value, int bits) {
129   if (mode == SENDER) {
130     Serial.println(label);
131     if (type == NEC) {
132       irsend.sendNEC(value, bits);
133     } 
134     else if (type == SONY) {
135       irsend.sendSony(value, bits);
136     } 
137     else if (type == RC5) {
138       irsend.sendRC5(value, bits);
139     } 
140     else if (type == RC6) {
141       irsend.sendRC6(value, bits);
142     } 
143     else {
144       Serial.print(label);
145       Serial.println("Bad type!");
146     }
147     delay(200);
148   } 
149   else if (mode == RECEIVER) {
150     irrecv.resume(); // Receive the next value
151     unsigned long max_time = millis() + 30000;
152     Serial.print(label);
153
154     // Wait for decode or timeout
155     while (!irrecv.decode(&results)) {
156       if (millis() > max_time) {
157         Serial.println("Timeout receiving data");
158         mode = ERROR;
159         return;
160       }
161     }
162     if (type == results.decode_type && value == results.value && bits == results.bits) {
163       Serial.println (": OK");
164       digitalWrite(LED_PIN, HIGH);
165       delay(20);
166       digitalWrite(LED_PIN, LOW);
167     } 
168     else {
169       Serial.println(": BAD");
170       dump(&results);
171       mode = ERROR;
172     }
173   }
174 }
175
176 // Test raw send or receive.  This is similar to the test method,
177 // except it send/receives raw data.
178 void testRaw(char *label, unsigned int *rawbuf, int rawlen) {
179   if (mode == SENDER) {
180     Serial.println(label);
181     irsend.sendRaw(rawbuf, rawlen, 38 /* kHz */);
182     delay(200);
183   } 
184   else if (mode == RECEIVER ) {
185     irrecv.resume(); // Receive the next value
186     unsigned long max_time = millis() + 30000;
187     Serial.print(label);
188
189     // Wait for decode or timeout
190     while (!irrecv.decode(&results)) {
191       if (millis() > max_time) {
192         Serial.println("Timeout receiving data");
193         mode = ERROR;
194         return;
195       }
196     }
197
198     // Received length has extra first element for gap
199     if (rawlen != results.rawlen - 1) {
200       Serial.print("Bad raw length ");
201       Serial.println(results.rawlen, DEC);
202       mode = ERROR;
203       return;
204     }
205     for (int i = 0; i < rawlen; i++) {
206       long got = results.rawbuf[i+1] * USECPERTICK;
207       // Adjust for extra duration of marks
208       if (i % 2 == 0) { 
209         got -= MARK_EXCESS;
210       } 
211       else {
212         got += MARK_EXCESS;
213       }
214       // See if close enough, within 25%
215       if (rawbuf[i] * 1.25 < got || got * 1.25 < rawbuf[i]) {
216         Serial.println(": BAD");
217         dump(&results);
218         mode = ERROR;
219         return;
220       }
221
222     }
223     Serial.println (": OK");
224     digitalWrite(LED_PIN, HIGH);
225     delay(20);
226     digitalWrite(LED_PIN, LOW);
227   }
228 }   
229
230 // This is the raw data corresponding to NEC 0x12345678
231 unsigned int sendbuf[] = { /* NEC format */
232   9000, 4500,
233   560, 560, 560, 560, 560, 560, 560, 1690, /* 1 */
234   560, 560, 560, 560, 560, 1690, 560, 560, /* 2 */
235   560, 560, 560, 560, 560, 1690, 560, 1690, /* 3 */
236   560, 560, 560, 1690, 560, 560, 560, 560, /* 4 */
237   560, 560, 560, 1690, 560, 560, 560, 1690, /* 5 */
238   560, 560, 560, 1690, 560, 1690, 560, 560, /* 6 */
239   560, 560, 560, 1690, 560, 1690, 560, 1690, /* 7 */
240   560, 1690, 560, 560, 560, 560, 560, 560, /* 8 */
241   560};
242
243 void loop() {
244   if (mode == SENDER) {
245     delay(2000);  // Delay for more than gap to give receiver a better chance to sync.
246   } 
247   else if (mode == RECEIVER) {
248     waitForGap(1000);
249   } 
250   else if (mode == ERROR) {
251     // Light up for 5 seconds for error
252     digitalWrite(LED_PIN, HIGH);
253     delay(5000);
254     digitalWrite(LED_PIN, LOW);
255     mode = RECEIVER;  // Try again
256     return;
257   }
258
259   // The test suite.
260   test("SONY1", SONY, 0x123, 12);
261   test("SONY2", SONY, 0x000, 12);
262   test("SONY3", SONY, 0xfff, 12);
263   test("SONY4", SONY, 0x12345, 20);
264   test("SONY5", SONY, 0x00000, 20);
265   test("SONY6", SONY, 0xfffff, 20);
266   test("NEC1", NEC, 0x12345678, 32);
267   test("NEC2", NEC, 0x00000000, 32);
268   test("NEC3", NEC, 0xffffffff, 32);
269   test("NEC4", NEC, REPEAT, 32);
270   test("RC51", RC5, 0x12345678, 32);
271   test("RC52", RC5, 0x0, 32);
272   test("RC53", RC5, 0xffffffff, 32);
273   test("RC61", RC6, 0x12345678, 32);
274   test("RC62", RC6, 0x0, 32);
275   test("RC63", RC6, 0xffffffff, 32);
276
277   // Tests of raw sending and receiving.
278   // First test sending raw and receiving raw.
279   // Then test sending raw and receiving decoded NEC
280   // Then test sending NEC and receiving raw
281   testRaw("RAW1", sendbuf, 67);
282   if (mode == SENDER) {
283     testRaw("RAW2", sendbuf, 67);
284     test("RAW3", NEC, 0x12345678, 32);
285   } 
286   else {
287     test("RAW2", NEC, 0x12345678, 32);
288     testRaw("RAW3", sendbuf, 67);
289   }
290 }