PDA

View Full Version : Sony SIRC IR Issue



Ryan7777
- 1st January 2009, 20:34
I just tossed this code together to see if I could make a simple on-off remote for my Sony TV, but it doesn't seem to want to work. I used an IR receiver module to compare my PIC produced signal with two different remotes that work with the TV, and the signals are very, Very close, but something still isnt right. I can't really see a make or break difference with my analog scope, but I have an LED connected to the IR receiver and it flashes, where as my signal seems to make it stay on, or at least its blinking fast enough to make it seem that way. I'm using HPWM (I know, I know.. ) to modulate the signal by using its pin as the low side of the LED and using RB0 as the highside and output. Can anyone offer corrections on the code (or my method)? Thanks ahead of time!


@ DEVICE pic16F648A, INTRC_OSC_NOCLKOUT, WDT_OFF, PWRT_OFF, MCLR_OFF, BOD_OFF

CMCON = 0

CCP1CON.2 = 1

CCP1CON.3 = 1

PORTB.3 = 0

Timingvar VAR WORD

HPWM 1,127,40000

Main:

Timingvar = 2704

GOSUB Header:

SELECT CASE Timingvar.11

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.10

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.9

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.8

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.7

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.6

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.5

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.4

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.3

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.2

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.1

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT

SELECT CASE Timingvar.0

CASE 0

GOSUB sZERO:

CASE 1

GOSUB sONE:

END SELECT



goto main:

Header:
LOW 0
pauseus 2400
high 0
Pauseus 600
Return

sONE:
HIGH 0
pauseus 1200
LOW 0
Pauseus 600
Return

sZERO:
HIGH 0
pauseus 600
LOW 0
Pauseus 600
Return

Darrel Taylor
- 2nd January 2009, 00:00
From the PBP manual, HPWM statement.
The highest frequency at any oscillator speed is 32767Hz.

You can get 40khz from the CCP module, but you'll have to do it manually.
<br>

Ryan7777
- 2nd January 2009, 16:18
Yeah, I've seen that speed limit, but the frequency seems very close. And the fact that my IR module was / is working on the bench would make me think that its close enough. But maybe not close enough for the module in my TV? I've never used the CCP module in the 16F648A part manually. The data sheet seems kind of vauge. I know you have to mess with Timer2.
can someone throw me a bone and explain how to set the bits? My math is terrible but I attempted to Freq = [(PR2)+1]*4*4(?)*1(?) and get no where near a 8 bit number for PR2. If you could explain that too, it'd be a huge help!

Thanks again

Darrel Taylor
- 2nd January 2009, 20:52
To understand How ...

Using The PIC Microcontroller Hardware PWM Feature & Infrared Communications
http://www.rentron.com/Infrared_Communication.htm

And for easy PWM calculations ...

mister_e's PicMultiCalc.
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2957
<br>

Bruce
- 4th January 2009, 19:46
Here's an easier way without hardware PWM. I haven't tested this on a Sony TV, but it
works great for testing our Sony decoders.


@ DEVICE PIC16F648A, xt_osc, wdt_off, mclr_off, lvp_off, protect_off

DEFINE OSC 4

' Sony TV - IR pulse timing
Synch CON 96 ' 96 x 25uS = 2.4mS (synch pulse with carrier ON)
Interbit CON 500 ' 500uS (delay between data bits with carrier OFF)
InterPacket CON 26000' 26mS (delay between data packets with carrier OFF)
Logic1 CON 48 ' 48 x 25uS = 1.2mS. Logic 1 bit = 1.2mS (carrier ON)
Logic0 CON 23 ' 24 x 25uS = 600uS. Logic 0 bit = 600uS (carrier ON)

