MCU / / 2022. 7. 20. 14:12

Remote Controller Format NEC & Pioneer

이쪽 관련 일을 하게 되면 간혹가다 IR 을 사용해야 할 경우가 있다.
물론 IR을 송신 수신 둘 다 사용해야 할 경우도 있고, 포맷도 크게 두 가지 있는데 업체에 따라 헤더 주파수가 약간 차이가 나는 경우도 있다.

 

이번 Pioneer DVD 는 헤더가 기본 NEC 와 100ms 정도 차이 남.

 

그래서 소스 변경을 하게 됨.

이번 수정으로 그냥 다 사용하였으면 하는 바람이 있다. ( 내가 못해서 그러는 것 같기도 하다 ... ... ... )

 

아래 헤더 파일과 소스 파일 이 있고, 간략하게 소스 첨부.

 

remote_control header, source.zip
다운로드

 

 

IR Code 송신 관련 소스.

void RemoOut_CommandWrite(RemoteConfig_Typedef* remoConfig, u8 custom1, u8 custom2, u8 data1, u8 data2)
{
    if(RemoOut_GetWaitState() == OFF)    
    {
        return;
    }
    if(remoConfig->GPIOx != NULL)    Remote_GpioOutput(remoConfig);
    RemoOut_SetWaitState(ON);
    RemoOut_RawCommand(remoConfig, custom1, custom2, data1, data2);
    
    remote_out_pin = remoConfig->hard_pin_out;
    *remote_out_pin = remoConfig->act_level;
    RemoOut_SetWaitState(OFF);
    while(RemoOut_GetWaitState() == OFF);    
    if(remoConfig->GPIOx != NULL)    Remote_GpioInput();
}


void RemoOut_RawCommand(RemoteConfig_Typedef* remoConfig, u8 custom1, u8 custom2, u8 data1, u8 data2)
{
    u32 cnt = 0;
    u8 protocol_buff[4] = {custom1, custom2, data1, data2};
    
    raw_out_buff[cnt++] = 10;            // tim2 start dummy
    switch(remoConfig->format)
    {
    case enumIndex_RemoteFormat_Nec:                REMOTE_SET_HEADER_TIME(raw_out_buff[cnt++], NEC_HDR_MARK, NEC_HDR_SPACE);                break;
    case enumIndex_RemoteFormat_Pioneer:            REMOTE_SET_HEADER_TIME(raw_out_buff[cnt++], PIONEER_HDR_MARK, PIONEER_HDR_SPACE);        break;
    }
    
    switch(remoConfig->format)
    {
    case enumIndex_RemoteFormat_Nec:                for(int i = 0; i < 4; i++)        cnt += RemoOut_DataToRaw(protocol_buff[i], &raw_out_buff[cnt]);            break;
    case enumIndex_RemoteFormat_Pioneer:            for(int i = 0; i < 2; i++)        cnt += RemoOut_DataToRaw(protocol_buff[i], &raw_out_buff[cnt]);            break;
    }
    raw_out_buff[cnt++] = NEC_BIT_MARK;
    
    remo_state_inc = 0;
    
    switch(remoConfig->format)
    {
    case enumIndex_RemoteFormat_Nec:                remo_state_max = NEC_COMMAND_BIT_LEN;            break;
    case enumIndex_RemoteFormat_Pioneer:            remo_state_max = PIONEER_COMMAND_BIT_LEN;        break;
    }
}
 

IR Code 수신 관련 소스.

#define    NEC_HDR_MARK            900
#define    NEC_HDR_SPACE            450
#define    NEC_RPT_SPACE            225
#define    PIONEER_HDR_MARK        225
#define    PIONEER_HDR_SPACE        110
#define    NEC_BIT_MARK            56
#define    NEC_BIT_ONE                167
#define    NEC_BIT_ZERO            56
#define    REMOTE_BIT_RANGE        50
#define    REMOTE_HDR_RANGE        100

