2013年7月19日金曜日

Sony "Bravia" Remote controller

Making remote controller

My TV is Sony's Bravia and I'd like to control my TV in my program.
My final target is to combine the wake up timer and remote controller. Special wake up timer will let me wake up with setting TV my favorite program or setting air conditioner with set of comfort temperature. 

The Tektronix TBS1022 help me to understand the protocol of IR signals of controller.

Protocol

Overall

IR signals consists of "Header", "Data" and "Address" area.










Size of "Data" is 8 bit and that of "Address" is 4 bit.

Each data cycle

Standard cycle of signal is 600usec(T).
"Header" consists of high condition for 4T period and low condition for 1T period.
i.e, "Header" is 2,400usec high state and 600usec low state.

Each bit data is presented by combination of high condition time and low condition time.

If bit is high, the signal consists of 2T high and 1T low. Please see below "Data 1".
If bit is low, the signal consists of 1T high and 1T low. Please see below "Data 0".

i.e, "Data 1" is 1,200usec high state and 600usec low state.
"Data 0" is 600usec high state and 600usec low state.













PWM waveform is used for above control and its frequency is 40kHz.


Repeat signal 4 times

Above protocol is send 4 time with specific interval.
Like below figure, the 45.0msec interval time is necessary for each command.











Command

I don't care which side is MSB-side. So maybe my understanding is not correct.
So the code is just reference data.
Please be apply my code to below sample program.

Address is 0x00 so only data code is written in below.
Volume-up : 0xC9
Volume-down : 0x49
Channel 1 : 0x01
Channel 2 : 0x08


In my program, 0x0C90 is set for "Volume-up".

Program

Below is my program for test above protocol. The wait time is a little bit different from above ideal specific. 

#include <p18f2320.h>
#include <delays.h>
#include "wait.h"

#pragma config OSC=HSPLL, FSCM=OFF, IESO=OFF, PWRT=ON
#pragma config BOR=ON, BORV=45, WDT=OFF, WDTPS=1024
#pragma config MCLRE=ON, PBAD=DIG, CCP2MX=C1
#pragma config STVR=OFF, LVP=OFF, DEBUG=OFF
#pragma config CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF, CPB=OFF
#pragma config CPD=OFF, WRT0=OFF, WRT1=OFF, WRT2=OFF, WRT3=OFF
#pragma config WRTB=OFF, WRTC=OFF, WRTD=OFF, EBTR0=OFF
#pragma config EBTR1=OFF, EBTR2=OFF, EBTR3=OFF, EBTRB=OFF

//10MHz OSC and OSC is set to HSPLL
#define MCLK 40
#define PERIOD 24

int sendData(unsigned int data);
int ledOn(int cycle);
int dataLow(void);
int dataHigh(void);
int headerIR(void);

void main(void)
{
  //PORT A initial setting
  ADCON1 &= 0x0F;
TRISA = 0x00;
  LATA = 0x00;

wait_ms(MCLK, 500);
while(1)
{
sendData(0x0490);
wait_ms(MCLK, 10);
}
}

int ledOn(int cycle)
{
int i;
for(i=0; i<cycle;i++)
{
LATAbits.LATA0 |= 0x01;
Delay100TCYx(1);
Delay10TCYx(2);
Delay1TCY();
Delay1TCY();
Delay1TCY();
LATAbits.LATA0 &= 0xFE;
Delay100TCYx(1);
//Delay10TCYx(2);
Delay1TCY();
Delay1TCY();
Delay1TCY();
Delay1TCY();
Delay1TCY();
}
return 0;
}


int headerIR(void)
{
//PWM on
int i;
for(i=0; i<96; i++)
{
LATAbits.LATA0 |= 0x01;
Delay100TCYx(1);
Delay10TCYx(2);
Delay1TCY();
Delay1TCY();
Delay1TCY();
LATAbits.LATA0 &= 0xFE;
Delay100TCYx(1);
//Delay10TCYx(2);
Delay1TCY();
Delay1TCY();
Delay1TCY();
Delay1TCY();
Delay1TCY();
}

//off 1T
LATAbits.LATA0 &= 0xFE;
Delay1KTCYx(6);
return 0;
}

int dataLow(void)
{
//on 1T
ledOn(PERIOD);

//off 1T
LATAbits.LATA0 &= 0xFE;
Delay1KTCYx(6);
}

int dataHigh(void)
{
//on 2T
ledOn(PERIOD * 2);
//off 1T
LATAbits.LATA0 &= 0xFE;
Delay1KTCYx(6);
}

int sendData(unsigned int data)
{
int cnt;
int i, j;
unsigned int restTime;

for(j=0; j<4; j++)
{
cnt = 0;
restTime = 450; //45usec / 100, to make caluculation decrease
//header
headerIR();
cnt += 5; //3000usec is used for header data

//data
for(i=11;i>=0;i--)
{
if( ((data >> i) &0x01) == 1)
{
dataHigh();
cnt += 3;
}
else
{
dataLow();
cnt += 2;
}
}

//wait
restTime -= cnt * 6;
Delay10KTCYx(restTime / 10);
Delay1KTCYx(restTime % 10);
}
}




0 件のコメント:

コメントを投稿