|
Sony remote control apply pulse width coding scheme for their protocol. The code exists of 12 bits sent on a 40kHz carrier wave. The code starts with a header of 2,4ms or 4 times T where T is 600µS. The header is followed by 7 command bits and 5 adres bits. The address and commands exists of logical ones and zeros. A logical one is formed by a space of 600µS or 1T and a pulse of 1200 µS or 2T. A logical zero is formed by a space of 600 µS and pulse of 600µS. The space between 2 transmitted codes when a button is being pressed is 40mS The bits are transmitted least significant bits first. The total length of a bitstream is always 45ms. The detail of this protocol is depicted on the picture below (as transmitted from the remote, at the receiver side, it is inverted): How to decode that at the receiver?? This is my method : - Configure an external interrupt at the falling edge.
- If a falling edge found, start Timer0 to count the time elapsed until a rising edge found.
- At the first time, always check for a start bit based on it’s time length depicted above. If found than set a flag for a sign for the next signal processing. If not found than ignore the rest.
- If start bit found, then start to count up every falling edge signal detected up to next 12bit. The shorter length is denoted as zero (0) and the longer one is one (1), as depicted above.
- After 12 bit data received, set a flag indicate that the data is ready for reading and also reset the start bit flag. This is my version. You can do other scheme of scenario.
My schematic used ATMEGA16, but you can use other chips as long it got interrupt pin. For the sensor I used vcd remote control sensor, but you can use any type that have filter of 38KHz to 40KHz on it. On the schematic you see DS1307 RTC, LCD connector, and also LM386 amplifier, that’s the whole project I build. But for this application note, I only focused on the Sony decoding.  Source code below :
$regfile = "m16def.dat" 'the chip type, subtitutes with the one you like $crystal = 11059200 'the crystal speed i used Config Timer0 = Timer , Prescale = 256 'config timer0 for data trap timer Stop Timer0 'stop timer0 first for other process Config Pind.3 = Input 'configure the int pin , i used int1 pin Set Portd.3 'set the pull up resistor Pin_ir Alias Pind.3 'alias for easy naming Config Int1 = Falling 'configure int1 on falling edge On Int1 Isr_int1 'the isr label Dim Data_ir As Word 'the variabel need for the purpose Dim Cnt_ir As Byte Dim Flag_ir_start As Bit Dim Flag_ir_ok As Bit Print "SONY REMOTE DECODER" 'print some output to rx Enable Interrupts 'enable global interrupt Enable Int1 'enable int1 interrupt Do 'main program start here If Flag_ir_ok = 1 Then 'wait flag_ir_ok=1 Reset Flag_ir_ok 'reset the flag Disable Int1 'disable the int1, so ignore all ir data from here Print Data_ir 'print the data Reset Flag_ir_ok 'reset the flag Enable Int1 'enable the int1 interrupt to receive ir sony again End If Wait 1 'wait for sometime Loop 'isr for infrared sensor Isr_int1: Timer0 = 0 'start timer0 to count Start Timer0 Bitwait Pin_ir , Set 'wait the pin_ir to high again Stop Timer0 'stop timer0 If Cnt_ir = 0 Then 'if this is the 1st data If Timer0 > 111 And Timer0 < 114 Then 'check for a start bit, with prescale=256 and Set Flag_ir_start 'crystal 11,0592MHz, got timer0 value between 111 and 114 Incr Cnt_ir 'as the correct ir start bit. Measure all the neccessary bit first End If ' if you want to change it End If If Flag_ir_start = 1 And Cnt_ir > 0 Then 'a start bit found -> start sampling for next 12 bit Decr Cnt_ir If Timer0 < 32 Then 'timer0<32 then it is a zero(0), else it is a one (1) Data_ir.cnt_ir = 0 'assign it to a word value for easy recording Else Data_ir.cnt_ir = 1 End If Cnt_ir = Cnt_ir + 2 If Cnt_ir > 11 Then 'got all 12 bit Shift Data_ir , Right , 1 'get rid of the start bit Reset Flag_ir_start 'reset the start bit flag Set Flag_ir_ok 'the data is ready to be read Cnt_ir = 0 'reset the counter End If End If Return
|