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.
Hi AtomSoft, is there a need of some capacitors with the IR sensor? I have made my own remote using your code. It works but not always. Like if i press the buttons from the remote 8 times, one time the receiver recognizes and not all 8 times :(
 
Yes a cap/resistor is needed on receiver... i would copy what Bill did on his Junebug...



If you download the assembly manual you will see the schematic which will show you how to setup the receiver with a cap & resistor...

EDIT:

But it sounds more of a timing issue since it does work sometimes... Can you post your code/schematic?
 
Last edited:
This is the part of receiver code related to IR.
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:
				if(CON_T > 0){update_toggle(1);}
				if(CON_S > 0){update_switch(1);}
				break;
			case 1:
				if(CON_T > 1){update_toggle(2);}
				if(CON_S > 1){update_switch(2);}
				break;
			case 2:
				if(CON_T > 2){update_toggle(3);}
				if(CON_S > 2){update_switch(3);}
			break;
			case 3:
				if(CON_T > 3){update_toggle(4);}
				if(CON_S > 3){update_switch(4);}
				break;
			case 4:
				if(CON_T > 4){update_toggle(5);}
				if(CON_S > 4){update_switch(5);}
				break;
			case 5:
				if(CON_T > 5){update_toggle(6);}
				if(CON_S > 5){update_switch(6);}
				break;
			case 6:
				if(CON_T > 6){update_toggle(7);}
				if(CON_S > 6){update_switch(7);}
				break;
			case 7:
				if(CON_T > 7){update_toggle(8);}
				if(CON_S > 7){update_switch(8);}
				break;
			case 8:
				if(CON_D > 0){update_dimmer(1,UP);}
				break;
			case 9:
				if(CON_D > 1){update_dimmer(2,UP);}
				break;
			case 10:
				MODE = TOGGLES;
				update_display(MODES);
				break;
			case 11:
				on_all();
				break;
			case 12:
				if(CON_D > 0){update_dimmer(1,DOWN);}
				break;
			case 13:
				if(CON_D > 1){update_dimmer(2,DOWN);}
				break;
			case 14:
				MODE = SWITCHES;
				update_display(MODES);
				break;
			case 15:
				off_all();
				break;
			default:
				break;
		}
	}
}

This is the transmitter code.

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
			lock_key();
			SendSIRC(addrSel,0);
		break;
		case 1:							// Toggle 2
			lock_key();
			SendSIRC(addrSel,1);
		break;
		case 2:							// Toggle 3
			lock_key();
			SendSIRC(addrSel,2);
		break;
		case 3:							// Toggle 4
			lock_key();
			SendSIRC(addrSel,3);
		break;
		case 4:							// Toggle 5
			lock_key();
			SendSIRC(addrSel,4);
		break;
		case 5:							// Toggle 6
			lock_key();
			SendSIRC(addrSel,5);
		break;
		case 6:							// Toggle 7
			lock_key();
			SendSIRC(addrSel,6);
		break;
		case 7:							// Toggle 8
			lock_key();
			SendSIRC(addrSel,7);
		break;
		case 8:							// Dimmer 1 Up
			repeat_key();
			SendSIRC(addrSel,8);
		break;
		case 9:							// Dimmer 2 Up
			repeat_key();
			SendSIRC(addrSel,9);
		break;
		case 10:						// Mode L
			lock_key();
			SendSIRC(addrSel,10);
			modeSel = MODE_L;
			ShowModeLED(MODE_L);
		break;
		case 11:						// Master On
			lock_key();
			SendSIRC(addrSel,11);
		break;
		case 12:						// Dimmer 1 Down
			repeat_key();
			SendSIRC(addrSel,12);
		break;
		case 13:						// Dimmer 2 Down
			repeat_key();
			SendSIRC(addrSel,13);
		break;
		case 14:						// Mode S
			lock_key();
			SendSIRC(addrSel,14);
			modeSel = MODE_S;
			ShowModeLED(MODE_S);
		break;
		case 15:						// Master Off
			lock_key();
			SendSIRC(addrSel,15);
		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;
}
 
I've used those kinds of IR modules before, mine glitched all over the place until I put the cap and resistor on, then it performed flawlessly.
According to the data sheet the cap should be 4.7u and the resistor should be 100ohms.

Do not trust simulators to give you the same results as real world devices, they never will, they are simply tools to help develop circuits, real world devices often have noise issues that you'll never see in a simulator. Also make sure you have a bypass capacitor on your micro controller itself as this may help as well.
 
Haxan can you get a universal remote to test it out first? I use a 4.7 cap and 100ohm like Bill does and it works 100% of the time. I even ported the same code to a 4mhz pic 12F629 and 12F683 and both works great!

If you have another IR Receiver part try replacing that one to see if its a damaged part... also ensure that its a 38khz or 40khz part.... both works for sony (for me at least)
 
I dont have 4.7uF cap at this time. Yes i have tried changing the IR receiver and still the same thing.

Is it necessary to keep on sending the signals when the button is pressed? I only send once when the button is released. Can this be the issue?

I have a SONY TV remote but that is not working at all. Maybe there is a clock difference.
 
Last edited:
lol, i havent attached any transistor. Just a simple 100ohm resistrance with the IR led to RA0 pin of the microcontroller.


The system works fine it a fixed level and distance from the apparatus.

Atom, the SONY TV remote might have a different clock speed, wont that effect the working. Maybe its the reason it is not communicating with my system.

When you made your own Remote, what resistors you used for Base and Collector portions of the transistor?
 
The 47u cap should work just as good as the 4.7u one. Have you checked the ouput of the module from a scope to see if it's getting a signal all the time and your mcu code is incorrect somehow?
 
Yes the code is correct as AtomSoft has used it in his project earlier in these threads. The communication goes on fine at a fixed height and distance from the receiver. About 2inch far from IR sensor and 2 inch high.

I dont have a transistor attached with the transmitting IR LED. I am going to try with this.
 
Still no go with transistor. I used 9014 transistor. Added a 100ohm resistance with base and collector both. Put the IR LED with emitter and ground. Still the same result.

It is purly line of sight right now. Like a laser beam. move it a little away from the path and the data doesnt go over.
 
Last edited:
Ok Sony IR is just that... IR ... The clocks are all the same for remotes... meaning... if you use a universal remote set to sony then it should work on any Receiver @ 40khz.... if the clock is different then it isnt sony ir (SIRC)
I say use a transistor mainly so you can use more current to power IR Led so you can send data further...

If it works line of sight then maybe its either a IR LED or IR Receiver issue meaning you have to try a different IR Receiver... maybe the 2 you have there tested arent 40khz or 38khz
 
I am tired of this SONY IR protocol. Philips RC5 was way easier to use. I have tried adding a transistor (9014) have changed IR LED, Receiver, tried different caps but there is still something wrong :(

Also the system doesnt respond to universal remote for SONY.
 
If i attach an LED with the IR receiver to sense the coming input, i see that when i use my remote, the LED blinks really fast but if i use universal remote, the IR LED blinks with lesser rate. I think it is a timings issue i am facing.

The problem is i am using 4MHz crystals on both side (Remote and Receiver). The original code made by atomsoft was for 8MHz. Can anyone suggest how to migrate from 8 to 4
 
Status
Not open for further replies.

Latest threads

Back
Top