Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of IR_remote by
ReceiverIR.cpp
00001 /** 00002 * IR receiver (Version 0.0.4) 00003 * 00004 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) 00005 * http://shinta.main.jp/ 00006 */ 00007 00008 #include "ReceiverIR.h" 00009 00010 #define LOCK() 00011 #define UNLOCK() 00012 00013 #define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3))) 00014 00015 /** 00016 * Constructor. 00017 * 00018 * @param rxpin Pin for receive IR signal. 00019 */ 00020 ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) { 00021 init_state(); 00022 evt.fall(this, &ReceiverIR::isr_fall); 00023 evt.rise(this, &ReceiverIR::isr_rise); 00024 evt.mode(PullUp); 00025 ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000); 00026 } 00027 00028 /** 00029 * Destructor. 00030 */ 00031 ReceiverIR::~ReceiverIR() { 00032 } 00033 00034 /** 00035 * Get state. 00036 * 00037 * @return Current state. 00038 */ 00039 ReceiverIR::State ReceiverIR::getState() { 00040 LOCK(); 00041 State s = work.state; 00042 UNLOCK(); 00043 return s; 00044 } 00045 00046 /** 00047 * Get data. 00048 * 00049 * @param format Pointer to format. 00050 * @param buf Buffer of a data. 00051 * @param bitlength Bit length of the buffer. 00052 * 00053 * @return Data bit length. 00054 */ 00055 int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) { 00056 LOCK(); 00057 00058 if (bitlength < data.bitcount) { 00059 UNLOCK(); 00060 return -1; 00061 } 00062 00063 const int nbits = data.bitcount; 00064 const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0); 00065 *format = data.format; 00066 for (int i = 0; i < nbytes; i++) { 00067 buf[i] = data.buffer[i]; 00068 } 00069 00070 init_state(); 00071 00072 UNLOCK(); 00073 return nbits; 00074 } 00075 00076 void ReceiverIR::init_state(void) { 00077 work.c1 = -1; 00078 work.c2 = -1; 00079 work.c3 = -1; 00080 work.d1 = -1; 00081 work.d2 = -1; 00082 work.state = Idle; 00083 data.format = RemoteIR::UNKNOWN; 00084 data.bitcount = 0; 00085 timer.stop(); 00086 timer.reset(); 00087 for (int i = 0; i < sizeof(data.buffer); i++) { 00088 data.buffer[i] = 0; 00089 } 00090 } 00091 00092 void ReceiverIR::isr_wdt(void) { 00093 LOCK(); 00094 static int cnt = 0; 00095 if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) { 00096 cnt++; 00097 if (cnt > 50) { 00098 #if 0 00099 printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", 00100 work.c1, 00101 work.c2, 00102 work.c3, 00103 work.d1, 00104 work.d2, 00105 work.state, 00106 data.format, 00107 data.bitcount); 00108 #endif 00109 init_state(); 00110 cnt = 0; 00111 } 00112 } else { 00113 cnt = 0; 00114 } 00115 UNLOCK(); 00116 } 00117 00118 void ReceiverIR::isr_fall(void) { 00119 LOCK(); 00120 switch (work.state) { 00121 case Idle: 00122 if (work.c1 < 0) { 00123 timer.start(); 00124 work.c1 = timer.read_us(); 00125 } else { 00126 work.c3 = timer.read_us(); 00127 int a = work.c2 - work.c1; 00128 int b = work.c3 - work.c2; 00129 if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) { 00130 /* 00131 * NEC. 00132 */ 00133 data.format = RemoteIR::NEC; 00134 work.state = Receiving; 00135 data.bitcount = 0; 00136 } else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) { 00137 /* 00138 * NEC Repeat. 00139 */ 00140 data.format = RemoteIR::NEC_REPEAT; 00141 work.state = Received; 00142 data.bitcount = 0; 00143 work.c1 = -1; 00144 work.c2 = -1; 00145 work.c3 = -1; 00146 work.d1 = -1; 00147 work.d2 = -1; 00148 } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) { 00149 /* 00150 * AEHA. 00151 */ 00152 data.format = RemoteIR::AEHA; 00153 work.state = Receiving; 00154 data.bitcount = 0; 00155 } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) { 00156 /* 00157 * AEHA Repeat. 00158 */ 00159 data.format = RemoteIR::AEHA_REPEAT; 00160 work.state = Received; 00161 data.bitcount = 0; 00162 work.c1 = -1; 00163 work.c2 = -1; 00164 work.c3 = -1; 00165 work.d1 = -1; 00166 work.d2 = -1; 00167 } else { 00168 init_state(); 00169 } 00170 } 00171 break; 00172 case Receiving: 00173 if (RemoteIR::NEC == data.format) { 00174 work.d2 = timer.read_us(); 00175 int a = work.d2 - work.d1; 00176 if (InRange(a, RemoteIR::TUS_NEC * 3)) { 00177 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00178 } else if (InRange(a, RemoteIR::TUS_NEC * 1)) { 00179 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00180 } 00181 data.bitcount++; 00182 #if 0 00183 /* 00184 * Length of NEC is always 32 bits. 00185 */ 00186 if (32 <= data.bitcount) { 00187 data.state = Received; 00188 work.c1 = -1; 00189 work.c2 = -1; 00190 work.c3 = -1; 00191 work.d1 = -1; 00192 work.d2 = -1; 00193 } 00194 #else 00195 /* 00196 * Set timeout for tail detection automatically. 00197 */ 00198 timeout.detach(); 00199 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5); 00200 #endif 00201 } else if (RemoteIR::AEHA == data.format) { 00202 work.d2 = timer.read_us(); 00203 int a = work.d2 - work.d1; 00204 if (InRange(a, RemoteIR::TUS_AEHA * 3)) { 00205 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00206 } else if (InRange(a, RemoteIR::TUS_AEHA * 1)) { 00207 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00208 } 00209 data.bitcount++; 00210 #if 0 00211 /* 00212 * Typical length of AEHA is 48 bits. 00213 * Please check a specification of your remote controller if you find a problem. 00214 */ 00215 if (48 <= data.bitcount) { 00216 data.state = Received; 00217 work.c1 = -1; 00218 work.c2 = -1; 00219 work.c3 = -1; 00220 work.d1 = -1; 00221 work.d2 = -1; 00222 } 00223 #else 00224 /* 00225 * Set timeout for tail detection automatically. 00226 */ 00227 timeout.detach(); 00228 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5); 00229 #endif 00230 } else if (RemoteIR::SONY == data.format) { 00231 work.d1 = timer.read_us(); 00232 } 00233 break; 00234 case Received: 00235 break; 00236 default: 00237 break; 00238 } 00239 UNLOCK(); 00240 } 00241 00242 void ReceiverIR::isr_rise(void) { 00243 LOCK(); 00244 switch (work.state) { 00245 case Idle: 00246 if (0 <= work.c1) { 00247 work.c2 = timer.read_us(); 00248 int a = work.c2 - work.c1; 00249 if (InRange(a, RemoteIR::TUS_SONY * 4)) { 00250 data.format = RemoteIR::SONY; 00251 work.state = Receiving; 00252 data.bitcount = 0; 00253 } else { 00254 static const int MINIMUM_LEADER_WIDTH = 150; 00255 if (a < MINIMUM_LEADER_WIDTH) { 00256 init_state(); 00257 } 00258 } 00259 } else { 00260 init_state(); 00261 } 00262 break; 00263 case Receiving: 00264 if (RemoteIR::NEC == data.format) { 00265 work.d1 = timer.read_us(); 00266 } else if (RemoteIR::AEHA == data.format) { 00267 work.d1 = timer.read_us(); 00268 } else if (RemoteIR::SONY == data.format) { 00269 work.d2 = timer.read_us(); 00270 int a = work.d2 - work.d1; 00271 if (InRange(a, RemoteIR::TUS_SONY * 2)) { 00272 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00273 } else if (InRange(a, RemoteIR::TUS_SONY * 1)) { 00274 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00275 } 00276 data.bitcount++; 00277 #if 0 00278 /* 00279 * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...) 00280 * By a model only? 00281 * Please check a specification of your remote controller if you find a problem. 00282 */ 00283 if (12 <= data.bitcount) { 00284 data.state = Received; 00285 work.c1 = -1; 00286 work.c2 = -1; 00287 work.c3 = -1; 00288 work.d1 = -1; 00289 work.d2 = -1; 00290 } 00291 #else 00292 /* 00293 * Set timeout for tail detection automatically. 00294 */ 00295 timeout.detach(); 00296 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4); 00297 #endif 00298 } 00299 break; 00300 case Received: 00301 break; 00302 default: 00303 break; 00304 } 00305 UNLOCK(); 00306 } 00307 00308 void ReceiverIR::isr_timeout(void) { 00309 LOCK(); 00310 #if 0 00311 printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", 00312 work.c1, 00313 work.c2, 00314 work.c3, 00315 work.d1, 00316 work.d2, 00317 work.state, 00318 data.format, 00319 data.bitcount); 00320 #endif 00321 if (work.state == Receiving) { 00322 work.state = Received; 00323 work.c1 = -1; 00324 work.c2 = -1; 00325 work.c3 = -1; 00326 work.d1 = -1; 00327 work.d2 = -1; 00328 } 00329 UNLOCK(); 00330 }
Generated on Thu Jul 21 2022 09:28:40 by
1.7.2
