Shop OBEX P1 Docs P2 Docs Learn Events
Servo problems — Parallax Forums

Servo problems

RichardFRichardF Posts: 168
edited 2007-06-07 22:12 in Propeller 1
The same servos I use with the BS2 are giving me problems with Propeller (different pulse widths for the same position, extremely jittery around neutral point, settings change from one day to the next, etc.) Is it possible that the servos (Hitec) don't like the 3.3 volt pulses? Also, they won't run at 80 megs, but will at 40 and below (sorta). I am pulsing the servos like this:

repeat
·outa[noparse][[/noparse]pin]~~
·waitcnt(clkfreq/1000*t + cnt)···········'t was 1 to 2 ms for the BS2, but is 2.5 ·to 3.5 ms for the Prop, but varies
·outa[noparse][[/noparse]pin]~···································· 'and is jittery
·waitcnt(clkfreq/50 + cnt)

thanks,
Richard
«1

Comments

  • Martin HebelMartin Hebel Posts: 1,239
    edited 2007-06-05 01:15
    The pulses need a good 20mS between each. Does
    waitcnt(clkfreq/50 + cnt)
    Provide this?

    Depending on clock freq, I'm not sure. Why not use:
    waitcnt(clkfreq/1000* 20 + cnt)
    to be sure you have 20mS irregardless of cklfreq.

    Also, using waitcnt(clkfreq/1000*t + cnt) you can only be good down to 1mS, which provides poor resolution for the servo (1 or 2mS)

    Get better resolution using:
    waitcnt(clkfreq/1_000_000 * t + cnt) ' where t = 1000 to 2000 uS

    -Martin


    -Martin

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    StampPlot - GUI and Plotting, and XBee Wireless Adapters
    Southern Illinois University Carbondale, Electronic Systems Technologies
  • ratronicratronic Posts: 1,451
    edited 2007-06-05 02:05
    Richard, this how you do it assm. I will have to freshen up spin and give to you if no body else does.

    Attached file you can change delay right now set for 1.5 ms high and delay1 for 20ms low repeating itself over and again. Dave


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Fix it if ain't broke·
    D Rat


    Dave Ratcliff· N6YEE
  • ratronicratronic Posts: 1,451
    edited 2007-06-05 03:12
    Richard, here is an example in spin. I'm not sure about time delay between spin op codes , but is close enough.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Fix it if ain't broke·
    D Rat


    Dave Ratcliff· N6YEE
  • rokickirokicki Posts: 1,000
    edited 2007-06-05 03:23
    Richard,

    Post the entire code please, including the con settings.

    The fact that it won't work at 80 but will at 40 is very suspicious.

    I'm driving the servos that came with my boebot just fine with the prop
    using code very close to yours.
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-06-05 07:54
    The way he is doing his waitcnts means that at 40Mhz his resolution may be higher providing less jitter.

    Graham
  • RichardFRichardF Posts: 168
    edited 2007-06-05 11:29
    This is the basic code I am using. The following problems occur (same problems occur with Parallax servo):
    1. Servo position/speed changes with clock frequency and won't run at all at 80mhz.
    2. Servo position changes between power off/on sessions!!!!!!!
    3. Neutral point is different than when position using BS2 (all settings different from BS2).
    4. I tried different pause times between pulses, jitters just as bad but at a different rate.
    5. Neutral point won't hold still, jumps all over the place.

    CON
    _clkmode = xtal1 + pll1x
    _xinfreq = 5_000_000
    var
    word position

    pub start
    position := 750 '1.3ms pulse
    position_servo(position)

    pri position_servo(posit)
    dira[noparse][[/noparse]16]~~
    repeat
    outa[noparse][[/noparse]16]~~
    waitcnt(clkfreq/posit+cnt)
    outa[noparse][[/noparse]16]~
    waitcnt(clkfreq/50+cnt)

    PS. All non-servo projects work fine at 80 mhz. This one with servos has come about to convert my BS2 Bot to a Prop Bot.
    Thanks,
    Richard
  • RichardFRichardF Posts: 168
    edited 2007-06-05 11:36
    Dave,
    Your code does the same thing! Won't run at 80mhz and 1.5ms isn't anywhere near neutral??????????
    Richard
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-06-05 12:08
    I'll check it out on my scope when I get home but you might want to try this:

    
    pri position_servo(posit)
    dira[noparse][[/noparse]16]~~
    ontime := clkfreq/posit
    offtime := clkfreq/50
    
    repeat
    outa[noparse][[/noparse]16]~~
    waitcnt(ontime+cnt)
    outa[noparse][[/noparse]16]~
    waitcnt(offtime+cnt)
    
    
    



    Just because the divide will take time and that will add a delay in itself otherwise.

    Graham
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-06-05 14:57
    If you don't have at least 15ms delay between pulses most servos will get very jittery from being overdriven. It also happens when you change the pulsewidth too quickly for the servo to reach the new location on a standard servo.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • ratronicratronic Posts: 1,451
    edited 2007-06-05 15:37
    Richard , I am a rookie at prop code , but I·see a positive pulse of 1.5 ms high and 20 ms low +or- ~ few us.
    I have seen it on the scope, also the code I gave the first time is set to center motor off w/ the motor preset
    to 1.5 ms.·This code I have attached is set for on time for 2 ms. I haven't run my servo on it, but I see it on the
    scope.·I will have check on dso scope to see the exact timing. Make sure to set servo motor to stop at 1.5 ms.

    P.S.· Can you guys in the know look at my code and tell me of any glaring defects. It may still be a little early for
    me·to be giving advise on the forum! I would appreciate it please!!!· Dave.
    ·


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Fix it if ain't broke·
    D Rat


    Dave Ratcliff· N6YEE
  • Don DDon D Posts: 27
    edited 2007-06-05 15:55
    Forgive the intrusion, but what is the V+ supply for your servo?
  • RichardFRichardF Posts: 168
    edited 2007-06-05 16:26
    Don,
    A 4 cell NiCd pack (4.8V).
    Richard
  • RichardFRichardF Posts: 168
    edited 2007-06-05 16:45
    I think I have found the problem, the crystal oscillator/PLL circuit in my chip must be bad. Here· is the test program I used and the results:

    1. I ran a servo test on the Futabo S3004 servo using the BS2. The servo range of movement from 1 to 2 milliseconds is as it should be; no jitters, smooth operation. I used the standard 20ms pause between pulses.

    2. I made up the same program using Spin and discovered that the problem lies in the xtal osc/PLL cicuitry or software. Here is the program that works fine and gives the same results as the BS2:

    con
    ·_clkmode = RCFAST

    Pub start
    ·repeat
    · dira[noparse][[/noparse]16]~~
    · outa[noparse][[/noparse]16]~~
    · waitcnt(clkfreq/666 + cnt)·· 'servo centered at 1.5 ms
    · outa[noparse][[/noparse]16]`
    · waitcnt(clkfreq/50 + cnt)···· '20ms pause between pulses

    Servo responds exactlyy the same as BS2 setup.

    As soon as I change the·_clkmode constant to any setting that uses the crystal and/or PLL the problem of·jitters and iconsistent·servo positions begins. _clkmode = XTAL1 wont work at all. Add the PLL (pll8x, etc) and the servo moves around but is jumping all over and the settinggs change. pll16x won't work at all.

    I am pretty much convinced that I have a bad chip, but I guess it could also be in the crystal. Maybe a Parallax employee could jump in here with a suggestion.
    Thanks to everyone that has responded. I have spent hours trying to sort this out; the last thing I thought it would be was the chip nono.gif
    Richard
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-06-05 16:49
    Richard,

    All Propeller Chips are tested before leaving Parallax. If something happened to the I/O pin of there was a ground loop or supply noise issue it is possible that the PLL circuit was damaged. Static is always a possibility as well. Do you have a scope? If so, can you take a screenshot of what the output looks like?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
  • Martin HebelMartin Hebel Posts: 1,239
    edited 2007-06-05 17:12
    When you change the clock mode, do you also modify all your code? As recommended by a couple people you are better off using code such as:

    waitcnt(clkfreq / 1_000_000 * uS + cnt) ' uS = 1000 to 2000 for 1 to 2 mS
    waitcnt(clkfreq / 1_000 * 20 + cnt) ' 20 mSec

    This code will be correct no matter what clock frequency you define, though possibly not fast enough when running off the slow internal oscillator. Also be aware the variations on the internal oscillators may lead to different positions for the same value.

    -Martin

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    StampPlot - GUI and Plotting, and XBee Wireless Adapters
    Southern Illinois University Carbondale, Electronic Systems Technologies
  • RichardFRichardF Posts: 168
    edited 2007-06-05 17:38
    Chris,
    Another anomoly is that the pulse width out is changing when I change PLLx settings. I can watch the servo arm jump to a new position when I change the multiplier for the PLL. Boy, that is really strange to me. I don't have a scope or eally acces to one. Can you suggest a more definitive test before I send the chip back for you to test?
    Thanks,
    Richard
  • RichardFRichardF Posts: 168
    edited 2007-06-05 17:41
    Martin,
    The way I time my pulses is the same as you proposed. You are correct in that pulse width should not change when I change the _clkmode, but it does and that is the problem. Appreciate your input.
    Richard
  • ratronicratronic Posts: 1,451
    edited 2007-06-05 18:17
    Are you using this for your clk setup using a 5mhz cyrstal = 80 mhz?

    · _clkmode = xtal1 + pll16x
    ··_ xinfreq = 5_000_000


    ·Dave.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Fix it if ain't broke·
    D Rat


    Dave Ratcliff· N6YEE
  • RichardFRichardF Posts: 168
    edited 2007-06-05 18:48
    Dave,
    Yes, but the 16x won't work, the others will (8,4,1)but jumping all over. I am now using the RCFAST mode and all works perfectly. My little robot just runs perfectly! Problem is, I want to do some accurate timing and that isn't going to happen with the internal RC oscillator. Plus I want my chip to work right.
    Richard
  • ratronicratronic Posts: 1,451
    edited 2007-06-05 19:20
    Richard , jeez then I don't where the problem is. Just if you change timing any where you have change all the rest of timing through out the program. I would like to see the resolution when get it figured out!!

    Good luck I hope you figure it !!!!
    Dave.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Fix it if ain't broke·
    D Rat


    Dave Ratcliff· N6YEE
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-06-05 19:43
    This code

     repeat
        dira[noparse][[/noparse]6]~~
        outa[noparse][[/noparse]6]~~
        waitcnt(clkfreq/666 + cnt)   'servo centered at 1.5 ms
        outa[noparse][[/noparse]6]~
        waitcnt(clkfreq/50 + cnt)     '20ms pause between pulses
    
    



    As you posted but without the typo on the second outa works perfectly at 80Mhz on my demoboard. 1.5ms pulse width and 20ms between pulses.

    Its your crystal/pll me thinks

    Graham
  • rokickirokicki Posts: 1,000
    edited 2007-06-05 19:56
    I wonder if somehow your crystal is actually oscillating at 2x or 3x or something, which would
    explain why it doesn't work at 16x (would be too fast for the prop) and also why you need to
    double the pulse width when using the PLL. Maybe there's a capacitance issue. Do you have
    another crystal to try? Maybe it's a capacitive loading issue? Maybe the wires between the
    prop and the crystal are too long?

    I would do a trivial one-second blink LED test and see if it "works" at the right speed when you
    use the crystal modes.
  • RichardFRichardF Posts: 168
    edited 2007-06-05 23:46
    robicki,
    I did as you suggested:
    CON
    _clkmode = XTAL1 + pll4x
    _xinfreq = 5_000_000
    PUB start
    dira[noparse][[/noparse]15]~~
    repeat
    outa[noparse][[/noparse]15]~~
    waitcnt(clkfreq/2+cnt)
    outa[noparse][[/noparse]15]~
    waitcnt(clkfreq/2+cnt)

    It clocks at exactly one second at all pllx settings (1,2,4,8,16). I don't know what to think. I am hoping Parallax can give me some other tests to run. The chip isn't expensive, but I would hate to get another one and find out it is somehow me causing the problem.
    Richard
  • Graham StablerGraham Stabler Posts: 2,507
    edited 2007-06-06 00:01
    I think we have now proven that the problem is not the propeller, the code works and the propeller works.

    However the system is not working. Is the propeller powered from a different power supply or from the 4.8v battery via a regulator? Is there a chance that the load of the servo is distrupting the power supply enough for it to cause a real problem at higher clock frequencies? Do you have the grounds of the servo supply and propeller supply connected (I guess you must).

    Here is another test, run the servo code in one cog and the 1 second flash code in another cog and see if trying to drive the servo disrupts the flashing timing.

    Power supply issues seem the most likely to me. Perhaps more capacitance on the regulator output.

    Graham
  • APAP Posts: 24
    edited 2007-06-06 01:02
    Guys - I can't help but chime in my $0.02 worth.

    1) Spin is slow, so "manually" timing the on/off pulses·induces some variability due to cog/hub window issues. There is timing overhead for code execution. You will especially see this if you change the PLL setting to run at lower clock speeds.

    2) The servo32.spin doesn't use spin language for timing pulses, it uses assembly language (which is MUCH faster code w/o all the overhead of spin).

    3) I believe servo32.spin controlls timing of pulses via the PHSA and PHSB counters of the cog it is running in. What this means is that there is absolutley ZERO variability in pulse time, giving control down to 1 or 2 clock pulses (12.5 or 25 nanoseconds). In my experience, "Servo32.spin" gives totally excellent results, and is rock-solid stable.

    4) The servo32.spin object handles all the headache of "feeding" servos pulses at 50Hz. All you have to do is call the PUB method "set" to update servo pulse width, in microseconds, whenever you want to change the servo position. Your main program running in cog 0 can choose to update servo positions once per minute, once per second, 50 times a second, or 500 times a second. The servo will still just see 50 Hz of pulses. Updating too fast (> 50Hz) won't induce jitter, because Servo32.spin just uses the most recent pulse value it got updated with.
  • Beau SchwabeBeau Schwabe Posts: 6,547
    edited 2007-06-06 03:24
    RichardF,

    On your servo, do you have a direct connection from the I/O pin to the servo, or do you have a resistor in series between the two? (<-4.7K works well) You have your ground connections in common right? (<- between the Propeller and your 4-cell battery pack?) How long are the leads from the I/O pin to the servo connection?


    AttoPilot,

    Thanks for the Plug... Servo32 was one of my first attempts at Propeller Assembly.······· Richard as a sanity check you might want to try·servo32, and then later if you decide to roll your own code to fit your needs, then go for it.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 6/6/2007 3:30:36 AM GMT
  • RinksCustomsRinksCustoms Posts: 531
    edited 2007-06-06 04:45
    i agree with the pilot (myself one in training), and Beau. Servo32 works well supplying 5 servos with no jitters & a separate li-ion pack reg'd to 6.2V (the upper limit on some nice high-end BB Hitech's i have, giant scale)..

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Definetly a E3 (Electronics Engineer Extrodinare!)
    "I laugh in the face of imposible,... not because i know it all, ... but because I don't know well enough!"
  • RichardFRichardF Posts: 168
    edited 2007-06-06 11:09
    Graham,
    I ran the tests you suggested. In all clock modes, the LED running in cog 0 flashes at exactly 1 Hz as expected, however, the servo speed for my bot wheels changes significantly with each change in clock mode and finding a stopped pulse width is nigh impossible die to jittering (except for RCFAST). Clearly, the servos running are effecting the PLL, but I don't understand how. I pulled out my trusty digital voltmeter and read the output of the 3.3 volt regulator with each change in clock mode. No matter what mode I am in it reads 3.26 volts! While watching the VM, I changed clock mode and here is what I observed:
    clkmode = RCFAST
    volts 3.26, servos stopped at clkfreq/652 as they should be
    clkmode = xtal1 + pll1x
    volts 3.26, one servo runs forward, one runs backward at medium speed
    clkmode = xtal1 + pll4x
    volts 3.25, left servo runs backwards slowly, right servo runs forward fast
    clkmode = xtal1 + pll16x
    volts 3.26, both servos run forward at medium speed

    Note that 16x is working today!!!!!

    The only difference in my setup and that from the PE kit circuit diagram is that I am running the 3.3 volt regulator straight off of a 4.8 volt NiCad pack.

    I am at a total loss at this point.

    I will attach the complete program in the next reply.

    Thanks for working with me on this,
    Richard
  • RichardFRichardF Posts: 168
    edited 2007-06-06 11:15
    Here is my complete program:

    CON
    ·' _clkmode····· = RCFAST
    ·_clkmode····· = XTAL1 + pll16x
    ·_xinfreq····· = 5_000_000
    ·stop = 0
    ·forward = 1
    ·back = 2
    ·left = 3
    ·right = 4
    VAR
    ·byte direct
    ·word ldir, rdir
    ·long stack0[noparse][[/noparse]20]

    PUB start
    ·'initialize/low battery monitor
    ·dira[noparse][[/noparse]26]~~
    ·repeat 300
    ·· outa[noparse][[/noparse]26]~~
    ·· waitcnt(clkfreq/3000+cnt)
    ·· outa[noparse][[/noparse]26]~
    ·· waitcnt(clkfreq/3000+cnt)
    ·'start main·
    ·direct := stop
    ·coginit(1,command_servos(@direct), @stack0)
    · direct := forward
    ·'flashing LED
    · repeat
    ··· dira[noparse][[/noparse]15]~~
    ··· outa[noparse][[/noparse]15]~~
    ··· waitcnt(clkfreq/2+cnt)
    ··· outa[noparse][[/noparse]15]~
    ··· waitcnt(clkfreq/2+cnt)
    pub command_servos(direction)|dir
    ·dir := byte[noparse][[/noparse]direction]
    · case dir
    ··· stop:
    ····· rdir := 652
    ····· ldir := 652
    ··· forward:
    ····· rdir := 600
    ····· ldir := 710
    ··· back:
    ····· rdir := 710
    ····· ldir := 600
    ··· left:
    ····· rdir := 600
    ····· ldir := 657
    ··· right:
    ····· rdir := 657
    ····· ldir := 710
    · run_servos(rdir,ldir)
    ·
    PUB run_servos(rd,ld)
    ·repeat
    ·· right_servo(rd)
    ·· left_servo(ld)
    PUB right_servo(r_dirs)
    ·dira[noparse][[/noparse]16]~~·······················
    ·outa[noparse][[/noparse]16]~~
    ·waitcnt(clkfreq/r_dirs+cnt)·······
    ·outa[noparse][[/noparse]16]~
    ·waitcnt(clkfreq/50+cnt)
    PUB left_servo(l_dirs)
    ·dira[noparse][[/noparse]17]~~························
    ·outa[noparse][[/noparse]17]~~
    ·waitcnt(clkfreq/l_dirs+cnt)·······
    ·outa[noparse][[/noparse]17]~
    ·waitcnt(clkfreq/50+cnt)
  • RichardFRichardF Posts: 168
    edited 2007-06-06 11:31
    Beau,
    My ground is in common to all voltage sources. My leads from the Prop pins to the servo connections is one proto board width, about 1 1/2 inch. My servo leads are 12 inches but are Hitec twisted wire. My bot is home brew with the PE kit protoboard sitting on top of a plywood board. The only thing I changed from the PE kit instructions was to elliminate the 9 volt battery and 5 volt regulator, and hook my 4-cell NiCad directly to the 3.3 v regulator input. I did not use the 1000 uf capacitor on the input of the 3.3 v reg, but I do have a 1000 uf and LED/resistor load on the output as instructed in the kit. The servo motors run directly off the NiCad input and have a common ground with the Prop chips 3.3 v regulator.
    Richard

    PS. I just put a 1000 uf cap across the regulator input and there was no change in behavior.
Sign In or Register to comment.