Infrared Rays library

Dependents:   mbed_IR

See http://developer.mbed.org/users/yasuyuki/notebook/IRmbed/

Revision:
1:71ca050c4d05
Parent:
0:c74b212c3cbf
--- a/IR.cpp	Thu Jun 26 13:56:36 2014 +0000
+++ b/IR.cpp	Fri Sep 25 17:11:16 2015 +0000
@@ -9,10 +9,10 @@
 // logical 0 = on 1T + off 1T
 // logical 1 = on 1T + off 3T
 // reader=on 16T + off 8T
-// stop=on 1T + 8ms
+// stop=on 1T
 // frame=108ms
 //
-// (2)Standard IR format
+// (2)AEHA format
 // IR carrier=33 - 40KHz
 // Time unit=0.35 - 0.50ms
 // logical 0 = on 1T + off 1T
@@ -26,18 +26,19 @@
 // logical 0 = off 1T + on 1T
 // logical 1 = off 1T + on 2T
 // reader=on 4T
+// frame=45ms
 //
 // caution:
 // no detecting repeat code, return bits=0;
 //
-// (C)Copyright 2014 All rights reserved by Y.Onodera
+// (C)Copyright 2014-2015 All rights reserved by Y.Onodera
 // http://einstlab.web.fc2.com
 //**********************
 
 #include "mbed.h"
 #include "IR.h"
 
