Shop OBEX P1 Docs P2 Docs Learn Events
PWM Signal Flaw — Parallax Forums

PWM Signal Flaw

QuadrtrFlyrQuadrtrFlyr Posts: 73
edited 2011-05-27 19:56 in Propeller 1
Hello folks,

I am currently working on code for my two ESC controllers. I am specifically working off of code posted in the OBEX (attached below). Everything was going alright until I started seeing jitter in one of the brushless motors when I switched to two PWM signals (Two Servo Assembly) generated by one cog instead of one PWM signal. I believe I have found the reason for this jitter but am not sure what to do about it. I have attached an image of the first pulse (position1) vs the second pulse (position2). The first pulse is clearly not as well defined as the second pulse which I think is due to the fact that there is a greater pause between the waitcnt command and position1 than the waitcnt command and position2..
position1:=80_000
  position2:=80_000
  waitcnt(clkfreq*10+cnt)

For all I know this problem might be insignificant and something else might be going on... Any help is appreciated.

Regards,
Robert

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2011-05-26 22:57
    Have you tried running two instances of the Single_Servo_Assembly object? Is the (mis)behaviour the same?
  • QuadrtrFlyrQuadrtrFlyr Posts: 73
    edited 2011-05-27 07:12
    I have tried that and it works fine separately.. To a certain extent the motors have stopped twitching but out of curiosity sake.. how would I make both signals ideal without using more than cog?

    Regards,
    Robert
  • kuronekokuroneko Posts: 3,623
    edited 2011-05-27 07:29
    I have tried that and it works fine separately..
    Odd, from my limited understanding that looked more like noise (when using the combined driver). Anyway, have a look at http://obex.parallax.com/objects/51/. This may be overkill but concentrates everything in a single cog und may well solve your issue.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-05-27 08:38
    The servo code you're using is... well... a little rough. Since you want to control a dual ESC I wrote the attached program that uses the counter modules in a cog to generate the servo pulses. You can set the refresh period (usually 20ms) and there is a method to write the position value in microseconds (gives you full control over position/speed).

    I've attached screen shots of the output of each channel (ch1 at 1ms, ch2 at 2ms) to show that the output is clean for both. Note, too, that using this approach (instead of the "walking servo" approach I normally use) means that the outputs are updated nearly simultaneously (ch1 leads ch2 by about 12 clock cycles) but both get refreshed at the rate specified by the start method. In "walking servo" code the second (and subsequent) servos update period [usually] wobbles with position changes in the earlier servos.
    1024 x 640 - 66K
    1024 x 640 - 66K
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-05-27 08:44
    BTW... you can use Spin to get that dual servo code and get the same precision (using counters and a synchronized waitcnt loop). I coded in PASM as that's what you already had -- didn't know if using PASM was part of your desired learning process.
  • kuronekokuroneko Posts: 3,623
    edited 2011-05-27 17:36
    @JonnyMac: Do you have an explanation as to why the original approach may have generated this dirty signal? Not entirely sure whether it was timing he was concerned about or general signal quality. I do get the timing part (given the way the object is written).
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2011-05-27 19:43
    "Do you have an explanation as to why the original approach may have generated this dirty signal?"

    If you look closer at the PASM program...

    mov dira,ServoPin1

    ...sets servo #1, but your negating it by doing this for servo #2 ...

    mov dira,ServoPin2

    ...doing it this way your setting the first servo pins dir to 0, causing it to float. for the second servo, you needed to do something like ...

    or dira,ServoPin2

    ... this way the first servo doesn't get changed.


    The same is true for the outa between the two servo's ... to 'set' the I/O high, you need to use OR operator, to 'clear' the I/O to low, you can use the ANDN operator.

    The reason that it works when you call two separate COG's is because the DIR register is isolated from one cog to the other, and ORed at the end.
  • kuronekokuroneko Posts: 3,623
    edited 2011-05-27 19:56
    ...doing it this way your setting the first servo pins dir to 0, causing it to float.
    Thanks, I was assuming that the servo line is pulled low for specifically that reason (shame it doesn't say anything about this in the object itself). No further questions.
Sign In or Register to comment.