' Packet format: 7 bits on left are button number. 5 bits on right select TV.
K1 CON %000000010000 ' BUTTON 1
K2 CON %100000010000 ' BUTTON 2
K3 CON %010000010000 ' BUTTON 3
K4 CON %110000010000 ' BUTTON 4
K5 CON %001000010000 ' BUTTON 5
K6 CON %101000010000 ' BUTTON 6
K7 CON %011000010000 ' BUTTON 7
K8 CON %111000010000 ' BUTTON 8
K9 CON %000100010000 ' BUTTON 9
K0 CON %100100010000 ' BUTTON 0
MENU CON %000000010000 ' MENU BUTTON
MUTE CON %001010010000 ' MUTE BUTTON
CHUP CON %000010010000 ' CHANNEL UP BUTTON
CHDWN CON %100010010000 ' CHANNEL DOWN BUTTON
VOLUP CON %010010010000 ' VOLUME UP BUTTON
VOLDWN CON %110010010000 ' VOLUME DOWN BUTTON
PREVCH CON %110111010000 ' PREVIOUS CHANNEL BUTTON
ENTER CON %110100010000 ' ENTER BUTTON
POWER CON %101010010000 ' ON/OFF POWER BUTTON

X VAR BYTE ' Data bit loop counter & bit index pointer
Duration VAR BYTE ' Duration of button press
Loops VAR BYTE ' Loop count
Cycles VAR BYTE BANK0 SYSTEM' Number of carrier cycles to generate
Key VAR WORD ' Button # to send

PORTB = %00000000 ' All outputs = 0 on boot
TRISB = %00000000 ' RB0 = IRLED out

@ #define IRTX PORTB ; Define port to use for IR out
@ #define PIN 0 ; Define port pin for IR out

GOTO Main ' Jump over pulse routine to Main

Pulse: ' Generate "Cycles" number of 40kHz pulses
ASM ; Keep this routine in code page 1, and jump over to Main
bsf IRTX,PIN ; 1uS, LED=on
goto $+1 ; + 2uS = 3uS
goto $+1 ; + 2uS = 5uS
goto $+1 ; + 2uS = 7uS
goto $+1 ; + 2uS = 9uS
goto $+1 ; + 2uS = 11uS
goto $+1 ; + 2uS = 13uS
bcf IRTX,PIN ; 1uS, LED=off
goto $+1 ; + 2uS = 3uS
goto $+1 ; + 2uS = 5uS
goto $+1 ; + 2uS = 7uS
goto $+1 ; + 2uS = 9uS
decfsz Cycles,f ; + 1uS = 10S
goto _Pulse ; + 2uS = 12uS
ENDASM
return ' Return to caller

Main:
PAUSE 5000
Key = POWER ' Press Power button
Duration = 2 ' Send it twice

FOR Loops = 1 TO Duration ' Loop 1 to duration
Cycles = Synch ' 2.4mS synch (carrier on)
GOSUB Pulse ' Send synch

' Synch done, now do data bits
FOR X = 11 to 0 STEP-1 ' 12-bits total MSB first
PAUSEUS InterBit ' Pause InterBit delay period (carrier off)
IF Key.0[X] = 1 THEN '
Cycles = Logic1 ' Logic 1
ELSE ' or
Cycles = Logic0 ' Logic 0
ENDIF
GOSUB Pulse ' Send data
NEXT X ' Loop for all 12-bits

PAUSEUS InterPacket ' Inter-Packet delay period (carrier off)
NEXT Loops ' Loop for duration
GOTO Main ' Return for more

END

Ryan7777
- 5th January 2009, 15:24
Thanks for both of your help, I had a look at bruce's site and his code for the encoder/decoder project. I borrowed his ASM code that did away with the HPWM altogether and had to add the 25ms delay in there. It works fine now. But I'll still try to get a grip on the HPWM for the 648A just in case i need it for something in the future. I have used it on other chips in the past and got it working just fine, but i don't remember having to worry about setting anything for timer 2. maybe that was just a dream? I've also used Darrels routine to handle pwm needs, but sometimes it just doesn't seem to want to work, even on a regular single channel HPWM... probably something im doing wrong. I'm so on and off again with PICs that I forget half of what I learn after learning it...

Anyway!

Thanks again!

Bruce
- 5th January 2009, 16:20
If you use the HPWM command you don't need to mess with Timer2. PBP handles this for
you automatically.

