UTMonkey
New Member
Hi All,
Thanks to the great advice given from this site I utilised the IR module of my JuneBug to detect SIRC codes. I have included the completed the code below - Thanks to all who helped!
How it works
The IR receiver has its output put into RB0, I configured INT0 on this port to trigger on the falling edge - or the beginning of a pulse.
When this happens the code clears TMR0L and enables the timer, the INT0 interrupt is then altered to fire upon the rising edge.
When this occurs TIMER0 is disabled and a reading is taken from TMR0L.
Taking TMR0L readings from as far away as 10 meters, gives me.
0x12-0x14 = for a StartBit
0x9 - 0xB = for a "one" bit
0x4 - 0x6 = for a "zero" Bit
What the code doesnt do
1. Nigel Goodwin's tutorials indicate the possibility of "extended" SIRC codes, these have not been accomodated into this code (but could be).
2. does not have any output routines, sorry I just wanted to check the IR functionality and so I havent patched this into any LCD code etc.
How to get it working
Best to run from MPLAB IDE in debug mode, when first run LED1 will light indicating it is ready to receive a code, when you fire a SIRC code at it LED2 should light indicating it has received a valid code.
At this stage, stop the debugger and inspect variables CommandCode and DeviceCode you should see the relevant 7 and 5 bit values.
To start again, run the debugger and press button 2 on the JuneBug to begin again.
Thanks to the great advice given from this site I utilised the IR module of my JuneBug to detect SIRC codes. I have included the completed the code below - Thanks to all who helped!
How it works
The IR receiver has its output put into RB0, I configured INT0 on this port to trigger on the falling edge - or the beginning of a pulse.
When this happens the code clears TMR0L and enables the timer, the INT0 interrupt is then altered to fire upon the rising edge.
When this occurs TIMER0 is disabled and a reading is taken from TMR0L.
Taking TMR0L readings from as far away as 10 meters, gives me.
0x12-0x14 = for a StartBit
0x9 - 0xB = for a "one" bit
0x4 - 0x6 = for a "zero" Bit
What the code doesnt do
1. Nigel Goodwin's tutorials indicate the possibility of "extended" SIRC codes, these have not been accomodated into this code (but could be).
2. does not have any output routines, sorry I just wanted to check the IR functionality and so I havent patched this into any LCD code etc.
How to get it working
Best to run from MPLAB IDE in debug mode, when first run LED1 will light indicating it is ready to receive a code, when you fire a SIRC code at it LED2 should light indicating it has received a valid code.
At this stage, stop the debugger and inspect variables CommandCode and DeviceCode you should see the relevant 7 and 5 bit values.
To start again, run the debugger and press button 2 on the JuneBug to begin again.
Code:
list p=18F1320
include <p18F1320.inc>
; include <Macros.inc> - Dont need
CONFIG OSC = INTIO1, WDT = OFF, LVP = OFF, DEBUG = ON
btDone equ 0x0
btStart equ 0x1
btCommand equ 0x2
cblock 0x00
Time2
BitCount
DeviceCode
CommandCode
IRStatus
Bit
ScratchCode
endc
org 0x0000
goto Init
;****************************
;* Interrupt Service *
;****************************
org 0x0008
ISR
bcf LATA, RA0
bcf LATA, RA6
btfsc IRStatus, btDone ;Has a code already been read?
goto ISR_Done
btfsc INTCON2, INTEDG0 ;Check if falling or rising signal
goto Rise
btg INTCON2, INTEDG0
clrf TMR0L ;Reset Timer
movlw b'11000111' ;Enable timer 0, use 8bit counter, use 256 prescaler
movwf T0CON ;Do it
goto ISR_Done
Rise
clrf T0CON ;Disable timer 0
movff TMR0L, Time2 ;Put timer 0 value into storage
btg INTCON2, INTEDG0
nop
GetPulseWidth
movlw 0x11 ;Check for start pulse,
;should be between 0x12 and 0x14
cpfsgt Time2 ;Greater than 0x11?
goto CheckZero
movlw 0x15
cpfslt Time2 ;Less than 0x15?
goto IRError ;Start Bit exceeds tolerance
StartBit ;We have a Start Bit
btfsc IRStatus, btStart ;Check if already set (ERROR)
goto IRError
bsf IRStatus, btStart ;Flag IRStatus
movlw 0x7
movwf BitCount
goto ISR_Done
CheckZero
movlw 0x3 ;Check for zero pulse
;Should be between 0x4 and 0x6
cpfsgt Time2 ;Greater than 0x3?
goto IRError
movlw 0x7
cpfslt Time2 ;Less than 0x7?
goto CheckOne
ZeroBit ;We have a zero bit
btfss IRStatus, btStart ;Check if we have previously had Start Bit
goto IRError
movlw 0x00
movwf Bit
call ProcessBit
goto ISR_Done
CheckOne
movlw 0x8 ;Check for One Pulse
;Should be between 0x9 and 0xB
cpfsgt Time2 ;Greater than 0x8?
goto IRError
movlw 0xC
cpfslt Time2 ;Less than 0xC
goto IRError
OneBit ;We have a One bit
btfss IRStatus, btStart ;Check if we have previously had Start Bit
goto IRError
movlw 0x1
movwf Bit
call ProcessBit
goto ISR_Done
IRError
call ClearVariables
bcf INTCON2, INTEDG0 ; Interrupt on falling edge
ISR_Done
clrf LATA
bcf INTCON, INT0IF
retfie FAST
;****************************
;* End of Interrupt Service *
;****************************
;*******************
;* Routines *
;*******************
ProcessBit
btfss Bit,0 ;Check if bit set
goto WriteZero
WriteOne
bsf ScratchCode, 0x7
goto RotateRight
WriteZero
bcf ScratchCode, 0x7
RotateRight
rrncf ScratchCode
decfsz BitCount
return
WhichCode
btfss IRStatus, btCommand
goto CommandCodeDone
DeviceCodeDone
rrncf ScratchCode ;a couple of more rotations
rrncf ScratchCode
movff ScratchCode, DeviceCode
bsf IRStatus, btDone
return
CommandCodeDone
movff ScratchCode, CommandCode
bsf IRStatus, btCommand
movlw 0x5
movwf BitCount
clrf ScratchCode
return
ClearVariables
clrf IRStatus
clrf DeviceCode
clrf CommandCode
clrf ScratchCode
return
;****************************
;* End of Routines *
;****************************
Init
call ClearVariables
bsf OSCCON, IRCF2 ;Set Internal 8MHz
bsf OSCCON, IRCF1
bsf OSCCON, IRCF0
bcf ADCON1, PCFG0 ; Set RA0 as digital
bsf TRISB, RB0 ; Make RB0 Input
bsf TRISB, RB2 ; Make RB5 Input
bcf INTCON2, RBPU
bsf ADCON1, PCFG4 ; Make RB0 digital
movlw b'10111110'
movwf TRISA
bcf LATA, RA0
bcf LATA, RA6
clrf T0CON
InitISR
movlw 0x13
sublw 0x13
bcf INTCON2, INTEDG0 ; Interrupt on falling edge
bsf INTCON, INT0IE ; Enable INT0 interrupt
bcf RCON, IPEN ; Disable priority interrupts
bcf INTCON, INT0IF ; Clear INT0 flag - This stumped me at first
bcf INTCON, PEIE ; Disable peripheral interrupts
bsf INTCON, GIE ; Enable global Interrupt
Main
bsf LATA, RA0 ;Light LED 1
bcf LATA, RA6
btfss IRStatus, btDone
goto Main
bcf LATA, RA0 ;Light LED 2
BSF LATA, RA6
WaitForRB2
btfsc PORTB, RB2
goto WaitForRB2
call ClearVariables
goto Main
end
Last edited: