RemotoIR Libraryに、IRC Helicopter Propo の受信処理と、受信パルス幅測定処理を追加したものです。
Dependents: SwiftPropoIR_TestProgram irRawDataDisplay spinner2 LPC1114_ir-spinne_main-propo
Fork of RemoteIR 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 * 130616 suupen 00009 * IRC Helicopter "SWIFT" Propo support 00010 * Conditional compilation 00011 * "SWIFT_PROTCOL" 00012 * "IR_RAW_DATA_ANALYSIS" 00013 *-------------------------------------------------------- 00014 */ 00015 00016 #include "ReceiverIR.h" 00017 00018 #define LOCK() 00019 #define UNLOCK() 00020 00021 #define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3))) 00022 00023 /** 00024 * Constructor. 00025 * 00026 * @param rxpin Pin for receive IR signal. 00027 */ 00028 ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) 00029 { 00030 init_state(); 00031 evt.fall(this, &ReceiverIR::isr_fall); 00032 evt.rise(this, &ReceiverIR::isr_rise); 00033 evt.mode(PullUp); 00034 ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000); 00035 } 00036 00037 /** 00038 * Destructor. 00039 */ 00040 ReceiverIR::~ReceiverIR() 00041 { 00042 } 00043 00044 /** 00045 * Get state. 00046 * 00047 * @return Current state. 00048 */ 00049 ReceiverIR::State ReceiverIR::getState() 00050 { 00051 LOCK(); 00052 State s = work.state; 00053 UNLOCK(); 00054 return s; 00055 } 00056 00057 /** 00058 * Get data. 00059 * 00060 * @param format Pointer to format. 00061 * @param buf Buffer of a data. 00062 * @param bitlength Bit length of the buffer. 00063 * 00064 * @return Data bit length. 00065 */ 00066 int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) 00067 { 00068 LOCK(); 00069 00070 if (bitlength < data.bitcount) { 00071 UNLOCK(); 00072 return -1; 00073 } 00074 00075 const int nbits = data.bitcount; 00076 const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0); 00077 *format = data.format; 00078 for (int i = 0; i < nbytes; i++) { 00079 buf[i] = data.buffer[i]; 00080 } 00081 00082 init_state(); 00083 00084 UNLOCK(); 00085 return nbits; 00086 } 00087 00088 void ReceiverIR::init_state(void) 00089 { 00090 work.c1 = -1; 00091 work.c2 = -1; 00092 work.c3 = -1; 00093 work.d1 = -1; 00094 work.d2 = -1; 00095 work.state = Idle; 00096 data.format = RemoteIR::UNKNOWN; 00097 data.bitcount = 0; 00098 timer.stop(); 00099 timer.reset(); 00100 for (int i = 0; i < sizeof(data.buffer); i++) { 00101 data.buffer[i] = 0; 00102 } 00103 } 00104 00105 #ifdef ERRORWAIT 00106 void ReceiverIR::errorWait(void) 00107 { 00108 work.state = ErrorWait; 00109 timeout.detach(); 00110 timeout.attach_us(this, &ReceiverIR::isr_timeout, 50 * 1000); // 50[ms]wait 00111 } 00112 #endif //ERRORWAIT 00113 00114 void ReceiverIR::isr_wdt(void) 00115 { 00116 LOCK(); 00117 static int cnt = 0; 00118 if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) { 00119 cnt++; 00120 if (cnt > 50) { 00121 #if 0 00122 printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", 00123 work.c1, 00124 work.c2, 00125 work.c3, 00126 work.d1, 00127 work.d2, 00128 work.state, 00129 data.format, 00130 data.bitcount); 00131 #endif 00132 init_state(); 00133 cnt = 0; 00134 } 00135 } else { 00136 cnt = 0; 00137 } 00138 UNLOCK(); 00139 } 00140 00141 void ReceiverIR::isr_fall(void) 00142 { 00143 00144 #ifdef IR_RAW_DATA_ANALYSIS 00145 switch (work.state) { 00146 case Idle: 00147 if (work.c1 < 0) { 00148 check.bitcount = 0; 00149 check.timecount[check.bitcount++] = 0; 00150 } else { 00151 check.timecount[check.bitcount++] = timer.read_us() & ~1; 00152 } 00153 break; 00154 case Receiving: 00155 00156 if ((check.bitcount < 1000)) { 00157 check.timecount[check.bitcount++] = timer.read_us() & ~1; 00158 } 00159 break; 00160 default: 00161 break; 00162 } 00163 #endif //IR_RAW_DATA_ANALYSIS 00164 00165 LOCK(); 00166 switch (work.state) { 00167 case Idle: 00168 if (work.c1 < 0) { 00169 timer.start(); 00170 work.c1 = timer.read_us(); 00171 } else { 00172 work.c3 = timer.read_us(); 00173 int a = work.c2 - work.c1; 00174 int b = work.c3 - work.c2; 00175 if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) { 00176 /* 00177 * NEC. 00178 */ 00179 data.format = RemoteIR::NEC; 00180 work.state = Receiving; 00181 data.bitcount = 0; 00182 } else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) { 00183 /* 00184 * NEC Repeat. 00185 */ 00186 data.format = RemoteIR::NEC_REPEAT; 00187 work.state = Received; 00188 data.bitcount = 0; 00189 work.c1 = -1; 00190 work.c2 = -1; 00191 work.c3 = -1; 00192 work.d1 = -1; 00193 work.d2 = -1; 00194 } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) { 00195 /* 00196 * AEHA. 00197 */ 00198 data.format = RemoteIR::AEHA; 00199 work.state = Receiving; 00200 data.bitcount = 0; 00201 } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) { 00202 /* 00203 * AEHA Repeat. 00204 */ 00205 data.format = RemoteIR::AEHA_REPEAT; 00206 work.state = Received; 00207 data.bitcount = 0; 00208 work.c1 = -1; 00209 work.c2 = -1; 00210 work.c3 = -1; 00211 work.d1 = -1; 00212 work.d2 = -1; 00213 #ifdef SWIFT_PROTCOL 00214 } else if (InRange(a, RemoteIR::TUS_SWIFT * 10) && InRange(b, RemoteIR::TUS_SWIFT * 3)) { 00215 /* 00216 * SWIFT. 00217 */ 00218 data.format = RemoteIR::SWIFT; 00219 work.state = Receiving; 00220 data.bitcount = 0; 00221 #endif // SWIFT_PROTCOL 00222 } else { 00223 #ifdef IR_RAW_DATA_ANALYSIS 00224 data.format = RemoteIR::UNKNOWN; 00225 work.state = Receiving; 00226 data.bitcount = 0; 00227 #else // ~IR_RAW_DATA_ANALYSIS 00228 #ifdef ERRORWAIT 00229 errorWait(); 00230 #else // ~ERRORWAIT 00231 init_state(); 00232 #endif // ERRORWAIT 00233 #endif // IR_RAW_DATA_ANALYSIS 00234 } 00235 } 00236 break; 00237 case Receiving: 00238 if (RemoteIR::NEC == data.format) { 00239 work.d2 = timer.read_us(); 00240 int a = work.d2 - work.d1; 00241 if (InRange(a, RemoteIR::TUS_NEC * 3)) { 00242 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00243 } else if (InRange(a, RemoteIR::TUS_NEC * 1)) { 00244 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00245 } 00246 data.bitcount++; 00247 #if 0 00248 /* 00249 * Length of NEC is always 32 bits. 00250 */ 00251 if (32 <= data.bitcount) { 00252 data.state = Received; 00253 work.c1 = -1; 00254 work.c2 = -1; 00255 work.c3 = -1; 00256 work.d1 = -1; 00257 work.d2 = -1; 00258 } 00259 #else 00260 /* 00261 * Set timeout for tail detection automatically. 00262 */ 00263 timeout.detach(); 00264 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5); 00265 #endif 00266 } else if (RemoteIR::AEHA == data.format) { 00267 work.d2 = timer.read_us(); 00268 int a = work.d2 - work.d1; 00269 if (InRange(a, RemoteIR::TUS_AEHA * 3)) { 00270 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00271 } else if (InRange(a, RemoteIR::TUS_AEHA * 1)) { 00272 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00273 } 00274 data.bitcount++; 00275 #if 0 00276 /* 00277 * Typical length of AEHA is 48 bits. 00278 * Please check a specification of your remote controller if you find a problem. 00279 */ 00280 if (48 <= data.bitcount) { 00281 data.state = Received; 00282 work.c1 = -1; 00283 work.c2 = -1; 00284 work.c3 = -1; 00285 work.d1 = -1; 00286 work.d2 = -1; 00287 } 00288 #else 00289 /* 00290 * Set timeout for tail detection automatically. 00291 */ 00292 timeout.detach(); 00293 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5); 00294 #endif 00295 } else if (RemoteIR::SONY == data.format) { 00296 work.d1 = timer.read_us(); 00297 #ifdef SWIFT_PROTCOL 00298 } else if (RemoteIR::SWIFT == data.format) { 00299 work.d2 = timer.read_us(); 00300 int a = work.d2 - work.d1; 00301 if (InRange(a, RemoteIR::TUS_SWIFT * 2)) { 00302 data.buffer[data.bitcount / 8] |= (1 << (7 - (data.bitcount % 8))); 00303 } else if (InRange(a, RemoteIR::TUS_SWIFT * 1)) { 00304 data.buffer[data.bitcount / 8] &= ~(1 << (7 - (data.bitcount % 8))); 00305 } 00306 data.bitcount++; 00307 #if 0 00308 /* 00309 * Length of SWIFT is always 32 bits. 00310 */ 00311 if (32 <= data.bitcount) { 00312 work.state = Received; 00313 work.c1 = -1; 00314 work.c2 = -1; 00315 work.c3 = -1; 00316 work.d1 = -1; 00317 work.d2 = -1; 00318 } 00319 #else 00320 /* 00321 * Set timeout for tail detection automatically. 00322 */ 00323 timeout.detach(); 00324 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SWIFT * 5); 00325 #endif 00326 #endif // SWIFT_PROTCOL 00327 00328 #ifdef IR_RAW_DATA_ANALYSIS 00329 } else if (RemoteIR::SWIFT == data.format) { 00330 /* 00331 * Set timeout for tail detection automatically. 00332 */ 00333 timeout.detach(); 00334 timeout.attach_us(this, &ReceiverIR::isr_timeout, (work.c3 - work.c2) * 5); 00335 #endif // IR_RAW_DATA_ANALYSIS 00336 } 00337 break; 00338 case Received: 00339 break; 00340 #ifdef ERRORWAIT 00341 case ErrorWait: 00342 errorWait(); 00343 break; 00344 #endif //ERRORWAIT 00345 default: 00346 break; 00347 } 00348 UNLOCK(); 00349 } 00350 00351 void ReceiverIR::isr_rise(void) 00352 { 00353 00354 #ifdef IR_RAW_DATA_ANALYSIS 00355 switch (work.state) { 00356 case Idle: 00357 case Receiving: 00358 check.timecount[check.bitcount++] = timer.read_us() | 1; 00359 break; 00360 #ifdef ERRORWAIT 00361 case ErrorWait: 00362 // nothing 00363 break; 00364 #endif //ERRORWAIT 00365 default: 00366 break; 00367 } 00368 #endif //IR_RAW_DATA_ANALYSIS 00369 00370 LOCK(); 00371 switch (work.state) { 00372 case Idle: 00373 if (0 <= work.c1) { 00374 work.c2 = timer.read_us(); 00375 int a = work.c2 - work.c1; 00376 if (InRange(a, RemoteIR::TUS_SONY * 4)) { 00377 data.format = RemoteIR::SONY; 00378 work.state = Receiving; 00379 data.bitcount = 0; 00380 } else { 00381 static const int MINIMUM_LEADER_WIDTH = 150; 00382 if (a < MINIMUM_LEADER_WIDTH) { 00383 init_state(); 00384 } 00385 } 00386 } else { 00387 init_state(); 00388 } 00389 break; 00390 case Receiving: 00391 if (RemoteIR::NEC == data.format) { 00392 work.d1 = timer.read_us(); 00393 } else if (RemoteIR::AEHA == data.format) { 00394 work.d1 = timer.read_us(); 00395 #ifdef SWIFT_PROTCOL 00396 } else if (RemoteIR::SWIFT == data.format) { 00397 work.d1 = timer.read_us(); 00398 #endif // SWIFT_PROTCOL 00399 } else if (RemoteIR::SONY == data.format) { 00400 work.d2 = timer.read_us(); 00401 int a = work.d2 - work.d1; 00402 if (InRange(a, RemoteIR::TUS_SONY * 2)) { 00403 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); 00404 } else if (InRange(a, RemoteIR::TUS_SONY * 1)) { 00405 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); 00406 } 00407 data.bitcount++; 00408 #if 0 00409 /* 00410 * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...) 00411 * By a model only? 00412 * Please check a specification of your remote controller if you find a problem. 00413 */ 00414 if (12 <= data.bitcount) { 00415 data.state = Received; 00416 work.c1 = -1; 00417 work.c2 = -1; 00418 work.c3 = -1; 00419 work.d1 = -1; 00420 work.d2 = -1; 00421 } 00422 #else 00423 /* 00424 * Set timeout for tail detection automatically. 00425 */ 00426 timeout.detach(); 00427 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4); 00428 #endif 00429 } 00430 break; 00431 case Received: 00432 break; 00433 #ifdef ERRORWAIT 00434 case ErrorWait: 00435 // nothing 00436 break; 00437 #endif //ERRORWAIT 00438 default: 00439 break; 00440 } 00441 UNLOCK(); 00442 } 00443 00444 void ReceiverIR::isr_timeout(void) 00445 { 00446 LOCK(); 00447 #if 0 00448 printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", 00449 work.c1, 00450 work.c2, 00451 work.c3, 00452 work.d1, 00453 work.d2, 00454 work.state, 00455 data.format, 00456 data.bitcount); 00457 #endif 00458 00459 #ifdef IR_RAW_DATA_ANALYSIS 00460 #if 1 //debug 00461 for ( int i = 0; i < check.bitcount; i++) { 00462 printf("%02d : %06d , %06d , %04d \n", 00463 i, 00464 check.timecount[i], 00465 check.timecount[i + 1], 00466 (check.timecount[i + 1] - check.timecount[i])); 00467 00468 if( (i % 2) != 0) { 00469 printf("\n"); 00470 } 00471 } 00472 printf("\n"); 00473 #endif //debug 00474 #endif //IR_RAW_DATA_ANALYSIS 00475 00476 if (work.state == Receiving) { 00477 work.state = Received; 00478 work.c1 = -1; 00479 work.c2 = -1; 00480 work.c3 = -1; 00481 work.d1 = -1; 00482 work.d2 = -1; 00483 } 00484 #ifdef ERRORWAIT 00485 else if(work.state == ErrorWait){ 00486 init_state(); 00487 } 00488 #endif // ERRORWAIT 00489 UNLOCK(); 00490 } 00491 00492
Generated on Thu Jul 14 2022 02:07:30 by 1.7.2