Infrared remote library for Arduino: send and receive infrared signals with multiple protocols Port from Arduino-IRremote https://github.com/z3t0/Arduino-IRremote
irRecv.cpp@8:0650578366fd, 2019-06-16 (annotated)
- Committer:
- eunmango
- Date:
- Sun Jun 16 04:36:58 2019 +0000
- Revision:
- 8:0650578366fd
- Parent:
- 4:5e46ae042bc7
dd
Who changed what in which revision?
User | Revision | Line number | New 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 | 3:17440cf7ab90 | 94 | IRrecv::IRrecv (PinName recvpin) : _recvpin(recvpin) |
yuhki50 | 0:70c8e56bac45 | 95 | { |
yuhki50 | 3:17440cf7ab90 | 96 | _recvpin.mode(PullNone); |
yuhki50 | 0:70c8e56bac45 | 97 | } |
yuhki50 | 0:70c8e56bac45 | 98 | |
yuhki50 | 0:70c8e56bac45 | 99 | //+============================================================================= |
yuhki50 | 3:17440cf7ab90 | 100 | // enable IR receive |
yuhki50 | 0:70c8e56bac45 | 101 | // |
yuhki50 | 0:70c8e56bac45 | 102 | void IRrecv::enableIRIn ( ) |
yuhki50 | 0:70c8e56bac45 | 103 | { |
yuhki50 | 3:17440cf7ab90 | 104 | _ticker.detach(); |
eunmango | 8:0650578366fd | 105 | _ticker.attach_us(this, &IRrecv::timer_isr, USECPERTICK); // 100ms마다, "timer_isr" 메소드 실행 |
yuhki50 | 0:70c8e56bac45 | 106 | |
yuhki50 | 0:70c8e56bac45 | 107 | // Initialize state machine variables |
eunmango | 8:0650578366fd | 108 | irparams.rcvstate = STATE_IDLE; // irparams라는 구조체의 muchine state를 의미하는 변수에 STATE_IDLE 상태(아마도 초기상태) 할당 |
eunmango | 8:0650578366fd | 109 | irparams.rawlen = 0; // raw buffer의 length 0으로 초기화 |
yuhki50 | 0:70c8e56bac45 | 110 | } |
yuhki50 | 0:70c8e56bac45 | 111 | |
yuhki50 | 0:70c8e56bac45 | 112 | //+============================================================================= |
yuhki50 | 3:17440cf7ab90 | 113 | // disable IR receive |
yuhki50 | 0:70c8e56bac45 | 114 | // |
yuhki50 | 3:17440cf7ab90 | 115 | void IRrecv::disableIRIn ( ) |
yuhki50 | 0:70c8e56bac45 | 116 | { |
yuhki50 | 3:17440cf7ab90 | 117 | _ticker.detach(); |
yuhki50 | 0:70c8e56bac45 | 118 | } |
yuhki50 | 0:70c8e56bac45 | 119 | |
yuhki50 | 0:70c8e56bac45 | 120 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 121 | // Return if receiving new IR signals |
yuhki50 | 0:70c8e56bac45 | 122 | // |
yuhki50 | 0:70c8e56bac45 | 123 | bool IRrecv::isIdle ( ) |
yuhki50 | 0:70c8e56bac45 | 124 | { |
yuhki50 | 4:5e46ae042bc7 | 125 | return irparams.rcvstate == STATE_IDLE || irparams.rcvstate == STATE_STOP; |
yuhki50 | 0:70c8e56bac45 | 126 | } |
yuhki50 | 3:17440cf7ab90 | 127 | |
yuhki50 | 0:70c8e56bac45 | 128 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 129 | // Restart the ISR state machine |
yuhki50 | 0:70c8e56bac45 | 130 | // |
yuhki50 | 0:70c8e56bac45 | 131 | void IRrecv::resume ( ) |
yuhki50 | 0:70c8e56bac45 | 132 | { |
yuhki50 | 0:70c8e56bac45 | 133 | irparams.rcvstate = STATE_IDLE; |
yuhki50 | 0:70c8e56bac45 | 134 | irparams.rawlen = 0; |
yuhki50 | 0:70c8e56bac45 | 135 | } |
yuhki50 | 0:70c8e56bac45 | 136 | |
yuhki50 | 0:70c8e56bac45 | 137 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 138 | // hashdecode - decode an arbitrary IR code. |
yuhki50 | 0:70c8e56bac45 | 139 | // Instead of decoding using a standard encoding scheme |
yuhki50 | 0:70c8e56bac45 | 140 | // (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. |
yuhki50 | 0:70c8e56bac45 | 141 | // |
yuhki50 | 0:70c8e56bac45 | 142 | // The algorithm: look at the sequence of MARK signals, and see if each one |
yuhki50 | 0:70c8e56bac45 | 143 | // is shorter (0), the same length (1), or longer (2) than the previous. |
yuhki50 | 0:70c8e56bac45 | 144 | // Do the same with the SPACE signals. Hash the resulting sequence of 0's, |
yuhki50 | 0:70c8e56bac45 | 145 | // 1's, and 2's to a 32-bit value. This will give a unique value for each |
yuhki50 | 0:70c8e56bac45 | 146 | // different code (probably), for most code systems. |
yuhki50 | 0:70c8e56bac45 | 147 | // |
yuhki50 | 0:70c8e56bac45 | 148 | // http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html |
yuhki50 | 0:70c8e56bac45 | 149 | // |
yuhki50 | 0:70c8e56bac45 | 150 | // Compare two tick values, returning 0 if newval is shorter, |
yuhki50 | 0:70c8e56bac45 | 151 | // 1 if newval is equal, and 2 if newval is longer |
yuhki50 | 0:70c8e56bac45 | 152 | // Use a tolerance of 20% |
yuhki50 | 0:70c8e56bac45 | 153 | // |
yuhki50 | 0:70c8e56bac45 | 154 | int IRrecv::compare (unsigned int oldval, unsigned int newval) |
yuhki50 | 0:70c8e56bac45 | 155 | { |
yuhki50 | 0:70c8e56bac45 | 156 | if (newval < oldval * .8) return 0 ; |
yuhki50 | 0:70c8e56bac45 | 157 | else if (oldval < newval * .8) return 2 ; |
yuhki50 | 0:70c8e56bac45 | 158 | else return 1 ; |
yuhki50 | 0:70c8e56bac45 | 159 | } |
yuhki50 | 0:70c8e56bac45 | 160 | |
yuhki50 | 0:70c8e56bac45 | 161 | //+============================================================================= |
yuhki50 | 0:70c8e56bac45 | 162 | // Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param |
yuhki50 | 0:70c8e56bac45 | 163 | // Converts the raw code values into a 32-bit hash code. |
yuhki50 | 0:70c8e56bac45 | 164 | // Hopefully this code is unique for each button. |
yuhki50 | 0:70c8e56bac45 | 165 | // This isn't a "real" decoding, just an arbitrary value. |
yuhki50 | 0:70c8e56bac45 | 166 | // |
yuhki50 | 0:70c8e56bac45 | 167 | #define FNV_PRIME_32 16777619 |
yuhki50 | 0:70c8e56bac45 | 168 | #define FNV_BASIS_32 2166136261 |
yuhki50 | 0:70c8e56bac45 | 169 | |
yuhki50 | 0:70c8e56bac45 | 170 | long IRrecv::decodeHash (decode_results *results) |
yuhki50 | 0:70c8e56bac45 | 171 | { |
yuhki50 | 4:5e46ae042bc7 | 172 | unsigned long hash = FNV_BASIS_32; |
yuhki50 | 0:70c8e56bac45 | 173 | |
yuhki50 | 0:70c8e56bac45 | 174 | // Require at least 6 samples to prevent triggering on noise |
yuhki50 | 0:70c8e56bac45 | 175 | if (results->rawlen < 6) return false ; |
yuhki50 | 0:70c8e56bac45 | 176 | |
yuhki50 | 0:70c8e56bac45 | 177 | for (int i = 1; (i + 2) < results->rawlen; i++) { |
yuhki50 | 0:70c8e56bac45 | 178 | int value = compare(results->rawbuf[i], results->rawbuf[i+2]); |
yuhki50 | 0:70c8e56bac45 | 179 | // Add value into the hash |
yuhki50 | 0:70c8e56bac45 | 180 | hash = (hash * FNV_PRIME_32) ^ value; |
yuhki50 | 0:70c8e56bac45 | 181 | } |
yuhki50 | 0:70c8e56bac45 | 182 | |
yuhki50 | 0:70c8e56bac45 | 183 | results->value = hash; |
yuhki50 | 0:70c8e56bac45 | 184 | results->bits = 32; |
yuhki50 | 0:70c8e56bac45 | 185 | results->decode_type = UNKNOWN; |
yuhki50 | 0:70c8e56bac45 | 186 | |
yuhki50 | 0:70c8e56bac45 | 187 | return true; |
yuhki50 | 0:70c8e56bac45 | 188 | } |