Servo Jitter

GreatWhiteNorth

New Member
I have a servo moving the head of my robot and when I use the servopos command to sweep the head back and forth, it looks like he's had a bit too much cafine! The servopos command is in a loop. I want to set the head position and then do other stuff (ie. readadc, check distances, issue other servopos commands for the tracks). The more stuff I try to do between servopos commands, the more jitter I get. If I don't to anything else but "pause", ie simple code that just issues servoposes followed by long pauses, the servo has no jitter at all.
I'm using a 28X1 part with firmware v5

Here is the code I'm having problems with.
 

Attachments

alband

Senior Member
What is it that determines the position of the head?
If that is constantly changing by 1 say, it will jitter. Try using something like:
Code:
main: servo,pin,150
label_1: servopos,pin,1st variable
let 2nd variable = 1st variable

label_2: whatever changes variable
if 1st variable > 2nd varibale then
let 3rd variable = 1st variable - 2nd variable
else
let 3rd variable = 2nd variable - 1st variable
endif
if 3rd variable > 5 then label_1
goto label_2
Basically, it is a routine to see how much the variable has changed. In this case, if it has changed more than 5, the head will move to the new position.
 

GreatWhiteNorth

New Member
head movement

The head moves in a fixed cycle (front, left, front, right, ...) based on a countdown. A counter variable is set by each state and is decremented everytime through the main loop. Whenever it reaches zero it goes to
the next state. By changing what this counter is set to and by changing the
delay in the main loop, I can set the time spent in each state.
So, I can have a high count setting and a low loop delay - many iterations per state
Or I can have a low counter setting and a high loop delay - few iterations per state
 

GreatWhiteNorth

New Member
variables affecting servo jitter

I started from a simple program which I thought would exibit servo jitter, but it didn't. So I started adding code and testing at each phase looking for jitter.
I made one change which seemed to introduce alot of jitter. I changed the state counter variable from b0 to b3. Using b0, almost no jitter, using b3, alot of jitter.

Code:
' Head Scanning Code

'Movement duration counter variables
'symbol head_move_counter = b3  ' using b3 I get jitter
symbol head_move_counter = b0   ' using b0 I don't ??


'Output pins
symbol green_eyes = 2
symbol head = 7


'Generic true/false symbols
symbol true = 1
symbol false = 0

'Servo positioning values
symbol centre_position = 150
symbol left_position = 200
symbol right_position = 100

'Head state machine variables
symbol head_transition = b8       'w4
symbol next_head_transition = b9

'Head state machine symbols
symbol head_forward_1         = 0
symbol head_centre_left_move  = 1
symbol head_left_position     = 2
symbol head_left_centre_move  = 3
symbol head_forward_2         = 4
symbol head_centre_right_move = 5
symbol head_right_position    = 6
symbol head_right_centre_move = 7

'Head move and wait times
symbol head_wait_time = 200
symbol head_centre_wait_time = 200
symbol head_move_time = 200

init:
 
 servo head, centre_position
 pause 200
 
 next_head_transition = head_forward_1
 head_move_counter = 0

main:

'scan horizen
if head_move_counter = 0 then   ' time to select next head state
  head_transition = next_head_transition
  select head_transition
    case head_forward_1
      head_move_counter = head_centre_wait_time 
      next_head_transition = head_centre_left_move
 
    case head_centre_left_move
      head_move_counter = head_move_time
     
      servopos head, left_position
      
      next_head_transition = head_left_position
 
    case head_left_position
      head_move_counter = head_wait_time
      next_head_transition = head_left_centre_move
 
    case head_left_centre_move
      head_move_counter = head_move_time
      
      servopos head, centre_position
      
      next_head_transition = head_forward_2
 
    case head_forward_2
      head_move_counter = head_wait_time
      next_head_transition = head_centre_right_move
 
    case head_centre_right_move
      head_move_counter = head_move_time
  
      servopos head, right_position
      
      next_head_transition = head_right_position
 
    case head_right_position
      head_move_counter = head_wait_time
      next_head_transition = head_right_centre_move
 
    case head_right_centre_move
      head_move_counter = head_move_time
      
      servopos head, centre_position
      
      next_head_transition = head_forward_1

   endselect

 endif
 

 head_move_counter = head_move_counter - 1

 pause 5

goto main
Very strange !!
 

GreatWhiteNorth

New Member
b3 causing servo jitter

Here is simple example showing the problem

Code:
'symbol state_counter = b3  ' jitter
symbol state_counter = b0   ' no jitter

init:
servo 7,150
state_counter=0

main:

 if state_counter=0 then
 
   servopos 7, 150
   state_counter = 200
 endif
 
 pause 5
 state_counter = state_counter - 1
 
 goto main
 

hippy

Ex-Staff (retired)
Thanks for the simple example program. I don't have any servos so cannot confirm behaviour but there should obviously be no difference in operation no matter which variable is used.

It is something we will investigate - Is it only b3 which fails or do other variables also cause jitter ?

Also, if you change "state_counter = 200" to "state_counter = 25" and increase "pause 5" to "pause 40", does that improve things ?
 
Last edited:

GreatWhiteNorth

New Member
Some variables cause jitter, others don't, I couldn't see any pattern to it.
The very simple example doesn't show as much jitter difference between b0 and b3 as the "Head Scanning Code" example I submitted.
Using b0 in my original code reduces jitter, but not as much as I had hoped. There seems to be more to this problem than just variables.
This can be seen on a scope, this jitter is seen as flashes (like a lost of signal). Since the servo is "twitching", I suspect a very short pulse is being put on the line.
 

alband

