Servo Jitter

John West

Senior Member
Is this a somewhat different problem requiring a new thread, or a continuation of the other one with all the same code, etc?
 

alhoop

Member
Is this a somewhat different problem requiring a new thread, or a continuation of the other one with all the same code, etc?
Same problem with different code - the old thread had no code associated with it. I just placed the code there but it didn't percolate to the top on forum.
Al
 

Rick100

Senior Member
Hello alhoop,

I tried your program with an 08m2 v4.A and a parallax servo and got jitter also. I put a disconnect command at the top of the program, because I read on the forum it might help, but it didn't. I don't have a solution to your problem except to rewrite the program using pulsout and pause commands.

Good luck,
Rick
 
Last edited:

John West

Senior Member
OK, alhoop. I understand. Next time just put the code in a new comment on the thread and it will pop up to the top of the thread list. Comment edits don't update that way. As for the problem, I can only agree with Rick100.
 

Rick100

Senior Member
Hello alhoop,

I changed your program to use hardware PWM to drive the servo instead of the servo command. It doesn't jitter anymore. To get the PWM frequency down to 50 Hz, I had to run the processor at 2 MHz. The downside of this approach is you loose resolution, with only only 47 steps from .75 to 2.25 milliseconds. You will have to fine tune the servo positions with your up, dwn, and lev variables. The allowable range for the pwmduty command is approximantly 23 to 70 to keep the servo from hitting the stops. I tested it with a Parallax servo.
I originally used a 4MHz processor clock and 61 Hz PWM frequency. This allowed better resolution. It worked but I read that running the frequency greater than 50 Hz might damage some servos.

Code:
[color=Navy]#picaxe [/color][color=Black]08M2[/color]
[color=Navy]#no_data[/color]
[color=Green]'modified to use hardware pwm for driving servo on C.2(leg 5)
'must run at 2Mhz to get pwm freq low enough
'pauses will have to be divided by 2
'drawback to this method is low resolution
'only 47 steps from .75 to 2.25 milliseconds
'tested on 08M2 and Parallax servo

' 2MHz clock 50Hz pwm / pwmduty range is 23 to 70 (.75 - 2.25 milliseconds high)

'semaphore program
;08m2[/color]

[color=Blue]symbol [/color][color=Purple]cnt [/color][color=DarkCyan]= [/color][color=Purple]b0[/color]
[color=Blue]symbol [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]b1[/color]
[color=Blue]symbol [/color][color=Purple]up [/color][color=DarkCyan]= [/color][color=Purple]b2[/color]
[color=Blue]symbol [/color][color=Purple]lev [/color][color=DarkCyan]= [/color][color=Purple]b3[/color]
[color=Blue]symbol [/color][color=Purple]dwn [/color][color=DarkCyan]= [/color][color=Purple]b4

   [/color][color=Blue]setfreq M2     [/color][color=Green]'for 50 Hz servo PWM

   'servo 2,125
   [/color][color=Blue]pwmout pwmdiv64[/color][color=Black], [/color][color=Blue]C.2[/color][color=Black], [/color][color=Navy]155[/color][color=Black], [/color][color=Navy]23 [/color][color=Green]; 50Hz at 2MHz

   'temp = 125
   [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Navy]38
   [/color][color=Green]'up = 125
   [/color][color=Purple]up[/color][color=DarkCyan]= [/color][color=Navy]38
   [/color][color=Green]'lev = 140
   [/color][color=Purple]lev [/color][color=DarkCyan]= [/color][color=Navy]44
   [/color][color=Green]'dwn = 150
   [/color][color=Purple]dwn [/color][color=DarkCyan]= [/color][color=Navy]47[/color]

[color=Black]start:
   [/color][color=Green];down red
   [/color][color=Blue]if [/color][color=Purple]pinc.4 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then [/color][color=Black]div
   [/color][color=Blue]high c.1
   low c.0
   if [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]dwn [/color][color=Blue]then [/color][color=Black]cont
   [/color][color=Blue]if [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]lev [/color][color=Blue]then 
      for [/color][color=Purple]cnt [/color][color=DarkCyan]= [/color][color=Purple]lev [/color][color=Blue]to [/color][color=Purple]dwn
         [/color][color=Green]'servopos 2,cnt
         [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]cnt
         [/color][color=Blue]pause [/color][color=Navy]100
      [/color][color=Blue]next [/color][color=Purple]cnt
   [/color][color=Blue]else 
      for [/color][color=Purple]cnt [/color][color=DarkCyan]= [/color][color=Purple]up [/color][color=Blue]to [/color][color=Purple]dwn
         [/color][color=Green]'servopos 2,cnt
         [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]cnt
         [/color][color=Blue]pause [/color][color=Navy]100
      [/color][color=Blue]next [/color][color=Purple]cnt
   [/color][color=Blue]endif
   [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]dwn[/color]
[color=Black]cont:
   [/color][color=Green]'servopos 2,dwn
   [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]dwn
   [/color][color=Blue]pause [/color][color=Navy]100
   [/color][color=Blue]goto [/color][color=Black]start[/color]
