cancel
Showing results for 
Search instead for 
Did you mean: 

Code Examples

MotooTanaka
Esteemed Contributor

IMG_4714.JPG

Hi,

There has been a question (request?) of RC5 IR remote receiver.

https://community.cypress.com/t5/PSoC-4-MCU/IR-interfacing-with-Capsense-Button/m-p/272229#M39274

And by googling the web I found many reference information such as

https://techdocs.altium.com/display/FPGA/Philips+RC5+Infrared+Transmission+Protocol

Then what I noticed was that the standard is usually not in use in Japan,

anyway as I don't watch TV so I don't have a remote control handy 😜

To make and test the receiver, I also needed an emulator of the remote control >_<

So I created an RC5 remote control emulator on CY8CKIT-044 and a sample receiver on CY8CKIT-042.

On CY8CKIT-044 (RC5 Remote Emulator),

when I typed 0 5 53 (which is toggle = 0, address = 5, command = 53 (35h)) similar to the reference site

the waveform on my oscilloscope seemed to be OK.

Note: I emulated the output signal of  IRM-36xx, not the real IR light.

Probably if I AND this signal with the carry pulse, IR light like signal could be generated, 

but I did not go that far.

IMG_4713.JPG

Then I connected CY8CKIT-042 and CY8CKIT-044 using

GND-GND

P0[1] - P0[1]

And when I typed below in the Tera Term connected to CY8CKIT-044 (remote control)

CY8CKIT-044 (RC5 remote control emulator)

001-Emu-log.JPG

CY8CKIT-042 (receiver) showed

002-RC5_log.JPG

So they seem to communicate OK.

 

CY8CKIT-044 (RC5 remote control emulator)

schematic

005_ir_emu_schematic.JPG

pins

006-ir_emu_pins.JPG

main.c

============================

#include "project.h"
#include "stdio.h"
#include "tty_utils.h"

#define RC5_ONE         0x01
#define RC5_ZERO        0x02
#define RC5_CLK_PER_BIT 2

void init_hardware(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */
    
    ShiftReg_Init() ;
    
    tty_init() ;
}

void print_data(uint32_t data)
{
    uint32_t mask = (0x01 << 27) ; /* 14 x 2 x halfbits */
    
    while(mask) {
        if (mask & data) {
            print("1") ;
        } else {
            print("0") ;
        }
        mask >>= 1 ;
    }
    print("\n") ;
}

void send_ir(int toggle, int address, int command)
{
    uint32_t data = 0x16 ; /* 010110 */
    uint32_t mask ;
    
    // Start Bit 1
    data = RC5_ONE ;
    // Start Bit 2
    data <<= RC5_CLK_PER_BIT ;
    data |= RC5_ONE ;
    // Toggle Bit
    data <<= RC5_CLK_PER_BIT ;    
    if (toggle) {
        data |= RC5_ONE ;
    } else {
        data |= RC5_ZERO ;
    }
    /* address 5bit */
    mask = 0x10 ; /* 1 0000 */
    while(mask) {
        data <<= RC5_CLK_PER_BIT ;
        if (address & mask) {
            data |= RC5_ONE ;
        } else {
            data |= RC5_ZERO ;
        }
        mask >>= 1 ;
    }
    /* command 6bit */
    mask = 0x20 ; /* 10 0000 */
    while(mask) {
        data <<= RC5_CLK_PER_BIT ;
        if (command & mask) {
            data |= RC5_ONE ;
        } else {
            data |= RC5_ZERO ;
        }
        mask >>= 1 ;
    }
    
print_data(data) ;

    ShiftReg_Stop() ;
    ShiftReg_WriteRegValue(data) ;
    ShiftReg_Enable() ;
}

int main(void)
{
    int ir_address = 0 ;
    int ir_command = 0 ;
    int ir_toggle = 0 ;
    
    init_hardware() ;
    
    splash("IR Remote Emulator") ;
    
    print("Enter toggle(0/1) address(5bit) command(6bit)\n\r") ;

    prompt() ;
    for(;;)
    {
        if (get_line()) {
            sscanf(str, "%d %d %d", &ir_toggle, &ir_address, &ir_command) ;
            snprintf(str, STR_BUF_LEN, "toggle: %d address: %d  command: %d\n\r", ir_toggle, ir_address, ir_command) ;
            print(str) ;
            send_ir(ir_toggle, ir_address, ir_command) ;
            prompt() ;
        }
    }
}

