Shop OBEX P1 Docs P2 Docs Learn Events
PASM-loop misses some IR-receiver pulses — Parallax Forums

PASM-loop misses some IR-receiver pulses

StefanL38StefanL38 Posts: 2,292
edited 2011-10-15 16:07 in Propeller 1
Hi,

my current project is "recording" IR-remote-signals in a special way.

I'm using an IR-receiver that is NOT decoding the carrier-frequency.
The Output of the TSOP98200 does still show all the single-pulses with carrier-frequency. (usually these receivers are used for lowest-level IR-repeaters re-emitting the carrier-signal)

Why am I using this one? Because I want to record all carrierfrequencies (30, 33, 36, 38, 40, 44, 50. 56 kHz) Because of this a standard demodulator with a fixed carrier-frequecy can't be used.

Now my current approach to to this is to measure the carrier-frequency of the first pulses.
Then setting up counterA to neg-edge-mode FRQA := 1 and then running a loop that looks for PHSA
beeing bigger than zero. This loop runs at a frequency of 8 times carrierfreuquency.
Whenever a carrier-pulse is detected a bit is added to a long But only at the carrier-frequency.
If 32 bits are put together this long will be stored into HUB-RAM.

This means each bit represents one carrier-pulse to reduce needed RAM.

Now the strange thing is that some pulses are not detected.
in the fixed-font part below you see a long row if "1"s but at two places 3 zeros inbetween.
(the bold red ones)
I re-checked with a digital storage oscilloscope (DSO) several times if these short "no carrier"-sequences are coming from the IR-receiver. The do not. The IR-receiver it self produces
a continious pulsetrain.

Know I'm puzzled why my PASM-loop is missing some pulses as the loop is running at 8 times higher speed as the pulses come in.
I'm using the counter which is independet of code-execution. The time between reading out PHSA and resetting PHSA to zero for the next cycle is pretty short.
Much shorter than a period. I even added another cog that strechtes the pulses from the IR-reiver from 1 microsecond up to half carrier-frequency (38kHz = 26 microseconds) Pulsewidth 13 microseconds.

How can it be that some pulses are detected as zero = no carrier-pulse? while there are carrier-pulses!
ser.start(30,31,0,115200) done
cognew(Toggle_Pin(0, 4),@ToggleStack)done
cognew(@entryMeasureFreq,0) done
ready for recording pulsetrain
wait for pulsetrain
wait for pulsetrain
11111111111111111111111111111111
11111111111111111111[COLOR=red][B]000[/B][/COLOR]111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
1111[COLOR=red][B]000[/B][/COLOR]1111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111111111
11111111111111111111111111100000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000001111
11111000111111111000000000000000
00000000000000000000000000000000
00000000000001111111111111111111
10000000000000000000000000000000
00000000000000000000000000000011
11111111111111111100000000000000
00000000000000000000000000000000
00000000000000111111111111111111
11000000000000000000000000000000
00000000000000000000000000000001
11111111111111111110000000000000
00000000000000000000000000000000
00000000000000011111111111111111
11100000000000000000000000111111
11111111111100000000000000000000
11111111111111111111000000000000
00000000000000000000000000000000
00000000000000001111111111111111
11110000000000000000000000000000
00000000000000000000000000000000
01111111111111111111100000000000
00000000011111111111111111111000
00000000000000000111111111110001
11111100000000000000000000111111
11111111111111000000000000000000
00111111111111111111110000000000
00000000001111111111111111111100
00000000000000000001111111111111
11111110000000000000000000011111
11111111111111100000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
recording of pulsetrain done
clockticks from pulse to pulse TestVar1 2090
_Period_8tel TestVar2 261
I attach my full testcode as a ZIP-archive.
and here is the interesting part of the PASM-code


edit:
arrrgh!! What is this forum-software doing with my well-fomatted fixed-font code????
Even when I copy it back from the forumsoftware-editor field and paste it into the propeller-tool
everything looks fine again. Only when showing it in the forum the columms jump back and forth like they want.

Forum-Administrator !! Get the forum-software-guy up and solving this problem!!!
DAT
              ORG 0
              
entryMeasureFreq
{
'  --------- Debugger Kernel add this at Entry (Addr 0) ---------
   long $34FC1202,$6CE81201,$83C120B,$8BC0E0A,$E87C0E03,$8BC0E0A
   long $EC7C0E05,$A0BC1207,$5C7C0003,$5C7C0003,$7FFC,$7FF8
'  --------------------------------------------------------------
}

