Saturday, February 6, 2016

Creating my own TV Tuner IR remote with a PIC16F684


While I was home this winter, I saw that the remote for our TV tuner was damaged physically, causing the buttons to not function responsively. Some of them just didn't work. I saw this as an opportunity for a fun couple days' project to build a new remote controller for the tuner.

The TV tuner was manufactured by a brand name RealView and, as expected, I couldn't find much detail about it. Thus, I had to reverse engineer the remote. From my previous experience in working with IR remotes, I had a hunch that the IR was most likely modulated at ~38kHz or ~56kHz. For those of you who don't know how this works, I highly recommend going through this website: http://www.sbprojects.com/knowledge/ir/

Thus, I connected a 38kHz IR receiver I had at home (TSOP1738) to an oscilloscope in order to figure out what IR protocol is used by the remote. Upon pressing the 4 key on the remote, I saw the following waveform:

Fig. 1: Oscilloscope waveform capture of the received IR signal

Note that I inverted the signal on the oscilloscope since the IR receiver output is active-low.

I then compared the waveform to some of the common IR protocols, paying particular attention to the initial first high and low states. After going through SIRC, RC5, RC6 among others, I noticed that this matched the NEC protocol: http://www.sbprojects.com/knowledge/ir/nec.php

Fig. 2: Standard NEC IR protocol pulse train

Fig. 3: NEC IR protocol logic high and logic low signals

Using the waveform shown above, I found that ~address was not being sent, meaning that the extended NEC protocol was being used:

Fig. 4: Extended NEC IR protocol pulse train

From the waveform, I found that the address was 0xBD02. I then proceeded to make a simple decoder with a PIC16F877A since I had a development board with an IR sensor mounted on it. Using this, I found all the required commands for the different keys of the remote. I decided to exclude some of the keys that were never used (eg play, pause, stop, fast forward, rewind).
You can find this part of the project here:
https://drive.google.com/file/d/0B4SoPFPRNziHZjk2N3pNLVE5V1E/view?usp=sharing

This left me with the following keys and commands:


KeyCommand
09
10
21
32
43
54
65
76
87
98
UP18
DOWN19
RIGHT16
LEFT17
PREVIOUS CHANNEL13
-/--10
POWER20
MENU21
MUTE12

I then proceeded to write an IR transmitter using the PIC16F684 (using the MPLAB X IDE and XC8 compiler), following the timing information from the extended NEC protocol. In order to connect all the keys, I connected them in matrix keypad form.

In order to power the remote off 2xAA batteries, it is necessary to use sleep mode - otherwise the battery will be drained extremely quickly. So, in order to detect when a button is pressed, an interrupt is used. After the IR command is sent, the microcontroller goes to sleep. The interrupt wakes up the microcontroller when a button is pressed. Debouncing is achieved using simple software delays. When a button is held down, the NEC command repeat sequence is not sent. Instead, the remote relies on releasing the button and pressing it again.

To minimize leakage current through the input capacitor, I decided not to use an electrolytic capacitor. A red LED illuminates to confirm that a button has been pressed.

 Fig. 5: Schematic of IR remote design

Everything was put together, a PCB was designed and when tested with the TV tuner, everything worked as expected! I measured the sleep current with a portable DMM and it was read as 1.6μA! I'm not sure how accurate the DMM is at such low currents, so I wouldn't entirely trust this number - however, it does seem to be within spec for the PIC16F684.

Due to a lack of time, I had to put the remote together with electric tape! Here you can see pictures of the final design:

Fig. 6: Final IR remote, top

 Fig. 7: Final IR remote, bottom

I am back at college now, but I have been told that the same set of batteries are still working on the remote, and it is working perfectly fine!

You can find the MPLABX project, source code, schematic and pcb files all here:
https://drive.google.com/file/d/0B4SoPFPRNziHV2I1U1Bldm1OYUE/view?usp=sharing

Let me know what you think! If you have any questions, let me know in the comments section!

9 comments:

  1. Salam Tahmid, your fan from Karachi, Pakistan here. Ill be really thankful if you could share Proteus model for SG3525 PWM controller with me.
    tauqeer75500@hotmail.com

    Thank You.

    ReplyDelete
  2. Hello Tahmid ... i have been read all your writtings ... and i like to ask you a questions ... can i have your email address or maybe a facebook contact so i can contact you... please i need you to fix my problem.. thanks..

    ReplyDelete
  3. Hello Tahmid ... i have been read all your writtings ... and i like to ask you a questions ... can i have your email address or maybe a facebook contact so i can contact you... please i need you to fix my problem.. thanks..

    ReplyDelete
  4. Hi! Tahmid! Needed ur help with the single phase inverter! Using microcontroller!ATMEGA16/32. Gone through! Your articles! Very helpful!. please provide the schematic and pcb files!!..plzz mail at shivamkumar0809@gmail.com! Or upload it!..would be so helpful!..thank you!!

    ReplyDelete
  5. Is 250W flyback converter practical?

    ReplyDelete
  6. Excellent and very cool idea and the subject at the top of magnificence and I am happy to this post..Interesting post! Thanks for writing it. What's wrong with this kind of post exactly? It follows your previous guideline for post length as well as clarity..

    Digital marketing company in Chennai

    ReplyDelete
  7. It is really a great and useful piece of info. I’m glad that you shared this helpful info with us. Please keep us informed like this. Thank you for sharing.

    Digital marketing company in Chennai

    ReplyDelete
  8. #define tx RA2_bit

    void Init_Timer1(){
    TMR1H = 0xfc;
    TMR1L = 0x18;
    T1CON = 0x01;
    INTCON.PEIE = 1; // Bit6 Enable Peripheral interrupts
    INTCON.RAIE = 1;
    PIE1.TMR1IE = 1; // Timer1 interrupt enabled
    PIR1.TMR1IF = 0; // Timer1 interrupt Flag cleared
    T1CON.TMR1GE=1;
    INTCON.GIE = 1;


    }


    void interrupt() {

    /*if(T1CON.TMR1GE){
    tx =1;
    TMR1H = 0xfc;
    TMR1L = 0x18;
    T1CON.TMR1ON = 1; //start timer1
    //fd=1;
    //TMR1IE_bit = 1; //enable timer 1 interrupt
    T1CON.TMR1GE=0;
    }*/

    if (TMR1IF_bit)
    {
    tx = 0;
    delay_us(500);
    //tx = 1;
    T1CON.TMR1ON = 0; //stop timer1
    INTCON.INTE = 1;
    PIR1.TMR1IF=0;
    TMR1IE_bit = 1; //enable timer 1 interrupt

    }

    }





    void main() {
    CMCON = 7; // disable comparator
    ANSEL = 0; // disable analogue
    TRISA = 0x18; // IR b0 = input, rest output
    TRISC = 0x01;
    TRISA.F4 = 1;
    PORTC=0x00;
    PORTA=0x00;
    INTCON.GIE=1;
    Init_Timer1();

    while(1){
    //if(RA4_bit==1)tx=1;else tx=0;


    }


    }
    please help me , swaponeee@gmail.com

    ReplyDelete
  9. Tahmid, best wishes for you. Can you suggest me the place or shop for PCB making in Dhaka. thanks in advance.

    ReplyDelete