]> git.piffa.net Git - arduino/blob - books/pdummies/Libraries/IRremote/IRremote.cpp
first commit
[arduino] / books / pdummies / Libraries / IRremote / IRremote.cpp
1 /*
2  * IRremote
3  * Version 0.11 August, 2009
4  * Copyright 2009 Ken Shirriff
5  * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
6  *
7  * Modified by Paul Stoffregen <paul@pjrc.com> to support other boards and timers
8  * Modified  by Mitra Ardron <mitra@mitra.biz> 
9  * Added Sanyo and Mitsubishi controllers
10  * Modified Sony to spot the repeat codes that some Sony's send
11  *
12  * Interrupt code based on NECIRrcv by Joe Knapp
13  * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556
14  * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/
15  *
16  * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
17  */
18
19 #include "IRremote.h"
20 #include "IRremoteInt.h"
21
22 // Provides ISR
23 #include <avr/interrupt.h>
24
25 volatile irparams_t irparams;
26
27 // These versions of MATCH, MATCH_MARK, and MATCH_SPACE are only for debugging.
28 // To use them, set DEBUG in IRremoteInt.h
29 // Normally macros are used for efficiency
30 #ifdef DEBUG
31 int MATCH(int measured, int desired) {
32   Serial.print("Testing: ");
33   Serial.print(TICKS_LOW(desired), DEC);
34   Serial.print(" <= ");
35   Serial.print(measured, DEC);
36   Serial.print(" <= ");
37   Serial.println(TICKS_HIGH(desired), DEC);
38   return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);
39 }
40
41 int MATCH_MARK(int measured_ticks, int desired_us) {
42   Serial.print("Testing mark ");
43   Serial.print(measured_ticks * USECPERTICK, DEC);
44   Serial.print(" vs ");
45   Serial.print(desired_us, DEC);
46   Serial.print(": ");
47   Serial.print(TICKS_LOW(desired_us + MARK_EXCESS), DEC);
48   Serial.print(" <= ");
49   Serial.print(measured_ticks, DEC);
50   Serial.print(" <= ");
51   Serial.println(TICKS_HIGH(desired_us + MARK_EXCESS), DEC);
52   return measured_ticks >= TICKS_LOW(desired_us + MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS);
53 }
54
55 int MATCH_SPACE(int measured_ticks, int desired_us) {
56   Serial.print("Testing space ");
57   Serial.print(measured_ticks * USECPERTICK, DEC);
58   Serial.print(" vs ");
59   Serial.print(desired_us, DEC);
60   Serial.print(": ");
61   Serial.print(TICKS_LOW(desired_us - MARK_EXCESS), DEC);
62   Serial.print(" <= ");
63   Serial.print(measured_ticks, DEC);
64   Serial.print(" <= ");
65   Serial.println(TICKS_HIGH(desired_us - MARK_EXCESS), DEC);
66   return measured_ticks >= TICKS_LOW(desired_us - MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS);
67 }
68 #endif
69
70 void IRsend::sendNEC(unsigned long data, int nbits)
71 {
72   enableIROut(38);
73   mark(NEC_HDR_MARK);
74   space(NEC_HDR_SPACE);
75   for (int i = 0; i < nbits; i++) {
76     if (data & TOPBIT) {
77       mark(NEC_BIT_MARK);
78       space(NEC_ONE_SPACE);
79     } 
80     else {
81       mark(NEC_BIT_MARK);
82       space(NEC_ZERO_SPACE);
83     }
84     data <<= 1;
85   }
86   mark(NEC_BIT_MARK);
87   space(0);
88 }
89
90 void IRsend::sendSony(unsigned long data, int nbits) {
91   enableIROut(40);
92   mark(SONY_HDR_MARK);
93   space(SONY_HDR_SPACE);
94   data = data << (32 - nbits);
95   for (int i = 0; i < nbits; i++) {
96     if (data & TOPBIT) {
97       mark(SONY_ONE_MARK);
98       space(SONY_HDR_SPACE);
99     } 
100     else {
101       mark(SONY_ZERO_MARK);
102       space(SONY_HDR_SPACE);
103     }
104     data <<= 1;
105   }
106 }
107
108 void IRsend::sendRaw(unsigned int buf[], int len, int hz)
109 {
110   enableIROut(hz);
111   for (int i = 0; i < len; i++) {
112     if (i & 1) {
113       space(buf[i]);
114     } 
115     else {
116       mark(buf[i]);
117     }
118   }
119   space(0); // Just to be sure
120 }
121
122 // Note: first bit must be a one (start bit)
123 void IRsend::sendRC5(unsigned long data, int nbits)
124 {
125   enableIROut(36);
126   data = data << (32 - nbits);
127   mark(RC5_T1); // First start bit
128   space(RC5_T1); // Second start bit
129   mark(RC5_T1); // Second start bit
130   for (int i = 0; i < nbits; i++) {
131     if (data & TOPBIT) {
132       space(RC5_T1); // 1 is space, then mark
133       mark(RC5_T1);
134     } 
135     else {
136       mark(RC5_T1);
137       space(RC5_T1);
138     }
139     data <<= 1;
140   }
141   space(0); // Turn off at end
142 }
143
144 // Caller needs to take care of flipping the toggle bit
145 void IRsend::sendRC6(unsigned long data, int nbits)
146 {
147   enableIROut(36);
148   data = data << (32 - nbits);
149   mark(RC6_HDR_MARK);
150   space(RC6_HDR_SPACE);
151   mark(RC6_T1); // start bit
152   space(RC6_T1);
153   int t;
154   for (int i = 0; i < nbits; i++) {
155     if (i == 3) {
156       // double-wide trailer bit
157       t = 2 * RC6_T1;
158     } 
159     else {
160       t = RC6_T1;
161     }
162     if (data & TOPBIT) {
163       mark(t);
164       space(t);
165     } 
166     else {
167       space(t);
168       mark(t);
169     }
170
171     data <<= 1;
172   }
173   space(0); // Turn off at end
174 }
175 void IRsend::sendPanasonic(unsigned int address, unsigned long data) {
176     enableIROut(35);
177     mark(PANASONIC_HDR_MARK);
178     space(PANASONIC_HDR_SPACE);
179     
180     for(int i=0;i<16;i++)
181     {
182         mark(PANASONIC_BIT_MARK);
183         if (address & 0x8000) {
184             space(PANASONIC_ONE_SPACE);
185         } else {
186             space(PANASONIC_ZERO_SPACE);
187         }
188         address <<= 1;        
189     }    
190     for (int i=0; i < 32; i++) {
191         mark(PANASONIC_BIT_MARK);
192         if (data & TOPBIT) {
193             space(PANASONIC_ONE_SPACE);
194         } else {
195             space(PANASONIC_ZERO_SPACE);
196         }
197         data <<= 1;
198     }
199     mark(PANASONIC_BIT_MARK);
200     space(0);
201 }
202 void IRsend::sendJVC(unsigned long data, int nbits, int repeat)
203 {
204     enableIROut(38);
205     data = data << (32 - nbits);
206     if (!repeat){
207         mark(JVC_HDR_MARK);
208         space(JVC_HDR_SPACE); 
209     }
210     for (int i = 0; i < nbits; i++) {
211         if (data & TOPBIT) {
212             mark(JVC_BIT_MARK);
213             space(JVC_ONE_SPACE); 
214         } 
215         else {
216             mark(JVC_BIT_MARK);
217             space(JVC_ZERO_SPACE); 
218         }
219         data <<= 1;
220     }
221     mark(JVC_BIT_MARK);
222     space(0);
223 }
224 void IRsend::mark(int time) {
225   // Sends an IR mark for the specified number of microseconds.
226   // The mark output is modulated at the PWM frequency.
227   TIMER_ENABLE_PWM; // Enable pin 3 PWM output
228   delayMicroseconds(time);
229 }
230
231 /* Leave pin off for time (given in microseconds) */
232 void IRsend::space(int time) {
233   // Sends an IR space for the specified number of microseconds.
234   // A space is no output, so the PWM output is disabled.
235   TIMER_DISABLE_PWM; // Disable pin 3 PWM output
236   delayMicroseconds(time);
237 }
238
239 void IRsend::enableIROut(int khz) {
240   // Enables IR output.  The khz value controls the modulation frequency in kilohertz.
241   // The IR output will be on pin 3 (OC2B).
242   // This routine is designed for 36-40KHz; if you use it for other values, it's up to you
243   // to make sure it gives reasonable results.  (Watch out for overflow / underflow / rounding.)
244   // TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B
245   // controlling the duty cycle.
246   // There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A)
247   // To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin.
248   // A few hours staring at the ATmega documentation and this will all make sense.
249   // See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details.
250
251   
252   // Disable the Timer2 Interrupt (which is used for receiving IR)
253   TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt
254   
255   pinMode(TIMER_PWM_PIN, OUTPUT);
256   digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low
257   
258   // COM2A = 00: disconnect OC2A
259   // COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted
260   // WGM2 = 101: phase-correct PWM with OCRA as top
261   // CS2 = 000: no prescaling
262   // The top value for the timer.  The modulation frequency will be SYSCLOCK / 2 / OCR2A.
263   TIMER_CONFIG_KHZ(khz);
264 }
265
266 IRrecv::IRrecv(int recvpin)
267 {
268   irparams.recvpin = recvpin;
269   irparams.blinkflag = 0;
270 }
271
272 // initialization
273 void IRrecv::enableIRIn() {
274   cli();
275   // setup pulse clock timer interrupt
276   //Prescale /8 (16M/8 = 0.5 microseconds per tick)
277   // Therefore, the timer interval can range from 0.5 to 128 microseconds
278   // depending on the reset value (255 to 0)
279   TIMER_CONFIG_NORMAL();
280
281   //Timer2 Overflow Interrupt Enable
282   TIMER_ENABLE_INTR;
283
284   TIMER_RESET;
285
286   sei();  // enable interrupts
287
288   // initialize state machine variables
289   irparams.rcvstate = STATE_IDLE;
290   irparams.rawlen = 0;
291
292   // set pin modes
293   pinMode(irparams.recvpin, INPUT);
294 }
295
296 // enable/disable blinking of pin 13 on IR processing
297 void IRrecv::blink13(int blinkflag)
298 {
299   irparams.blinkflag = blinkflag;
300   if (blinkflag)
301     pinMode(BLINKLED, OUTPUT);
302 }
303
304 // TIMER2 interrupt code to collect raw data.
305 // Widths of alternating SPACE, MARK are recorded in rawbuf.
306 // Recorded in ticks of 50 microseconds.
307 // rawlen counts the number of entries recorded so far.
308 // First entry is the SPACE between transmissions.
309 // As soon as a SPACE gets long, ready is set, state switches to IDLE, timing of SPACE continues.
310 // As soon as first MARK arrives, gap width is recorded, ready is cleared, and new logging starts
311 ISR(TIMER_INTR_NAME)
312 {
313   TIMER_RESET;
314
315   uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin);
316
317   irparams.timer++; // One more 50us tick
318   if (irparams.rawlen >= RAWBUF) {
319     // Buffer overflow
320     irparams.rcvstate = STATE_STOP;
321   }
322   switch(irparams.rcvstate) {
323   case STATE_IDLE: // In the middle of a gap
324     if (irdata == MARK) {
325       if (irparams.timer < GAP_TICKS) {
326         // Not big enough to be a gap.
327         irparams.timer = 0;
328       } 
329       else {
330         // gap just ended, record duration and start recording transmission
331         irparams.rawlen = 0;
332         irparams.rawbuf[irparams.rawlen++] = irparams.timer;
333         irparams.timer = 0;
334         irparams.rcvstate = STATE_MARK;
335       }
336     }
337     break;
338   case STATE_MARK: // timing MARK
339     if (irdata == SPACE) {   // MARK ended, record time
340       irparams.rawbuf[irparams.rawlen++] = irparams.timer;
341       irparams.timer = 0;
342       irparams.rcvstate = STATE_SPACE;
343     }
344     break;
345   case STATE_SPACE: // timing SPACE
346     if (irdata == MARK) { // SPACE just ended, record it
347       irparams.rawbuf[irparams.rawlen++] = irparams.timer;
348       irparams.timer = 0;
349       irparams.rcvstate = STATE_MARK;
350     } 
351     else { // SPACE
352       if (irparams.timer > GAP_TICKS) {
353         // big SPACE, indicates gap between codes
354         // Mark current code as ready for processing
355         // Switch to STOP
356         // Don't reset timer; keep counting space width
357         irparams.rcvstate = STATE_STOP;
358       } 
359     }
360     break;
361   case STATE_STOP: // waiting, measuring gap
362     if (irdata == MARK) { // reset gap timer
363       irparams.timer = 0;
364     }
365     break;
366   }
367
368   if (irparams.blinkflag) {
369     if (irdata == MARK) {
370       BLINKLED_ON();  // turn pin 13 LED on
371     } 
372     else {
373       BLINKLED_OFF();  // turn pin 13 LED off
374     }
375   }
376 }
377
378 void IRrecv::resume() {
379   irparams.rcvstate = STATE_IDLE;
380   irparams.rawlen = 0;
381 }
382
383
384
385 // Decodes the received IR message
386 // Returns 0 if no data ready, 1 if data ready.
387 // Results of decoding are stored in results
388 int IRrecv::decode(decode_results *results) {
389   results->rawbuf = irparams.rawbuf;
390   results->rawlen = irparams.rawlen;
391   if (irparams.rcvstate != STATE_STOP) {
392     return ERR;
393   }
394 #ifdef DEBUG
395   Serial.println("Attempting NEC decode");
396 #endif
397   if (decodeNEC(results)) {
398     return DECODED;
399   }
400 #ifdef DEBUG
401   Serial.println("Attempting Sony decode");
402 #endif
403   if (decodeSony(results)) {
404     return DECODED;
405   }
406 #ifdef DEBUG
407   Serial.println("Attempting Sanyo decode");
408 #endif
409   if (decodeSanyo(results)) {
410     return DECODED;
411   }
412 #ifdef DEBUG
413   Serial.println("Attempting Mitsubishi decode");
414 #endif
415   if (decodeMitsubishi(results)) {
416     return DECODED;
417   }
418 #ifdef DEBUG
419   Serial.println("Attempting RC5 decode");
420 #endif  
421   if (decodeRC5(results)) {
422     return DECODED;
423   }
424 #ifdef DEBUG
425   Serial.println("Attempting RC6 decode");
426 #endif 
427   if (decodeRC6(results)) {
428     return DECODED;
429   }
430 #ifdef DEBUG
431     Serial.println("Attempting Panasonic decode");
432 #endif 
433     if (decodePanasonic(results)) {
434         return DECODED;
435     }
436 #ifdef DEBUG
437     Serial.println("Attempting JVC decode");
438 #endif 
439     if (decodeJVC(results)) {
440         return DECODED;
441     }
442   // decodeHash returns a hash on any input.
443   // Thus, it needs to be last in the list.
444   // If you add any decodes, add them before this.
445   if (decodeHash(results)) {
446     return DECODED;
447   }
448   // Throw away and start over
449   resume();
450   return ERR;
451 }
452
453 // NECs have a repeat only 4 items long
454 long IRrecv::decodeNEC(decode_results *results) {
455   long data = 0;
456   int offset = 1; // Skip first space
457   // Initial mark
458   if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) {
459     return ERR;
460   }
461   offset++;
462   // Check for repeat
463   if (irparams.rawlen == 4 &&
464     MATCH_SPACE(results->rawbuf[offset], NEC_RPT_SPACE) &&
465     MATCH_MARK(results->rawbuf[offset+1], NEC_BIT_MARK)) {
466     results->bits = 0;
467     results->value = REPEAT;
468     results->decode_type = NEC;
469     return DECODED;
470   }
471   if (irparams.rawlen < 2 * NEC_BITS + 4) {
472     return ERR;
473   }
474   // Initial space  
475   if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) {
476     return ERR;
477   }
478   offset++;
479   for (int i = 0; i < NEC_BITS; i++) {
480     if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) {
481       return ERR;
482     }
483     offset++;
484     if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE)) {
485       data = (data << 1) | 1;
486     } 
487     else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) {
488       data <<= 1;
489     } 
490     else {
491       return ERR;
492     }
493     offset++;
494   }
495   // Success
496   results->bits = NEC_BITS;
497   results->value = data;
498   results->decode_type = NEC;
499   return DECODED;
500 }
501
502 long IRrecv::decodeSony(decode_results *results) {
503   long data = 0;
504   if (irparams.rawlen < 2 * SONY_BITS + 2) {
505     return ERR;
506   }
507   int offset = 0; // Dont skip first space, check its size
508
509   // Some Sony's deliver repeats fast after first
510   // unfortunately can't spot difference from of repeat from two fast clicks
511   if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) {
512     // Serial.print("IR Gap found: ");
513     results->bits = 0;
514     results->value = REPEAT;
515     results->decode_type = SANYO;
516     return DECODED;
517   }
518   offset++;
519
520   // Initial mark
521   if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) {
522     return ERR;
523   }
524   offset++;
525
526   while (offset + 1 < irparams.rawlen) {
527     if (!MATCH_SPACE(results->rawbuf[offset], SONY_HDR_SPACE)) {
528       break;
529     }
530     offset++;
531     if (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK)) {
532       data = (data << 1) | 1;
533     } 
534     else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK)) {
535       data <<= 1;
536     } 
537     else {
538       return ERR;
539     }
540     offset++;
541   }
542
543   // Success
544   results->bits = (offset - 1) / 2;
545   if (results->bits < 12) {
546     results->bits = 0;
547     return ERR;
548   }
549   results->value = data;
550   results->decode_type = SONY;
551   return DECODED;
552 }
553
554 // I think this is a Sanyo decoder - serial = SA 8650B
555 // Looks like Sony except for timings, 48 chars of data and time/space different
556 long IRrecv::decodeSanyo(decode_results *results) {
557   long data = 0;
558   if (irparams.rawlen < 2 * SANYO_BITS + 2) {
559     return ERR;
560   }
561   int offset = 0; // Skip first space
562   // Initial space  
563   /* Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay
564   Serial.print("IR Gap: ");
565   Serial.println( results->rawbuf[offset]);
566   Serial.println( "test against:");
567   Serial.println(results->rawbuf[offset]);
568   */
569   if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) {
570     // Serial.print("IR Gap found: ");
571     results->bits = 0;
572     results->value = REPEAT;
573     results->decode_type = SANYO;
574     return DECODED;
575   }
576   offset++;
577
578   // Initial mark
579   if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) {
580     return ERR;
581   }
582   offset++;
583
584   // Skip Second Mark
585   if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) {
586     return ERR;
587   }
588   offset++;
589
590   while (offset + 1 < irparams.rawlen) {
591     if (!MATCH_SPACE(results->rawbuf[offset], SANYO_HDR_SPACE)) {
592       break;
593     }
594     offset++;
595     if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) {
596       data = (data << 1) | 1;
597     } 
598     else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) {
599       data <<= 1;
600     } 
601     else {
602       return ERR;
603     }
604     offset++;
605   }
606
607   // Success
608   results->bits = (offset - 1) / 2;
609   if (results->bits < 12) {
610     results->bits = 0;
611     return ERR;
612   }
613   results->value = data;
614   results->decode_type = SANYO;
615   return DECODED;
616 }
617
618 // Looks like Sony except for timings, 48 chars of data and time/space different
619 long IRrecv::decodeMitsubishi(decode_results *results) {
620   // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2);
621   long data = 0;
622   if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) {
623     return ERR;
624   }
625   int offset = 0; // Skip first space
626   // Initial space  
627   /* Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay
628   Serial.print("IR Gap: ");
629   Serial.println( results->rawbuf[offset]);
630   Serial.println( "test against:");
631   Serial.println(results->rawbuf[offset]);
632   */
633   /* Not seeing double keys from Mitsubishi
634   if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) {
635     // Serial.print("IR Gap found: ");
636     results->bits = 0;
637     results->value = REPEAT;
638     results->decode_type = MITSUBISHI;
639     return DECODED;
640   }
641   */
642   offset++;
643
644   // Typical
645   // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 
646
647   // Initial Space
648   if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) {
649     return ERR;
650   }
651   offset++;
652   while (offset + 1 < irparams.rawlen) {
653     if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK)) {
654       data = (data << 1) | 1;
655     } 
656     else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK)) {
657       data <<= 1;
658     } 
659     else {
660       // Serial.println("A"); Serial.println(offset); Serial.println(results->rawbuf[offset]);
661       return ERR;
662     }
663     offset++;
664     if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) {
665       // Serial.println("B"); Serial.println(offset); Serial.println(results->rawbuf[offset]);
666       break;
667     }
668     offset++;
669   }
670
671   // Success
672   results->bits = (offset - 1) / 2;
673   if (results->bits < MITSUBISHI_BITS) {
674     results->bits = 0;
675     return ERR;
676   }
677   results->value = data;
678   results->decode_type = MITSUBISHI;
679   return DECODED;
680 }
681
682
683 // Gets one undecoded level at a time from the raw buffer.
684 // The RC5/6 decoding is easier if the data is broken into time intervals.
685 // E.g. if the buffer has MARK for 2 time intervals and SPACE for 1,
686 // successive calls to getRClevel will return MARK, MARK, SPACE.
687 // offset and used are updated to keep track of the current position.
688 // t1 is the time interval for a single bit in microseconds.
689 // Returns -1 for error (measured time interval is not a multiple of t1).
690 int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) {
691   if (*offset >= results->rawlen) {
692     // After end of recorded buffer, assume SPACE.
693     return SPACE;
694   }
695   int width = results->rawbuf[*offset];
696   int val = ((*offset) % 2) ? MARK : SPACE;
697   int correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS;
698
699   int avail;
700   if (MATCH(width, t1 + correction)) {
701     avail = 1;
702   } 
703   else if (MATCH(width, 2*t1 + correction)) {
704     avail = 2;
705   } 
706   else if (MATCH(width, 3*t1 + correction)) {
707     avail = 3;
708   } 
709   else {
710     return -1;
711   }
712
713   (*used)++;
714   if (*used >= avail) {
715     *used = 0;
716     (*offset)++;
717   }
718 #ifdef DEBUG
719   if (val == MARK) {
720     Serial.println("MARK");
721   } 
722   else {
723     Serial.println("SPACE");
724   }
725 #endif
726   return val;   
727 }
728
729 long IRrecv::decodeRC5(decode_results *results) {
730   if (irparams.rawlen < MIN_RC5_SAMPLES + 2) {
731     return ERR;
732   }
733   int offset = 1; // Skip gap space
734   long data = 0;
735   int used = 0;
736   // Get start bits
737   if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR;
738   if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return ERR;
739   if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR;
740   int nbits;
741   for (nbits = 0; offset < irparams.rawlen; nbits++) {
742     int levelA = getRClevel(results, &offset, &used, RC5_T1); 
743     int levelB = getRClevel(results, &offset, &used, RC5_T1);
744     if (levelA == SPACE && levelB == MARK) {
745       // 1 bit
746       data = (data << 1) | 1;
747     } 
748     else if (levelA == MARK && levelB == SPACE) {
749       // zero bit
750       data <<= 1;
751     } 
752     else {
753       return ERR;
754     } 
755   }
756
757   // Success
758   results->bits = nbits;
759   results->value = data;
760   results->decode_type = RC5;
761   return DECODED;
762 }
763
764 long IRrecv::decodeRC6(decode_results *results) {
765   if (results->rawlen < MIN_RC6_SAMPLES) {
766     return ERR;
767   }
768   int offset = 1; // Skip first space
769   // Initial mark
770   if (!MATCH_MARK(results->rawbuf[offset], RC6_HDR_MARK)) {
771     return ERR;
772   }
773   offset++;
774   if (!MATCH_SPACE(results->rawbuf[offset], RC6_HDR_SPACE)) {
775     return ERR;
776   }
777   offset++;
778   long data = 0;
779   int used = 0;
780   // Get start bit (1)
781   if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return ERR;
782   if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return ERR;
783   int nbits;
784   for (nbits = 0; offset < results->rawlen; nbits++) {
785     int levelA, levelB; // Next two levels
786     levelA = getRClevel(results, &offset, &used, RC6_T1); 
787     if (nbits == 3) {
788       // T bit is double wide; make sure second half matches
789       if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return ERR;
790     } 
791     levelB = getRClevel(results, &offset, &used, RC6_T1);
792     if (nbits == 3) {
793       // T bit is double wide; make sure second half matches
794       if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return ERR;
795     } 
796     if (levelA == MARK && levelB == SPACE) { // reversed compared to RC5
797       // 1 bit
798       data = (data << 1) | 1;
799     } 
800     else if (levelA == SPACE && levelB == MARK) {
801       // zero bit
802       data <<= 1;
803     } 
804     else {
805       return ERR; // Error
806     } 
807   }
808   // Success
809   results->bits = nbits;
810   results->value = data;
811   results->decode_type = RC6;
812   return DECODED;
813 }
814 long IRrecv::decodePanasonic(decode_results *results) {
815     unsigned long long data = 0;
816     int offset = 1;
817     
818     if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_MARK)) {
819         return ERR;
820     }
821     offset++;
822     if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_SPACE)) {
823         return ERR;
824     }
825     offset++;
826     
827     // decode address
828     for (int i = 0; i < PANASONIC_BITS; i++) {
829         if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) {
830             return ERR;
831         }
832         if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE)) {
833             data = (data << 1) | 1;
834         } else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) {
835             data <<= 1;
836         } else {
837             return ERR;
838         }
839         offset++;
840     }
841     results->value = (unsigned long)data;
842     results->panasonicAddress = (unsigned int)(data >> 32);
843     results->decode_type = PANASONIC;
844     results->bits = PANASONIC_BITS;
845     return DECODED;
846 }
847 long IRrecv::decodeJVC(decode_results *results) {
848     long data = 0;
849     int offset = 1; // Skip first space
850     // Check for repeat
851     if (irparams.rawlen - 1 == 33 &&
852         MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK) &&
853         MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK)) {
854         results->bits = 0;
855         results->value = REPEAT;
856         results->decode_type = JVC;
857         return DECODED;
858     } 
859     // Initial mark
860     if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) {
861         return ERR;
862     }
863     offset++; 
864     if (irparams.rawlen < 2 * JVC_BITS + 1 ) {
865         return ERR;
866     }
867     // Initial space 
868     if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) {
869         return ERR;
870     }
871     offset++;
872     for (int i = 0; i < JVC_BITS; i++) {
873         if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) {
874             return ERR;
875         }
876         offset++;
877         if (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE)) {
878             data = (data << 1) | 1;
879         } 
880         else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) {
881             data <<= 1;
882         } 
883         else {
884             return ERR;
885         }
886         offset++;
887     }
888     //Stop bit
889     if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)){
890         return ERR;
891     }
892     // Success
893     results->bits = JVC_BITS;
894     results->value = data;
895     results->decode_type = JVC;
896     return DECODED;
897 }
898
899 /* -----------------------------------------------------------------------
900  * hashdecode - decode an arbitrary IR code.
901  * Instead of decoding using a standard encoding scheme
902  * (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
903  *
904  * The algorithm: look at the sequence of MARK signals, and see if each one
905  * is shorter (0), the same length (1), or longer (2) than the previous.
906  * Do the same with the SPACE signals.  Hszh the resulting sequence of 0's,
907  * 1's, and 2's to a 32-bit value.  This will give a unique value for each
908  * different code (probably), for most code systems.
909  *
910  * http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
911  */
912
913 // Compare two tick values, returning 0 if newval is shorter,
914 // 1 if newval is equal, and 2 if newval is longer
915 // Use a tolerance of 20%
916 int IRrecv::compare(unsigned int oldval, unsigned int newval) {
917   if (newval < oldval * .8) {
918     return 0;
919   } 
920   else if (oldval < newval * .8) {
921     return 2;
922   } 
923   else {
924     return 1;
925   }
926 }
927
928 // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
929 #define FNV_PRIME_32 16777619
930 #define FNV_BASIS_32 2166136261
931
932 /* Converts the raw code values into a 32-bit hash code.
933  * Hopefully this code is unique for each button.
934  * This isn't a "real" decoding, just an arbitrary value.
935  */
936 long IRrecv::decodeHash(decode_results *results) {
937   // Require at least 6 samples to prevent triggering on noise
938   if (results->rawlen < 6) {
939     return ERR;
940   }
941   long hash = FNV_BASIS_32;
942   for (int i = 1; i+2 < results->rawlen; i++) {
943     int value =  compare(results->rawbuf[i], results->rawbuf[i+2]);
944     // Add value into the hash
945     hash = (hash * FNV_PRIME_32) ^ value;
946   }
947   results->value = hash;
948   results->bits = 32;
949   results->decode_type = UNKNOWN;
950   return DECODED;
951 }
952
953 /* Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand )
954
955 The Dish send function needs to be repeated 4 times, and the Sharp function
956 has the necessary repeat built in because of the need to invert the signal.
957
958 Sharp protocol documentation:
959 http://www.sbprojects.com/knowledge/ir/sharp.htm
960
961 Here are the LIRC files that I found that seem to match the remote codes
962 from the oscilloscope:
963
964 Sharp LCD TV:
965 http://lirc.sourceforge.net/remotes/sharp/GA538WJSA
966
967 DISH NETWORK (echostar 301):
968 http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx
969
970 For the DISH codes, only send the last for characters of the hex.
971 i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the
972 linked LIRC file.
973 */
974
975 void IRsend::sendSharp(unsigned long data, int nbits) {
976   unsigned long invertdata = data ^ SHARP_TOGGLE_MASK;
977   enableIROut(38);
978   for (int i = 0; i < nbits; i++) {
979     if (data & 0x4000) {
980       mark(SHARP_BIT_MARK);
981       space(SHARP_ONE_SPACE);
982     }
983     else {
984       mark(SHARP_BIT_MARK);
985       space(SHARP_ZERO_SPACE);
986     }
987     data <<= 1;
988   }
989   
990   mark(SHARP_BIT_MARK);
991   space(SHARP_ZERO_SPACE);
992   delay(46);
993   for (int i = 0; i < nbits; i++) {
994     if (invertdata & 0x4000) {
995       mark(SHARP_BIT_MARK);
996       space(SHARP_ONE_SPACE);
997     }
998     else {
999       mark(SHARP_BIT_MARK);
1000       space(SHARP_ZERO_SPACE);
1001     }
1002     invertdata <<= 1;
1003   }
1004   mark(SHARP_BIT_MARK);
1005   space(SHARP_ZERO_SPACE);
1006   delay(46);
1007 }
1008
1009 void IRsend::sendDISH(unsigned long data, int nbits)
1010 {
1011   enableIROut(56);
1012   mark(DISH_HDR_MARK);
1013   space(DISH_HDR_SPACE);
1014   for (int i = 0; i < nbits; i++) {
1015     if (data & DISH_TOP_BIT) {
1016       mark(DISH_BIT_MARK);
1017       space(DISH_ONE_SPACE);
1018     }
1019     else {
1020       mark(DISH_BIT_MARK);
1021       space(DISH_ZERO_SPACE);
1022     }
1023     data <<= 1;
1024   }
1025 }