StartOfCode   call       #SetOutPuts
              call       #Read_SPIN_CmdM
              call       #SetupCounterMode
              'initialise variables for recording IR-signalstates
              mov       _IR_Recv_Long,  #0                  'reset long containing bits of sampled pulsetrain

              mov       _HUB_Base_AdrM, par
              add       _HUB_Base_AdrM, #ptr2HUB_RAM_Buff
              mov       _HUB_Act_Idx, _HUB_Base_AdrM        'Reset BufferIndex to baseadress
              mov       _Buff_Count,    _BuffSize           'setup variable for buffer-filling-loop
              mov       _32Bit_Count,   #c_NoOfBitsPerLong  'setup variable for filling long with IR-statebits               
              mov       _Period_8Cycl,  #0                 

              mov       _CarrierOnFlag, #0      
              mov       _CarrierONCnt,  #0                 
              mov       _CarrierOffCnt, #0 
              mov       _NrOfPulses,    #0
              mov       _LastNoOfPulses,#0
              mov       _NewNoOfPulses, #0
              mov       _SumOfPulses,   #0
              mov       _PeriodFrac,    #1
              shl       _PeriodFrac,    #c_Divisor         '_PeriodFrac contains the fractional how often 
              
              call       #MeasureCarrierFreq
              'coming back from this subr means new carrier-period starts right now
              'the counter is already prepared through a mov PHSA, #0 to catch the next high-to-low-transition
              'and PHSA containing 1 (and not a highrer value)

              mov       _TestVar1M,     #0'_Period 
              mov       _TestVar2M,     _Period_8tel 
              mov       _SPIN_CmdM,     #1               'set Status to 0 to indicate command finished
              call      #Write_SPIN_CmdM
               
              xor       OutA,           _LED_RightM        'set bit "_LED_LeftM" in OutA-register to 1
              mov       PHSA,           #0

[COLOR=blue] Record_IR_Bits_Loop
              waitcnt   _MFlopMatch,    _Period_8tel       'wait for 1/8 of a period
              mov       _NrOfPulses,    PHSA               'PHSA holds actual sum of pulses update actual number of pulses

[/COLOR] [COLOR=blue]               add       _Period_8Cycl,  #1                 'increment number of Period 8th cycles
              cmp       _Period_8Cycl,  _PeriodFrac wz     'check if a complete period is over
        if_nz jmp       #Record_IR_Bits_Loop               'only if period is over do the rest

[/COLOR] [COLOR=blue]               mov       PHSA,           #0
              mov       _Period_8Cycl,  #0                 'reset loopcounter
        
              cmp       _NrOfPulses,    #1 wc              'check if there were new pulses
        if_c  mov       _IR_Recv_Bit,   #0                 'no pulse received => set IR_Recv_Bit to 0
        if_nc mov       _IR_Recv_Bit,   #1                 'a pulse received => set IR_Recv_Bit to 1

[/COLOR] [COLOR=blue]               add       _IR_Recv_Long,  _IR_Recv_Bit       'add actual bit to long
              sub       _32Bit_Count,   #1 wz              'check for last loop within actual long          
        if_nz shl       _IR_Recv_Long,  #1                 'if not last bit shift bits 1 to the left

[/COLOR] [COLOR=blue]         if_z  call      #WriteLongToBuffer

[/COLOR] [COLOR=blue]         if_z  sub       _Buff_Count,    #1 wz              'if byte was written to buffer decrement _Buff_Count by one
        if_z  jmp       #Recording_finished                'if _Buff_Count reaches zero buffer is full 

[/COLOR] [COLOR=blue]               'mov       _NrOfPulses,    PHSA               'PHSA holds actual sum of pulses update actual number of pulses
              'cmp       _NrOfPulses,    #1 wc              'check if there were new pulses
        'if_nc or        OutA,           _VPTriggerPin      'if _NrOfPulses is >= 1 then the C-Flag is cleared
        'if_nc add       _TestVar1M,     #1
              jmp       #Record_IR_Bits_Loop
