Infrared Rays library

Dependents:   mbed_IR

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

IR.cpp

Committer:
yasuyuki
Date:
2015-09-25
Revision:
1:71ca050c4d05
Parent:
0:c74b212c3cbf

File content as of revision 1:71ca050c4d05:

//**********************
// IR.cpp for mbed
//
// IR ir(P0_12);
//
// (1)NEC format
// IR carrier=38KHz
// Time unit=0.56ms
// logical 0 = on 1T + off 1T
// logical 1 = on 1T + off 3T
// reader=on 16T + off 8T
// stop=on 1T
// frame=108ms
//
// (2)AEHA format
// IR carrier=33 - 40KHz
// Time unit=0.35 - 0.50ms
// logical 0 = on 1T + off 1T
// logical 1 = on 1T + off 3T
// reader=on 8T + off 4T
// trailer=on 1T + 8ms
//
// (3)SONY format
// IR carrier=40KHz
// Time unit=0.6ms
// 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-2015 All rights reserved by Y.Onodera
// http://einstlab.web.fc2.com
//**********************

#include "mbed.h"
#include "IR.h"

IR::IR (PinName irin, PinName irout) : _irin(irin),_irout(irout){
    init();
}


void IR::init()
{
    _irin.mode(PullUp);
    _irout=0;
}

unsigned char IR::countHigh(){

    unsigned char i=0;

    while(_irin==1);    // wait

    while(_irin==0){
        ++i;
        wait_us(26);
        wait_us(26);
        if(i==0) return 0;  // timeout
    }
    // NEC:i=19*8=152, i*2*26.5us=8056us
    // AEHA:i=19*4=76,  i*2*26.5us=4028us
    // 1T:i=19*1=19

    return i;

}


unsigned char IR::countLow(){

    unsigned char i=0;

    while(_irin==0);    // wait

    while(_irin==1){
        ++i;
        wait_us(26);
        if(i==0) return 0;  // timeout
    }
    // NEC:i=19*8=152, i*26.5us=4028us
    // AEHA:i=19*4=76,  i*26.5us=2014us
    // 1T:i=19*1=19
    // 3T:i=19*3=57

    return i;

}


void IR::getIR2(){

    unsigned char i;
    unsigned short j;   // capable 32768 bits = 4096 bytes
    unsigned char k;

    bits=0;
    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();
            if(k==0){
                buf[j]>>=(8-i);
                return;
            }
            if(mode!=3){
                buf[j]>>=1;
                // Threschold = 38, 19 = 1T, 57 = 3T; for NEC
                // Threschold = 30, 15 = 1T, 45 = 3T; for AEHA
                buf[j]+=((k>30) ? 0x80: 0);
                ++bits;
            }
        }
    }

}


void IR::getIR(){

    unsigned char i;

    i = countHigh();    // Start
    mode=0;
    if(40<i){
        if(i<51){
            mode=3; // SONY, 46
        }else{
            if(100<i){
                mode=1; // NEC, 173
            }else{
                mode=2; // AEHA, 54-77
            }
        }
        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;
    }
        
}