yasuyuki onodera / IR

Dependents:   mbed_IR

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers IR.cpp Source File

IR.cpp

00001 //**********************
00002 // IR.cpp for mbed
00003 //
00004 // IR ir(P0_12);
00005 //
00006 // (1)NEC format
00007 // IR carrier=38KHz
00008 // Time unit=0.56ms
00009 // logical 0 = on 1T + off 1T
00010 // logical 1 = on 1T + off 3T
00011 // reader=on 16T + off 8T
00012 // stop=on 1T
00013 // frame=108ms
00014 //
00015 // (2)AEHA format
00016 // IR carrier=33 - 40KHz
00017 // Time unit=0.35 - 0.50ms
00018 // logical 0 = on 1T + off 1T
00019 // logical 1 = on 1T + off 3T
00020 // reader=on 8T + off 4T
00021 // trailer=on 1T + 8ms
00022 //
00023 // (3)SONY format
00024 // IR carrier=40KHz
00025 // Time unit=0.6ms
00026 // logical 0 = off 1T + on 1T
00027 // logical 1 = off 1T + on 2T
00028 // reader=on 4T
00029 // frame=45ms
00030 //
00031 // caution:
00032 // no detecting repeat code, return bits=0;
00033 //
00034 // (C)Copyright 2014-2015 All rights reserved by Y.Onodera
00035 // http://einstlab.web.fc2.com
00036 //**********************
00037 
00038 #include "mbed.h"
00039 #include "IR.h"
00040 
00041 IR::IR (PinName irin, PinName irout) : _irin(irin),_irout(irout){
00042     init();
00043 }
00044 
00045 
00046 void IR::init()
00047 {
00048     _irin.mode(PullUp);
00049     _irout=0;
00050 }
00051 
00052 unsigned char IR::countHigh(){
00053 
00054     unsigned char i=0;
00055 
00056     while(_irin==1);    // wait
00057 
00058     while(_irin==0){
00059         ++i;
00060         wait_us(26);
00061         wait_us(26);
00062         if(i==0) return 0;  // timeout
00063     }
00064     // NEC:i=19*8=152, i*2*26.5us=8056us
00065     // AEHA:i=19*4=76,  i*2*26.5us=4028us
00066     // 1T:i=19*1=19
00067 
00068     return i;
00069 
00070 }
00071 
00072 
00073 unsigned char IR::countLow(){
00074 
00075     unsigned char i=0;
00076 
00077     while(_irin==0);    // wait
00078 
00079     while(_irin==1){
00080         ++i;
00081         wait_us(26);
00082         if(i==0) return 0;  // timeout
00083     }
00084     // NEC:i=19*8=152, i*26.5us=4028us
00085     // AEHA:i=19*4=76,  i*26.5us=2014us
00086     // 1T:i=19*1=19
00087     // 3T:i=19*3=57
00088 
00089     return i;
00090 
00091 }
00092 
00093 
00094 void IR::getIR2(){
00095 
00096     unsigned char i;
00097     unsigned short j;   // capable 32768 bits = 4096 bytes
00098     unsigned char k;
00099 
00100     bits=0;
00101     for(j=0;j<IR_LIMITS;j++){  // buffer bytes LIMITS
00102         for(i=0;i<8;i++){   // 8 bits
00103             k = countHigh()*2;
00104             if(mode==3){
00105                 buf[j]>>=1;
00106                 // Threschold = 35, 23 = 1T, 46 = 2T; for SONY
00107                 buf[j]+=((k>30) ? 0x80: 0);
00108                 ++bits;
00109             }
00110             k = countLow();
00111             if(k==0){
00112                 buf[j]>>=(8-i);
00113                 return;
00114             }
00115             if(mode!=3){
00116                 buf[j]>>=1;
00117                 // Threschold = 38, 19 = 1T, 57 = 3T; for NEC
00118                 // Threschold = 30, 15 = 1T, 45 = 3T; for AEHA
00119                 buf[j]+=((k>30) ? 0x80: 0);
00120                 ++bits;
00121             }
00122         }
00123     }
00124 
00125 }
00126 
00127 
00128 void IR::getIR(){
00129 
00130     unsigned char i;
00131 
00132     i = countHigh();    // Start
00133     mode=0;
00134     if(40<i){
00135         if(i<51){
00136             mode=3; // SONY, 46
00137         }else{
00138             if(100<i){
00139                 mode=1; // NEC, 173
00140             }else{
00141                 mode=2; // AEHA, 54-77
00142             }
00143         }
00144         i = countLow();
00145         getIR2();
00146     }
00147 
00148 }
00149 
00150 
00151 // out ON with 38KHz
00152 void IR::outON(char n, char t)
00153 {
00154 
00155     unsigned char i,j;
00156 
00157     for(j=0;j<t;j++){
00158         for(i=0;i<n;i++){
00159             // 38KHz, 1/3duty
00160             _irout=1; // LED ON=8.6ms
00161             wait_us(6);
00162             _irout=0; // LED OFF=17.4ms
00163             wait_us(15);
00164         }
00165     }
00166     
00167 }
00168 
00169 // out OFF without 38KHz
00170 void IR::outOFF(char n, char t)
00171 {
00172 
00173     unsigned char i,j;
00174 
00175     for(j=0;j<t;j++){
00176         for(i=0;i<n;i++){
00177             // 38KHz, 1/3duty
00178             _irout=0; // LED OFF
00179             wait_us(6);
00180             _irout=0; // LED OFF
00181             wait_us(15);
00182         }
00183     }
00184     
00185 }
00186 
00187 
00188 void IR::setIR()
00189 {
00190 
00191     unsigned char j,t;
00192     unsigned short i,n;
00193 
00194     if(bits==0)return;      // no data
00195 
00196     // reader
00197     switch(mode){
00198         case 1:
00199             if(bits!=32)return;
00200             outON(NEC,16);  // ON(16T)
00201             outOFF(NEC,8);  // OFF(8T)
00202             t=16+8;
00203             break;
00204         case 2:
00205             if(bits>IR_LIMITS*8)return;
00206             outON(AEHA,8);  // ON(8T)
00207             outOFF(AEHA,4); // OFF(4T)
00208             t=8+4;
00209             break;
00210         case 3:
00211             if(!(bits==12 || bits==15 || bits==20))return;
00212             outON(SONY,4);  // ON(4T)
00213             t=4;
00214             break;
00215     }
00216 
00217     // data
00218     switch(mode){
00219         case 1:
00220             for(i=0;i<4;i++){
00221                 for(j=0;j<8;j++){
00222                     if(buf[i] & (0x1<<j)){
00223                         outON(NEC,1);   // ON(1T)
00224                         outOFF(NEC,3);  // OFF(3T)
00225                         t+=4;
00226                     }else{
00227                         outON(NEC,1);   // ON(1T)
00228                         outOFF(NEC,1);  // OFF(1T)
00229                         t+=2;
00230                     }
00231                 }
00232             }
00233             break;
00234         case 2:
00235             i=0;
00236             n=0;
00237             do{
00238                 for(j=0;j<8;j++){
00239                     if(buf[i] & (0x1<<j)){
00240                         outON(AEHA,1);  // ON(1T)
00241                         outOFF(AEHA,3); // OFF(3T)
00242                         t+=4;
00243                     }else{
00244                         outON(AEHA,1);  // ON(1T)
00245                         outOFF(AEHA,1); // OFF(1T)
00246                         t+=2;
00247                     }
00248                     if(++n == bits)break;
00249                 }
00250                 ++i;
00251             }while(n < bits && i<IR_LIMITS);
00252             break;
00253         case 3:
00254             i=0;
00255             n=0;
00256             do{
00257                 for(j=0;j<8;j++){
00258                     if(buf[i] & (0x1<<j)){
00259                         outOFF(SONY,1); // OFF(1T)
00260                         outON(SONY,2);  // ON(2T)
00261                         t+=3;
00262                     }else{
00263                         outOFF(SONY,1); // OFF(1T)
00264                         outON(SONY,1);  // ON(1T)
00265                         t+=2;
00266                     }
00267                     if(++n == bits)break;
00268                 }
00269                 ++i;
00270             }while(n < bits && i<IR_LIMITS);
00271             break;
00272     }
00273         
00274     // stop
00275     switch(mode){
00276         case 1:
00277             t=192-t;
00278             outON(NEC,1);   // ON(1T)
00279             outOFF(NEC,t);  // frame=108ms=192T
00280             break;
00281         case 2:
00282             outON(AEHA,1);  // ON(1T)
00283             outOFF(AEHA,16); // 8ms=16T
00284             break;
00285         case 3:
00286             t=75-t;
00287             outOFF(SONY,t); // frame=45ms=75T
00288             break;
00289     }
00290         
00291 }
00292 
00293