[/COLOR]              
Recording_finished
              
              mov       _TestVar1M,     _Period
              'mov        _TestVar2M,     _Snapshot2
              'sub        _TestVar2M,     _Snapshot1

              mov       _SPIN_CmdM,     #0               'set Status to 0 to indicate command finished
              call      #Write_SPIN_CmdM

infLoop       nop
              jmp       #infLoop





'SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
'# START Subroutines
'#########################################################
SetOutPuts    mov       _BitMaskM,      _LED_LeftM
              or        _BitMaskM,      _LED_MiddleM
              or        _BitMaskM,      _LED_RightM
              'or        _BitMaskM,      _MonoFlopPin
              or        _BitMaskM,      _VPTriggerPin
              or        _BitMaskM,      _toggleBit
              or        DirA,           _BitMaskM          'set   bits of BitMakM in DirA-register to 1  
              andn      OutA,           _BitMaskM          'clear bits of BitMakM in OutA-register to 0

SetOutPuts_ret ret
'---------------------------------------------------------


'#########################################################
SetupCounterMode  'setup counter-mode and initialise INcS-Register and TSUM-register
 ' 3         2         1
 '10987654321098765432109876543210
 '10987654321098765432109876543210
'%-CMODEPLL--------B__PIN---A__PIN
'%00111000000000000000000000000011
  
              movi      CTRA,           #c_NegEdgeDetectorNoPLL  'setup counter for negative-edge-mode
              movs      CTRA,           #%000000010              'sense IO-pin 2
              mov       FRQA,           #1                       'load summand-register with 1
              mov       PHSA,           #0                       'load summerise-register with 0
SetupCounterMode_ret ret
'---------------------------------------------------------


'#########################################################
MeasureCarrierFreq
              or        OutA,           _LED_LeftM         'set bit "_LED_LeftM" in OutA-register to 1

              cmp        _TestVar2M,    #120 wz
        if_z  jmp        #PresetPeriod
              
              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO
                                                           'which means pulsetrain starts
              mov       _InputStateM,   #8                 'load bitpattern that should be matched
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until INA-registerbit specified in _IR_Recv_Pin2
                                                           'has the same state as in _InputStateM
              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO

              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO
                                                           'which means pulsetrain starts
              mov       _InputStateM,   #8                 'load bitpattern that should be matched
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until INA-registerbit specified in _IR_Recv_Pin2
                                                           'has the same state as in _InputStateM
              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO

              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO
                                                           'which means pulsetrain starts
              mov       _InputStateM,   #8                 'load bitpattern that should be matched
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until INA-registerbit specified in _IR_Recv_Pin2
                                                           'has the same state as in _InputStateM
              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO

              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO
                                                           'which means pulsetrain starts
              mov       _InputStateM,   #8                 'load bitpattern that should be matched
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until INA-registerbit specified in _IR_Recv_Pin2
                                                           'has the same state as in _InputStateM
              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO


              mov       _InputStateM,   #0                 'load BitPattern ZERO  
WaitIRPinLow  waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO
                                                           'which means pulsetrain starts
              mov       _FirstPulse,    cnt                'take snapshot of free running systemcounter

              or        OutA,           _LED_MiddleM       'set bit "_LED_MiddleM" in OutA-register to 1


              mov       _InputStateM,   #8                 'load bitpattern that should be matched
WaitIRPinHigh waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until INA-registerbit specified in _IR_Recv_Pin2
                                                           'has the same state as in _InputStateM
              mov       _InputStateM,   #0                 'load BitPattern ZERO  
WaitIRPinLow2 waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO
                                                           'which means pulsetrain starts
              mov       _SecondPulse,   cnt                'take snapshot of free running systemcounter

              andn      OutA,           _LED_LeftM         'clear bit "_LED_LeftM" in OutA-register to 0
              
              mov       _Period,        _SecondPulse
              sub       _Period,        _FirstPulse        'calculate clockticks of pulsedistance (=carrier-frequency)
              mov       _Period25,      _Period
              shr       _Period25,      #c_Divisor         'shr c_Divisor bits to the right means divide by 2^c_Divisor

              jmp       #here
