diff --git a/IRremote.cpp b/IRremote.cpp index 3912eae..21a5acb 100644 --- a/IRremote.cpp +++ b/IRremote.cpp @@ -5,6 +5,9 @@ * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html * * Modified by Paul Stoffregen to support other boards and timers + * Modified by Mitra Ardron + * Added Sanyo and Mitsubishi controllers + * Modified Sony to spot the repeat codes that some Sony's send * * Interrupt code based on NECIRrcv by Joe Knapp * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 @@ -400,6 +403,18 @@ int IRrecv::decode(decode_results *results) { if (decodeSony(results)) { return DECODED; } +#ifdef DEBUG + Serial.println("Attempting Sanyo decode"); +#endif + if (decodeSanyo(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting Mitsubishi decode"); +#endif + if (decodeMitsubishi(results)) { + return DECODED; + } #ifdef DEBUG Serial.println("Attempting RC5 decode"); #endif @@ -435,6 +450,7 @@ int IRrecv::decode(decode_results *results) { return ERR; } +// NECs have a repeat only 4 items long long IRrecv::decodeNEC(decode_results *results) { long data = 0; int offset = 1; // Skip first space @@ -488,7 +504,19 @@ long IRrecv::decodeSony(decode_results *results) { if (irparams.rawlen < 2 * SONY_BITS + 2) { return ERR; } - int offset = 1; // Skip first space + int offset = 0; // Dont skip first space, check its size + + // Some Sony's deliver repeats fast after first + // unfortunately can't spot difference from of repeat from two fast clicks + if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) { + // Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + results->decode_type = SANYO; + return DECODED; + } + offset++; + // Initial mark if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) { return ERR; @@ -523,6 +551,135 @@ long IRrecv::decodeSony(decode_results *results) { return DECODED; } +// I think this is a Sanyo decoder - serial = SA 8650B +// Looks like Sony except for timings, 48 chars of data and time/space different +long IRrecv::decodeSanyo(decode_results *results) { + long data = 0; + if (irparams.rawlen < 2 * SANYO_BITS + 2) { + return ERR; + } + int offset = 0; // Skip first space + // Initial space + /* 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 + Serial.print("IR Gap: "); + Serial.println( results->rawbuf[offset]); + Serial.println( "test against:"); + Serial.println(results->rawbuf[offset]); + */ + if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) { + // Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + results->decode_type = SANYO; + return DECODED; + } + offset++; + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) { + return ERR; + } + offset++; + + // Skip Second Mark + if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) { + return ERR; + } + offset++; + + while (offset + 1 < irparams.rawlen) { + if (!MATCH_SPACE(results->rawbuf[offset], SANYO_HDR_SPACE)) { + break; + } + offset++; + if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) { + data = (data << 1) | 1; + } + else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) { + data <<= 1; + } + else { + return ERR; + } + offset++; + } + + // Success + results->bits = (offset - 1) / 2; + if (results->bits < 12) { + results->bits = 0; + return ERR; + } + results->value = data; + results->decode_type = SANYO; + return DECODED; +} + +// Looks like Sony except for timings, 48 chars of data and time/space different +long IRrecv::decodeMitsubishi(decode_results *results) { + // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2); + long data = 0; + if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) { + return ERR; + } + int offset = 0; // Skip first space + // Initial space + /* 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 + Serial.print("IR Gap: "); + Serial.println( results->rawbuf[offset]); + Serial.println( "test against:"); + Serial.println(results->rawbuf[offset]); + */ + /* Not seeing double keys from Mitsubishi + if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) { + // Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + results->decode_type = MITSUBISHI; + return DECODED; + } + */ + offset++; + + // Typical + // 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 + + // Initial Space + if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) { + return ERR; + } + offset++; + while (offset + 1 < irparams.rawlen) { + if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK)) { + data = (data << 1) | 1; + } + else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK)) { + data <<= 1; + } + else { + // Serial.println("A"); Serial.println(offset); Serial.println(results->rawbuf[offset]); + return ERR; + } + offset++; + if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) { + // Serial.println("B"); Serial.println(offset); Serial.println(results->rawbuf[offset]); + break; + } + offset++; + } + + // Success + results->bits = (offset - 1) / 2; + if (results->bits < MITSUBISHI_BITS) { + results->bits = 0; + return ERR; + } + results->value = data; + results->decode_type = MITSUBISHI; + return DECODED; +} + + // Gets one undecoded level at a time from the raw buffer. // The RC5/6 decoding is easier if the data is broken into time intervals. // E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, diff --git a/IRremote.h b/IRremote.h index acc2385..0e5fdf2 100644 --- a/IRremote.h +++ b/IRremote.h @@ -3,6 +3,7 @@ * Version 0.1 July, 2009 * Copyright 2009 Ken Shirriff * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com + * Edited by Mitra to add new controller SANYO * * Interrupt code based on NECIRrcv by Joe Knapp * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 @@ -42,6 +43,8 @@ public: #define SHARP 6 #define PANASONIC 7 #define JVC 8 +#define SANYO 9 +#define MITSUBISHI 10 #define UNKNOWN -1 // Decoded value for NEC when a repeat code is received @@ -61,6 +64,8 @@ private: int getRClevel(decode_results *results, int *offset, int *used, int t1); long decodeNEC(decode_results *results); long decodeSony(decode_results *results); + long decodeSanyo(decode_results *results); + long decodeMitsubishi(decode_results *results); long decodeRC5(decode_results *results); long decodeRC6(decode_results *results); long decodePanasonic(decode_results *results); @@ -84,6 +89,9 @@ public: IRsend() {} void sendNEC(unsigned long data, int nbits); void sendSony(unsigned long data, int nbits); + // Neither Sanyo nor Mitsubishi send is implemented yet + // void sendSanyo(unsigned long data, int nbits); + // void sendMitsubishi(unsigned long data, int nbits); void sendRaw(unsigned int buf[], int len, int hz); void sendRC5(unsigned long data, int nbits); void sendRC6(unsigned long data, int nbits); diff --git a/IRremoteInt.h b/IRremoteInt.h index 0724ca9..9971e7d 100644 --- a/IRremoteInt.h +++ b/IRremoteInt.h @@ -87,7 +87,8 @@ #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif - +// Pulse parms are *50-100 for the Mark and *50+100 for the space +// First MARK is the one after the long gap // pulse parameters in usec #define NEC_HDR_MARK 9000 #define NEC_HDR_SPACE 4500 @@ -101,6 +102,26 @@ #define SONY_ONE_MARK 1200 #define SONY_ZERO_MARK 600 #define SONY_RPT_LENGTH 45000 +#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround + +// SA 8650B +#define SANYO_HDR_MARK 3500 // seen range 3500 +#define SANYO_HDR_SPACE 950 // seen 950 +#define SANYO_ONE_MARK 2400 // seen 2400 +#define SANYO_ZERO_MARK 700 // seen 700 +#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround +#define SANYO_RPT_LENGTH 45000 + +// Mitsubishi RM 75501 +// 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 + +// #define MITSUBISHI_HDR_MARK 250 // seen range 3500 +#define MITSUBISHI_HDR_SPACE 350 // 7*50+100 +#define MITSUBISHI_ONE_MARK 1950 // 41*50-100 +#define MITSUBISHI_ZERO_MARK 750 // 17*50-100 +// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround +// #define MITSUBISHI_RPT_LENGTH 45000 + #define RC5_T1 889 #define RC5_RPT_LENGTH 46000 @@ -186,6 +207,8 @@ extern volatile irparams_t irparams; #define NEC_BITS 32 #define SONY_BITS 12 +#define SANYO_BITS 12 +#define MITSUBISHI_BITS 16 #define MIN_RC5_SAMPLES 11 #define MIN_RC6_SAMPLES 1 #define PANASONIC_BITS 48 diff --git a/keywords.txt b/keywords.txt index 91c41f9..74010c4 100644 --- a/keywords.txt +++ b/keywords.txt @@ -6,24 +6,26 @@ # Datatypes (KEYWORD1) ####################################### -decode_results KEYWORD1 -IRrecv KEYWORD1 -IRsend KEYWORD1 +decode_results KEYWORD1 +IRrecv KEYWORD1 +IRsend KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### -blink13 KEYWORD2 -decode KEYWORD2 -enableIRIn KEYWORD2 -resume KEYWORD2 -enableIROut KEYWORD2 -sendNEC KEYWORD2 -sendSony KEYWORD2 -sendRaw KEYWORD2 -sendRC5 KEYWORD2 -sendRC6 KEYWORD2 +blink13 KEYWORD2 +decode KEYWORD2 +enableIRIn KEYWORD2 +resume KEYWORD2 +enableIROut KEYWORD2 +sendNEC KEYWORD2 +sendSony KEYWORD2 +sendSanyo KEYWORD2 +sendMitsubishi KEYWORD2 +sendRaw KEYWORD2 +sendRC5 KEYWORD2 +sendRC6 KEYWORD2 sendDISH KEYWORD2 sendSharp KEYWORD2 sendPanasonic KEYWORD2 @@ -34,13 +36,15 @@ sendJVC KEYWORD2 # Constants (LITERAL1) ####################################### -NEC LITERAL1 -SONY LITERAL1 -RC5 LITERAL1 -RC6 LITERAL1 +NEC LITERAL1 +SONY LITERAL1 +SANYO LITERAL1 +MITSUBISHI LITERAL1 +RC5 LITERAL1 +RC6 LITERAL1 DISH LITERAL1 SHARP LITERAL1 PANASONIC LITERAL1 JVC LITERAL1 -UNKNOWN LITERAL1 -REPEAT LITERAL1 \ No newline at end of file +UNKNOWN LITERAL1 +REPEAT LITERAL1 \ No newline at end of file