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
    heh its not a timing issue trust me i use 3 different remotes... 1 sony, 1 my cable and 1 universal and all works... Dont wanna sound mean or anything but its something you have wrong... post your FULL schematic and code for both...

    The universal remote sends the same timing but it may send the code out over and over every 40ms or so... You have to remember a protocol cannot have different timing or it would work at all ... it would not even be the same protocol if timing is different...
     
  2. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    AtomSoft here is the code i am using for Receiving PIC18F4520.

    Now dont know how to show you the schemetic. Will you like Proteus design file?

    Can you please test the code using 4MHz oscillator?

    I am calling the code in my main loop:
    Code (text):

    if(IR_Pin == 0){ReadIR();}
     

    Code (text):

    void ReadIR(void)
    {
        IntBusyFlag = 1;
        GetSIRC(&IR_Add,&IR_Cmd);
        if(IR_Add == Room_IR_Add)
        {
            Status_var = FROM_Remote;
            switch(IR_Cmd){
                case 0:
                    update_toggle(1);
                    update_switch(1);
                    break;
                case 1:
                    update_toggle(2);
                    update_switch(2);
                    break;
                case 2:
                    update_toggle(3);
                    update_switch(3);
                break;
                case 3:
                    update_toggle(4);
                    update_switch(4);
                    break;
                default:
                    break;
            }
        }
    }


    void GetSIRC(unsigned char *address, unsigned char *command){
        unsigned char ir_add;
        unsigned char ir_cmd;
        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
            Delay100TCYx(1);        //200uS delay
            Delay10TCYx(9);
        }
       
        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
            Delay100TCYx(1);        //200uS delay
            Delay10TCYx(9);
        }
       
        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
            Delay100TCYx(1);        //200uS delay
            Delay10TCYx(9);
        }
       
        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;
    }
     


    This is the code i am using for my custom Remote (transmitter):
    Code (text):

    #include <p18cxxx.h>
    #include <delays.h>
    #include <portb.h>    /* for the RB0/INT0 interrupt */

    #pragma config WDT = OFF, LVP = OFF, OSC = XT, DEBUG = OFF

    #define keypadPort PORTC                // Keypad attached with PORT
    #define ADDRESS_BTN1 PORTAbits.RA1
    #define ADDRESS_BTN2 PORTAbits.RA2
    #define ADDRESS_BTN3 PORTAbits.RA3
    #define ADDRESS_BTN4 PORTAbits.RA4
    #define ADDRESS_LED1 PORTBbits.RB1
    #define ADDRESS_LED2 PORTBbits.RB2
    #define ADDRESS_LED3 PORTBbits.RB3
    #define ADDRESS_LED4 PORTBbits.RB4
    #define MODE_LED1 PORTBbits.RB5
    #define MODE_LED2 PORTBbits.RB6
    #define irPin  LATAbits.LATA0

    #define MODE_L 1
    #define MODE_S 2

    void main(void);
    void ReadKeypad(void);
    void ReadAddressKeys(void);
    void SendSIRC(unsigned char Dev, unsigned char Cmd);
    void PulseIt(unsigned char time);
    void lock_key(void);
    void repeat_key(void);
    void ShowAddressLED(unsigned char);
    void ShowModeLED(unsigned char);
    void EnableINT0(void);

    ram unsigned char keypad[]              = {0x11,0x21,0x41,0x81,0x12,0x22,0x42,0x82,0x14,0x24,0x44,0x84,0x18,0x28,0x48,0x88};
    ram unsigned char character[]           = {0,4,8,12, 1,5,9,13, 2,6,10,14, 3,7,11,15};
    ram unsigned char k_i,k_ii;
    ram unsigned int keypress_count         = 0;
    ram unsigned int keypad_loop_flag       = 0;
    ram unsigned char keyNum                = 0;
    ram unsigned char addrSel               = 1;
    ram unsigned char modeSel               = MODE_L;
    ram unsigned long timer                 = 0;

    /* ~~~~ Interrupt Handler ~~~~ */
    void i_handler (void);
    #pragma code i_interrupt = 0x08
    void i_int (void)
    {
        _asm goto i_handler _endasm
    }
    #pragma code
    #pragma interrupt i_handler
    void i_handler (void)
    {
        timer = 0;
        INTCONbits.GIEH = 0;            // Disable High Priority Global Interrupts
        INTCONbits.INT0IF = 0;          // Clear INT0 Interrupt Flag
        ShowModeLED(modeSel);
        ShowAddressLED(addrSel);
    }

    void main(void){

        ADCON1 = 0x0F;
        TRISA  = 0b00011110;
        TRISB  = 0x01;
        TRISC  = 0b11110000;
        TRISD  = 0x00;
        TRISE  = 0x00;
        PORTA  = 0x00;
        PORTB  = 0x00;
        PORTC  = 0x00;
        PORTE  = 0x00;
        PORTD  = 0x00;

        ADDRESS_LED1    = 0;
        ADDRESS_LED2    = 0;
        ADDRESS_LED3    = 0;
        ADDRESS_LED4    = 0;
        MODE_LED1       = 0;
        MODE_LED2       = 0;
        ShowAddressLED(addrSel);
        ShowModeLED(MODE_L);   
       
        while(1)
        {
            ReadKeypad();
            ReadAddressKeys();
            timer++;
            if(timer > 30000){ShowAddressLED(0);ShowModeLED(0);EnableINT0();Sleep();}
        }
    }

    void EnableINT0(void)
    {
        OpenRB0INT(PORTB_CHANGE_INT_ON & PORTB_PULLUPS_OFF & RISING_EDGE_INT & PORTB_INT_PRIO_HIGH);
        RCONbits.IPEN       = 1;        // Enable High Priority Interrupts
        INTCONbits.GIEH     = 1;        // Disable High Priority Global Interrupts
    }

    void SendSIRC(unsigned char Adr, unsigned char Cmd)
    {
        char x;
        PulseIt(4);             //Logic Start

        for(x=0;x<7;x++){
            if(Cmd & 0x01)
                PulseIt(2);     //Logic 1
            else
                PulseIt(1);     //Logic 0
            Cmd >>= 1;
        }
        for(x=0;x<5;x++){
            if(Adr & 0x01)
                PulseIt(2);     //Logic 1
            else
                PulseIt(1);     //Logic 0
            Adr >>= 1;
        }
        //Delay10KTCYx(45);       //45mS Delay
        Delay10KTCYx(1);         //My New 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;
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();                  //About 7uS
            irPin = 0;
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            Nop();
            //Delay10TCY();           //About 18uS
        }
    }

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

    void ShowAddressLED(unsigned char address)
    {
        switch(address)
        {
            case 0: ADDRESS_LED1 = 0;ADDRESS_LED2 = 0;ADDRESS_LED3 = 0;ADDRESS_LED4 = 0;break;
            case 1: ADDRESS_LED1 = 1;ADDRESS_LED2 = 0;ADDRESS_LED3 = 0;ADDRESS_LED4 = 0;break;
            case 2: ADDRESS_LED1 = 0;ADDRESS_LED2 = 1;ADDRESS_LED3 = 0;ADDRESS_LED4 = 0;break;
            case 3: ADDRESS_LED1 = 0;ADDRESS_LED2 = 0;ADDRESS_LED3 = 1;ADDRESS_LED4 = 0;break;
            case 4: ADDRESS_LED1 = 0;ADDRESS_LED2 = 0;ADDRESS_LED3 = 0;ADDRESS_LED4 = 1;break;
            default:ADDRESS_LED1 = 1;ADDRESS_LED2 = 0;ADDRESS_LED3 = 0;ADDRESS_LED4 = 0;break;
        }
    }

    void ShowModeLED(unsigned char mode)
    {
        switch(mode)
        {
            case 0:      MODE_LED1 = 0;MODE_LED2 = 0;break;
            case MODE_L: MODE_LED1 = 1;MODE_LED2 = 0;break;
            case MODE_S: MODE_LED1 = 0;MODE_LED2 = 1;break;
            default:MODE_LED1 = 1;MODE_LED2 = 0;break;
        }
    }

    void ReadAddressKeys()
    {
        while(ADDRESS_BTN1 != 1 || ADDRESS_BTN2 != 1 || ADDRESS_BTN3 != 1 || ADDRESS_BTN4 != 1)
        {
            if(ADDRESS_BTN1 == 0){addrSel = 1;}
            else if(ADDRESS_BTN2 == 0){addrSel = 2;}
            else if(ADDRESS_BTN3 == 0){addrSel = 3;}
            else if(ADDRESS_BTN4 == 0){addrSel = 4;}
            ShowAddressLED(addrSel);
            timer = 0;          // For Sleep
        }
    }


    void ReadKeypad()
    {
        keypadPort = 0x0F;
        if(keypadPort == 0x0F){keypad_loop_flag = 0;return;}
        if(keypadPort != 0x0F)
        {
            for(k_i = 0;k_i < 4; k_i++)
            {
                keypadPort = 1 << k_i;
                for(k_ii = 0;k_ii < 16;k_ii++)
                {
                    if(keypadPort == keypad[k_ii])
                    {
                        keyNum = character[k_ii];
                        k_i = 4;
                        break;
                    }
                }
            }
        }

        timer = 0;          // For Sleep

        if(modeSel ==MODE_L)
        {
            SendSIRC(addrSel,10);
        }else{
            SendSIRC(addrSel,14);
        }

        switch(keyNum)
        {
            case 0:                         // Toggle 1
                repeat_key();//lock_key();
                SendSIRC(addrSel,0);
            break;
            case 1:                         // Toggle 2
                repeat_key();//lock_key();
                SendSIRC(addrSel,1);
            break;
            case 2:                         // Toggle 3
                repeat_key();//lock_key();
                SendSIRC(addrSel,2);
            break;
            case 3:                         // Toggle 4
                repeat_key();//lock_key();
                SendSIRC(addrSel,3);
            break;
            default:
            break;
        }
        Delay1KTCYx(5);
    }

    void lock_key(void)
    {
        while(keypadPort != 0x0F){keypadPort = 0x0F;}
    }

    void repeat_key(void)
    {
        while(keypadPort != 0x0F)
        {
            keypress_count++;
            if(keypad_loop_flag == 1 && keypress_count > 300){break;}           // Adjust Num to increase/decrease fast loop speed
            if(keypress_count > 10000){keypad_loop_flag=1;break;}           // Adjust Num to increase/decrease duration of flagging fast loop
        }
       
        keypress_count = 0;
    }
     
     
  3. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Proteus will be fine
     
  4. dave

    Dave New Member

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


     
  5. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0

    Here you go AtomSoft and thank you spending time with me to solve this issue. It wants me to pull me hair out :(
     

    Attached Files:

  6. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    In practical circuit i have the IR connected as attached.

    and the receiver is with 47uF cap and a resistor of 100ohm as mentioned in your previous posts.
     

    Attached Files:

  7. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    ok cool ill download it now and check it out
     
  8. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Try this on your hardware:
    Code (text):

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

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

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

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    ok i will try it now. Thank you AtomSoft.

    Have you tried it with 4MHz clock (just curious :D)
     
  10. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    i have this as my receive code: (tested on my current hardware...)
    Code (text):

    void GetSIRC(unsigned char *address, unsigned char *command){
        unsigned char ir_add;
        unsigned char ir_cmd;
        char x;

    StartLook:
        ir_add = ir_cmd = 0;

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

        while(irPin == 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(irPin);           //wait for it to be low
            lTime = 0;              //reset the counter

            while(irPin == 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(irPin);           //wait for it to be low
            lTime = 0;              //reset the counter

            while(irPin == 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;
    }
     
     
  11. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    The one for your receiver works with PIC with 8Mhz :) right?
     
  12. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    That receiver code i posted above is for 4 mhz
     
  13. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    oh.

    The one i am using is different which i thought was for 4MHz:
    Code (text):

    void GetSIRC(unsigned char *address, unsigned char *command){
        unsigned char ir_add;
        unsigned char ir_cmd;
        char x;
       
    StartLook:
        ir_add = ir_cmd = 0;
       
        while(irPin);               //wait for it to be low
        lTime = 0;                  //reset the counter
       
        while(irPin == 0){          //while the pin is low which is our pulse count
            lTime++;                //increment every 200uS until pin is high
            Delay100TCYx(1);        //200uS delay
            Delay10TCYx(9);
        }
       
        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(irPin);               //wait for it to be low
            lTime = 0;              //reset the counter
       
        while(irPin == 0){          //while the pin is low which is our pulse count
            lTime++;                //increment every 200uS until pin is high
            Delay100TCYx(1);        //200uS delay
            Delay10TCYx(9);
        }
       
        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(irPin);               //wait for it to be low
            lTime = 0;              //reset the counter
       
        while(irPin == 0){          //while the pin is low which is our pulse count
            lTime++;                //increment every 200uS until pin is high
            Delay100TCYx(1);        //200uS delay
            Delay10TCYx(9);
        }
       
        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;
    }
     
     
  14. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    No difference by changing the PulseIt function for the transmitter.

    Can you please share your delay_100us function :)
     
  15. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    that code is wrtten in BoostC so it has that as a internal command for C18 to delay 100us at 4mhz just make something like...
    Code (text):

    void delay_100us (char time){
        char x;

        for(x=0;x<time;x++)
            Delay10TCYx(9);
    }
     
    EDIT: You can use the above... should be almost 100us on the dot
     
    Last edited: Apr 15, 2010
  16. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    same no good result ... i feel like slapping my head a few times.


    Everything works flawlessly in simulation, but in real hardware i do not understand what is wrong.

    I have a red LED attached with the IR receiver sensor. When i use the universal SONY remote, the red LED blinks slower then when i use my remote. For this reason i thought that my remote is sending data way more faster.
     
    Last edited: Apr 15, 2010
  17. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    heh check this... is your IR Receiver OUT pin normally high or low?
     
  18. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    In general, the OUT is giving 0.45 volts
     
  19. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    ... more thinking time.. heh
     
  20. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    When you click a button from Remote, does it keep sending same code to your receiver or does it send the code once?
     
  21. haxan

    haxan New Member

    Joined:
    Nov 17, 2009
    Messages:
    387
    Likes:
    0
    AtomSoft, can you please send your Transmitter (Remote) Schematic diagram. My IR Transmitter LED is not running bright enough for better range. It works only if it is close.
     

Share This Page