• 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.

Sony Infared Code in C18

Status
Not open for further replies.

AtomSoft

Well-Known Member
Here is my code for transmitter 8mhz using 18F1320 and C18:
Code:
/* **************************************************************************
;																			*
;	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
    }
}
 

haxan

New Member
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:

spiralbrain

New Member
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
 

Attachments

Last edited:

haxan

New Member
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.
 

AtomSoft

Well-Known Member
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.
 

haxan

New Member
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.
 

haxan

New Member
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:

haxan

New Member
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:
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:

haxan

New Member
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:
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;
}
 

haxan

New Member
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.
 

Attachments

haxan

New Member
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.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top