Servo problems
RichardF
Posts: 168
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
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
Comments
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
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ D Rat
Dave Ratcliff· N6YEE
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ D Rat
Dave Ratcliff· N6YEE
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
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
Your code does the same thing! Won't run at 80mhz and 1.5ms isn't anywhere near neutral??????????
Richard
Just because the divide will take time and that will add a delay in itself otherwise.
Graham
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
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.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ D Rat
Dave Ratcliff· N6YEE
A 4 cell NiCd pack (4.8V).
Richard
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
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
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
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
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
· _clkmode = xtal1 + pll16x
··_ xinfreq = 5_000_000
·Dave.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ D Rat
Dave Ratcliff· N6YEE
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
Good luck I hope you figure it !!!!
Dave.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ D Rat
Dave Ratcliff· N6YEE
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
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.
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
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
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.
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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!"
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
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)
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.