[color=Green];up[/color]
[color=Black]div:
   [/color][color=Blue]if [/color][color=Purple]pinc.3 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then [/color][color=Black]st
   [/color][color=Blue]high c.1
   high c.0
   if [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]lev [/color][color=Blue]then [/color][color=Black]cont1
   [/color][color=Blue]if [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]up [/color][color=Blue]then
      for [/color][color=Purple]cnt [/color][color=DarkCyan]= [/color][color=Purple]up [/color][color=Blue]to [/color][color=Purple]lev
         [/color][color=Green]'servopos 2,cnt
         [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]cnt
         [/color][color=Blue]pause [/color][color=Navy]100
      [/color][color=Blue]next [/color][color=Purple]cnt
   [/color][color=Blue]else
      for [/color][color=Purple]cnt [/color][color=DarkCyan]= [/color][color=Purple]dwn [/color][color=Blue]to [/color][color=Purple]lev [/color][color=Blue]step [/color][color=DarkCyan]- [/color][color=Navy]1
         [/color][color=Green]'servopos 2,cnt
         [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]cnt
         [/color][color=Blue]pause [/color][color=Navy]100
      [/color][color=Blue]next [/color][color=Purple]cnt
   [/color][color=Blue]endif
   
   [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]lev[/color]
[color=Black]cont1:
   [/color][color=Green]'servopos 2,lev
   [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]lev
   [/color][color=Blue]pause [/color][color=Navy]100
   [/color][color=Blue]goto [/color][color=Black]start
   [/color][color=Green];level yellow[/color]
[color=Black]st: 
   [/color][color=Blue]high c.0[/color][color=Black]:[/color][color=Blue]low c.1
   if [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]up [/color][color=Blue]then [/color][color=Black]cont2
   [/color][color=Blue]if [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]lev [/color][color=Blue]then 
      for [/color][color=Purple]cnt [/color][color=DarkCyan]= [/color][color=Purple]lev [/color][color=Blue]to [/color][color=Purple]up [/color][color=Blue]step [/color][color=DarkCyan]-[/color][color=Navy]1
         [/color][color=Green]'servopos 2,cnt
         [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]cnt
         [/color][color=Blue]pause [/color][color=Navy]100
      [/color][color=Blue]next [/color][color=Purple]cnt
   [/color][color=Blue]else
      for [/color][color=Purple]cnt [/color][color=DarkCyan]= [/color][color=Purple]dwn [/color][color=Blue]to [/color][color=Purple]up [/color][color=Blue]step [/color][color=DarkCyan]- [/color][color=Navy]1
         [/color][color=Green]'servopos 2,cnt
         [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]cnt
         [/color][color=Blue]pause [/color][color=Navy]100
      [/color][color=Blue]next [/color][color=Purple]cnt
   [/color][color=Blue]endif
   [/color][color=Purple]temp [/color][color=DarkCyan]= [/color][color=Purple]up[/color]
[color=Black]cont2:
   [/color][color=Green]'servopos 2,up
   [/color][color=Blue]pwmduty C.2[/color][color=Black],[/color][color=Purple]up
   [/color][color=Blue]pause [/color][color=Navy]100
   [/color][color=Blue]goto [/color][color=Black]start[/color]
Good luck,
Rick
 

alhoop

Member
Thanks Rick:
First, I should have used twitch instead of jitter - the servo would do a quick twitch every 22.67 seconds.
Changing the last servopos to servo in each block of code seems to have fixed the problem, at least I got tired of watching for a twitch.
How long it will last I don't know.
Code:
if pinc.4 = 1 then div
high c.1:low c.0
if temp = dwn then cont
if temp = lev then 
for cnt = lev to dwn
servopos 2,cnt:pause 100:next cnt
else for cnt = up to dwn:servopos 2,cnt
pause 100:next cnt
endif
temp = dwn
cont:
servo 2,dwn   ;this was changed from servopos 2,xxx in each block of code
pause 100
goto start
Al
 

Goeytex

Senior Member
I downloaded the original code and tried it. I also got twitching. However, when I added "disablebod" at the beginning of the program, the twitching went away.

So I wrote a small program to test/verify. All it does is enable the servo, move it to pos 125 and then puts the program into a loop checking an I/O pin. The servo twitches on a predictable basis. Then added "disablebod" and the twitching went away.

A good TEK digital scope shows no drops/anomalies in the supply voltage at the Picaxe supply pin but I will test further.

The Picaxe is supplied by a 150ma LDO with 22uf output cap as well as a 100nF bypass cap. The the servo is supplied by a bench supply set for 6.5 Volts. There is a 220uf cap across the supply leads to the servo.

My guess is that brownout detection may be interfering with the internal servo routine.

EDIT: Correction. I did not wait long enough. Disabling BOD simply changed the frequency of the twitching.
 
Last edited:

Rick100

Senior Member
EDIT: Correction. I did not wait long enough. Disabling BOD simply changed the frequency of the twitching.
When I was testing the original code, the twitch was very unpredictable. I would think it went away, but after a few power cycles it would eventually show up again.
 

Goeytex

Senior Member
The test program twitched like clockwork about 1 time per second. With disablebod added, it became random with time between glitches pf up to 3 minutes. Also adding a pause 10 anywhere in the code after "servo" changed the glitch rate.

It has been my experience that sometimes by adding a pause 10 or other values at certain places in the code, that the glitching is minimized or even disappears.

I have seldom had good / stable results with the Picaxe Servo / servopos commands. There seems to always be a glitch, twitch or a conflict with another command. The most stable results have been with bit-banging using pulsout & pause / pauseus.
 
Top