I know this is an old thread, I am trying to decode a PT2262 encoder using a PIC could do with someone looking at my code to see where I am going wrong. The code is modified from Bruce's Holtec decoding routine. 
I can read the buttons pressed using the code below, but it only works if I hold the Tx a few inches from the Rx. I think there is a timing problem. 
I have measured the waveforms at the output of the encoder and they are;
120uS for a logic 0 and 400uS for a logic 1 with a duty cycle of 500uS. Each pulse train is spaced at 4mS, each button press is repeated 4 times. See the data sheet posted in dhoustons link above.
I am using the bit24 (sync) as the reference bit as its the only constant in the pulse train.
Thanks Nick
	Code:
	@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_OFF & _BOD_OFF & _CP_ON & _CPD_ON
OSCCON  = %01110000     ' Internal 8MHz osc
ANSEL = %00000000
CMCON0 = 7
Define OSC 8                ' Define oscilator speed
DEFINE DEBUG_REG GPIO
DEFINE DEBUG_BIT 0 				'GPIO.0
DEFINE DEBUG_MODE 0 			'Inverted
DEFINE DEBUG_BAUD 9600          'Baud rate to LCD
define DEBUG_PACING 1000
DEFINE PULSIN_MAX 3000  ' Set MAX wait period
INCLUDE "modedefs.bas"
GPIO=0                 ' All outputs = 0 on boot
GPIO=%00100000         ' GPIO.5 = in, rest outputs.
PBIT        VAR BYTE[24]' Pulse-in results of high-going address/data/ synch
NUMS        VAR WORD    ' Pulsin result of low-going synch period
ADDRESS     VAR Byte    ' Holds decoded 8-bit address
ADDRESS2    VAR Byte    ' 2nd address storage for verification pass
ADDRESS3    VAR BYTE    ' 3rd address storage for verification pass
DBYTE       VAR BYTE    ' Holds decoded 8-bit data byte
DBYTE2      VAR BYTE    ' 2nd data byte storage for verification pass
DBYTE3      VAR BYTE    ' 3rd data byte storage for verification pass
X           VAR BYTE    ' GP loop counter/array index pointer
Y           VAR BYTE    ' Address & Data bit index pointer
Z           var byte    ' Used to display button press
LOOPS       VAR BYTE    ' Loop counter for address & data match
P_MAX       VAR BYTE    ' Wide pulse (indicates GND)
P_MIN       VAR BYTE    ' Narrow pulse (indicates Vcc)
DIN         VAR GPIO.5  ' Data input pin from RF receiver
LED         VAR GPIO.2  ' Visual cue
High LED
pause 2000
Debug $FE,1,"Power UP"   'Output received data to the world
pause 500
Debug $FE,1,"Waiting for"   'Output received data to the world
Debug $FE,$C0,"Button press"
Begin:                  ' Clear vars on power up & start over.
    ADDRESS=0 : ADDRESS2=0 : ADDRESS3=0 : DBYTE=0 : DBYTE2=0 : DBYTE3=0 : LOOPS=0
    
GET_P:
    'PULSIN DIN,0,NUMS   ' Get low going synch period pulse.
    'IF NUMS = 0 THEN    ' If NUMS=0, no synch pulse within defined period.
    ' Loops=0            ' Clear "1st pass" address & data loop counter.
    ' GOTO GET_P         ' Keep looking.
   ' ENDIF
    
    ' Normally the synch pulse is between 11-16mS, so we'll reject any synch pulse < 10mS
    ' to allow for variations in timing & transmitter voltages.
    'IF NUMS < 1000 THEN GET_P ' 1000 X 10uS = 10mS (PULSIN = 10uS resolution at 4MHz)
    FOR X = 0 TO 24        ' 25 bits in total for pt2262
     PULSIN DIN,1,NUMS     ' 
     
     IF NUMS < 20 THEN GET_P 'USED TO REJECT NOISE
     
     PBIT[X] = NCD NUMS    ' 25 bits total. 1 synch, 16 address, 8 data
    NEXT X                 ' Note that the PT2262 uses two pulses form each bit.
    
    ' Now load P_MAX & P_MIN for sort loops below to sort out
    ' address/data bit logic states.
    P_MAX = PBIT[0] ' Not used yet       
    P_MIN = PBIT[24] ' "narrow" synch bit
   
    ' Decode 8-bit address
    ADDRESS = $FF  ' Start with all 1's & find each zero bit
    Y=0             ' Zero address bit index pointer
    
    ' PBIT[0] + PBIT[1]=1st address bit. PBIT[14] + PBIT[15]=last
    FOR X = 0 to 15  STEP 2 ' Increment x 2 each pass
      IF (PBIT[X] = P_MIN) AND (PBIT[X+1] = P_MIN) THEN
         ADDRESS.0[Y]=0
      ENDIF
      Y=Y+1   ' Increment address bit index pointer
    NEXT X
     
    ' Decode 8-bit data byte (decode button press)
    DBYTE = $FF  ' Start with all 1's & find each zero bit
    Y=0          ' Zero data bit index pointer
    
    ' PBIT[16] + PBIT[17]=1st data bit. PBIT[22] + PBIT[23]=last
    FOR X = 16 TO 23 STEP 2 ' Increment x 2 each pass
      IF PBIT[X] AND PBIT[X+1] = P_MIN THEN DBYTE.0[Y]=0
      Y=Y+1   ' Increment data bit index pointer
    NEXT X
    
    ' On 1st pass, load 1st address & data into verify registers,
    ' then return for 2nd pass at pulsin. We'll make address &
    ' data match twice before moving on.
    
    Loops = Loops + 1   ' Increment loop counter
    'if LOOPS = 1 THEN GET_P
    IF Loops = 1 THEN   ' 2nd pass through?
     Address2 = Address ' Yes. Load 1st address into match register
     DBYTE2 = DBYTE     ' Load 1st data into match register
     GOTO GET_P         ' Get 2nd readings for comparison with 1st two
    ENDIF
    
    ' 2nd pass, so verify address & data bytes.
    ' If they match, show button press
CONTINUE:
    IF (DBYTE = DBYTE2) AND (ADDRESS = ADDRESS2) THEN  ' Show only if both data bytes equal
        
        
        if DBYTE2 = %11110001 THEN Z = "B"
        
        if DBYTE2 = %11111000 THEN Z = "A"
        
        if DBYTE2 = %11110010 THEN Z = "D"
        
        if DBYTE2 = %11110100 THEN Z = "C"
         
        Debug $FE,1,"Add=",$14,#address2   'Output received data to the world
        Debug $FE,$C0,"Button=",$14,z
    ENDIF
    
    GOTO Begin  ' Start over.
        
    END
 
				
			
Bookmarks