If you need hardware PWM for a frequency not supported by the HPWM command, then
you need to set everything up manually.

xervox
- 3rd September 2012, 13:27
How pins connect the buttons?pull up ,pull down?Thanks:smile:

xervox
- 4th September 2012, 08:09
This program how can I make 15 bit or 20 bit?

eggman
- 4th September 2012, 14:37
here's how I set up the registers to use HPWM:

PR2 = %00011001 ' Set PWM frequency to +/- 40kHz, set to 26 for 38kHz or 28 for 36kHz
CCP1CON = %00001100 ' Mode select = PWM
T2CON = %00000100 ' Timer2 ON + 1:1 prescale
CCPR1L = %00001101 ' PWM duty cycle 50%

kzeoprf
- 8th August 2015, 08:10
Hi All,
I want to make a Sony remote. I wrote the attached code, and I do not see any results. The IR Led is on the colector of a npn transistor, which is controlled by PORTC.2 (for pwm).Anyhelp!.
When I connect a red led instead of the if Is see the led going on off, when the rotary is used, and in idle it goes on and of periodically with a period of ~1sec. The used pic is pic18f2550.
I think i need help now, if anyone couldhelp thanks.


DEFINE OSC 4


DEFINE BUTTON_PAUSE 20
DEFINE PULSIN_MAX 5000

INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts


ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT0_INT, _Rot_Encoder, PBP, yes
INT_Handler INT2_INT, _but_int, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

addr CON %00011010 ' 26 = DVD address code
code CON $49 ' http://www.winpicprog.co.uk/pic_tutorial5.html

' Packet format: 7 bits on left are button number. 5 bits on right select TV.

MENU CON 0 ' MENU BUTTON
MUTE CON 20 ' MUTE BUTTON
CHUP CON 16 ' CHANNEL UP BUTTON
CHDWN CON 17 ' CHANNEL DOWN BUTTON
VOLUP CON 18 ' VOLUME UP BUTTON
VOLDWN CON 19 ' VOLUME DOWN BUTTON
ENTER CON 11 ' ENTER BUTTON

X VAR BYTE ' Data bit loop counter & bit index pointer
Duration VAR BYTE ' Duration of button press
Key VAR BYTE ' Button # to send
Y VAR BYTE ' Data bit loop counter & bit index pointer


PR2 = %00011001 ' Set PWM frequency to +/- 40kHz, set to 26 for 38kHz or 28 for 36kHz
CCP1CON = %00001100 ' Mode select = PWM
T2CON = %00000100 ' Timer2 ON + 1:1 prescale
CCPR1L = %00001101 ' PWM duty cycle 50%

TRISA = 0
TRISB = 0 ' RB0 = IRLED out
TRISB.0 = 1
TRISB.1 = 1
TRISB.2 = 1
TRISC = 0 ' RB0 = IRLED out

STATIC_CONTROL_MODE VAR BYTE
OLDBITS VAR BYTE
NEWBITS VAR BYTE
COUN VAR WORD
adraneia VAR WORD


IROUT VAR PORTC.2
led VAR PORTC.1
ENC0 VAR PORTB.0
ENC1 VAR PORTB.1
BUTT VAR PORTB.2

Duration = 3 ' Send it twice
COUN = 0
adraneia = 0

high led
pause 1000
low led

GOTO Main ' Jump over pulse routine to Main


but_int:
@ INT_DISABLE INT2_INT
adraneia = 0
IF BUTT = 0 THEN
high led
COUN = 0
WHILE BUTT = 0
COUN = COUN + 1
PAUSE 200
WEND

IF COUN > 13 THEN
Key = MUTE
COUN = 0
goto POUT_I
ENDIF

IF COUN > 40 THEN
Key = MENU
COUN = 0
goto POUT_I
ENDIF

COUN = 0
IF STATIC_CONTROL_MODE = 0 THEN
STATIC_CONTROL_MODE = 1
ELSE
STATIC_CONTROL_MODE = 0
ENDIF
Key = volup
goto POUT_I
endif
goto done_but


