Let's Make Robots!

How, When, Damn it, Why do servos jitter?

I've had a lot of trouble with servo jitter lately, I seem so have solved the problem but I'm not sure why it has worked.

servos.jpgAt first I thought it was the power supply being spiked, no amount of decoupling capacitors solved the problem.

I thought it was software and although my code was improved, the jitter continued.

Because I was using optic sensors, I thought fluctuations in the light is causing my inputs to give false readings. Still no luck and I stubbed my toe in the dark.

The oscilloscope showed clean power and signals to the servo but ocassionally the pulse width changed rapidly.

Still could be software. Debug was slowing the whole thing down too much so I got the picaxe to transmit just the 3 variables I was interested in via the sertxd command and serial cable to the terminal emulator built into the programming editor.

My software was behaving and all of a sudden my servo was behaving. I tried a different servo, same thing, jumps all over the place like a kangaroo in peakhour traffic the moment I removed the sertxd command. So now I'm baffled and wondering if anyone out there knows what is going on. For now I've left the sertxd command in.

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Sometimes, in rare ocations, the reason is someting else.

Sometimes people do not use Picaxe! 

This is rare, because the other thing, described above is very common (Jitter happening with picaxe) - and so you should look for your jitter-problems there. However, there CAN be another issue; Your CPU could be sending out a lot of alternating and rapidly changing inputs to the poor servo.

This happens usually when you are placing the servo somewhere according to something else in the code, perhaps an input, perhaps a calculation (that could have overflows) etc - instead of someting simple, like you push a button, and want the servo to go there.

The above sollution will still find the problem.. but you may end up with a hard time fixing it, no matter how much of the above cure you take, it jitters when you use the servo.

In this case you should have a look at this:

http://letsmakerobots.com/node/650#comment-1575 

Good advise, that's how I corrected some earlier faults in my code. I too found the little servos to be less stable.

I used an oscillioscope to determine that the problem was not something like rapidly changing inputs. Multimeters and oscillioscopes can be good debugging tools, especially if a problem is a combination of code and hardware.

PS. sorry for mis-spelling your name (with a z) when I first joined. I know another Fritz who is spelled with a z.

No worriez, people doez it all ze zime ;)

However, I think the servos react to one cycle out ouf sync. I doubt that you can see that on your scope?

As far as I have found, there are four things that might cause jitter. I've only run servos using a picaxe so I don't know about the other processors.

1) Resonators.

Some picaxes have the option of using an external resonator, although they have an internal 4mhz resonator in the chip. The picaxe 28 board has an external resonator of 4Mhz. The external ones are much more accurate than the internal ones. You have to use the setfreq  command to select the external resonator or it will just default to the internal.

Because timing of the pulses to the servo are very short (0.75 - 2.25 ms) it helps to have more precise timing. 

2) power supply 

Using a separate power supply to the servos is generally the best way to reduce jitter. This is not because of spikes on the power line to the servos, but rather spikes on the signal line. Servos cause spikes on the power line which, through the other components, might result in short spikes on the signal line. These spikes mess with the pulses to the servo making them too long or short, which causes the jitter.

3) timer

The picaxe has only 1 timer. If you use the servo command, the picaxe will use that timer to time the servo pulses. Each 40ms a pulse is send to the servos, changing or confirming the servo position. Any other picaxe command that makes use of the timer, will interfere with that. Sometimes the command wont work and sometimes you'll see extreme servo spasms. 

The picaxe manual is not very clear on which commands you shouldn't use at the same time, but there are a few references. In any case; you should avoid making use of any combination of commands that use the timer. Some commands that use the timer

 

  • serial communication. e.g sertxd, serrxd, serin, serout etc.
  • servo commands. (servo and servopos)
  • PWM commands (PWMOUT, PWMDUTY, HPWMOUT, etc.)
  • timer variable

 

 If you look at Fritz! code in See what Robot Sees you can see he sets the servo pin low before issueing the sertxd, so the servo command running in the background stops.

4) servopos

according to the picaxe manual, the servo command, should only be used to initialize the servo. Each time this command is run, it resets the timer, which can cause jitter. The servopos command should be used to change the servo position as it doen't reset the timer, but does change the pulse length. In my experience I haven't noticed any difference whether I use servopos or servo, but thats what it says in the manual.

 Hope this helps 

It happens at 4Mhz and 16Mhz which are the only two frequencies that the servo commands work at. I'll post the code so you can see for yourself. Fact is, it wasn't till I used a command that interfered with the timer that it came good making me think it's something to do with the timer reseting after reaching 65535 asumming it's a 16bit timer. (overflowing)

