Navigation
IR Introduction
|
JVC DecoderThe JVC protocol allows control of over 256 different devices with 256 different commands per device. On my PIC IR decoder addresses are shown on the left two digits, while commands are shown on the right two. The device address and the command number are both displayed in hexadecimal format. Only the first message is preceded by a 8.4ms pre-pulse while all repetitions of the that code are not. To us this pre-pulse adds no significant value and is therefore completely ignored by the software. JVC Decoder Software
In my knowledge base you can read that the JVC protocol uses pulse distance modulation of the IR carrier to transmit a total of 16 bits.
A logical zero is represented by an interval of 1.05 ms, while a logical one is represented by double that value.
I'm going to use the average value between these intervals as a threshold to determine wether a "0" or a "1" was received.
Any interval shorter than 1.5 ms is interpreted as a "0" and intervals above 1.5 ms are interpreted as a "1".
Intervals longer than 3 ms cause the routine to exit with an error condition.
Again the IR decoding software relies on a state machine. The picture above shows all different states during the decoding process. ;-----------------------------------------------------------------------------
;
; IR receiver state machine
;
;-----------------------------------------------------------------------------
IR_MACHINE MOVF IR_STATE,W Jump to present state
MOVWF PCL
Here we go again! Nothing new here. As usual the IR_MACHINE routine is called every 50 µs by the main program loop. ;---------------------------------------STATE 0, WAIT FOR FIRST FALLING EDGE--
IR_STATE_0 BTFSC PORTA,4 Input still high?
RETURN Yes! Nothing to do here
CLRF IR_SHIFT Prepare shift register
MOVLW %1000.0000
MOVWF IR_SHIFT+1
CLRF BIT_TIMER Clear bit timer
MOVLW IR_STATE_1 Next stop is state 1
MOVWF IR_STATE
RETURN
As long as the input remains high we return immediately.
Otherwise the IR shift register, which will hold the received message, is initialized.
The "1" in the most significant bit of the shift register will roll out after 16 shifts, indicating the end of the message.
;---------------------------------------------STATE 1, FALLING EDGE DETECTED--
IR_STATE_1 INCF BIT_TIMER Increment bit timer
BTFSC PORTA,4 Input still low?
GOTO .HIGH No! Pulse is over now.
MOVLW PULSE_MAX See if max pulse width reached
XORWF BIT_TIMER,W
BTFSS STATUS,ZERO
RETURN Not yet!
MOVLW IR_ERROR_0 Wait until pulse goes high again
MOVWF IR_STATE before accepting new command
RETURN
.HIGH MOVLW IR_STATE_2 Input is now high
MOVWF IR_STATE Next stop is state 2
RETURN
We arrive at state 1 when a low level on the input was detected and we will stay here until the input goes high again or until the maximum pulse width is reached.
;-------------STATE 2, WAIT FOR PULSE TO GO LOW AGAIN, THEN MEASURE INTERVAL--
IR_STATE_2 INCF BIT_TIMER Increment bit timer
MOVLW BIT_TIME*3 Should we keep waiting?
XORWF BIT_TIMER,W
BTFSC STATUS,ZERO
GOTO IR_ERROR_1 No, we've waited 3 bit times already!
BTFSC PORTA,4
RETURN Keep waiting while input remains high
MOVLW BIT_TIME/2+BIT_TIME*-1 Use 1.5 bit time as threshold
ADDWF BIT_TIMER,W Carry is 1 if more than 1.5 times
RRF IR_SHIFT+1,F Roll carry into result
RRF IR_SHIFT,F
CLRF BIT_TIMER Restart bit timer
MOVLW IR_STATE_1 Return to state 1 if not done yet
MOVWF IR_STATE
BTFSS STATUS,CARRY See if we're done
RETURN Not done yet, continue with state 1
MOVLW IR_STATE_3 Message received, but wait 3ms longer
MOVWF IR_STATE to see if nothing follows.
CLRF BIT_TIMER
RETURN
Again we begin by incrementing BIT_TIMER.
Then we check to see if BIT_TIMER has reached its upper limit of 3 bit times.
Clearly that would indicate an error situation and causes us to jump to IR_ERROR_1.
Since we've arrived at the next pulse now we must clear BIT_TIMER before we can measure the next interval.
And if more bits are to follow we must continue with state 1 again.
;-------------------STATE 3, RECEIVED MESSAGE, WAIT 3MS TO ENSURE IT WAS JVC--
IR_STATE_3 INCF BIT_TIMER Increment bit timer
BTFSC PORTA,4 Input still low?
GOTO .HIGH No! Pulse is over now.
MOVLW PULSE_MAX See if max pulse width reached
XORWF BIT_TIMER,W
BTFSS STATUS,ZERO
RETURN Not yet!
MOVLW IR_ERROR_0 Wait until pulse goes high again
MOVWF IR_STATE before. accepting new command
RETURN
.HIGH MOVLW IR_STATE_4 Input is now high
MOVWF IR_STATE Continue with 3ms delay
RETURN
After receiving the entire message we must make sure that no more bits follow.
At first I didn't have this check and it appeared that the receiver also listened to NEC remote controls, which is not desirable because it only displayed erratic codes.
;---------------------------STATE 4, INPUT MUST REMAIN HIGH FOR AT LEAST 3MS--
IR_STATE_4 INCF BIT_TIMER Increment bit timer
BTFSS PORTA,4 Has the input gone low now?
GOTO .ERROR Yes! This is not good!
MOVLW BIT_TIME*3 Have we waited long enough now?
XORWF BIT_TIMER,W
BTFSS STATUS,ZERO
RETURN Not yet!
MOVLW CLR_TIME Set display clear timer
MOVWF CLR_DELAY
MOVLW DP_TIME Flash receive LED
MOVWF DP_DELAY
SWAPF IR_SHIFT,W Work from left to right
CALL HEX2SEGMENTS
MOVWF DIGIT1
MOVF IR_SHIFT,W Do the same with 2nd digit
CALL HEX2SEGMENTS
ANDLW %0111.1111 Flash dot of this digit
MOVWF DIGIT2
SWAPF IR_SHIFT+1,W And with the 3d digit
CALL HEX2SEGMENTS
MOVWF DIGIT3
MOVF IR_SHIFT+1,W And finally with the last digit
CALL HEX2SEGMENTS
MOVWF DIGIT4
MOVLW IR_STATE_0 We're done! Let's get some rest
MOVWF IR_STATE
RETURN
.ERROR MOVLW IR_ERROR_0 Wait until input gets high again
MOVWF IR_STATE before returning to state 0
RETURN
The first few lines of this state are responsible for ensuring that no more bits follow the received code, which would tell us that we're not receiving a JVC protocol. Once we are certain that nothing follows we can finally display the received message. We've seen all this before. So I'm not going to explain it again. However there is one little thing I should mention here. Because of the very fast repetition rate of the JVC code I had to decrease the value of DP_TIME to make the IR receive dot flicker again. However the value is now very low and may cause the dot to flicker in an irregular manner. This is just caused by the interference between the repetition rate of the IR messages and the display scan frequency. It doesn't affect the actual reception of the message. ;----------------------------------IR ERROR 0, WAIT FOR INPUT TO RETURN HIGH--
IR_ERROR_0 MOVLW IR_STATE_0 Reset state machine only if input is
BTFSC PORTA,4 high
MOVWF IR_STATE
RETURN
;-----------------------------------------------------------IR ERROR STATE 1--
IR_ERROR_1 MOVLW IR_STATE_0 Return to IR state 0
MOVWF IR_STATE
RETURN
Should I really explain these two routines again? We've seen them a couple of times before. |