sendHeaderI:
TRISC.2 = 0
PauseUs 2400 ' Lead_in pulse
TRISC.2 = 1
pauseus 600
RETURN

sendZeroI:
TRISC.2 = 0
PauseUs 600 ' Lead_in pulse
TRISC.2 = 1
pauseus 600
RETURN


sendOneI:
TRISC.2 = 0
PauseUs 1200 ' Lead_in pulse
TRISC.2 = 1
pauseus 600
RETURN

POUT_I: ' send IR code
for Y = 1 to Duration ' five times
X= 0
GOSUB sendHeader
FOR X = 6 to 0 STEP-1 ' 12-bits total MSB first
IF Key.0[X] = 1 THEN '
GOSUB sendOneI
ELSE
GOSUB sendZeroI
ENDIF
NEXT X
Key = addr
X = 0
FOR X = 4 to 0 STEP-1 ' 12-bits total MSB first
IF Key.0[X] = 1 THEN '
GOSUB sendOneI
ELSE
GOSUB sendZeroI
ENDIF
NEXT X
TRISC.2 = 1
Pauseus 1000
next Y
GOTO done_but

done_but:
@ INT_ENABLE INT2_INT
@ INT_RETURN


Main:
PAUSE 5000
OLDBITS.1 = ENC1
OLDBITS.0 = ENC0
STATIC_CONTROL_MODE = 0
high led

@INT_ENABLE INT0_INT ;RB Port Change Interrupt
@INT_ENABLE INT2_INT ;RB Port Change Interrupt

loopw:
PAUSE 200
adraneia = adraneia + 1
if adraneia > 150 then
low led
adraneia = 0
sleep 36000
endif

Goto loopw ' Do it forever


'---[RBC - interrupt handler]---------------------------------------------------
Rot_Encoder:
@ INT_DISABLE INT0_INT

NEWBITS.1 = PORTB.1
NEWBITS.0 = PORTB.0
high led
adraneia = 0
IF NEWBITS.0 = 0 AND OLDBITS.0 = 1 THEN
IF NEWBITS.1 = 1 THEN
GOTO GODOWN
ELSE
GOTO GOUP
ENDIF
ENDIF
goto DoneRotEnc


GOUP:
if STATIC_CONTROL_MODE = 1 then
GOTO GOCHUP
ELSE
goto GOVOLUP
ENDIF

GODOWN:
if STATIC_CONTROL_MODE = 1 then
GOTO GOCHDW
ELSE
goto GOVOLDW
ENDIF

GOVOLUP:
Key = VOLUP
GOTO POUT


GOVOLDW:
Key = VOLDWN
GOTO POUT


GOCHDW:
Key = CHDWN
goto POUT


GOCHUP:
Key = CHUP
goto POUT


sendHeader:
TRISC.2 = 0
PauseUs 2400 ' Lead_in pulse
TRISC.2 = 1
pauseus 600
RETURN

sendZero:
TRISC.2 = 0
PauseUs 600 ' Lead_in pulse
TRISC.2 = 1
pauseus 600
RETURN


sendOne:
TRISC.2 = 0
PauseUs 1200 ' Lead_in pulse
TRISC.2 = 1
pauseus 600
RETURN

POUT: ' send IR code
for Y = 1 to Duration ' five times

GOSUB sendHeader
FOR X = 0 to 6 ' 12-bits total MSB first
IF Key.0[X] = 1 THEN '
GOSUB sendOne
ELSE
GOSUB sendZero
ENDIF
NEXT X
Key = addr
X = 0
FOR X = 0 to 4 ' 12-bits total MSB first
IF Key.0[X] = 1 THEN '
GOSUB sendOne
ELSE
GOSUB sendZero
ENDIF
NEXT X
TRISC.2 = 1
Pauseus 1000
next Y
GOTO DoneRotEnc

DoneRotEnc:
OLDBITS = NEWBITS
@ INT_ENABLE INT0_INT
@ INT_RETURN



END