void RemoteIn_RcvFrame(u16 period, RemoteConfig_Typedef* remoConfig)
{
    static u8     remote_header = 0;
    static u8    remote_status = REMOTE_STATE_INDEX_WAIT;
    static u8    remote_bit_count;
    
    if(*(remoConfig->hard_pin_in))
    {
        if((period < (NEC_HDR_MARK + REMOTE_HDR_RANGE)) && (period > (NEC_HDR_MARK - REMOTE_HDR_RANGE)))
        {
            remote_status = REMOTE_STATE_INDEX_NEC_HEADER;
            remote_header = REMOTE_STATE_INDEX_NEC_HEADER;
        }
        else if((period < (PIONEER_HDR_MARK + REMOTE_HDR_RANGE)) && (period > (PIONEER_HDR_MARK - REMOTE_HDR_RANGE)))
        {
            remote_status = REMOTE_STATE_INDEX_PIONEER_HEADER;
            remote_header = REMOTE_STATE_INDEX_PIONEER_HEADER;
        }
        else if((period < (NEC_BIT_MARK + REMOTE_BIT_RANGE)) && (period > (NEC_BIT_MARK - REMOTE_BIT_RANGE)))
        {
            remote_status = REMOTE_STATE_INDEX_RECEIVING_BIT;
        }
        else
        {
            remote_status = REMOTE_STATE_INDEX_WAIT;
            remote_header = REMOTE_STATE_INDEX_WAIT;
        }
    }
    else
    {
        switch(remote_status)
        {
        case REMOTE_STATE_INDEX_NEC_HEADER:
            if((period < (NEC_HDR_SPACE + REMOTE_HDR_RANGE)) && (period > (NEC_HDR_SPACE - REMOTE_HDR_RANGE)))
            {
                memset(&sRemote.code, 0x00, sizeof(RemoteCode_DataTypedef));
                remote_bit_count = 1;
                remote_header = REMOTE_STATE_INDEX_NEC_HEADER;
            }
            else if((period < (NEC_RPT_SPACE + REMOTE_HDR_RANGE)) && (period > (NEC_RPT_SPACE - REMOTE_HDR_RANGE)))
            {        
                remote_status = REMOTE_STATE_INDEX_WAIT;
                remote_header = REMOTE_STATE_INDEX_WAIT;
//                printf("@");
            }        
            else
            {
                remote_status = REMOTE_STATE_INDEX_WAIT;
                remote_header = REMOTE_STATE_INDEX_WAIT;
            }
            break;
            
        case REMOTE_STATE_INDEX_PIONEER_HEADER:
            if((period < (PIONEER_HDR_SPACE + REMOTE_HDR_RANGE)) && (period > (PIONEER_HDR_SPACE - REMOTE_HDR_RANGE)))
            {
                memset(&sRemote.code, 0x00, sizeof(RemoteCode_DataTypedef));
                remote_bit_count = 1;
                remote_header = REMOTE_STATE_INDEX_PIONEER_HEADER;
            }
            else
            {
                remote_status = REMOTE_STATE_INDEX_WAIT;
                remote_header = REMOTE_STATE_INDEX_WAIT;
            }
            break;
            
        case REMOTE_STATE_INDEX_RECEIVING_BIT:
            if((period < (NEC_BIT_ONE + REMOTE_BIT_RANGE)) && (period > (NEC_BIT_ONE - REMOTE_BIT_RANGE)))
            {
                if(remote_bit_count < 8)
                {
                    sRemote.code.custom1 |= REMOTE_MASK_BIT;
                    sRemote.code.custom1 >>= 1;
                }
                else if(remote_bit_count == 8)
                {
                    sRemote.code.custom1 |= REMOTE_MASK_BIT;
                }
                else if(remote_bit_count < 16)
                {
                    sRemote.code.custom2 |= REMOTE_MASK_BIT;
                    sRemote.code.custom2 >>= 1;
                }
                else if(remote_bit_count == 16)
                {
                    sRemote.code.custom2 |= REMOTE_MASK_BIT;
                    if(remote_header == REMOTE_STATE_INDEX_PIONEER_HEADER)
                    {
//                        printf("\r\n REMOTE_STATE_INDEX_PIONEER_HEADER, %02x %02x %02x %02x", sRemote.code.custom1, sRemote.code.custom2, sRemote.code.data1, sRemote.code.data2);
                        if(RemoOut_GetWaitState())        remoConfig->call_func(&sRemote, enumIndex_RemoteFormat_Pioneer);
                    }
                }
                else if(remote_bit_count < 24)
                {
                    sRemote.code.data1 |= REMOTE_MASK_BIT;
                    sRemote.code.data1 >>= 1;
                }
                else if(remote_bit_count == 24)
                {
                    sRemote.code.data1 |= REMOTE_MASK_BIT;
                }
                else if(remote_bit_count < 32)
                {
                    sRemote.code.data2 |= REMOTE_MASK_BIT;
                    sRemote.code.data2 >>= 1;
                }
                else if(remote_bit_count == 32)
                {
                    sRemote.code.data2 |= REMOTE_MASK_BIT;
                    if(remote_header == REMOTE_STATE_INDEX_NEC_HEADER)
                    {
//                        printf("\r\n REMOTE_STATE_INDEX_NEC_HEADER, %02x %02x %02x %02x", sRemote.code.custom1, sRemote.code.custom2, sRemote.code.data1, sRemote.code.data2);
                        if(RemoOut_GetWaitState())        remoConfig->call_func(&sRemote, enumIndex_RemoteFormat_Nec);
                    }
                }
                remote_bit_count++;
                remote_status = REMOTE_STATE_INDEX_NOTHING;
            }
            else if((period < (NEC_BIT_ZERO + REMOTE_BIT_RANGE)) && (period > (NEC_BIT_ZERO - REMOTE_BIT_RANGE)))
            {
                if(remote_bit_count < 8)                                    sRemote.code.custom1 >>= 1;
                else if(remote_bit_count > 8 && remote_bit_count < 16)        sRemote.code.custom2 >>= 1;
                else if(remote_bit_count == 16)
                {
                    if(remote_header == REMOTE_STATE_INDEX_PIONEER_HEADER)
                    {
//                        printf("\r\n REMOTE_STATE_INDEX_PIONEER_HEADER, %02x %02x %02x %02x", sRemote.code.custom1, sRemote.code.custom2, sRemote.code.data1, sRemote.code.data2);
                        if(RemoOut_GetWaitState())        remoConfig->call_func(&sRemote, enumIndex_RemoteFormat_Pioneer);
                    }
                }
                else if(remote_bit_count > 16 && remote_bit_count < 24)        sRemote.code.data1 >>= 1;
                else if(remote_bit_count > 24 && remote_bit_count < 32)        sRemote.code.data2 >>= 1;
                else if(remote_bit_count == 32)                            
                {
                    if(remote_header == REMOTE_STATE_INDEX_NEC_HEADER)
                    {
//                        printf("\r\n REMOTE_STATE_INDEX_NEC_HEADER, %02x %02x %02x %02x", sRemote.code.custom1, sRemote.code.custom2, sRemote.code.data1, sRemote.code.data2);
                        if(RemoOut_GetWaitState())        remoConfig->call_func(&sRemote, enumIndex_RemoteFormat_Nec);
                    }
                }
                
                remote_bit_count++;
                remote_status = REMOTE_STATE_INDEX_NOTHING;
            }
            else
            {
                remote_status = REMOTE_STATE_INDEX_WAIT;
                remote_header = REMOTE_STATE_INDEX_WAIT;
            }
            break;
            
        }
    }
}
사업자 정보 표시
봄해(BOMHAI) | 이동현 | 경기도 수원시 장안구 상률로 32 103동 1301 | 사업자 등록번호 : 564-09-02316 | TEL : 010-2977-3322 | Mail : dylan@bomhai.com | 통신판매신고번호 : 2023-수원장안-0750호 | 사이버몰의 이용약관 바로가기
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유