-IR::IR (PinName irin) : _irin(irin){
+IR::IR (PinName irin, PinName irout) : _irin(irin),_irout(irout){
     init();
 }
 
@@ -45,9 +46,10 @@
 void IR::init()
 {
     _irin.mode(PullUp);
+    _irout=0;
 }
 
-unsigned char IR::CountHigh(){
+unsigned char IR::countHigh(){
 
     unsigned char i=0;
 
@@ -57,10 +59,10 @@
         ++i;
         wait_us(26);
         wait_us(26);
-        if(i==0) return 0;
+        if(i==0) return 0;  // timeout
     }
     // NEC:i=19*8=152, i*2*26.5us=8056us
-    // STD:i=19*4=76,  i*2*26.5us=4028us
+    // AEHA:i=19*4=76,  i*2*26.5us=4028us
     // 1T:i=19*1=19
 
     return i;
@@ -68,7 +70,7 @@
 }
 
 
-unsigned char IR::CountLow(){
+unsigned char IR::countLow(){
 
     unsigned char i=0;
 
@@ -77,10 +79,10 @@
     while(_irin==1){
         ++i;
         wait_us(26);
-        if(i==0) return 0;
+        if(i==0) return 0;  // timeout
     }
     // NEC:i=19*8=152, i*26.5us=4028us
-    // STD:i=19*4=76,  i*26.5us=2014us
+    // AEHA:i=19*4=76,  i*26.5us=2014us
     // 1T:i=19*1=19
     // 3T:i=19*3=57
 
@@ -89,22 +91,23 @@
 }
 
 
-void IR::GetIR2(){
+void IR::getIR2(){
 
-    unsigned char i,j;
+    unsigned char i;
+    unsigned short j;   // capable 32768 bits = 4096 bytes
     unsigned char k;
 
     bits=0;
-    for(j=0;j<16;j++){
-        for(i=0;i<8;i++){
-            k = CountHigh()*2;
+    for(j=0;j<IR_LIMITS;j++){  // buffer bytes LIMITS
+        for(i=0;i<8;i++){   // 8 bits
+            k = countHigh()*2;
             if(mode==3){
                 buf[j]>>=1;
                 // Threschold = 35, 23 = 1T, 46 = 2T; for SONY
                 buf[j]+=((k>30) ? 0x80: 0);
                 ++bits;
             }
-            k = CountLow();
+            k = countLow();
             if(k==0){
                 buf[j]>>=(8-i);
                 return;
@@ -112,7 +115,7 @@
             if(mode!=3){
                 buf[j]>>=1;
                 // Threschold = 38, 19 = 1T, 57 = 3T; for NEC
-                // Threschold = 30, 15 = 1T, 45 = 3T; for STD
+                // Threschold = 30, 15 = 1T, 45 = 3T; for AEHA
                 buf[j]+=((k>30) ? 0x80: 0);
                 ++bits;
             }
@@ -122,11 +125,11 @@
 }
 
 
-void IR::GetIR(){
+void IR::getIR(){
 
     unsigned char i;
 
-    i = CountHigh();    // Start
+    i = countHigh();    // Start
     mode=0;
     if(40<i){
         if(i<51){
@@ -135,11 +138,156 @@
             if(100<i){
                 mode=1; // NEC, 173
             }else{
-                mode=2; // STD, 54-77
+                mode=2; // AEHA, 54-77
             }
         }
-        i = CountLow();
-        GetIR2();
+        i = countLow();
+        getIR2();
     }
 
 }
+
+
+// out ON with 38KHz
+void IR::outON(char n, char t)
+{
+
+    unsigned char i,j;
+
+    for(j=0;j<t;j++){
+        for(i=0;i<n;i++){
+            // 38KHz, 1/3duty
+            _irout=1; // LED ON=8.6ms
+            wait_us(6);
+            _irout=0; // LED OFF=17.4ms
+            wait_us(15);
+        }
+    }
+    
+}
+
+// out OFF without 38KHz
+void IR::outOFF(char n, char t)
+{
+
+    unsigned char i,j;
+
+    for(j=0;j<t;j++){
+        for(i=0;i<n;i++){
+            // 38KHz, 1/3duty
+            _irout=0; // LED OFF
+            wait_us(6);
+            _irout=0; // LED OFF
+            wait_us(15);
+        }
+    }
+    
+}
+
+
+void IR::setIR()
+{
+
+    unsigned char j,t;
+    unsigned short i,n;
+
+    if(bits==0)return;      // no data
+
+    // reader
+    switch(mode){
+        case 1:
+            if(bits!=32)return;
+            outON(NEC,16);  // ON(16T)
+            outOFF(NEC,8);  // OFF(8T)
+            t=16+8;
+            break;
+        case 2:
+            if(bits>IR_LIMITS*8)return;
+            outON(AEHA,8);  // ON(8T)
+            outOFF(AEHA,4); // OFF(4T)
+            t=8+4;
+            break;
+        case 3:
+            if(!(bits==12 || bits==15 || bits==20))return;
+            outON(SONY,4);  // ON(4T)
+            t=4;
+            break;
+    }
+
+    // data
+    switch(mode){
+        case 1:
+            for(i=0;i<4;i++){
+                for(j=0;j<8;j++){
+                    if(buf[i] & (0x1<<j)){
+                        outON(NEC,1);   // ON(1T)
+                        outOFF(NEC,3);  // OFF(3T)
+                        t+=4;
+                    }else{
+                        outON(NEC,1);   // ON(1T)
+                        outOFF(NEC,1);  // OFF(1T)
+                        t+=2;
+                    }
+                }
+            }
+            break;
+        case 2:
+            i=0;
+            n=0;
+            do{
+                for(j=0;j<8;j++){
+                    if(buf[i] & (0x1<<j)){
+                        outON(AEHA,1);  // ON(1T)
+                        outOFF(AEHA,3); // OFF(3T)
+                        t+=4;
+                    }else{
+                        outON(AEHA,1);  // ON(1T)
+                        outOFF(AEHA,1); // OFF(1T)
+                        t+=2;
+                    }
+                    if(++n == bits)break;
+                }
+                ++i;
+            }while(n < bits && i<IR_LIMITS);
+            break;
+        case 3:
+            i=0;
+            n=0;
+            do{
+                for(j=0;j<8;j++){
+                    if(buf[i] & (0x1<<j)){
+                        outOFF(SONY,1); // OFF(1T)
+                        outON(SONY,2);  // ON(2T)
+                        t+=3;
+                    }else{
+                        outOFF(SONY,1); // OFF(1T)
+                        outON(SONY,1);  // ON(1T)
+                        t+=2;
+                    }
+                    if(++n == bits)break;
+                }
+                ++i;
+            }while(n < bits && i<IR_LIMITS);
+            break;
+    }
+        
+    // stop
+    switch(mode){
+        case 1:
+            t=192-t;
+            outON(NEC,1);   // ON(1T)
+            outOFF(NEC,t);  // frame=108ms=192T
+            break;
+        case 2:
+            outON(AEHA,1);  // ON(1T)
+            outOFF(AEHA,16); // 8ms=16T
+            break;
+        case 3:
+            t=75-t;
+            outOFF(SONY,t); // frame=45ms=75T
+            break;
+    }
+        
+}
+
+