PresetPeriod  mov       _Period,        _2000

              mov       _Period_8tel,   _Period
              shr       _Period_8tel,   #c_Divisor         'shr 3 bits to the right means divide by 2^3 = 8 - 1/8 of a period
              mov       _MFlopMatch,    _SecondPulse       'copy value of systemcounter-snapshot before 
              add       _MFlopMatch,    _Period            'add clockticks of 1 period
              sub       _MFlopMatch,    _AheadTicks        'substract clockticks to be ahead of the next high-to-low-transition              
              mov       PHSA,           #0                 'prepare counter to detect high-to-low-transition
              or        OutA,           _LED_MiddleM         'set bit "_LED_LeftM" in OutA-register to 1
              jmp       #MeasureCarrierFreq_ret
              
here          mov       _Period_8tel,   _Period
              shr       _Period_8tel,   #c_Divisor         'shr 3 bits to the right means divide by 2^3 = 8 - 1/8 of a period

              'wait until next pulse-period begins
              mov       _MFlopMatch,    _SecondPulse       'copy value of systemcounter-snapshot before 
              add       _MFlopMatch,    _Period            'add clockticks of 1 period
              sub       _MFlopMatch,    _AheadTicks        'substract clockticks to be ahead of the next high-to-low-transition

              waitcnt   _MFlopMatch,    _Period
              
              mov       PHSA,           #0                 'prepare counter to detect high-to-low-transition
              or        OutA,           _LED_MiddleM         'set bit "_LED_LeftM" in OutA-register to 1
MeasureCarrierFreq_ret ret
'---------------------------------------------------------


'#########################################################
WriteLongToBuffer
              wrlong    _IR_Recv_Long,  _HUB_Act_Idx        'write long to HUB-RAM
              add       _HUB_Act_Idx,   #4                  'set HUB-RAM-adress to next long
              
              mov       _IR_Recv_Long,  #0                  'reset long that contains sampled bits of pulsetrain
              mov       _32Bit_Count,   #c_NoOfBitsPerLong  'setup variable for filling long with IR-statebits               
WriteLongToBuffer_ret ret
'---------------------------------------------------------

              
'#########################################################
ReSyncToCarrier
              mov       _InputStateM,   #0                 'load BitPattern ZERO  
              waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO
              mov       _MFlopMatch,    cnt                'new snapshot of systemcounter
              add       _MFlopMatch,    _Period
              sub       _MFlopMatch,    _AheadTicks

              or        OutA,           _DebugPin
              add       _TestVar2M,     #1
              
              waitcnt   _MFlopMatch,    _Period
              'mov       _IR_Recv_Bit,   #1                 'resyncing means a pulse has occurred so set _IR_Recv_Bit to 1 
ReSyncToCarrier_ret ret
'---------------------------------------------------------


'#########################################################
Read_SPIN_CmdM                  
              mov       _HUB_Base_AdrM, par
              add       _HUB_Base_AdrM, #ptr2_S2A_Cmd
              rdlong    _SPIN_CmdM,     _HUB_Base_AdrM 

              mov       _HUB_Base_AdrM, par
              add       _HUB_Base_AdrM, #ptr2TestVar1
              rdlong    _TestVar1M,     _HUB_Base_AdrM

              mov       _HUB_Base_AdrM, par
              add       _HUB_Base_AdrM, #ptr2TestVar2
              rdlong    _TestVar2M,     _HUB_Base_AdrM

Read_SPIN_CmdM_ret ret
'---------------------------------------------------------


'#########################################################
Write_SPIN_CmdM                  
              mov       _HUB_Base_AdrM, par
              add       _HUB_Base_AdrM, #ptr2TestVar1
              wrlong    _TestVar1M,     _HUB_Base_AdrM

              mov       _HUB_Base_AdrM, par
              add       _HUB_Base_AdrM, #ptr2TestVar2
              wrlong    _TestVar2M,     _HUB_Base_AdrM

              mov       _HUB_Base_AdrM, par
              add       _HUB_Base_AdrM, #ptr2_S2A_Cmd
              wrlong    _SPIN_CmdM,     _HUB_Base_AdrM

Write_SPIN_CmdM_ret ret
'---------------------------------------------------------


              
_IR_Recv_Pin2 long |< 3
_MonoFlopPin  long |< c_IR_Recv_Pin
_DebugPin     long |< 5
_VPTriggerPin long |< 6

_10microSecs  long c_10microSecs

_toggleBit    long |< c_C3_LED

_LED_LeftM    long |< c_LED_Left
_LED_MiddleM  long |< c_LED_Middle     
_LED_RightM   long |< c_LED_Right      