As it happens (coincidence again?) I too am toying with a picaxe and two cheap servos these days (well nights mostly).

Could you post the bare minimum code that still causes jitter? Maybe I can replicate your results. Just to see if we can isolate the cause by the method of elimination. A description or diagram of your electronic setup might also help.

8ik

Wikipedia Affiliate Button

 As I mentioned, I have done as much as possible to eliminate code and power fluctuations. I welcome your scientific aproach and hope you can duplicate the results. Otherwise put a dummy sertxd command into a project that jitters and let me know if it fixes it.

#picaxe 40x1

setfreq em16


let pins=0
low portc 0,5,6,7
servo 7,150
let b0=150
let b1=10

main:
  servopos 7,b0                                                        'Position servo
  readadc 5,b2                                                         'read left ambiant light
  let b2=255-b2
  readadc 6,b3                                                         'read right ambiant light
  let b3=255-b3
 
  let pin2=1                                                             'Turn on IR LEDs
  pause 15                                                              'Allow time for inputs to stabilise
 
  readadc 5,b4                                                         'Front left IR
  let b2=b4-b2       
   
  readadc 6,b5                                                          'Front right IR
  let b3=b5-b3-26                                                     'Calibrate right IR to match left
  let w5=b3*100/121
  let b3=w5+26
 
  let pin2=0                                                              'turn off IR LEDs
  pause 15                                                               'Allow time for inputs to stabilise  
 
  sertxd (#b2," ",#b3," ",#b0,13,10)                           'Transmit data to emulator
   
  if b2<150 or b3<150 then                                        'If Object is within range
    let b2=b2/b1                                                        'scale variable to prevent servo overshoot
    let b3=b3/b1
    let b0=b0+b3-b2 min 75 max 225                          'adjust servo position to track object
    pin0=1                        'turn on object detect LED
  else
    pin0=0                        'turn off object detect LED
    if b0>150 then let b0=b0-1 min 150 end if              're-centre servo if object lost
    if b0<150 then let b0=b0+1 max 150 end if            're-centre servo if object lost
  end if
   
  goto main

heya OB,

 I've run into a similar issue with a setup that I have. I used two different input devices. one being a pot that pretty much no jitter, then I used an ir distance setup, a gp2d12. using the ir setup, I get jitter like crazy. After looking at the debug readings, even when pointing at something stable and not moving, i'd get some fluctions in readings that would cause the servo to jitter. I've tried to smooth it out and it has cleaned up the smaller jitter, but I do get some large fluctuations that I'd want to get rid of as well. I have a plan for that as well but haven't implemented it

I used the same code for both of the input devices. I'll try some work on it to see if I can smooth it out more as I have a couple of ideas.

here is the code that I use.

-----------------------------------------------------------------------------------------

'this is a test for the adc/pot to adjust a servo based on it's motion
symbol smooth_val =4

servo 4, 75
disablebod
'setfreq m8 'this won't work as documented in the pic manual
main:
gosub getadc4pot
'gosub donothingcool
goto main

getadc4pot:
readadc 1,w0
let b6 = w0 'set b6 here or go into an infinite outerloop
'below is the special sauce calc...it works wonders...perfect 75-225 range on adc input.
let w1=w0*10/17+75 'MIN 80 MAX 220
'added min and max for some short throw servos
servopos 4, w1
pause 10
'readadc 1, b6 'might not need this here...we'll see
do until b6 != w0
'gosub donothing 'use this for testing
readadc 1, b6
    {'try smoothing out data
    if b6 > w0 then
    b7 = b6 - w0
    elseif b6 < w0 then
    b7 = w0 - b6
    endif   
    'this should be obvious as to what this does
    if b7 <= smooth_val then
    b6 = w0
    endif
    }
    'the above loops eat a lot of vars...need to clean it up.
'pause 10 'this will cause too much stuttering
'debug b6
'debug causes stuttering as well but I get the readings I need.
loop
return

I just got some sharp sensors the other day and haven't had a chance to play with them yet. It seems your code attempts to ignore readings that jump suddenly from the norm thus filtering wild fluctuations. When I get inputs like this I average the input with the previous 9. This helps the program to filter out fluctuations caused by fluroesent lights without missing out on valid input changes. It all depends on the nature of the fluctuations.
I don't have any fluroresnt ligthts and this seems to help quite a bit. Anyway, this code ignores a set level of variance, 5 seems to be a good number to use. From what I've noted, the noise is from the ir reciever readings. using a pot that doesn't fluctuate gives great results...using a device that tends to have a bit of noise well...you seem to be seeing the result.  Anyway, that was my 2 cents...take it or leave it....