============================

 

CY8CKIT-042 (receiver) 

schematic

003-test_rc5_schematic.JPG

pins

004-test_rc5_pins.JPG

main.c

========================

#include "project.h"
#include "stdio.h"
#include "tty_utils.h"

#define IR_ST_IDLE       0
#define IR_ST_START_BIT  1
#define IR_ST_TOGGLE     2
#define IR_ST_ADDRESS    3
#define IR_ST_COMMAND    4
#define IR_ST_DATA_READY 5

#define IR_ADDRESS_WIDTH 5
#define IR_COMMAND_WIDTH 6

volatile int ir_status = IR_ST_IDLE ;
volatile int ir_address_bit = 0 ; /* 5bit */
volatile int ir_command_bit = 0 ; /* 6bit */
volatile int ir_toggle      = 0 ;
volatile int ir_address     = 0 ;
volatile int ir_command     = 0 ;

CY_ISR_PROTO(timer_isr) ;

CY_ISR(ir_isr)
{
    isr_ir_ClearPending() ;
    
    if (ir_status == IR_ST_IDLE) {
        ir_status = IR_ST_START_BIT ;
        isr_ir_Disable() ;
        isr_ir_ClearPending() ;
        isr_bit_ClearPending() ;
        isr_bit_StartEx(timer_isr) ;
        bit_timer_ClearInterrupt(bit_timer_INTR_MASK_CC_MATCH) ;
        bit_timer_Enable() ;
    }
}

CY_ISR(timer_isr)
{
    int ir_in ;
    
    bit_timer_ClearInterrupt(bit_timer_INTR_MASK_CC_MATCH) ;
    ir_in = IR_input_Read() ;
    
    switch(ir_status) {
    case IR_ST_IDLE: // should not come here
        break ;
    case IR_ST_START_BIT:
        if (ir_in == 1) {
            ir_status = IR_ST_TOGGLE ;
        } else {
            ir_status = IR_ST_IDLE ;
        }
        break ;
    case IR_ST_TOGGLE:
        ir_toggle = ir_in ;
        ir_status = IR_ST_ADDRESS ;
        break ;
    case IR_ST_ADDRESS:
        ir_address <<= 1 ;
        ir_address |= ir_in ;
        if (++ir_address_bit >= IR_ADDRESS_WIDTH) {
            ir_status = IR_ST_COMMAND ;
        }
        break ;
    case IR_ST_COMMAND:
        ir_command <<= 1 ;
        ir_command |= ir_in ;
        if (++ir_command_bit >= IR_COMMAND_WIDTH) {
            ir_status = IR_ST_DATA_READY ;
            isr_bit_Disable() ;
            isr_bit_ClearPending() ;
            bit_timer_Stop() ;
        }
        break ;
    case IR_ST_DATA_READY: // should not come here
    default:               // should not come here
        break ;
    }
}

void clear_data(void)
{
    ir_toggle = 0 ;
    ir_address = 0 ;
    ir_address_bit = 0 ;
    ir_command = 0 ;
    ir_command_bit = 0 ;
}

void init_hardware(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */
    
    tty_init() ;
    
    splash("RC5 Test") ;
    
    isr_ir_ClearPending() ;
    isr_ir_StartEx(ir_isr) ;
    
    isr_bit_ClearPending() ;
    isr_bit_StartEx(timer_isr) ;
    
    bit_timer_Init() ;
}

int main(void)
{
    init_hardware() ;

    for(;;)
    {
        if (ir_status == IR_ST_DATA_READY) {
            snprintf(str, STR_BUF_LEN, "toggle: %d address %d: command %d\n\r", 
                ir_toggle, ir_address, ir_command) ;
            print(str) ;
            clear_data() ;
            ir_status = IR_ST_IDLE ;
            isr_ir_ClearPending() ;
            isr_ir_StartEx(ir_isr) ;
            // isr_ir_Enable() ;
        }
    }
}

========================

Well, let me call it a day 😉

moto

 

1 Reply
PREM_KB
New Contributor II

Hello sir,

Thank you so so much for sharing this information and such example code. I will try it out in my custom controller PCB and let you know the results. Thanks again.

 

Regards,

Prem KB

0 Likes