Thanks Richard.
Makes sense though kinda heavy in respect of calculations.
Ioannis
Thanks Richard.
Makes sense though kinda heavy in respect of calculations.
Ioannis
maybe but it has positive indication of failure , it ceases testing on failure and it actually detects failures.kinda heavy in respect of calculations.
i would not be quibbling over a few words of code space when the entire process of encoding the bit stream into an unnecessary byte array
of times instead of directly into a bit array on detection would be heaps more efficient.
if the correct conditions can be met the pbp abs command can substituted for byte results like below
failure detection comparison
Code:'parse byte_array define OSC 8 bit_array var byte[4] byte_array var byte[32] arraywrite byte_array,[80,80,160,80,80,160,80,160,_ 80,160,80,80,160,80,80,160,_ 160,80,80,80,80,160,160,80,_ 80,80,80,160,80,110,160,160] n var byte index var byte trisa.1 =0 porta=2 pause 1000 serout2 porta.1 ,84 ,["ready",13] n = 32 index = 0 find_bit: if byte_array[index]>145 then '>725ìs if byte_array[index]<180 then bit_array.0[index]=0 index=index+1 if index<n then find_bit endif endif if byte_array[index]<100 then '>725ìs if byte_array[index]>75 then bit_array.0[index]=1 index=index+1 if index<n then find_bit endif endif serout2 porta.1 ,84 ,[bin8 bit_array[3], bin8 bit_array[2], _ bin8 bit_array[1], bin8 bit_array[0],13] ;my way tolerance con 20 a_one con 90 ; mean value of a one bit a_zero con 160 ; mean value of a zero bit fail var bit clear_result: bit_array[0] = 0 bit_array[1] = 0 bit_array[2] = 0 bit_array[3] = 0 get_result: n = 32 fail = 0 while n && (!fail) n = n-1 index = byte_array[n] - a_one; bytewise abs shortcut if index.7 then index = ~index+1; bytewise abs shortcut if index <tolerance then ; (abs(byte_array[n] - a_one)) < tolerance bit_array.0[n] = 1 else index = byte_array[n] - a_zero ; bytewise abs shortcut if index.7 then index = ~index+1 ; bytewise abs shortcut if index then fail = 1 ;(abs(byte_array[n] - a_zero))>tolerance endif serout2 porta.1 ,84 ,["."] wend if fail then serout2 porta.1 ,84 ,[13,"fail",13] else serout2 porta.1 ,84 ,[13,bin8 bit_array[3], bin8 bit_array[2], _ bin8 bit_array[1], bin8 bit_array[0],13] endif
Warning I'm not a teacher
result of sim
![]()
Warning I'm not a teacher
Sure I agree but could not find a fast way to encode directly the PWM bit stream into bits. The bits are coming from an RF radio receiver and have the typical 66-bit format of a keeloq transmission: 16ms guard time (low), 12 bits of 400us/400us as preamble, a 3-4ms low header and then the 66 bits of the data....when the entire process of encoding the bit stream into an unnecessary byte array
of times instead of directly into a bit array on detection would be heaps more efficient...
My routine to receive all these bits is based on the PulsIn command in a while-wend loop:
Obviously, cannot show the DECRYPT_K routine... Sorry.Code:code VAR byte[9] BANK0 ' PWM read in code1 var byte[66] ' Keeloq bits to be decrypted KEY_0 var byte BANK0 KEY_1 var byte BANK0 KEY_2 VAR BYTE BANK0 KEY_3 VAR BYTE BANK0 KEY_4 VAR BYTE BANK0 KEY_5 VAR BYTE BANK0 KEY_6 VAR BYTE BANK0 KEY_7 VAR BYTE BANK0 mask VAR BYTE BANK0 CSR_0 VAR BYTE BANK0 CSR_1 VAR BYTE BANK0 CSR_2 VAR BYTE BANK0 CSR_3 VAR BYTE BANK0 pass VAR BYTE BANK0 CNT1 VAR BYTE BANK0 CNT2 VAR BYTE BANK0 temp var word OVER: while 1 main: index=0 guard: pulsin portb.0,0,temp 'find header of 16ms if temp<2500 then main ' PIC is clocked at 8MHz, so a PulsIn step is 5usec. if temp>4400 then main ' 5usec x 2500= 12.5ms up to 5usec x 4400=22ms preamp: pulsin portb.0,1,temp 'then skip 12 pulses of 50% Duty, 400usec if temp<50 then main if temp>90 then main index=index+1 if index<11 then preamp index=0 pulsetrain: 'now collect 66 pulses ~800/400 usec pulsin portb.0,1,code1[index] index=index+1 if index<66 then pulsetrain index=0 find_code: 'convert pulse width to binary 66 bit stream if code1[index]>130 then if code1[index]<170 then code.0[index]=0 endif endif if code1[index]<80 then if code1[index]>55 then code.0[index]=1 endif endif index=index+1 if index<66 then find_code 'Display the encrypted and decrypted array hserout ["Rec: ",bin2 code[8]," ",bin8 code[7]," ",bin8 code[6]," ",bin8 code[5]," ",bin8 code[4],":",bin8 code[3]," ",bin8 code[2]," ",hex2 code[1]," ",hex2 code[0],13,10] 'display pulse train CSR_0=CODE[0]:CSR_1=CODE[1]:CSR_2=CODE[2]:CSR_3=CODE[3] GOSUB DECRYPT_K hserout ["Dec: ",bin2 code[8]," ",bin8 code[7]," ",bin8 code[6]," ",bin8 code[5]," ",bin8 code[4],":",bin8 CSR_3," ",bin8 CSR_2," ",hex2 CSR_1," ",hex2 CSR_0,13,10,13,10] wend
The above code is not near your fail safe program and will try to fit in the code space after a clean up of the rest code.
Ioannis
Last edited by Ioannis; - 4th June 2022 at 14:52.
The more I observe your code and way of thinking, the more I see its briliance.
Thank you again Richard,
Ioannis
a couple of ways
Code:pulsetrain: index=67 while index while !portb.0 :wend ;wait for hi index=index-1 pauseus 600 ;bit period=3*te ie 3*400=1200uS code.0[index]= ~ portb.0 ;sample @midpoint of bit period while portb.0 :wend ;wait for lo wend
;or with some simple time supervision
Code:fail var bit timer var word ext @timer = TMR1L PRELOAD CON 65535-820 ;@8MHz timer prediv 2 each tick=1uS pulsetrain: index=67 t1con=0 fail=0 while index timer=preload while !portb.0 :wend ;wait for hi t1con=$21 index=index-1 pauseus 600 ;bit period=3*te ie 3*400=1200uS code.0[index]= ~ portb.0 ;sample @midpoint of bit period while portb.0 && !pir1.0 :wend ;wait for lo t1con=0 fail=fail | pir1.0 wend
or sample @50,250,450,650,850 uS past transition to hi
where valid result is
11000 for a 1
11110 for a 0
there are endless methods
Warning I'm not a teacher
My simple thinking lead me to this version ditching the big array:
And then came your masterpiece of coding with TMR1...! Amazing!Code:index=0 pulsetrain: 'now collect 66 pulses ~800/400 ìsec pulsin portb.0,1,temp1 if temp1<55 then main if temp1>170 then main if temp1<130 then code.0[index]=1 else code.0[index]=0 endif index=index+1 if index<66 then pulsetrain
It just needs to be reversed (the code array) I guess. No big deal.
Thanks,
Ioannis
Last edited by Ioannis; - 5th June 2022 at 11:37.
In a noisy environment you can over sample a bit to be sure of data validity, i expect the serial data from a keeloq
chip to be quite clean so a single sample point would suffice
sample @50,250,450,650,850 uS past transition to hi
where valid result is
11000 for a 1
11110 for a 0
Code:sample var bitfail var bit fail=0 pulsetrain: index=67 while index && !fail while !portb.0 :wend pauseus 50 ;50 if !portb.0 then fail = fail | 1 pauseus 200 ;250 if !portb.0 then fail = fail | 1 pauseus 200 ;450 sample=portb.0 pauseus 200 ;650 if portb.0^sample then fail = fail | 1 pauseus 200 ;850 if portb.0 then fail = fail | 1 index=index-1 code.0[index]= !sample wend
Warning I'm not a teacher
Bookmarks