Shop OBEX P1 Docs P2 Docs Learn Events
unexpectedly long pwm pulse lengths from r/c receiver — Parallax Forums

unexpectedly long pwm pulse lengths from r/c receiver

northcovenorthcove Posts: 49
edited 2008-12-08 20:54 in Propeller 1
A PWM signal from a standard R/C receiver is connected to a Propeller pin with a 1k resistor. Sometimes my waitpeq/waitpne loop measures pulses that are roughly 3000 usecs long, roughly twice the expected length. Any ideas what is causing this? The signal looks normal on my oscope. The attached sample code reproduced the issue. Any help with this will be greatly appreciated!

con
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000  
  pwm_in_pin = 11
  dbg_tx_pin = 17
  dbg_baud = 19_200
obj
  dbg : "Simple_Serial"
pub run | t
  dbg.start ( -1, dbg_tx_pin, dbg_baud )
  dbg.str ( string ( "pwm test" ) )
  dbg.tx ( 13 )
  dbg.tx ( 10 )  
  dira [noparse][[/noparse] pwm_in_pin ]~  
  repeat
    waitpne ( 0, |< pwm_in_pin, 0 )
    t := cnt
    waitpeq ( 0, |< pwm_in_pin, 0 )
    t := ||( cnt - t ) / ( clkfreq / 1_000_000 )   'convert to usecs
    if t > 2000
      dbg.dec ( t )       
      dbg.tx ( 13 )
      dbg.tx ( 10 )




The output looks something like this:

pwm test
2996
2995
2996
3010
3011
2996
2995
2998
3001
3007
3011
3008
3005
3007
2996
2991
2960
8342

Comments

  • whickerwhicker Posts: 749
    edited 2008-12-08 19:00
    I would think that the debug code has something to do with this. you'd almost need another cog to poll and print the value.
    let's ignore that for now...

    am I correct in saying that waitpne and waitpeq don't detect rising edge and falling edge, but rather just a high or low level?
    does adding one line before the repeat, as so:

    ...
      repeat
        waitpeq (0, |< pwm_in_pin, 0)          <----- here
        waitpne (0, |< pwm_in_pin, 0)
        t := cnt
        waitpeq (0, |< pwm_in_pin, 0)
    ...
    
    



    fix the problem?
  • northcovenorthcove Posts: 49
    edited 2008-12-08 19:23
    whicker said...
    fix the problem?
    I tried that but unfortunately adding a waitpeq as you suggest has no effect. But thanks for suggesting it.
  • JasonDorieJasonDorie Posts: 1,930
    edited 2008-12-08 20:54
    I would change it to look something like this:

      repeat
        waitpeq ( 0, |< pwm_in_pin, 0 )
        waitpne ( 0, |< pwm_in_pin, 0 )
        t := cnt
        waitpeq ( 0, |< pwm_in_pin, 0 )
        t2 := cnt
        t := ||( t2 - t ) / constant( clkfreq / 1_000_000 )   'convert to usecs
        if t > 2000
          dbg.dec ( t )       
          dbg.tx ( 13 )
          dbg.tx ( 10 )
    
    

    That way you're not only waiting for the rising edge of the signal, but you're also caching the counter value as quickly as possible before doing the math on it.· I'm not sure what order SPIN evaluates things in, but if it were to compute the divisor first, that divide would take a significant amount of time.· Adding constant() to it makes it evaluate at compile time, speeding up the code even more.

    Since the debug code is 'outside' the timing loop, it shouldn't really be a problem, though it will mean that you don't get readings as often as you should.

    If you can spare a cog, I'd suggest using the RCInput object found here:
    http://forums.parallax.com/showthread.php?p=690465

    It works well, and can easily be modified to handle fewer inputs with higher precision.· There's also one in the standard libs that ship with the Prop, but it requires sequential inputs, where the above object does not.

    Jason
    ·
Sign In or Register to comment.