Maestro Control Center Scripting Issues (adding more Servos)

Okay this one has got me stumped I have spent a better part of a day trying to get my script to work on multiply servos to no avail. I can run servo 0 no problem it does exactly what I want it to do. I need to run 6 servos using the the same script 0-5. Any help would be greatly appreciated

200
begin dup while
  3oclock
  1oclock1
  12oclock1
  11oclock
  10oclock
  11oclock
  12oclock2
  1oclock2
  all_frames
  1 minus
repeat

sub 3oclock # was 99-96 ms
99 96 99 96 99 96 99 96
all_frames
return

sub 1oclock1 #was 80-77 ms
80 77 80 77 80 77 80 77
all_frames
return

sub 1oclock2 #was 80-77 ms
77 80 77 80 77 80 77 80
all_frames
return

sub 12oclock1 #full extension counterclockwise 55-65 ms
55 65  
all_frames
return

sub 12oclock2 #full extension counterclockwise 55-65 ms
70 65
all_frames
return

sub 11oclock
37 40 37 40 37 40 37 40
all_frames
return

sub 10oclock
20 23 20 23 20 23 20 23
all_frames
return

#begin 
 #neutral
 #drop
 #quit
#repeat



#sub frame_1 #slow speed
  #10 1 acceleration
  #100 1 speed
  #100 times # times the servo positioning
  #1 servo
  #1 delay_seconds
  #moving_wait
  #return

#sub frame_2
  #8 1 acceleration
  #80 1 speed
  #1000 times
  #1 servo
  #3 delay_seconds
  #moving_wait
  #return

#sub delay_seconds
  #begin dup while      # check if the count has reached zero
    #1 minus 1000 delay # subtract one and delay 1s
  #repeat
  #drop return          # remove the 0 from the stack and return

sub moving_wait
  begin
    get_moving_state
  while
    # wait until it is no longer moving
  repeat
  return

sub neutral
    6000 1 servo
    return

sub all_frames
  begin depth
  1 greater_than
  while
    servo0
  repeat
  return
  
sub servo0
    5 1 acceleration
    60 1 speed
    100 times
    0 servo 
    200 delay
    moving_wait
  return

sub servo1
    5 1 acceleration
    60 1 speed
    100 times
    1 servo 
    200 delay
    moving_wait
  return

sub servo2
    5 1 acceleration
    60 1 speed
    100 times
    2 servo 
    200 delay
    moving_wait
  return

sub servo3
    5 1 acceleration
    60 1 speed
    100 times
    3 servo 
    200 delay
    moving_wait
  return

sub servo4
    5 1 acceleration
    60 1 speed
    100 times
    4 servo 
    200 delay
    moving_wait
  return

sub servo5
    5 1 acceleration
    60 1 speed
    100 times
    5 servo 
    200 delay
    moving_wait
  return

Hello.

It is not entirely clear to me how you want your code to work, but it looks like right now your all_frames subroutine simply calls your servo0 subroutine in a loop until the stack is left with only 1 value, so your other servo# subroutines never get called.

I suspect you want the servo# subroutines to get called in turn, but it looks like you are always either putting 8 numbers or 2 numbers on the stack before calling all_frames, and you didn’t describe how you want those values to be used with 6 servos. If my observation above does not help get you on the right track, could you explain in more detail what you want to happen with the values on stack when you call all_frames?

Brandon

HI Brandon

I would like to have the sub all_frames call all the servos to run all the previous subs at the same time. I have written before the all_frames sub. I have tried writing as follow bellow but isnt working correctly it will do 1 of the 2 number associated with each servo.

Thanks
Too Tall

sub all_frames
  begin depth
  1 greater_than
  while
    servo0
    servo1
    servo2
    servo3
    servo4
  repeat
  return

