SONY SIRC Remote Controlled device using PIC Micro-controller and mikroC

Published by MKDas on

In this article, we are going to make our own remote-controlled device using SONY SIRC remote protocol. In the previous article, we have learned the basic pattern of this protocol and now we will use that in our circuit. We’ll use PIC12F675 micro-controller and mikroC Pro for the PIC compiler. Let’s make our ‘SONY SIRC Remote Controlled device using PIC Micro-controller and mikroC’.

Disclaimer: Electricity is always dangerous. Skill required to work with electricity. Do work at your own risk. The author will not be responsible for any misuse or harmful act. This website contents are also copyright protected. Anything copied and directly posted on your website and claiming it as yours is prohibited and nonsensical. The author published all the articles as open source to help you to make your project and learning purpose only. Learn and make one for yourself. If need any help feel free to ask the author. The author will be helpful to you. Thanks.


In my previous article, I’ve explained this protocol. Please read that article first to learn about SONY SIRC. SIRC protocol is one of the most common protocols in remote-controlled systems. This protocol uses a start bit, then a command, and then an address bit. All these are transmitted at 40KHz modulation. A remote sensor is used to receive that modulated signal and decode the pattern. After that, micro-controllers are used further to decode the command and address from that received signal.

Circuit Diagram:

SONY SIRC Remote Controlled
Circuit diagram of our remote controller

MikroC Code with the library:

Here is the library of the SONY SIRC remote decoder. I used mikroC pro for PIC with a valid license. If you are having a problem building the hex let me know.

sbit ir_rx at GP3_bit; // Sensor pin

// function prototypes
void get_mark_time(void);

// global variables
unsigned char counter = 0;
unsigned char bitcount;
unsigned char ir_address;
unsigned char ir_command;
unsigned int mark_time;

void interrupt() iv 0x0004 ics ICS_AUTO
    if (TMR0IF_bit)
        counter++;              // increment counter
        TMR0IF_bit = 0;         // Clear Timer0 overflow interrupt flag

void main() 
  CMCON = 0x07;                 // disable comparator
  ANSEL = 0x00;                 // disable analogue
  OPTION_REG = 0x03;            // TMR0 prescaler set to 1:16
  TRISIO = 0x08;                // IR GP3 = input, rest output
  GPIO = 0x00;                  // all outputs off
  // start timer 0 counting
  GIE_bit = 1;                  // Global interrupt enable
  T0IE_bit = 1;                 // Enable Timer0 overflow interrupt
      ir_command = 0;
      ir_address = 0;
      if ((mark_time > 120) && (mark_time < 200))  // set the frequency limit
          for(bitcount = 0 ; bitcount < 7 ; bitcount++)
              get_mark_time();                               // get a Sony IR bit
              ir_command >>= 1;                              // shift
              ir_command &= 0x7f;                            // top bit zero
              if (mark_time > 0x40)
                  ir_command ^= 0x80;                        // top bit 1
          ir_command >>= 1;                                  // shift 1 unused bit
          ir_command &= 0x7F;                                // clear top bit

          for(bitcount = 0 ; bitcount < 5 ; bitcount++)
              get_mark_time();                               // get a Sony IR bit
              ir_address >>= 1;                              // shift
              ir_address &= 0x7f;                            // top bit zero
              if (mark_time > 0x40)
                  ir_address ^= 0x80;                        // top bit 1
          ir_address >>= 3;                                  // shift 3 unused bits
          ir_address &= 0x1F;                                // clear top 3 bits
      if(ir_address == 1)
      {                                                      // TV
          if(ir_command == 0)
          {                                                  // button 1
              GP0_bit = ~GP0_bit;
          if(ir_command == 1)
          {                                                  // button 2
              GP1_bit = ~GP1_bit;
          if(ir_command == 2)
          {                                                  // button 3
              GP2_bit = ~GP2_bit;
          Delay_ms(200);                                     // avoid double toggle

// get time of mark, then ignore space
void get_mark_time(void)
    while(ir_rx);                           // wait for a mark
    TMR0 = 0;
    while(!ir_rx);                          // wait for space
    mark_time = (counter << 8) + TMR0;      // collect integer mark time

Download the hex file instead.

Test result:

I’ve made a video for this purpose. Please play this video.


I hope this project was helpful to you. If you make one for yourself, it will be a great pleasure for me. Anywhere you need help, let me know. Please share this project and subscribe to my blog. Thank you.


I'm Mithun K. Das; B.Sc. in EEE from KUET, Bangladesh. Blog: "First, electronics was my passion, then it was my education, and finally, electronics is now my profession." I run my own electronics lab, M's Lab ( Where I work with the creation of new products from ideas to something in real life. Besides this is my personal blog where I write for hobbyists and newcomers in the electronics arena. I also have a YouTube channel where I publish other helpful videos, you can find the link inside the articles. I always try to keep it simple so that it becomes easy to understand. I hope these will help them to learn electronics and apply the knowledge in their real life.


Ajape · March 18, 2021 at 9:44 am

thank you for the new development, more grace to you

Joy · March 29, 2021 at 1:26 am

Sir i want change remote but what can i do ?.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *