Continue to Site

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.
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...
 
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:
if(IR_Pin == 0){ReadIR();}


Code:
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:
#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;
}
 
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.
 

Attachments

  • Untitled-1..jpg
    Untitled-1..jpg
    11 KB · Views: 177
Try this on your hardware:
Code:
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
	}
}
 
i have this as my receive code: (tested on my current hardware...)
Code:
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;
}
 
That receiver code i posted above is for 4 mhz

oh.

The one i am using is different which i thought was for 4MHz:
Code:
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;
}
 
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:
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:
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:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top