Senior Member
Have you got the servo line tied to ground? - this isn't normally needed but might help.
Also, whilst investigating variables, have you tried using the word variables. Since the number is no more that 200 it shouldn't affect the second byte. As stated the change in variables shouldn't have any affect but since it seems to be, why not try it?

Very odd...:confused:
 

GreatWhiteNorth

New Member
variables affecting jitter

Thanks for the suggestions alband.

I pulled the servo control line to ground with a 10K resistor, but it had
no effect. Changing the output pins had no effect either. I tested the variables up to b9 and the jitter issues follow the word boundaries. This is
what I have found so far:

Code:
'symbol state_counter = b0 'no jitter
'symbol state_counter = b1 'no jitter
'symbol state_counter = b2 ' jitter
'symbol state_counter = b3 ' jitter
'symbol state_counter = b4 ' no jitter
'symbol state_counter = b5 ' no jitter
'symbol state_counter = b6 ' jitter
'symbol state_counter = b7 ' jitter
'symbol state_counter = b8 ' no jitter
symbol state_counter = b9 ' no jitter



symbol head_state = b10            'w3
symbol next_head_state = b11

symbol take_distance_reading = b12 'w4
symbol distance_value = b13

symbol servo_pin = 0
symbol led_pin = 2

symbol head_forward_s = 1
symbol head_move_forward_left_s = 2
symbol head_left_s = 3
symbol head_move_left_forward_s = 4
symbol head_forward_2_s = 5
symbol head_move_forward_right_s = 6
symbol head_right_s = 7
symbol head_move_right_forward_s = 8

init:
servo servo_pin,150
state_counter =0
low led_pin
next_head_state = head_forward_s

main:

 if state_counter=0 then
   head_state = next_head_state
   select head_state
   
   case head_forward_s
     state_counter = 200
     next_head_state = head_move_forward_left_s
     
   case head_move_forward_left_s
     servopos servo_pin, 100
     state_counter = 200
     next_head_state = head_left_s
     
   case head_left_s
     state_counter = 200
     next_head_state = head_move_left_forward_s
     
   case head_move_left_forward_s
     servopos servo_pin, 150
     state_counter = 200
     next_head_state=head_forward_2_s
     
   case head_forward_2_s
     state_counter = 200
     next_head_state = head_move_forward_right_s
     
   case head_move_forward_right_s
     servopos servo_pin, 200
     state_counter = 200
     next_head_state = head_right_s
     
   case head_right_s
     state_counter = 200
     next_head_state = head_move_right_forward_s
     
   case head_move_right_forward_s
     servopos servo_pin, 150
     state_counter = 200
     next_head_state=head_forward_s
     
   endselect
   
 
 endif
 
 take_distance_reading = state_counter//5
 if take_distance_reading = 0 then
    high led_pin
    readadc 0,distance_value
    low led_pin
 endif
 
 state_counter = state_counter - 1
 
 goto main
 

alband

Senior Member
'symbol state_counter = b0 'no jitter
'symbol state_counter = b1 'no jitter
'symbol state_counter = b2 ' jitter
'symbol state_counter = b3 ' jitter
'symbol state_counter = b4 ' no jitter
'symbol state_counter = b5 ' no jitter
'symbol state_counter = b6 ' jitter
'symbol state_counter = b7 ' jitter
'symbol state_counter = b8 ' no jitter
symbol state_counter = b9 ' no jitter
Very interesting that they are in pairs.
I would assume then that w0 = j, w1 = nj, w2 = j, w3 = nj and w4 = j?
 

GreatWhiteNorth

New Member
odd words causing jitter

Actually, w0 has no jitter and all the odd numbered words I've tested cause jitter. I modified my original program to only use byte variables from even numbered words and I don't get any jitter anymore!

Quite amazing!

example code snippet for the byte variables
Code:
'Movement duration counter variables
symbol head_move_counter = b0  'w0
symbol track_move_counter = b1 'w0

'Movement direction variable
symbol direction = b4 'w2

'Servo speed variables
symbol left_track_speed = b5   'w2
symbol right_track_speed = b8  'w4

'Head state machine variables
symbol head_transition = b9       'w4
symbol next_head_transition = b12  'w6

'Object distance variables
symbol object_distance_left = b13   'w6
symbol object_distance_centre = b16 'w8

symbol object_distance_right = b17   'w8
symbol close_objects = b20   'w10

symbol stop_and_scan = b21   'w10

symbol head_check_for_objects = b24 '12
 

alband

Senior Member
Ok, yeah, that's what I meant to write but I got mixed up.
That is very weird.

This is definitely one for:

Technical!...
 

GreatWhiteNorth

New Member
prizes for finding bugs

If this is a real bug, do I get a prize for finding it? :)
(and for coming up with a workaround!)

Now back to my regular scheduled programming
 

hippy

Ex-Staff (retired)
Thanks for testing. No prizes I'm afraid but congratulations on the analysis and the workround.

I cannot confirm what the issue is but it has given a valuable indicator of what the underlying problem may be which will help us investigating this further. Many thanks.
 

lbenson

Senior Member
Good catch, eclectic. Makes one wonder if the jitter would occur with the same program on an 18X part.
 

GreatWhiteNorth

New Member
So what is the final word on this issue? What version will it be fixed in?
Is it all the odd numbered words that cause the jitter? I'm starting to
run out of variables. I could try them myself, but if you already have the answer, it would save some time.


Thanks.
 

GreatWhiteNorth

New Member
No I haven't, they look like an improvement, maybe I'll get myself some.
Thanks for the pointer to the #7 post, that seems to be my problem.
 

Technical

Technical Support
Staff member
The latest 28X1 firmware also has this odd word issue corrected, but the 28X2 would probably be a better choice if buying a new chip.
 
Top