Shop OBEX P1 Docs P2 Docs Learn Events
IR Record and Playback — Parallax Forums

IR Record and Playback

william chanwilliam chan Posts: 1,326
edited 2008-12-10 14:08 in Propeller 1
Hi guys,

The 38Khz carrier using CTRA works perfectly.
But now the record and playback in SPIN only works for about 20% of equipments I tested.
For example, it works with Panasonic remotes, but not Philips or LG remotes.

Could it be SPIN is too slow to make accurate sampling at 80Mhz?
The record_ir() code I copied from the IR_Kit in the OBEX.
I wrote the playback_ir code(), but it seems difficult to accurately match the time per loop for record and playback.


CON
 _maxbuff = 500          'number of marks and spaces max 
 _quiet   = 10000         'ir completely quiet  

VAR
        long    buff[noparse][[/noparse]_maxbuff]
        long    samples


pub record_ir | iron, iroff

  dira[noparse][[/noparse]ird1_pin]~                          'make irdetector pin input 
  samples~
  repeat while ina[noparse][[/noparse]ird1_pin]==1     'wait any mark
  repeat
    iron~
    repeat while ina[noparse][[/noparse]ird1_pin]==0  'time mark
      iron++
      if iron > 10000                      'this just balances mark/space counts
         return
    buff[noparse][[/noparse]samples++]:=iron 
    iroff~
    repeat while ina[noparse][[/noparse]ird1_pin]==1  'time space
      iroff++
      if iroff>_quiet                        'end of train
        buff[noparse][[/noparse]samples++]:=iroff        'save last
        return
    buff[noparse][[/noparse]samples++]:=iroff
    if samples => _maxbuff-2
      samples -= 2                         'don't overfill the buffer


PUB playback_ir | i, count
    
  i~
  repeat
    if i => samples                  ' done?
       quit
    count := buff[noparse][[/noparse]i++]               
    dira[noparse][[/noparse]irled_pin]~~               ' Make pin output to send IR signal
    repeat while count>0         ' mark
       count--
       if count > 10000             ' this just balances time per loop   
    count := buff[noparse][[/noparse]i++]                  
    dira[noparse][[/noparse]irled_pin]~                 ' Make pin input to pause IR signal
    repeat while count>0         ' space 
       count--
       if count > 10000             ' this just balances time per loop 



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.fd.com.my
www.mercedes.com.my

Post Edited (william chan) : 12/10/2008 1:31:02 AM GMT

Comments

  • Chuck RiceChuck Rice Posts: 210
    edited 2008-12-10 02:50
    How do you know you are running at 80MHz? The code as posted would run at 12MHz. What happens if you insert
    _clkmode = xtal1 + pll16x                             'Set to run at 80 MHz
    _xinfreq = 5_000_000
    
    


    At the top of the file?
  • william chanwilliam chan Posts: 1,326
    edited 2008-12-10 03:27
    I am running at 80Mhz, I am sure.
    I didn't post the clock and freq code b'cos I don't want too much clutter on the example code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.fd.com.my
    www.mercedes.com.my
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-10 05:52
    Since you want to check for a timeout, both in the time to wait for a pulse and the pulse width
    noPulse := false
    temp := cnt
    repeat until ina[noparse][[/noparse]ird1_pin] <> 0
       if (waitTime := cnt - temp) > timeout
          noPulse := true
          quit
    if noPulse
       ' no pulse was detected
    else
       tooLong := false
       temp := cnt
       repeat until ina[noparse][[/noparse]ird1_pin] == 0
          if (pulseWidth := cnt - temp) > timeout
             tooLong := true
             quit
       if tooLong
          ' width of pulse > timeout
       else
          ' we have a valid pulse, save it and the off time prior to the pulse to the array
    


    Note that you'd have two values for each pulse, the off time prior to each pulse and the on time of the pulse.
    You'd obviously ignore the first off time since its unrelated to the pulse train. To play it back, you'd set the
    DIRA bit to 1 and do a WAITCNT(value[noparse][[/noparse] x ] + cnt) where value[noparse][[/noparse] x ] is the first time value, then toggle the
    DIRA bit, increment x, and do another WAITCNT repeating the whole sequence for each recorded time value.
    At the end of the pulse train, you'd just set the DIRA bit to 0 turning off the IR pulses.

    Post Edited (Mike Green) : 12/10/2008 6:00:54 AM GMT
  • william chanwilliam chan Posts: 1,326
    edited 2008-12-10 07:35
    Mike,

    I don't quite understand why your code is totally different from mine.
    Would your code's timing be more accurate?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.fd.com.my
    www.mercedes.com.my
  • william chanwilliam chan Posts: 1,326
    edited 2008-12-10 12:50
    Ok, I am beginning too understand your code better now. Thanks.

    But there is a small problem.

    Sometimes when we WAITCNT(buff[noparse][[/noparse] x ] + cnt) during playback, the value of buff[noparse][[/noparse]x] may be too small, causing the cog to wait forever.
    If we set a minimum to the value of buff[noparse][[/noparse]x], it will cause the pulse train to become unfaithful.

    So how now?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.fd.com.my
    www.mercedes.com.my
  • Mike GreenMike Green Posts: 23,101
    edited 2008-12-10 14:08
    1) The code I wrote is essentially independent of the execution speed of the various statements and only dependent on the system clock.

    2) You're correct about there being a minimum WAITCNT increment. It's roughly 400. You might set 1000 as a minimum. It's only about 12us, less than a half cycle of the 38KHz carrier. You shouldn't see delays this short.
Sign In or Register to comment.