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);
}
}




2013年7月17日水曜日

Tektronix Oscilloscope

Tektronix Oscilloscope

I got Tektronix TBS1022 that is just only 500 hundred dollar with 5 year guarantee. Now the Japanese yen become weak so there is a possibility of changing the sales price in Japan. Actually apple's iPod and iPad become a little bit expensive... Before changing the price, I decided to buy.

Band width is only 25MHz but it is enough for me to analyze my boards.




















In the near future, I'm going to make remote controller of my TV by using PIC by analyzing its signals.

2013年4月3日水曜日

two dimensional array on iOS

Making two dimensional array on iOS.

By using NSMutableArray class, changeable   two dimensional array can be made by like following.

notice: I don't guarantee any issues caused by below source

- (NSMutableArray*)twoDimensionalArray:(int)width height:(int)height
{
    NSMutableArray* folder=[NSMutableArray array];
    for(int i=0;i<height;i++)
    {
        [folder addObject:[[NSMutableArray alloc] initWithCapacity:width]];
    }
    
    return folder;
}

- (void)exampleFunc
{
    NSMutableArray* array=[NSMutableArray array];
    array=[self twoDimensionalArray:2 height:2];
    
    int k=1;
    for(int j=0;j<2;j++)
    {
        for(int i=0; i<2;i++)
        {
            [[array objectAtIndex:j] addObject:[NSNumber numberWithInt:k]];
            k++;
        }
    }
    
    for(int j=0;j<2;j++)
    {
        for(int i=0; i<2;i++)
        {
            NSLog(@"val:%d",[[[array objectAtIndex:j] objectAtIndex:i] intValue]);
        }
    }
}

2012年7月1日日曜日

Wake-up timer trial 1

Special wake-up timer

I try to make wake-up timer for studying PIC IC.

Function
The function I want apply is that PIC set LED light intensity high step by step before wake-up alarm sounds.


Every people can wake up easily if they can recognize the day has already start. The LED play a roll of morning sun.
I try to buy such timer, but there are no items which can satisfy my request.
So... I start to make it by myself.

Preparations
PIC18F452 : Main pic
PIC16F88 : Used for beeping the sounder
LCD Module SD1602 : displaying the necessary information, such as time and time to wake-up.
RTC : RTC-8564-NB timer-IC

Report
Below is the B.B pictures I build-up.
It seems work well, but the necessary function, i.e. lighting up LED, is not implemented. Next step I'd like to introduced it.
After I have finishing building up and debugging them, I'd like to disclose the circuit and code.




Date setting is very hard for me... 


Below is the program code for accessing RTC-IC.
//I don't guarantee any problems which are caused by below function, thanks.


unsigned int i2c_write(char addr, unsigned char data);
unsigned char i2c_read(char addr, unsigned char* data);
unsigned char i2c_read_time(char addr, unsigned char* data, unsigned char size);
unsigned int i2c_bit_write(char addr, unsigned char data,unsigned char bit);

//I2C write function

unsigned int i2c_write(char addr, unsigned char data)
{
//Start Condition
    IdleI2C();
    StartI2C();
    while(SSPCON2bits.SEN){;}
       
//Write Slave Address wtih Write mode
if(WriteI2C(SLV_RTC)<0){return 1;}
IdleI2C();
    //Write address of device
    if(WriteI2C(addr)){return 2;}
IdleI2C();
//Write address of data
if(WriteI2C(data)){return 3;}
//Send Stop
IdleI2C();
    StopI2C();
while(SSPCON2bits.PEN);
Delay10TCYx(4);
   
return 0;

}

//I2C read function
unsigned char i2c_read(char addr, unsigned char* data)
{
//Start I2C
IdleI2C();
    StartI2C();
    while(SSPCON2bits.SEN);
    //Write Slave Address wtih Write mode
if(WriteI2C(SLV_RTC)<0){return 1;}
IdleI2C();
    //Write address of device
    if(WriteI2C(addr)){return 2;}
IdleI2C();
    RestartI2C();
while(SSPCON2bits.RSEN);
    //Write Slave Address wtih Read mode
    if(WriteI2C(SLV_RTC | 0x01)){return 3;}
IdleI2C();      
//Read Data
while(DataRdyI2C());
    *data = ReadI2C();
Delay10TCYx(20);
    //Send NAck signal
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN);
    //Send Stop Signal
    StopI2C();
while(SSPCON2bits.PEN);
   
return 0;
}


//Read data sequentially
unsigned char i2c_read_time(char addr, unsigned char* data, unsigned char size)
{
unsigned char i;
//Start I2C
IdleI2C();
    StartI2C();
    while(SSPCON2bits.SEN);
    //Write Slave Address wtih Write mode
if(WriteI2C(0xA2)<0){return 1;}
IdleI2C();
    //Write address of device
    if(WriteI2C(addr)){return 2;}
IdleI2C();
    RestartI2C();
while(SSPCON2bits.RSEN);
    //Write Slave Address wtih Read mode
    if(WriteI2C(0xA3)){return 3;}
IdleI2C();        
//Read Data
for(i=0;i<=size;i++){
while(DataRdyI2C());
data[i] = ReadI2C();
Delay10TCYx(20);
if(i < size){
SSPCON2bits.ACKDT = 0;
}else
{
SSPCON2bits.ACKDT = 1;
}
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN);
}

    //Send Stop Signal
    StopI2C();
while(SSPCON2bits.PEN);

return 0;
}

//Change only target bit of inputed address

unsigned int i2c_bit_write(char addr, unsigned char bitshift, unsigned char data)
{
unsigned char read_data;

//Read the registered value
IdleI2C();
    StartI2C();
    while(SSPCON2bits.SEN);
    //Write Slave Address wtih Write mode
if(WriteI2C(SLV_RTC)<0){return 1;}
IdleI2C();
    //Write address of device
    if(WriteI2C(addr)){return 2;}
IdleI2C();
    RestartI2C();
while(SSPCON2bits.RSEN);
    //Write Slave Address wtih Read mode
    if(WriteI2C(SLV_RTC | 0x01)){return 3;}
IdleI2C();      
//Read Data
while(DataRdyI2C());
    read_data = ReadI2C();
Delay10TCYx(20);
    //Send NAck signal
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while(SSPCON2bits.ACKEN);
    //Send Stop Signal
    StopI2C();
while(SSPCON2bits.PEN);

//Write target bit
if(data){
read_data |= (data << bitshift);
}
else{
data = 0xFF - (0x01 << bitshift);
read_data &= data;
}

//Start Condition
    IdleI2C();
    StartI2C();
    while(SSPCON2bits.SEN){;}
       
//Write Slave Address wtih Write mode
    //if(WriteI2C(SLV_RTC)<0){return -1;}
if(WriteI2C(SLV_RTC)<0){return 1;}
IdleI2C();
    //Delay10TCYx(20);
    //Write address of device
    if(WriteI2C(addr)){return 2;}
IdleI2C();
//Write address of data
if(WriteI2C(read_data)){return 3;}
//Send Stop
IdleI2C();
    StopI2C();
while(SSPCON2bits.PEN);
Delay10TCYx(4);
   
return 0;

}