RemotoIR Libraryに、IRC Helicopter Propo の受信処理と、受信パルス幅測定処理を追加したものです。

Dependents:   SwiftPropoIR_TestProgram irRawDataDisplay spinner2 LPC1114_ir-spinne_main-propo

Fork of RemoteIR by Shinichiro Nakamura

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ReceiverIR.cpp Source File

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