_BuffSize     long c_Buffer_Size

_zero         long 0

_AheadTicks   long c_AheadTicks

_CarrierOnFlag long 1
_2000         long 2000


_SPIN_CmdM    res 1
_TestVar1M    res 1
_TestVar2M    res 1

_HUB_Act_Idx  res 1
_HUB_Base_AdrM res 1

_Buff_Count   res 1

_32Bit_Count  res 1

_FirstPulse   res 1
_SecondPulse  res 1

_Period       res 1
_Period25     res 1
_Period50     res 1
_Period75     res 1

_MFlopMatch   res 1
_EOSamplMatch res 1

_IR_Recv_Bit  res 1
_IR_Recv_Long res 1

_InputStateM  res 1

_BitMaskM     res 1

_dummyLongM   res 1

_NrOfPulses     res 1
_LastNoOfPulses res 1
_NewNoOfPulses  res 1
_SumOfPulses    res 1
_MatchVal       res 1
_Period_8tel    res 1
_Period_8Cycl   res 1
_CarrierOffCnt  res 1
_CarrierONCnt   res 1
_PeriodFrac     res 1
_Snapshot1      res 1
_Snapshot2      res 1
I hope some PASM-gurus can explain to me why some pulses are missing and how I can
make 101% sure that not even a single pulse is missing.

keep the hints coming
best regards

