Infrared remote library for Arduino: send and receive infrared signals with multiple protocols Port from Arduino-IRremote https://github.com/z3t0/Arduino-IRremote

Dependents:   Lilnija_29012017 NucleoF042K6_IRReceiver

Committer:
yuhki50
Date:
Sat Jan 23 06:16:48 2016 +0000
Revision:
0:70c8e56bac45
Child:
3:17440cf7ab90
import https://github.com/z3t0/Arduino-IRremote e3ec11d

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yuhki50 0:70c8e56bac45 1 #include "IRremote.h"
yuhki50 0:70c8e56bac45 2 #include "IRremoteInt.h"
yuhki50 0:70c8e56bac45 3
yuhki50 0:70c8e56bac45 4 //+=============================================================================
yuhki50 0:70c8e56bac45 5 // Decodes the received IR message
yuhki50 0:70c8e56bac45 6 // Returns 0 if no data ready, 1 if data ready.
yuhki50 0:70c8e56bac45 7 // Results of decoding are stored in results
yuhki50 0:70c8e56bac45 8 //
yuhki50 0:70c8e56bac45 9 int IRrecv::decode (decode_results *results)
yuhki50 0:70c8e56bac45 10 {
yuhki50 0:70c8e56bac45 11 results->rawbuf = irparams.rawbuf;
yuhki50 0:70c8e56bac45 12 results->rawlen = irparams.rawlen;
yuhki50 0:70c8e56bac45 13
yuhki50 0:70c8e56bac45 14 results->overflow = irparams.overflow;
yuhki50 0:70c8e56bac45 15
yuhki50 0:70c8e56bac45 16 if (irparams.rcvstate != STATE_STOP) return false ;
yuhki50 0:70c8e56bac45 17
yuhki50 0:70c8e56bac45 18 #if DECODE_NEC
yuhki50 0:70c8e56bac45 19 DBG_PRINTLN("Attempting NEC decode");
yuhki50 0:70c8e56bac45 20 if (decodeNEC(results)) return true ;
yuhki50 0:70c8e56bac45 21 #endif
yuhki50 0:70c8e56bac45 22
yuhki50 0:70c8e56bac45 23 #if DECODE_SONY
yuhki50 0:70c8e56bac45 24 DBG_PRINTLN("Attempting Sony decode");
yuhki50 0:70c8e56bac45 25 if (decodeSony(results)) return true ;
yuhki50 0:70c8e56bac45 26 #endif
yuhki50 0:70c8e56bac45 27
yuhki50 0:70c8e56bac45 28 #if DECODE_SANYO
yuhki50 0:70c8e56bac45 29 DBG_PRINTLN("Attempting Sanyo decode");
yuhki50 0:70c8e56bac45 30 if (decodeSanyo(results)) return true ;
yuhki50 0:70c8e56bac45 31 #endif
yuhki50 0:70c8e56bac45 32
yuhki50 0:70c8e56bac45 33 #if DECODE_MITSUBISHI
yuhki50 0:70c8e56bac45 34 DBG_PRINTLN("Attempting Mitsubishi decode");
yuhki50 0:70c8e56bac45 35 if (decodeMitsubishi(results)) return true ;
yuhki50 0:70c8e56bac45 36 #endif
yuhki50 0:70c8e56bac45 37
yuhki50 0:70c8e56bac45 38 #if DECODE_RC5
yuhki50 0:70c8e56bac45 39 DBG_PRINTLN("Attempting RC5 decode");
yuhki50 0:70c8e56bac45 40 if (decodeRC5(results)) return true ;
yuhki50 0:70c8e56bac45 41 #endif
yuhki50 0:70c8e56bac45 42
yuhki50 0:70c8e56bac45 43 #if DECODE_RC6
yuhki50 0:70c8e56bac45 44 DBG_PRINTLN("Attempting RC6 decode");
yuhki50 0:70c8e56bac45 45 if (decodeRC6(results)) return true ;
yuhki50 0:70c8e56bac45 46 #endif
yuhki50 0:70c8e56bac45 47
yuhki50 0:70c8e56bac45 48 #if DECODE_PANASONIC
yuhki50 0:70c8e56bac45 49 DBG_PRINTLN("Attempting Panasonic decode");
yuhki50 0:70c8e56bac45 50 if (decodePanasonic(results)) return true ;
yuhki50 0:70c8e56bac45 51 #endif
yuhki50 0:70c8e56bac45 52
yuhki50 0:70c8e56bac45 53 #if DECODE_LG
yuhki50 0:70c8e56bac45 54 DBG_PRINTLN("Attempting LG decode");
yuhki50 0:70c8e56bac45 55 if (decodeLG(results)) return true ;
yuhki50 0:70c8e56bac45 56 #endif
yuhki50 0:70c8e56bac45 57
yuhki50 0:70c8e56bac45 58 #if DECODE_JVC
yuhki50 0:70c8e56bac45 59 DBG_PRINTLN("Attempting JVC decode");
yuhki50 0:70c8e56bac45 60 if (decodeJVC(results)) return true ;
yuhki50 0:70c8e56bac45 61 #endif
yuhki50 0:70c8e56bac45 62
yuhki50 0:70c8e56bac45 63 #if DECODE_SAMSUNG
yuhki50 0:70c8e56bac45 64 DBG_PRINTLN("Attempting SAMSUNG decode");
yuhki50 0:70c8e56bac45 65 if (decodeSAMSUNG(results)) return true ;
yuhki50 0:70c8e56bac45 66 #endif
yuhki50 0:70c8e56bac45 67
yuhki50 0:70c8e56bac45 68 #if DECODE_WHYNTER
yuhki50 0:70c8e56bac45 69 DBG_PRINTLN("Attempting Whynter decode");
yuhki50 0:70c8e56bac45 70 if (decodeWhynter(results)) return true ;
yuhki50 0:70c8e56bac45 71 #endif
yuhki50 0:70c8e56bac45 72
yuhki50 0:70c8e56bac45 73 #if DECODE_AIWA_RC_T501
yuhki50 0:70c8e56bac45 74 DBG_PRINTLN("Attempting Aiwa RC-T501 decode");
yuhki50 0:70c8e56bac45 75 if (decodeAiwaRCT501(results)) return true ;
yuhki50 0:70c8e56bac45 76 #endif
yuhki50 0:70c8e56bac45 77
yuhki50 0:70c8e56bac45 78 #if DECODE_DENON
yuhki50 0:70c8e56bac45 79 DBG_PRINTLN("Attempting Denon decode");
yuhki50 0:70c8e56bac45 80 if (decodeDenon(results)) return true ;
yuhki50 0:70c8e56bac45 81 #endif
yuhki50 0:70c8e56bac45 82
yuhki50 0:70c8e56bac45 83 // decodeHash returns a hash on any input.
yuhki50 0:70c8e56bac45 84 // Thus, it needs to be last in the list.
yuhki50 0:70c8e56bac45 85 // If you add any decodes, add them before this.
yuhki50 0:70c8e56bac45 86 if (decodeHash(results)) return true ;
yuhki50 0:70c8e56bac45 87
yuhki50 0:70c8e56bac45 88 // Throw away and start over
yuhki50 0:70c8e56bac45 89 resume();
yuhki50 0:70c8e56bac45 90 return false;
yuhki50 0:70c8e56bac45 91 }
yuhki50 0:70c8e56bac45 92
yuhki50 0:70c8e56bac45 93 //+=============================================================================
yuhki50 0:70c8e56bac45 94 IRrecv::IRrecv (int recvpin)
yuhki50 0:70c8e56bac45 95 {
yuhki50 0:70c8e56bac45 96 irparams.recvpin = recvpin;
yuhki50 0:70c8e56bac45 97 irparams.blinkflag = 0;
yuhki50 0:70c8e56bac45 98 }
yuhki50 0:70c8e56bac45 99
yuhki50 0:70c8e56bac45 100 IRrecv::IRrecv (int recvpin, int blinkpin)
yuhki50 0:70c8e56bac45 101 {
yuhki50 0:70c8e56bac45 102 irparams.recvpin = recvpin;
yuhki50 0:70c8e56bac45 103 irparams.blinkpin = blinkpin;
yuhki50 0:70c8e56bac45 104 pinMode(blinkpin, OUTPUT);
yuhki50 0:70c8e56bac45 105 irparams.blinkflag = 0;
yuhki50 0:70c8e56bac45 106 }
yuhki50 0:70c8e56bac45 107
yuhki50 0:70c8e56bac45 108
yuhki50 0:70c8e56bac45 109
yuhki50 0:70c8e56bac45 110 //+=============================================================================
yuhki50 0:70c8e56bac45 111 // initialization
yuhki50 0:70c8e56bac45 112 //
yuhki50 0:70c8e56bac45 113 void IRrecv::enableIRIn ( )
yuhki50 0:70c8e56bac45 114 {
yuhki50 0:70c8e56bac45 115 cli();
yuhki50 0:70c8e56bac45 116 // Setup pulse clock timer interrupt
yuhki50 0:70c8e56bac45 117 // Prescale /8 (16M/8 = 0.5 microseconds per tick)
yuhki50 0:70c8e56bac45 118 // Therefore, the timer interval can range from 0.5 to 128 microseconds
yuhki50 0:70c8e56bac45 119 // Depending on the reset value (255 to 0)
yuhki50 0:70c8e56bac45 120 TIMER_CONFIG_NORMAL();
yuhki50 0:70c8e56bac45 121
yuhki50 0:70c8e56bac45 122 // Timer2 Overflow Interrupt Enable
yuhki50 0:70c8e56bac45 123 TIMER_ENABLE_INTR;
yuhki50 0:70c8e56bac45 124
yuhki50 0:70c8e56bac45 125 TIMER_RESET;
yuhki50 0:70c8e56bac45 126
yuhki50 0:70c8e56bac45 127 sei(); // enable interrupts
yuhki50 0:70c8e56bac45 128
yuhki50 0:70c8e56bac45 129 // Initialize state machine variables
yuhki50 0:70c8e56bac45 130 irparams.rcvstate = STATE_IDLE;
yuhki50 0:70c8e56bac45 131 irparams.rawlen = 0;
yuhki50 0:70c8e56bac45 132
yuhki50 0:70c8e56bac45 133 // Set pin modes
yuhki50 0:70c8e56bac45 134 pinMode(irparams.recvpin, INPUT);
yuhki50 0:70c8e56bac45 135 }
yuhki50 0:70c8e56bac45 136
yuhki50 0:70c8e56bac45 137 //+=============================================================================
yuhki50 0:70c8e56bac45 138 // Enable/disable blinking of pin 13 on IR processing
yuhki50 0:70c8e56bac45 139 //
yuhki50 0:70c8e56bac45 140 void IRrecv::blink13 (int blinkflag)
yuhki50 0:70c8e56bac45 141 {
yuhki50 0:70c8e56bac45 142 irparams.blinkflag = blinkflag;
yuhki50 0:70c8e56bac45 143 if (blinkflag) pinMode(BLINKLED, OUTPUT) ;
yuhki50 0:70c8e56bac45 144 }
yuhki50 0:70c8e56bac45 145
yuhki50 0:70c8e56bac45 146 //+=============================================================================
yuhki50 0:70c8e56bac45 147 // Return if receiving new IR signals
yuhki50 0:70c8e56bac45 148 //
yuhki50 0:70c8e56bac45 149 bool IRrecv::isIdle ( )
yuhki50 0:70c8e56bac45 150 {
yuhki50 0:70c8e56bac45 151 return (irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP) ? true : false;
yuhki50 0:70c8e56bac45 152 }
yuhki50 0:70c8e56bac45 153 //+=============================================================================
yuhki50 0:70c8e56bac45 154 // Restart the ISR state machine
yuhki50 0:70c8e56bac45 155 //
yuhki50 0:70c8e56bac45 156 void IRrecv::resume ( )
yuhki50 0:70c8e56bac45 157 {
yuhki50 0:70c8e56bac45 158 irparams.rcvstate = STATE_IDLE;
yuhki50 0:70c8e56bac45 159 irparams.rawlen = 0;
yuhki50 0:70c8e56bac45 160 }
yuhki50 0:70c8e56bac45 161
yuhki50 0:70c8e56bac45 162 //+=============================================================================
yuhki50 0:70c8e56bac45 163 // hashdecode - decode an arbitrary IR code.
yuhki50 0:70c8e56bac45 164 // Instead of decoding using a standard encoding scheme
yuhki50 0:70c8e56bac45 165 // (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value.
yuhki50 0:70c8e56bac45 166 //
yuhki50 0:70c8e56bac45 167 // The algorithm: look at the sequence of MARK signals, and see if each one
yuhki50 0:70c8e56bac45 168 // is shorter (0), the same length (1), or longer (2) than the previous.
yuhki50 0:70c8e56bac45 169 // Do the same with the SPACE signals. Hash the resulting sequence of 0's,
yuhki50 0:70c8e56bac45 170 // 1's, and 2's to a 32-bit value. This will give a unique value for each
yuhki50 0:70c8e56bac45 171 // different code (probably), for most code systems.
yuhki50 0:70c8e56bac45 172 //
yuhki50 0:70c8e56bac45 173 // http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
yuhki50 0:70c8e56bac45 174 //
yuhki50 0:70c8e56bac45 175 // Compare two tick values, returning 0 if newval is shorter,
yuhki50 0:70c8e56bac45 176 // 1 if newval is equal, and 2 if newval is longer
yuhki50 0:70c8e56bac45 177 // Use a tolerance of 20%
yuhki50 0:70c8e56bac45 178 //
yuhki50 0:70c8e56bac45 179 int IRrecv::compare (unsigned int oldval, unsigned int newval)
yuhki50 0:70c8e56bac45 180 {
yuhki50 0:70c8e56bac45 181 if (newval < oldval * .8) return 0 ;
yuhki50 0:70c8e56bac45 182 else if (oldval < newval * .8) return 2 ;
yuhki50 0:70c8e56bac45 183 else return 1 ;
yuhki50 0:70c8e56bac45 184 }
yuhki50 0:70c8e56bac45 185
yuhki50 0:70c8e56bac45 186 //+=============================================================================
yuhki50 0:70c8e56bac45 187 // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
yuhki50 0:70c8e56bac45 188 // Converts the raw code values into a 32-bit hash code.
yuhki50 0:70c8e56bac45 189 // Hopefully this code is unique for each button.
yuhki50 0:70c8e56bac45 190 // This isn't a "real" decoding, just an arbitrary value.
yuhki50 0:70c8e56bac45 191 //
yuhki50 0:70c8e56bac45 192 #define FNV_PRIME_32 16777619
yuhki50 0:70c8e56bac45 193 #define FNV_BASIS_32 2166136261
yuhki50 0:70c8e56bac45 194
yuhki50 0:70c8e56bac45 195 long IRrecv::decodeHash (decode_results *results)
yuhki50 0:70c8e56bac45 196 {
yuhki50 0:70c8e56bac45 197 long hash = FNV_BASIS_32;
yuhki50 0:70c8e56bac45 198
yuhki50 0:70c8e56bac45 199 // Require at least 6 samples to prevent triggering on noise
yuhki50 0:70c8e56bac45 200 if (results->rawlen < 6) return false ;
yuhki50 0:70c8e56bac45 201
yuhki50 0:70c8e56bac45 202 for (int i = 1; (i + 2) < results->rawlen; i++) {
yuhki50 0:70c8e56bac45 203 int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
yuhki50 0:70c8e56bac45 204 // Add value into the hash
yuhki50 0:70c8e56bac45 205 hash = (hash * FNV_PRIME_32) ^ value;
yuhki50 0:70c8e56bac45 206 }
yuhki50 0:70c8e56bac45 207
yuhki50 0:70c8e56bac45 208 results->value = hash;
yuhki50 0:70c8e56bac45 209 results->bits = 32;
yuhki50 0:70c8e56bac45 210 results->decode_type = UNKNOWN;
yuhki50 0:70c8e56bac45 211
yuhki50 0:70c8e56bac45 212 return true;
yuhki50 0:70c8e56bac45 213 }