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.

  • 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 ya go:

Code:
/* **************************************************************************
;																			*
;	Filename: SIRC															*
;	Date: May 29, 2009														*
;	File Version: 001														*
;																			*
;	Author:   Jason Lopez													*
;	Company:  AtomSoft														*
;																			*
;****************************************************************************
; Notes:
; I am delaying in this code a nice even number every 200uS. Mainly because if
; i count each pulse it would be accurate but too many counts for a char type
; and i dont want to use a int. So i can get a 600 count by skipping every 300uS
; and the count will be a nice low number...3
; 
; For a 1.2mS aka HIGH i should get a count of 6 and for the start 2.4mS i should
; get a count of 12. Since this isnt too accurate i range it about 1-2 numbers 
; above or below the standard.
; 
;****************************************************************************
*/
#include <p18f2525.h>
#include <delays.h>
#include <string.h>

#pragma config WDT = OFF, LVP = OFF, OSC = INTIO67, XINST = OFF

unsigned char lTime;

unsigned char MyAdd;
unsigned char MyCmd;

#define irTris TRISCbits.TRISC4
#define irPin PORTCbits.RC4

void main(void);
void GetSIRC(unsigned char *address, unsigned char *command);

void main(void){

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

    TRISC = 0;
    irTris = 1;

    while(1){
        GetSIRC(&MyAdd,&MyCmd);
    }
}

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(4);        //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
            Delay100TCYx(4);    //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
            Delay100TCYx(4);    //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;
}

I even made a little RBG led test using digits 1-7. Ill make a small vid and show in a bit.
 
Last edited:

Pommie

Well-Known Member
Most Helpful Member
Hi Jason,

You have been busy lately. I wrote the same code a while back but mine is slightly different. I notice that you are oring the received bit into bit 7 and so your data is left justified. By oring into the lower bits you get the values published by Sony.

Here's mine for comparison,
Code:
#define IR_in   PORTAbits.RA6
#define IR_tris TRISAbits.TRISA6

unsigned char GetPulse(void){
unsigned char count;
    count=0;
    IR_tris=1;
    while(IR_in==1); 
    while(IR_in==0){
        count++;
        Delay100TCYx(1);   //50uS assumes 8MHz
    }
    return count;
}

void GetIR(char *cmd,char *dev){
char i;
    *cmd=0;
    *dev=0;
    while(GetPulse()<40);    //wait for start pulse
    for(i=0;i<7;i++){
        *cmd=*cmd>>1;
        if(GetPulse()>18)
            [COLOR="Red"]*cmd|=0x40;[/COLOR]
    }
    for(i=0;i<5;i++){
        *dev=*dev>>1;
        if(GetPulse()>18)
            [COLOR="red"]*dev|=0x10;[/COLOR]
    }
}

Mike.
 

AtomSoft

Well-Known Member
Darn i knew i miscounted bits :D since its 7 bits you or 0x40 for the 7th and since its 5 bits for address you or with 0x10

Thanks i fixed my code now :D your a great fixer dude!
 

Pommie

Well-Known Member
Most Helpful Member
Jason,

If you set MPLAB to convert tabs to spaces then it comes out fine.

Mike.
 

AtomSoft

Well-Known Member
OOPS i knew i forgot to do something when i redid my PC lol thanks i forgot about that option completely lol. heh look at this:

[embed]http://www.youtube.com/v/itfGGLP3Imw[/embed]
I had to attach the code. I set the tab to space thing and closed and reopened but still ugly looking lol.
 

Attachments

  • sirc.c
    3.7 KB · Views: 201
Last edited:

Pommie

Well-Known Member
Most Helpful Member
Looks good. It's always pleasing when something like this finally works.

Mike.
 

AtomSoft

Well-Known Member
i fixed the coding issue! I had to manually replace all the spacing with new tabs lol
Code:
/* **************************************************************************
;																			*
;	Filename: SIRC															*
;	Date: May 29, 2009														*
;	File Version: 001														*
;																			*
;	Author:   Jason Lopez													*
;	Company:  AtomSoft														*
;																			*
;****************************************************************************
; Notes:
; I am delaying in this code a nice even number every 200uS. Mainly because if
; i count each pulse it would be accurate but too many counts for a char type
; and i dont want to use a int. So i can get a 600 count by skipping every 300uS
; and the count will be a nice low number...3
; 
; For a 1.2mS aka HIGH i should get a count of 6 and for the start 2.4mS i should
; get a count of 12. Since this isnt too accurate i range it about 1-2 numbers 
; above or below the standard.
; 
;****************************************************************************
*/
#include <p18f2525.h>
#include <delays.h>
#include <string.h>

