1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Sony Infared Code in C18

Discussion in 'Microcontrollers' started by AtomSoft, May 29, 2009.

  1. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    sure give me a minute... what speed ? 8mhz or 4mhz?
     
    Last edited: Apr 20, 2010
  2. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Here is my code for transmitter 8mhz using 18F1320 and C18:
    Code (text):

    /* **************************************************************************
    ;                                                                           *
    ;   Filename: SIRC                                                          *
    ;   Date: May 29, 2009                                                      *
    ;   File Version: 001                                                       *
    ;                                                                           *
    ;   Author:   Jason Lopez                                                   *
    ;   Company:  AtomSoft                                                      *
    ;                                                                           *
    ;****************************************************************************
    ; Notes:
    ;
    */
    #include <p18f1320.h>
    #include <delays.h>
    #include <string.h>

    #pragma config WDT = OFF, LVP = OFF, OSC = INTIO2, MCLRE = OFF

    #define irTris TRISBbits.TRISB0
    #define irPin  LATBbits.LATB0

    #define BtnTris  TRISBbits.TRISB1
    #define Btn      PORTBbits.RB1

    #define TV 1
    #define POWER 21

    void main(void);
    void SendSIRC(unsigned char myDEV, unsigned char myCMD);
    void PulseIt(unsigned char time);

    void main(void){

        char tmp;
        OSCCON = 0x72;                  //8MHz clock
        //while(!OSCCONbits.IOFS);        //wait for osc stable
        ADCON1 = 0xFF;

        BtnTris = 1;
        irTris = 0;
             
        while(1){
            if(Btn){
                SendSIRC(TV,POWER);
                Delay10KTCYx(1);
                while(Btn);
            }
        }
    }

    void SendSIRC(unsigned char myDEV, unsigned char myCMD){
        char x;
        PulseIt(4);             //Logic Start

        for(x=0;x<7;x++){
            if(myCMD & 0x01){
                PulseIt(2);     //Logic 1
            } else {
                PulseIt(1);     //Logic 0
            }

            myCMD >>= 1;
        }
        for(x=0;x<5;x++){
            if(myDEV & 0x01){
                PulseIt(2);     //Logic 1
            } else {
                PulseIt(1);     //Logic 0
            }
            myDEV >>= 1;
        }
        Delay10KTCYx(90);       //45mS Delay
    }

    void PulseIt(unsigned char time){
        unsigned char x,y,z;

    for(y=0;y<time;y++){
        for(x=0;x<24;x++){          //600uS worth
            irPin = 1;
            Delay10TCY();
            Nop();
            Nop();
            Nop();                  //About 7uS
            irPin = 0;
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Delay10TCY();
            Delay10TCY();           //About 18uS
        }
    }

        for(x=0;x<24;x++){          //600uS worth
            irPin = 0;
            Delay10TCY();
            Nop();
            Nop();
            Nop();                  //About 7uS
            irPin = 0;
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Delay10TCY();
            Delay10TCY();           //About 18uS
        }
    }

     
     
  3. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    Dude thanks, i actually wanted to see the Schematic diagram not the code :D . Can you please send the Schematic diagram.

    I am using the following schematic but the IR LED is still not bright enough.
    Untitled-1.jpg

    I have also tried moving the IR LED into Emitter portion and reducing base resistor to 100ohm but only increases the range by a few Centimeters.
     
    Last edited: Apr 20, 2010
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. spiralbrain

    spiralbrain New Member

    Joined:
    Aug 2, 2003
    Messages:
    8
    Likes:
    0
    Location:
    Earth

    Ive been working with something similar using the 12F629 using Hi-Tech C, before I found this thread. My code uses almost similar technique to duplicate a car audio remote buttons. It uses a data table to store 16 bit values, it goes to sleep mode when not in operation and reduces current drawn to less than 2uA, ideal for battery operation. Jason has done a very good job I am always impressed with what he makes.

    Haxan try this configuration for the transmitter, if you really want to see how bright the LED gets use a phone camera to see IR.


    Spiral
     

    Attached Files:

    Last edited: Apr 21, 2010
  6. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    I have same configuration other than the cap you have. I will try that now. My range is only 2 feet from remote to receiver.
     
  7. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    If i use a standard Sony Remote, i get range upto no more than 10 feet (with new batteries) Also sometimes the button pressed sends some other signal for example if 1 is pressed, it sends 2. Is there any way to reduce this noise (or whatever this is) and how to increase range.
     
  8. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    The range depends on the remote & ir receiver but on my universal remote which I paid $4 for i can get about 20-30 feet. The receiver has to be in the correct angle. You have to remember this isnt a WIFI type thing its a POINT TO POINT comm. If its off by a little you look lots of feet. Also some IR Receivers can sense from further away. take the TSOP1138 and TSOP34838 they both work great!
    For noise check the datasheet for more info.

    Some examples of disturbance signals
    which are suppressed are:
    • DC light (e.g. from tungsten bulb or sunlight)
    • Continuous signals at any frequency
    • Modulated noise from fluorescent lamps with electronic
    ballasts

    Here are some datasheets for those parts:
    http://www.electro-tech-online.com/custompdfs/2010/06/tsop11xx.pdf
    http://www.electro-tech-online.com/custompdfs/2010/06/tsop348.pdf

    Take a look they have usefull information on them.
     
  9. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    I have Receiver TSOP1738 which i used with Philiphs RC5 as well. This used to give me ranges greater than 30 feet and also angle was not that much problem.

    Sony however is being a pain in the head. The receiver receives signal from quite far if i attach an LED along with Output pin of receiver but doesnt decode the signal properly.
     
  10. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    I have tried changing the receiver. the IR receiver that i have now is as attached. It has a metal casing around it. The result is pretty much still the same

    [​IMG]

    [​IMG]
     
  11. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    Ok i have tried out a different one and it works perfect with too many angles and alooooot of range :)

    The problem is that if i add a cap of 4.7uF it stops working. Maybe it has something built in. This eases work for me :)
     
    Last edited: Jun 16, 2010
  12. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    may also be the power your feeding to it. Check datasheet to be sure
     
  13. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    AtomSoft, have you ever faced this problem in which the microcontroller gets stuck into a loop when remote is used?

    It sometime happens that when i use remote, after a few signals i send, the controller kinda gets locked into some sort of loop which cannot be broken by any other input method other than using remote again.

    Can this be a software bug or something to do with hardware?

    My guess is that it gets stuck somewere in these loops "while(IR_Pin == 0)"

    any advice


    The code i am using (which you wrote) is as follows:

    Code (text):
    void GetSIRC(unsigned char *address, unsigned char *command){
        unsigned char ir_add;
        unsigned char ir_cmd;
        unsigned char lTime;
        char x;

    StartLook:
        ir_add = ir_cmd = 0;

        while(IR_Pin);               //wait for it to be low
        lTime = 0;                  //reset the counter

        while(IR_Pin == 0){          //while the pin is low which is our pulse count
            lTime++;                //increment every 200uS until pin is high
            delay_100us(2);         //200uS delay
        }

        if(lTime <= 10)             //Start too short
            goto StartLook;         //Restart
        if(lTime >= 14)             //Start too long
            goto StartLook;         //Restart
               
        lTime = 0;
        for(x=0;x<7;x++){           //repeat 7 times for command
            ir_cmd >>= 1;           //if it was skipped or is done ORing then shift over the 1

            while(IR_Pin);           //wait for it to be low
            lTime = 0;              //reset the counter

            while(IR_Pin == 0){      //while the pin is low which is our pulse count
                lTime++;            //increment every 200uS until pin is high
                delay_100us(2);     //200uS delay
            }

            if(lTime >= 6)          //If its high then OR a 1 in else skip
                ir_cmd |= 0x40;     //if its less than 6 its a 0 so dont OR it     
                                   
        }
        for(x=0;x<5;x++){           //repeat 5 times for address/device
            ir_add >>= 1;           //if it was skipped or is done ORing then shift over the 1

            while(IR_Pin);           //wait for it to be low
            lTime = 0;              //reset the counter

            while(IR_Pin == 0){      //while the pin is low which is our pulse count
                lTime++;            //increment every 200uS until pin is high
                delay_100us(2);     //200uS delay
            }

            if(lTime >= 6)          //If its high then OR a 1 in else skip
                ir_add |= 0x10;     //if its less than 6 its a 0 so dont OR it         
        }

        *address = ir_add;
        *command = ir_cmd;
    }
     
    Last edited: Jun 19, 2010
  14. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    Ok no problem i have added timeouts into it in order to avoid problems. works better now :)
    The value of timeouts can be changed according to MCU speed.

    Code (text):

    void GetSIRC(unsigned char *address, unsigned char *command){
        unsigned char ir_add;
        unsigned char ir_cmd;
        unsigned char lTime;
        unsigned long int IRTimeOut = 0;
        char x;

    StartLook:
        ir_add = ir_cmd = 0;

        while(IR_Pin)
        {if(IRTimeOut++ > 10000){return;}}      //wait for it to be low
        IRTimeOut = 0;
        lTime = 0;                              //reset the counter

        while(IR_Pin == 0){                     //while the pin is low which is our pulse count
            lTime++;                            //increment every 200uS until pin is high
            delay_100us(2);                     //200uS delay
            if(IRTimeOut++ > 10000){return;}
        }
        IRTimeOut = 0;

        if(lTime <= 10)                         //Start too short
            goto StartLook;                     //Restart
        if(lTime >= 14)                         //Start too long
            goto StartLook;                     //Restart
               
        lTime = 0;
        for(x=0;x<7;x++){                       //repeat 7 times for command
            ir_cmd >>= 1;                       //if it was skipped or is done ORing then shift over the 1

            while(IR_Pin)                       //wait for it to be low
            {if(IRTimeOut++ > 10000){return;}}
            IRTimeOut = 0;
            lTime = 0;                          //reset the counter

            while(IR_Pin == 0){                 //while the pin is low which is our pulse count
                lTime++;                        //increment every 200uS until pin is high
                delay_100us(2);                 //200uS delay
                if(IRTimeOut++ > 10000){return;}
            }
            IRTimeOut = 0;

            if(lTime >= 6)                      //If its high then OR a 1 in else skip
                ir_cmd |= 0x40;                 //if its less than 6 its a 0 so dont OR it     
                                   
        }
        for(x=0;x<5;x++){                       //repeat 5 times for address/device
            ir_add >>= 1;                       //if it was skipped or is done ORing then shift over the 1

            while(IR_Pin)                       //wait for it to be low
            {if(IRTimeOut++ > 10000){return;}}
            IRTimeOut = 0;
            lTime = 0;                          //reset the counter

            while(IR_Pin == 0){                 //while the pin is low which is our pulse count
                lTime++;                        //increment every 200uS until pin is high
                delay_100us(2);                 //200uS delay
                if(IRTimeOut++ > 10000){return;}
            }
            IRTimeOut = 0;

            if(lTime >= 6)          //If its high then OR a 1 in else skip
                ir_add |= 0x10;     //if its less than 6 its a 0 so dont OR it         
        }

        *address = ir_add;
        *command = ir_cmd;
    }
     
     
  15. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    I have stumbled on another issue. My receiver section works great with universal SONY remote now. However, the remote i just made works fine but with very less range.

    I dont know what i can be doing wrong. If the universal remote gives 30 feet range, mine only gives 6 feet.

    I have used the same transistor (S8050) used in the universal remote.

    Here is the schematic of IR LED i am using.
     

    Attached Files:

  16. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    have you tried removing the cap and seeing if it made a difference? also distance can depend on power / actual IR LED part also
     
  17. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    makes no difference with Cap. I am using the same IR LED. How can i increase power somehow ?
     
  18. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    lower resistor value...
     
  19. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    i am using 39 ohm already. Will just simply remove it and try i guess. Thanks though
     
  20. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    Any suggestion on how to process signal once for some keys and repeatedly on some? I have tried adding synchronizing bits in the communication protocol but it becomes too messy. Now i am thinking to do this only on receiver side, transmitter should keep on sending the signal when a button is pressed.
     
  21. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US

Share This Page