As I mentioned before, it looks like you are putting 8 or 2 numbers on the stack before calling all_frames, but it is not set to handle either of those cases. In the modified all_frames subroutine you posted, if you only want the while loop to run through once, it can only support 5 values (one for each of your servo# subroutines.

It is not clear to me what you want each of the values you are putting on the stack to do, since you have 8 of them, but only 6 servos. Could you explain in detail what you want each of the values you are putting on the stack to do? For example, what do you want to happen when you call your 3oclock subroutine (copied below for reference)?

sub 3oclock # was 99-96 ms
  99 96 99 96 99 96 99 96
  all_frames
return

And what do you want it to do when you instead only put 2 values on the stack, such as with your 12oclock1 subroutine?

sub 12oclock1 #full extension counterclockwise 55-65 ms
  55 65  
  all_frames
return

Brandon

the 12oclock and 3oclock etc subframes are the positions that I want all the servo to travel to simultaneously I am trying to get the all_frames to do is basically clone servo0 to the remaining servos (1-5) because I want all 6 servos to run the exact same routine in a loop. Hope that has clarified what I am trying to do.

Update

I took a moment and rewrote the entire script and I am now getting the desired response out of all six servos. If you could take a second and see if there is some other way to write it to reduce the size I would be much appreciated.

200
begin dup while
  3oclock
  1oclock1
  12oclock1
  11oclock
  10oclock
  11oclock
  12oclock2
  1oclock2
  1 minus
repeat

sub 3oclock #9900-9600 ms
99 servo0 99 servo1 99 servo2 99 servo3 99 servo4 99 servo5
96 servo0 96 servo1 96 servo2 96 servo3 96 servo4 96 servo5
moving_wait
return

sub 1oclock1 #8000-7700 ms
80 servo0 80 servo1 80 servo2 80 servo3 80 servo4 80 servo5
77 servo0 77 servo1 77 servo2 77 servo3 77 servo4 77 servo5
moving_wait
return

sub 1oclock2 #8000-7700 ms
77 servo0 77 servo1 77 servo2 77 servo3 77 servo4 77 servo5
80 servo0 80 servo1 80 servo2 80 servo3 80 servo4 80 servo5
moving_wait
return

sub 12oclock1 #full extension counterclockwise 55-65 ms
55 servo0 55 servo1 55 servo2 55 servo3 55 servo4 55 servo5
65 servo0 65 servo1 65 servo2 65 servo3 65 servo4 65 servo5
moving_wait
return

sub 12oclock2 #full extension counterclockwise 55-65 ms
70 servo0 70 servo1 70 servo2 70 servo3 70 servo4 70 servo5
65 servo0 65 servo1 65 servo2 65 servo3 65 servo4 65 servo5
moving_wait
return

sub 11oclock
37 servo0 37 servo1 37 servo2 37 servo3 37 servo4 37 servo5
40 servo0 40 servo1 40 servo2 40 servo3 40 servo4 40 servo5 
moving_wait
return

sub 10oclock
20 servo0 20 servo1 20 servo2 20 servo3 20 servo4 20 servo5
23 servo0 23 servo1 23 servo2 23 servo3 23 servo4 23 servo5
moving_wait
return

#begin 
 #neutral
 #drop
 #quit
#repeat

sub moving_wait
  begin
    get_moving_state
  while
    # wait until it is no longer moving
  repeat
  return

sub neutral
    6000 1 servo
    return
  
sub servo0
    5 0 acceleration
    60 0 speed
    100 times
    0 servo 
    200 delay
  return

sub servo1
    5 1 acceleration
    60 1 speed
    100 times
    1 servo 
    200 delay
  return

sub servo2
    5 2 acceleration
    60 2 speed
    100 times
    2 servo 
    200 delay
  return

sub servo3
    5 3 acceleration
    60 3 speed
    100 times
    3 servo 
    200 delay
  return

sub servo4
    5 4 acceleration
    60 4 speed
    100 times
    4 servo 
    200 delay
  return

sub servo5
    5 5 acceleration
    60 5 speed
    100 times
    5 servo 
    200 delay
  return

Thanks
Too Tall

I am glad to hear you got it working how you wanted!

There are probably a lot of ways you could make it simpler and reduce the size of the script. The main thing to look for is when code is repeated and if you can better utilize subroutines instead, or if code is repeated that does not need to be.

For example, it does not look like you are changing the speed and acceleration settings throughout the script, so you could just configure the desired settings in the “Channel Settings” tab, and the Maestro will use those when it boots up. If you want it in the script for redundancy, you could still remove the speed and acceleration commands from your individual subroutines and just set the speed and acceleration to the beginning of your script (before your main loop), like this:

#set the speed and acceleration of all 6 servos to 60 and 5 respectively
0 begin dup 6 less_than while
  dup dup 
  60 swap speed
  5 swap acceleration
  1 plus
repeat
drop

begin
  # main loop
repeat

Additionally, since you want to use the same position for all of your servos, you can have a single subroutine that takes the target position and applies it to all of the servo channels, instead of having a separate subroutine for each channel. For example, something like this:

sub set_servos
  100 times
  0 begin dup 6 less_than while 
    over over servo 
    1 plus
    #200 delay
  repeat
  moving_wait
  drop drop
return

So, 60 set_servos will set the target position of all 6 servo channels to 6000 quarter-microseconds. In your updated script, there is still a 200 ms delay between setting the position of each servo. If you really want that delay instead of setting them all at the same time like you described, then you can uncomment the 200 delay line of code by removing the #.

Using that set_servos subroutine will allow you to simplify your other subroutines. For example, 3oclock would look like this:

sub 3oclock
    99 set_servos
    96 set_servos
return

Brandon

2 Likes