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:
Thu Mar 10 15:39:34 2016 +0000
Revision:
7:c82a0d54a024
Parent:
0:70c8e56bac45
change USECPERTICK

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 // Gets one undecoded level at a time from the raw buffer.
yuhki50 0:70c8e56bac45 6 // The RC5/6 decoding is easier if the data is broken into time intervals.
yuhki50 0:70c8e56bac45 7 // E.g. if the buffer has MARK for 2 time intervals and SPACE for 1,
yuhki50 0:70c8e56bac45 8 // successive calls to getRClevel will return MARK, MARK, SPACE.
yuhki50 0:70c8e56bac45 9 // offset and used are updated to keep track of the current position.
yuhki50 0:70c8e56bac45 10 // t1 is the time interval for a single bit in microseconds.
yuhki50 0:70c8e56bac45 11 // Returns -1 for error (measured time interval is not a multiple of t1).
yuhki50 0:70c8e56bac45 12 //
yuhki50 0:70c8e56bac45 13 #if (DECODE_RC5 || DECODE_RC6)
yuhki50 0:70c8e56bac45 14 int IRrecv::getRClevel (decode_results *results, int *offset, int *used, int t1)
yuhki50 0:70c8e56bac45 15 {
yuhki50 0:70c8e56bac45 16 int width;
yuhki50 0:70c8e56bac45 17 int val;
yuhki50 0:70c8e56bac45 18 int correction;
yuhki50 0:70c8e56bac45 19 int avail;
yuhki50 0:70c8e56bac45 20
yuhki50 0:70c8e56bac45 21 if (*offset >= results->rawlen) return SPACE ; // After end of recorded buffer, assume SPACE.
yuhki50 0:70c8e56bac45 22 width = results->rawbuf[*offset];
yuhki50 0:70c8e56bac45 23 val = ((*offset) % 2) ? MARK : SPACE;
yuhki50 0:70c8e56bac45 24 correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS;
yuhki50 0:70c8e56bac45 25
yuhki50 0:70c8e56bac45 26 if (MATCH(width, ( t1) + correction)) avail = 1 ;
yuhki50 0:70c8e56bac45 27 else if (MATCH(width, (2*t1) + correction)) avail = 2 ;
yuhki50 0:70c8e56bac45 28 else if (MATCH(width, (3*t1) + correction)) avail = 3 ;
yuhki50 0:70c8e56bac45 29 else return -1 ;
yuhki50 0:70c8e56bac45 30
yuhki50 0:70c8e56bac45 31 (*used)++;
yuhki50 0:70c8e56bac45 32 if (*used >= avail) {
yuhki50 0:70c8e56bac45 33 *used = 0;
yuhki50 0:70c8e56bac45 34 (*offset)++;
yuhki50 0:70c8e56bac45 35 }
yuhki50 0:70c8e56bac45 36
yuhki50 0:70c8e56bac45 37 DBG_PRINTLN( (val == MARK) ? "MARK" : "SPACE" );
yuhki50 0:70c8e56bac45 38
yuhki50 0:70c8e56bac45 39 return val;
yuhki50 0:70c8e56bac45 40 }
yuhki50 0:70c8e56bac45 41 #endif
yuhki50 0:70c8e56bac45 42
yuhki50 0:70c8e56bac45 43 //==============================================================================
yuhki50 0:70c8e56bac45 44 // RRRR CCCC 55555
yuhki50 0:70c8e56bac45 45 // R R C 5
yuhki50 0:70c8e56bac45 46 // RRRR C 5555
yuhki50 0:70c8e56bac45 47 // R R C 5
yuhki50 0:70c8e56bac45 48 // R R CCCC 5555
yuhki50 0:70c8e56bac45 49 //
yuhki50 0:70c8e56bac45 50 // NB: First bit must be a one (start bit)
yuhki50 0:70c8e56bac45 51 //
yuhki50 0:70c8e56bac45 52 #define MIN_RC5_SAMPLES 11
yuhki50 0:70c8e56bac45 53 #define RC5_T1 889
yuhki50 0:70c8e56bac45 54 #define RC5_RPT_LENGTH 46000
yuhki50 0:70c8e56bac45 55
yuhki50 0:70c8e56bac45 56 //+=============================================================================
yuhki50 0:70c8e56bac45 57 #if SEND_RC5
yuhki50 0:70c8e56bac45 58 void IRsend::sendRC5 (unsigned long data, int nbits)
yuhki50 0:70c8e56bac45 59 {
yuhki50 0:70c8e56bac45 60 // Set IR carrier frequency
yuhki50 0:70c8e56bac45 61 enableIROut(36);
yuhki50 0:70c8e56bac45 62
yuhki50 0:70c8e56bac45 63 // Start
yuhki50 0:70c8e56bac45 64 mark(RC5_T1);
yuhki50 0:70c8e56bac45 65 space(RC5_T1);
yuhki50 0:70c8e56bac45 66 mark(RC5_T1);
yuhki50 0:70c8e56bac45 67
yuhki50 0:70c8e56bac45 68 // Data
yuhki50 0:70c8e56bac45 69 for (unsigned long mask = 1UL << (nbits - 1); mask; mask >>= 1) {
yuhki50 0:70c8e56bac45 70 if (data & mask) {
yuhki50 0:70c8e56bac45 71 space(RC5_T1); // 1 is space, then mark
yuhki50 0:70c8e56bac45 72 mark(RC5_T1);
yuhki50 0:70c8e56bac45 73 } else {
yuhki50 0:70c8e56bac45 74 mark(RC5_T1);
yuhki50 0:70c8e56bac45 75 space(RC5_T1);
yuhki50 0:70c8e56bac45 76 }
yuhki50 0:70c8e56bac45 77 }
yuhki50 0:70c8e56bac45 78
yuhki50 0:70c8e56bac45 79 space(0); // Always end with the LED off
yuhki50 0:70c8e56bac45 80 }
yuhki50 0:70c8e56bac45 81 #endif
yuhki50 0:70c8e56bac45 82
yuhki50 0:70c8e56bac45 83 //+=============================================================================
yuhki50 0:70c8e56bac45 84 #if DECODE_RC5
yuhki50 0:70c8e56bac45 85 bool IRrecv::decodeRC5 (decode_results *results)
yuhki50 0:70c8e56bac45 86 {
yuhki50 0:70c8e56bac45 87 int nbits;
yuhki50 0:70c8e56bac45 88 long data = 0;
yuhki50 0:70c8e56bac45 89 int used = 0;
yuhki50 0:70c8e56bac45 90 int offset = 1; // Skip gap space
yuhki50 0:70c8e56bac45 91
yuhki50 0:70c8e56bac45 92 if (irparams.rawlen < MIN_RC5_SAMPLES + 2) return false ;
yuhki50 0:70c8e56bac45 93
yuhki50 0:70c8e56bac45 94 // Get start bits
yuhki50 0:70c8e56bac45 95 if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ;
yuhki50 0:70c8e56bac45 96 if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return false ;
yuhki50 0:70c8e56bac45 97 if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return false ;
yuhki50 0:70c8e56bac45 98
yuhki50 0:70c8e56bac45 99 for (nbits = 0; offset < irparams.rawlen; nbits++) {
yuhki50 0:70c8e56bac45 100 int levelA = getRClevel(results, &offset, &used, RC5_T1);
yuhki50 0:70c8e56bac45 101 int levelB = getRClevel(results, &offset, &used, RC5_T1);
yuhki50 0:70c8e56bac45 102
yuhki50 0:70c8e56bac45 103 if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 1 ;
yuhki50 0:70c8e56bac45 104 else if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 0 ;
yuhki50 0:70c8e56bac45 105 else return false ;
yuhki50 0:70c8e56bac45 106 }
yuhki50 0:70c8e56bac45 107
yuhki50 0:70c8e56bac45 108 // Success
yuhki50 0:70c8e56bac45 109 results->bits = nbits;
yuhki50 0:70c8e56bac45 110 results->value = data;
yuhki50 0:70c8e56bac45 111 results->decode_type = RC5;
yuhki50 0:70c8e56bac45 112 return true;
yuhki50 0:70c8e56bac45 113 }
yuhki50 0:70c8e56bac45 114 #endif
yuhki50 0:70c8e56bac45 115
yuhki50 0:70c8e56bac45 116 //+=============================================================================
yuhki50 0:70c8e56bac45 117 // RRRR CCCC 6666
yuhki50 0:70c8e56bac45 118 // R R C 6
yuhki50 0:70c8e56bac45 119 // RRRR C 6666
yuhki50 0:70c8e56bac45 120 // R R C 6 6
yuhki50 0:70c8e56bac45 121 // R R CCCC 666
yuhki50 0:70c8e56bac45 122 //
yuhki50 0:70c8e56bac45 123 // NB : Caller needs to take care of flipping the toggle bit
yuhki50 0:70c8e56bac45 124 //
yuhki50 0:70c8e56bac45 125 #define MIN_RC6_SAMPLES 1
yuhki50 0:70c8e56bac45 126 #define RC6_HDR_MARK 2666
yuhki50 0:70c8e56bac45 127 #define RC6_HDR_SPACE 889
yuhki50 0:70c8e56bac45 128 #define RC6_T1 444
yuhki50 0:70c8e56bac45 129 #define RC6_RPT_LENGTH 46000
yuhki50 0:70c8e56bac45 130
yuhki50 0:70c8e56bac45 131 #if SEND_RC6
yuhki50 0:70c8e56bac45 132 void IRsend::sendRC6 (unsigned long data, int nbits)
yuhki50 0:70c8e56bac45 133 {
yuhki50 0:70c8e56bac45 134 // Set IR carrier frequency
yuhki50 0:70c8e56bac45 135 enableIROut(36);
yuhki50 0:70c8e56bac45 136
yuhki50 0:70c8e56bac45 137 // Header
yuhki50 0:70c8e56bac45 138 mark(RC6_HDR_MARK);
yuhki50 0:70c8e56bac45 139 space(RC6_HDR_SPACE);
yuhki50 0:70c8e56bac45 140
yuhki50 0:70c8e56bac45 141 // Start bit
yuhki50 0:70c8e56bac45 142 mark(RC6_T1);
yuhki50 0:70c8e56bac45 143 space(RC6_T1);
yuhki50 0:70c8e56bac45 144
yuhki50 0:70c8e56bac45 145 // Data
yuhki50 0:70c8e56bac45 146 for (unsigned long i = 1, mask = 1UL << (nbits - 1); mask; i++, mask >>= 1) {
yuhki50 0:70c8e56bac45 147 // The fourth bit we send is a "double width trailer bit"
yuhki50 0:70c8e56bac45 148 int t = (i == 4) ? (RC6_T1 * 2) : (RC6_T1) ;
yuhki50 0:70c8e56bac45 149 if (data & mask) {
yuhki50 0:70c8e56bac45 150 mark(t);
yuhki50 0:70c8e56bac45 151 space(t);
yuhki50 0:70c8e56bac45 152 } else {
yuhki50 0:70c8e56bac45 153 space(t);
yuhki50 0:70c8e56bac45 154 mark(t);
yuhki50 0:70c8e56bac45 155 }
yuhki50 0:70c8e56bac45 156 }
yuhki50 0:70c8e56bac45 157
yuhki50 0:70c8e56bac45 158 space(0); // Always end with the LED off
yuhki50 0:70c8e56bac45 159 }
yuhki50 0:70c8e56bac45 160 #endif
yuhki50 0:70c8e56bac45 161
yuhki50 0:70c8e56bac45 162 //+=============================================================================
yuhki50 0:70c8e56bac45 163 #if DECODE_RC6
yuhki50 0:70c8e56bac45 164 bool IRrecv::decodeRC6 (decode_results *results)
yuhki50 0:70c8e56bac45 165 {
yuhki50 0:70c8e56bac45 166 int nbits;
yuhki50 0:70c8e56bac45 167 long data = 0;
yuhki50 0:70c8e56bac45 168 int used = 0;
yuhki50 0:70c8e56bac45 169 int offset = 1; // Skip first space
yuhki50 0:70c8e56bac45 170
yuhki50 0:70c8e56bac45 171 if (results->rawlen < MIN_RC6_SAMPLES) return false ;
yuhki50 0:70c8e56bac45 172
yuhki50 0:70c8e56bac45 173 // Initial mark
yuhki50 0:70c8e56bac45 174 if (!MATCH_MARK(results->rawbuf[offset++], RC6_HDR_MARK)) return false ;
yuhki50 0:70c8e56bac45 175 if (!MATCH_SPACE(results->rawbuf[offset++], RC6_HDR_SPACE)) return false ;
yuhki50 0:70c8e56bac45 176
yuhki50 0:70c8e56bac45 177 // Get start bit (1)
yuhki50 0:70c8e56bac45 178 if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return false ;
yuhki50 0:70c8e56bac45 179 if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return false ;
yuhki50 0:70c8e56bac45 180
yuhki50 0:70c8e56bac45 181 for (nbits = 0; offset < results->rawlen; nbits++) {
yuhki50 0:70c8e56bac45 182 int levelA, levelB; // Next two levels
yuhki50 0:70c8e56bac45 183
yuhki50 0:70c8e56bac45 184 levelA = getRClevel(results, &offset, &used, RC6_T1);
yuhki50 0:70c8e56bac45 185 if (nbits == 3) {
yuhki50 0:70c8e56bac45 186 // T bit is double wide; make sure second half matches
yuhki50 0:70c8e56bac45 187 if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return false;
yuhki50 0:70c8e56bac45 188 }
yuhki50 0:70c8e56bac45 189
yuhki50 0:70c8e56bac45 190 levelB = getRClevel(results, &offset, &used, RC6_T1);
yuhki50 0:70c8e56bac45 191 if (nbits == 3) {
yuhki50 0:70c8e56bac45 192 // T bit is double wide; make sure second half matches
yuhki50 0:70c8e56bac45 193 if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return false;
yuhki50 0:70c8e56bac45 194 }
yuhki50 0:70c8e56bac45 195
yuhki50 0:70c8e56bac45 196 if ((levelA == MARK ) && (levelB == SPACE)) data = (data << 1) | 1 ; // inverted compared to RC5
yuhki50 0:70c8e56bac45 197 else if ((levelA == SPACE) && (levelB == MARK )) data = (data << 1) | 0 ; // ...
yuhki50 0:70c8e56bac45 198 else return false ; // Error
yuhki50 0:70c8e56bac45 199 }
yuhki50 0:70c8e56bac45 200
yuhki50 0:70c8e56bac45 201 // Success
yuhki50 0:70c8e56bac45 202 results->bits = nbits;
yuhki50 0:70c8e56bac45 203 results->value = data;
yuhki50 0:70c8e56bac45 204 results->decode_type = RC6;
yuhki50 0:70c8e56bac45 205 return true;
yuhki50 0:70c8e56bac45 206 }
yuhki50 0:70c8e56bac45 207 #endif