#pragma config WDT = OFF, LVP = OFF, OSC = INTIO67, XINST = OFF

unsigned char lTime;

unsigned char MyAdd;
unsigned char MyCmd;

#define irTris TRISCbits.TRISC4
#define irPin PORTCbits.RC4

#define Led_Red LATCbits.LATC1
#define Led_Blue LATCbits.LATC2
#define Led_Green LATCbits.LATC3

void main(void);
void GetSIRC(unsigned char *address, unsigned char *command);

void main(void){

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

TRISC = 0;
irTris = 1;

while(1){
GetSIRC(&MyAdd,&MyCmd);

switch(MyCmd){
    case 0:
        Led_Red = 0;
        Led_Blue = 1;
        Led_Green = 1;
        break;
    case 1:
        Led_Red = 1;
        Led_Blue = 0;
        Led_Green = 1;
        break;
    case 2:
        Led_Red = 1;
        Led_Blue = 1;
        Led_Green = 0;
        break;
    case 3:
        Led_Red = 0;
        Led_Blue = 0;
        Led_Green = 1;
        break;
    case 4:
        Led_Red = 1;
        Led_Blue = 0;
        Led_Green = 0;
        break;
    case 5:
        Led_Red = 0;
        Led_Blue = 0;
        Led_Green = 0;
        break;
    case 6:
        Led_Red = 1;
        Led_Blue = 1;
        Led_Green = 1;
        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(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(4);        //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
            Delay100TCYx(4);    //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
            Delay100TCYx(4);    //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;
}

Thanks Pommie (MIKE) and MIKE lol. I fixed the first post code with the nice looking code so everyone can understand it better lol
 
Last edited:

be80be

Well-Known Member
Atom that's great work i'm just starting some c18. looked at some lcd code you did it was very good to. Maybe i can to lol.
 

AtomSoft

Well-Known Member
I just made a nice remote using SONY (SIRC) Protocol.

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 TRISAbits.TRISA0
#define irPin  LATAbits.LATA0

#define UpTris  TRISBbits.TRISB5
#define DwnTris TRISBbits.TRISB4

#define Up_Btn  PORTBbits.RB5
#define Dwn_Btn PORTBbits.RB4


void main(void);
void SendSIRC(unsigned char Dev, unsigned char Cmd);
void PulseIt(unsigned char time);

void main(void){

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

    UpTris = 1;
    DwnTris = 1;
    irTris = 0;

    SendSIRC(1,1);
    while(1){
        if(Up_Btn == 0){
            SendSIRC(1,0);
            Delay10KTCYx(1);
        }
        if(Dwn_Btn == 0){
            SendSIRC(1,1);
            Delay10KTCYx(1);
        }
    }
}

void SendSIRC(unsigned char Dev, 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(Dev & 0x01)
            PulseIt(2);     //Logic 1
        else
            PulseIt(1);     //Logic 0
        Cmd <<= 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
    }
}
 

Sceadwian

Banned
Well then you can't fault him either way Mike, I think all of his projects have worked out =)
 

Mike - K8LH

Well-Known Member
AtomSoft,

Have you considered using the PWM module set up for 38 KHz? Then all you have to do is set a 50% duty cycle for 600, 1200, or 2400 usec periods and 0% duty cycle for the 600 usec periods. You could do it all in the background off of the TMR2 interrupt flag quite easily.
 

AtomSoft

Well-Known Member
Thanks Colin Mac :D its that i sometimes like to create something to test another. And end up in a never ending cycle of creations lol

Mike:
lol if the quality of the quantity is good then its good lol
 

AtomSoft

Well-Known Member
Here is the video of the test remote using my IR receiver and my universal remote (just for proof):

[embed]http://www.youtube.com/v/ZSrNUnipI8Y[/embed]


I used the 18F1320 for both the Remote and Receiver. Here is the code for both of them.
 

Attachments

  • 1320.zip
    35.3 KB · Views: 118
Last edited:

be80be

Well-Known Member
Man there got to be a better way to set C18 up I built going to try it out. You have your files on E drive C18 didn't no where to look seeing mine are on C drive Then I have to set the tool set up. C18 a pain in butt. Got to be easier way.
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top