Shop OBEX P1 Docs P2 Docs Learn Events
Counter PWM with no jitter? — Parallax Forums

Counter PWM with no jitter?

Dave MatthewsDave Matthews Posts: 93
edited 2014-02-18 12:35 in Propeller 1
I need to output a signal that will span from 1.0 to 1kHz that will have a duty cycle span of 1 to 99%. I thought I could do that with the Counters, but I had less than good results. Perhaps it is my bad coding or perhaps it is because "for values of FRQA which are not a power of 2, there will be jitter present on the output signal since the most significant bit of PHSA will toggle at an inconstant rate". (Propeller application note AN001, page 17.)

I tried a few examples in the OBEX for counter use to provide such PWM with duty cycle control, but they all had jitter. The spin examples work fine.

Am I correct in my conclusion that using counters exclusively will not give me a jitter free signal for my needs?

Dave

Comments

  • tonyp12tonyp12 Posts: 1,951
    edited 2014-02-17 14:40
    Use PLL Mode, The fixed multiply by 16 and then a user selectable divide by 16 should smooth things out
  • jmgjmg Posts: 15,173
    edited 2014-02-17 14:51
    If you want to control Frequency and duty cycle, then you effectively need to alternate ON time, then OFF time.
    That's probably easier with just WAITCNT.

    There will be a SW limit on how short one can be, but 1kHz 1% is 10us, which will be fine in PASM.

    With On/Off time loading there should be no jitter between cycles, and the granularity will be small at 1Hz~1kHz
    (I think ~12 MilliHertz)
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-02-17 15:21
    tonyp12 wrote:
    Use PLL Mode, The fixed multiply by 16 and then a user selectable divide by 16 should smooth things out
    You can't get there with PLL. The NCO clock has to be between 4 MHz and 8 MHz for the PLL to lock. 4 MHz / 16 = 250 kHz. He needs 1 Hz to 1 kHz.

    I'm with jmg: do it in software with PASM.

    -Phil
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2014-02-17 15:41
    While the software solution should have no jitter when running there may be a big phase jump when changing frequency or duty cycle.

    Duane J
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-02-17 15:56
    You can't get there with PLL. The NCO clock has to be between 4 MHz and 8 MHz for the PLL to lock. 4 MHz / 16 = 250 kHz. He needs 1 Hz to 1 kHz.

    I'm with jmg: do it in software with PASM.

    -Phil

    I think I've tested the 8 channel 8-bit PWM module in my Tachyon to 5kHz, It's table based so a 256 byte table holds the pattern for 8 channels.
  • AribaAriba Posts: 2,690
    edited 2014-02-17 15:57
    I think the best approach is to use a software loop for the frequency and a counter to generate the pulslength.
    At such low frequencies you can do it all in Spin:
    CON
      _clkmode  = xtal1 + pll16x
      _xinfreq  = 5_000_000
    
       OUT_PIN = 16
    
    VAR
      long  freq, width
      long  stack[16]
        
    PUB Main
      freq := 1000   'Hz
      width := 33    '%
      cognew(pwm(OUT_PIN),@stack)
    
      repeat
        'you can change freq and width here
    
    PUB pwm(pin) : time | period, puls
      ctra := %00100<<26 + pin
      frqa := 1
      dira[pin] := 1
      time := cnt
      repeat
        period := clkfreq/freq
        puls := period * width / 100
        time += period
        waitcnt(time)
        phsa := -puls
    '
    

    Andy
  • jmgjmg Posts: 15,173
    edited 2014-02-17 19:02
    Ariba wrote: »
    I think the best approach is to use a software loop for the frequency and a counter to generate the pulslength.

    A benefit of this approach, is a second (same freq) PWM comes almost for free by using the 2nd counter.

    I can't see a way to avoid a small phase shift on the two though ?
  • kuronekokuroneko Posts: 3,623
    edited 2014-02-17 20:34
    Ariba wrote: »
    I think the best approach is to use a software loop for the frequency and a counter to generate the pulslength.
    This may not be an issue for the OP but
    waitcnt(time)
        phsa := -puls
    
    will suffer from hub aliasing. IOW +1 for a pure PASM solution.
  • AribaAriba Posts: 2,690
    edited 2014-02-17 20:55
    Hmm... if it is a problem then this modification may help:
    period := (clkfreq/freq) & $FFFFFFF0
    
    It will add a little frequency error of max 0.02% but should remove any jitter.

    Andy
  • Dave MatthewsDave Matthews Posts: 93
    edited 2014-02-18 05:20
    Thank you for the example code, I will learn from it!
  • Dave MatthewsDave Matthews Posts: 93
    edited 2014-02-18 07:22
    Thanks everyone for the excellent and prompt help and advice. And extra thanks to Ariba for the code, I have done some initial testing and it works fine. This forum is a great resource!

    Dave
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-02-18 08:39
    I've attached a simple dual-motor object that uses a code loop like Andy showed you. I use a variation of this (with more resolution) in a friend's commercial pan/tilt controller for movie cameras.
  • Dave MatthewsDave Matthews Posts: 93
    edited 2014-02-18 12:35
    Thanks Jon, very much appreciate this example, and -all- of your examples!
    Dave
Sign In or Register to comment.