#picaxe 08m2
#terminal 38400
#no_data
#no_end
Symbol Debug_Pin = C.4 ;20uS pulse sent to sync oscilloscope - if req'd
symbol Data_Pin = C.3 ;Infrared input from TSOP decoder
;NOTE: The output from the 'TSOP' range of
;IR detectors is inverted:-
;LOW = Carrier burst detected
;HIGH = Space
;
;
;
symbol PULSE_1_SPACE = 1200 ;(1.5mS) ;a "0" bit is (theoretically) 0.562ms burst and 0.562ms space
;a "1" bit is 0.562ms burst and 1.687ms space
symbol AGC_Pulse_Length = 7100 ;(8.875mS) ;leading pulse burst is 9mS and 4.5ms space
symbol AGC_Pulse_Length_Max = 7300 ;(9.125mS) ;upper limit
; 28 - 63 spare
symbol BitStore = 64 ;Space for 64 bytes in here (32 word values)
setfreq M32
sertxd ("NEC Protocol Analyser",cr,lf)
do
gosub Get_Data
if b0 <> $FF then
sertxd(cr,lf,cr,lf,"Data Byte: 0x")
gosub B0_TO_HEX
sertxd(", (",#b0," decimal)",cr,lf)
endif
loop
Get_Data:
pulsin Data_Pin,0,W9 ;Measure the low-going pulse. (TSOP o/p goes low, when it detects 38KHz carrier)
if W9 < AGC_Pulse_Length or W9 > AGC_Pulse_Length_Max then
if W9 <> 0 then ;assuming it's not 'no pulse at all'
sertxd(cr,lf,"Abort - pulse length: ",#W9)
endif
b0=$FF
return
endif
;
; We are in the 4.5mS 'space', after the the initial 9mS carrier burst
;
bptr = BitStore ;point at our storage location
pulsout Debug_Pin,15 ;if required.
;
; Now we will be measuring the lengths of the high-going pulses. These are the gaps between 38KHz carrier detection
; and the length of these gaps signifies a "0" or a "1", depending on their length.
;
for b2 = 1 to 32
;
; Measure the length of the next 32 bits and store their lengths (in 1.25uS units)
; in RAM. (The Picaxe isn't fast enough to analyse them on the fly.) Each Pulsin command
; has an 81.92uS timeout @ 32MHZ, so if we enter this loop 'under false pretences', we
; could be stuck here for 2.6S. Make sure AGC_Pulse_Length is set tight enough to prevent this.
;
pulsin Data_Pin,1,W0 : @bptrinc = b0 : @bptrinc = b1 ; (uses 2 * 32 bytes)
next b2
pulsout Debug_Pin,15 ;if required
;
; Print data
;
sertxd (cr,lf,cr,lf,"PACKET DECODE:-")
bptr = BitStore ;Point at start of our store
;
; Print out the timings first
;
; W9 is the length of the input pulse - but needs to be multplied by 1.25 to get mS units.
W10 = W9 / 4 ;x = 1.25Y => x = (Y + 0.25Y)
W10 = W10 + W9
sertxd(cr,lf,"Start pulse: ",#W10,"uS",cr,lf,cr,lf,"Timings:-",cr,lf)
sertxd (cr,lf,"Address Byte: ")
gosub PrintTimingsFromBitStore
sertxd (cr,lf,"Inverted Address Byte: ")
gosub PrintTimingsFromBitStore
sertxd (cr,lf,"Data Byte: ")
gosub PrintTimingsFromBitStore
sertxd (cr,lf,"Inverted Data Byte: ")
gosub PrintTimingsFromBitStore
sertxd (cr,lf,cr,lf,"Data interpretation:-",cr,lf)
;
; Now print the interpreted values these pulses represent
;
bptr = BitStore ;Point at start of our store again
gosub GetDataFromBitStore ;Get the Address Byte
;(Returns 'b0' and prints out its values in binary)
b20 = b0 ;save for comparison
gosub GetDataFromBitStore ;Get the Inverted Address Byte
;
; Check data validity
;
b21 = b0 xor b20
if b21 = $FF then
sertxd (" (ok)")
else
sertxd (" *BAD!*")
b0 = $FF
return
endif
gosub GetDataFromBitStore ;get the actual data byte
b22 = b0 ;save for comparison...
gosub GetDataFromBitStore ;...with the inverted byte
;
; Check data validity
;
b21 = b0 xor b22
if b21 = $FF then
sertxd (" (ok)")
else
sertxd (" *BAD!*") ;some remotes make use of BOTH bytes for actual data!
b0 = $FF
return
endif
b0 = b22 ;Return the Data byte to caller
b1 = b20 ;and the controller address
return
PrintTimingsFromBitStore:
;
; Print the timing values of the next eight pulses in the store
;
for b1 = 1 to 8 ;do for next 8 stored samples
b2 = @bptrinc : b3 = @bptrinc ;Get pair of bytes in W1
;
; Print the length of the pulse in uS (multiple by 1.25, as before)
;
W2 = W1 / 4
W2 = W2 + W1
sertxd(#W2)
;
; Add a comma, unless it's the last one
;
if b1 <> 8 then
sertxd(",")
endif
next b1
sertxd(" (uSecs)")
return
GetDataFromBitStore:
;
; Interpret the next eight stored timings as a data byte; LSb first, so needs reversing.
;
b4 = 0 ;result
for b1 = 1 to 8 ;do for next 8 stored samples
b0 = 0 : b2 = @bptrinc : b3 = @bptrinc : if W1 > PULSE_1_SPACE then : b0 = %10000000 endif
b4 = b4 / 2 ;shift previous answer 1 bit right
b4 = b4 + b0 ;and add in the new 'bit'
next b1
b0 = b4 ;return result
sertxd(cr,lf,"RCV'D-> ","[",#bit0,"][",#bit1,"][",#bit2,"][",#bit3,"][",#bit4,"][",#bit5,"][",#bit6,"][",#bit7,"]")
sertxd(" => ",#bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0," <=") ; debug print of byte in binary
return
;-----------bin to hex debug dump----------------
B0_TO_HEX:
b1 = b0 / 16 + "0"
gosub Nybble
b1 = b0 & 15 + "0"
Nybble:
if b1 > "9" then : b1 = b1 + 7 endif
sertxd(b1)
return