Stefan

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-14 14:28
    Why don't you toggle a pin directly after the waitcnt? Then you can have a look at the scope at which times you sample. Maybe you simply have problems with the tolerances. The IR senders frequency is maybe not stable enough.

    I really wonder why you want to keep all these bits?! The only thing I'd keep is the frequency you measured and translate the rest into a signal without carrier information. If you are interested I can post some code from my experiments (using a receiver) which translates the signal into a table of high and low times and a string which even is human-readable that describes the whole cycle.

    With the timing-table and the length of a cycle you could even detect which remote control is sending.

    As far as I remember playback of this signal has also been implemented and I successfully send recorded codes to the TV and a digital picture-frame.
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-10-14 16:42
    Hi MagIO,

    thank you for answering. The alternative for storing the signal I see is to store the duration-times when the carrier is On/Off. Now this could be done as a multiple of the carrierfrequency or in 1/10 milliseconds.
    Both result in 16 bit values (as the pauses between repeats can be 20-100 milliseconds.) Now with more signal-analysis these pauses could be found and somehow reduced to a 8bit value. So I would need
    estimated half the memory for the price that some strange IR-remotes won't match with bordervalues to determine what is a repeat pause.

    Reducing the information to databits has the same problems. How short/long is a "1" and a "0" and I would have to implement bi-phase-coding, pulse-distance-coding, pulse-length-coding.

    If you have code doing all this reliable I would like to see it.
    As I plan to use a 4MBit flash-ROM I don't worry too much about memory with my approach. In my method the duration of carrier On/Off is represented by the number of bits beeing "1" or "0".
    So playing back will be very easy. Whenever a bit is "1" send a single carrier-pulse = IR-LED on for some microseconds. Whenever a bit is "0" the IR-LED stays off.
    Moving from bit to bit is done with the carrier-frequency.

    I changed my code to use POS-mode instead of edge-mode. This means the PHSA-register counts up not only if a transition is detected but wenever and as long as HIGH-level is detected.
    This means I have to detect is PHSA = 0 or is it greater than 0 (regardless of how much greater than 0) greater than 0 means a carrier-signal has been detected.

    With this change I get sequences of "1"s without one, two or three zeros inbetween. So for the IR-remote I did this primary testing it now seems to work reliable.
    Next testphase will be other IR-remotes with new and quite weak batteries to see if it then works reliable too And playing back.

    keep the suggestions coming
    best regards

    Stefan
  • kuronekokuroneko Posts: 3,623
    edited 2011-10-14 20:51
    StefanL38 wrote: »
    How can it be that some pulses are detected as zero = no carrier-pulse? while there are carrier-pulses!
    Self-inflicted damage. What it boils down to is that you get your carrier frequency measurement wrong by 10 cycles which has a cumulative affect later when you sample the pulses. I applied a 1us/25us fake pulse train (2080 cycles) and also removed the monoflop, 1us is more than enough for a counter to spot. Now look at your first timestamp sample:
    mov       _InputStateM,   #8                 'load bitpattern that should be matched
                  waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until INA-registerbit specified in _IR_Recv_Pin2
                                                               'has the same state as in _InputStateM
                  [COLOR="red"]mov       _InputStateM,   #0[/COLOR]                 'load BitPattern ZERO  
                  [COLOR="red"]waitpeq   _InputStateM,   _IR_Recv_Pin2[/COLOR]      'wait until specified bit "_IR_Recv_Pin" is ZERO
    
                  mov       _InputStateM,   #0                 'load BitPattern ZERO  
    WaitIRPinLow  waitpeq   _InputStateM,   _IR_Recv_Pin2      'wait until specified bit "_IR_Recv_Pin" is ZERO
                                                               'which means pulsetrain starts
                  mov       _FirstPulse,    cnt                'take snapshot of free running systemcounter
    
    Or cleaned up a bit:
    waitpeq _IR_Recv_Pin2, _IR_Recv_Pin2    ' wait for high
                    [COLOR="red"]waitpne _IR_Recv_Pin2, _IR_Recv_Pin2[/COLOR]    ' wait for low
    WaitIRPinLow    waitpne _IR_Recv_Pin2, _IR_Recv_Pin2    ' wait for low
    
                    mov     _FirstPulse, cnt
    
    You measure between two consecutive high-low edges but the red bits of code delay the first measurement by 10 and 6 cycles respectively (2070 and 2074 cycles/period). To me this simply looks like a copy/paste error. Just make sure that you really use alternating blocks, i.e. inserting another wait for high removes the reported glitch.

    For the record, if you look at your scan result you'll find two more gaps (4 total).
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-10-15 02:33
    Hi Kuroneko,

    thank you very much for analysing my code and showing how it can be coded shorter.
    I corrected my code but there is still a gap. I guess the carrier-frequency is not that stable. (Yesterday I opened another IR-remote-control that was already defect. No chrystal just a capacitor or maybe a resonator)
    I guess that having measured the carrier-frequency with some deviation it might be that right inbetween the last

    mov _NrOfPulses, PHSA

    and resetting PHSA to zero

    mov _NrOfPulses, #0

    some pulses are not catched. Anyway until now I'm satisfied with the solution to use the counter in POS-mode. Meaning PHSA counts up whenever the IR-Pin is high.
    As I only have to detect zero pulses or more than zero pulses it doesn't matter what the exact number in PHSA is.
    With this mode I had no more gaps.

    In the backround of my head I have a vaque idea of using two cogs:
    one cog for resyncing on each single pulse and signaling each pulse towards the second cog. And the second cog collecting the bits together and writing the bitstream to HUB-RAM.
    But I have to think more about this before I can start coding it.

    best regards

    Stefan
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-15 09:51
    Ok, I'll search for my code this evening and post it!

    What I do is:
    Find the high-times and low-times allowing a deviation and build up a timing table which is sorted (the longest low-time is dismissed because it is the pause between 2 repeats). Together with the typical number of bits send per periode and of course with the carrier frequency this gives a "fingerprint" of a remote control without knowing the real codes so far.

    What I plan to do is to create a hash-value out of this, so that finding the right codes is easier.

    Let's say I have 4 different high-times and 2 different low-times, then I say high 1 = A, high 2 = B, high 3 = C and high 4 = D.
    Low 1 = a and low 2 = b. This way I can translate each cycle into a sequence of letters and easily compare this sequence with codes that have been learned before.

    With all the timing-information and the letter-sequence you can also recreate the signal. This is as far as I remember already working.

    I think if you manage your 000-problem your code would be perfect to feed my code ;o)
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-10-15 10:17
    Hi MagIO2,

    I have solved the 000-gap problem. the solution is to use the counter in POS-mode. Or when using it without the monoflop with NEG-mode. This means PHSA counts up whenever the IR-Pin is high.
    As I only have to detect zero pulses or more than zero pulses it doesn't matter what the exact number in PHSA is.
    With this mode I have no more gaps just a slight deviation in the numbers of "1" and "0".

    best regards

    Stefan
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-15 11:53
    Ok, here is the latest code I found.
    You inspired me to continue with this stuff again, so I'll setup my gadgetganster board again! I wanted to continue with code for learning IR codes and write them to different files.

    By the way ... can you tell us a bit more about your project (if you want to)?
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-15 13:06
    Hmm .. the latest does not seem to be the best for you to see what's going on ;o)

    Here is the code in version 2 which at least shows you the string I talked about.

    And for all who don't want to run the code, here is an example of a sample:
    analysing...
    Total # of samples per sequence: 1181
    Summary 0s:
    12, 171, 0, 0, 0, 0, 0, 0, 0, 0,
    Summary 1s:
    9, 30, 82, 451, 0, 0, 0, 0, 0, 0,
    bCaBaBaAaAaAaBaAaBaBaAaAaAaAaBaAaAaD36
    bCaBaBaAaAaAaBaAaBaBaAaAaAaAaBaAaAaD
    

    As far as I remember, the code samples twice because some IR codes contain a switching bit, some send a code only once and then just a repeat code. Forgot what the 36 means at the end of code 1, but I'll find it out ;o) ....
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-10-15 13:55
    HI MagIO2,

    thank you for sharing your code. As you haven't commented your code I'm too lazy (at the moment) to analyse your code.

    best regards

    Stefan
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-15 14:07
    Hmmm ... I'm sorry for that! I'm going to improve it and add plenty of comments as soon as I understand what I did ;o)

    But I found out that IRbase2 is pretty nice. You can scan a whole remote control and save the codes on SD card.
    First you're asked for a filename, then you enter the key-name. After confirming with return you push the according key on the control and the code is displayed and stored on SD card. When entering space the file is closed and the last key is played back on an IR diode attached to two pins. One pin is replaying the signal, the other pin toggles with carrier frequency.
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-10-15 14:28
    I don't have a GadgetGangster PPB. I have a parallax PPDB, a C3 and a self assembled board.

    The C3 needs a different SD-card-driver as the SPI-bus is multiplexed. I haven't dived into that yet. To tell about the project. I want to record all common carrier-frequencies and store 50-60 IR-commands for playing back.
    I don't want to use an SD-card. I want to use a SPI-flash-ROM.

    Next step is to play back the IR-code from my stored bitstream representing carrier On/Off.
    What do you think how much memory does your time-classifying-approach save about my carrier-On/Off-approach?

    best regards

    Stefan
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-15 15:14
    I think we have the focus on different things. You want to record and playback and I want to have a general purpose driver. So it can record, replay and understand. The understand-part is the reason for translating the IR signal into timing-table and signal string. Because then you can simply do a string-compare to find out which key has been pressed.

    With the bitstream you can't do that, as small deviations will cause a failure of the compare.

    If I read your initial post right you need ~2000 bits => 250byte per key
    What I measured is the code of a JVC IR remote control which has a pretty long message and it could be packed to 18 bytes per key. Additionally 32 bytes are needed for storing the time-table per different remote control.

    Playback is easy. You attach one side of the diode to one pin and the other side to another pin. On one pin you constantly output the carrier frequency, on the other pin you output the signal you recorded.

    regards,
    Andreas
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-10-15 15:23
    Hi Andreas,

    Your functionality with the timing table is great. Especially for recognizing codes.

    As you wrote my code would feed perfect into your code. Does your code use a carrier-demodulating IR-receiver? And therefore is fixed to a certain carrier-frequency?

    So my code would expand on different carrierfrequencies? The timing analysing would be made from the numbers of "1"'s and "0"'s my code delivers?

    best regards

    Stefan
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-10-15 16:07
    Yes, I currently use a TSOP which is doing the demodulation. As long as you are close enough these devices also recognize signals modulated with other carrier-frequencies.
    Yes, my hardware setup is theoretically fixed to a carrier frequency. And the code maybe needs some little adjustments. Function analyze works without a change. addList tries to find the timing entry in the list and adds it if no value close enough is found. The deviation allowed is currently set to +/- 2 bits. translate should work and printTrans also needs to take care of the deviation. So, depending on how big the difference the length of the 1s in a row and the 0s in a row is, the deviation maybe has to be changed.

    And yes, that's what I'd expect. You simply read the signal into the sigBuf which currently has a size of 257 longs and let my code do the analysis.

    For detection of the type of IR control I think some "normalization" or maybe averaging of the timing values needs to be done to make them comparable. My idea is to normalize somehow depending on the carrier frequency. So it would be nice to know the timings you measured.
Sign In or Register to comment.