Stop Servo after sequenze

Hi guys,

i need some help please. I am starting a sequenze with a button. When the sequenze ends i hear the servo still spinning and getting warm. Is there a possibility to stop the servo after the button push and the sequence ends, and start the servo again after the second button push to go on with another sequenze?

And a little porblem on top. Sometimes when i push the button, it takes so mich time to start the sequenze sometimes it doesnt start. I am absoultley new in this Pololu bisiness :smile: .

Here is my code and i am so thankful for any help.

goto main_loop    # Run the main loop when the script starts (see below).
 
# This subroutine returns 1 if the button is pressed, 0 otherwise.
# To convert the input value (0-1023) to a digital value (0 or 1) representing
# the state of the button, we make a comparison to an arbitrary threshold (500).
# This subroutine puts a logical value of 1 or a 0 on the stack, depending
# on whether the button is pressed or not.
sub button
  0 get_position 500 less_than
  return
 
# This subroutine uses the BUTTON subroutine above to wait for a button press,
# including a small delay to eliminate noise or bounces on the input.
sub wait_for_button_press
  wait_for_button_open_10ms
  wait_for_button_closed_10ms
  return
 
# Wait for the button to be NOT pressed for at least 10 ms.
sub wait_for_button_open_10ms
  get_ms # put the current time on the stack
  begin
    # reset the time on the stack if it is pressed
    button
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if drop return endif
    endif
  repeat
 
# Wait for the button to be pressed for at least 10 ms.
sub wait_for_button_closed_10ms
  get_ms
  begin
    # reset the time on the stack if it is not pressed
    button
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat
 
# An example of how to use wait_for_button_press is shown below:
 
# Uses WAIT_FOR_BUTTON_PRESS to allow a user to step through
# a sequence of positions on servo 1.2.3.4.5

main_loop:
begin
# Sequence 0   
wait_for_button_press

sub Sequence_0
  500 0 0 3968 8000 3200 frame_1..5 # Frame 0
  500 5824 frame_5 # Frame 1
  500 9216 2624 frame_3_4 # Frame 2
  repeat

sub frame_1..5
wait_for_button_press
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  delay
  return

sub frame_5
wait_for_button_press
  5 servo
  delay
  return

sub frame_3_4
wait_for_button_press
  4 servo
  3 servo
  delay
  return

Hello.

It isn’t quite clear to me how you want the sequence to work since your main loop is not complete. For example, as it is now when you main loop starts, it will wait for a button press before continuing into the definition of your Sequence_0 subroutine, which isn’t how subroutines are intended to be used. Also, it looks like you added wait_for_button_presscommands to the start of each frame as well, so right now your code requires 2 button presses before your sequence actually starts, and a button press between each movement.

You might try changing your main loop to something like this and seeing if it helps:

main_loop:
begin
 Sequence_0   
repeat

Also, you will need to change the repeat at the end of your Sequence_0 subroutine to a return (as shown below) or you will get an error:

sub Sequence_0
  500 0 0 3968 8000 3200 frame_1..5 # Frame 0
  500 5824 frame_5 # Frame 1
  500 9216 2624 frame_3_4 # Frame 2
  return

As far as your servos buzzing and getting warm, you can try turning off the servo signals while you’re waiting for the button to be pressed; for some servos this will cause them to stop holding their position. However, please note that some digital servos will continue holding the last commanded position even after the signal stops. You can turn off the signals for a particular channel by setting the target to 0. It looks like you are using servo channels 1-5, so that would look like this:

0 1 servo
0 2 servo
0 3 servo
0 4 servo
0 5 servo

A good place to add those lines of code would probably be the beginning of the wait_for_button_press subroutine, like this:

sub wait_for_button_press

  0 1 servo
  0 2 servo
  0 3 servo
  0 4 servo
  0 5 servo

  wait_for_button_open_10ms
  wait_for_button_closed_10ms
  return

Brandon

Hi Brandon,

thank you for your help. As I mentioned, I’m completely new to this field :sweat_smile:. I got the code from a YouTuber who created a simple tutorial for triggering the sequence with a button press. However, I’ve already noticed that the code doesn’t quite work as shown in the video.

I will try out your modified code directly, and what you’re saying sounds plausible :stuck_out_tongue_winking_eye:.

I have one more question: I’m using 3 servo motors, but I need Servo 5 to start first after pressing the button, then Servo 4 and 5 should start simultaneously with a 1-second delay. If I press the button again, Servo 4 and 5 should first react, return to the original position, and then Servo 5 should start with a 1-second delay.

I hope it’s clear what I mean.

Thanks again for the help.

The code you posted (even with the modifications I suggested) won’t do what you described; however, the sequence you described is not entirely clear to me; you only mention 2 servos but you say you have 3, so I suspect you have some typos somewhere. If you describe in more detail how you want it to work, I can try to help you get that behavior.

Brandon

Hi Brandon,

Actually, I thought that the code should be very simple.

Channel 0 is the button; then I use 3 servos, Channel 5, 4, and 3.
When pressing the button, Servo Channel 5 should first react and move to a position, then with a delay, Servo Channel 4+3 should move simultaneously.

If I press the button again, Servo Channel 5 should first return to the initial position, and with a short delay, Servo Channel 4+3 should simultaneously return to the initial position.

Maybe the pictures will help to understand it better. What I wanna to do ist only to press the button, open the helmet, press the button again close the helmet.

Thanks fpr your help

02_image1
01_image0

Thank you for the clarification (your previous post never mentioned servo 3). That looks like a fun project!

To get the kind of behavior your described, I suggest removing the wait_for_button_press commands inside of your subroutines, then rewriting your main_loop so it looks something like this:

main_loop:
  #initialize servos
  500 0 0 3968 8000 3200 frame_1..5 # Frame 0
begin
  #when button is pressed move servo 5, then move 3 and 4
  wait_for_button_press
  1000 5824 frame_5
  500 9216 2624 frame_3_4 

  #when button is pressed again move servo 3 adn 4, then move 5
  wait_for_button_press
  1000 3968 8000 frame_3_4 
  500 3200 frame_5
repeat

Please note that the 1000 in the lines after the wait_for_button_press commands is specifying how long to wait between moving the servos in milliseconds.

By the way, I noticed that one of your position values is very low at only 2624, which corresponds to 656μs. This might be okay for some servos, but for reference, standard hobby RC signals generally use a pulse width between 1000μs and 2000μs, and it is possible to cause some servos to damage themselves by sending it a position outside of its physical range. Unless you adjusted the Min and Max settings in the “Channel Settings” tab of the Maestro Control Center, the Maestro will limit the range to the standard range, but since you mentioned that your servo sometimes sounds like it’s still buzzing and getting warm I thought it was worth mentioning. Since it looks like you aren’t using the full range of the servo, you might consider adjusting the servo horn so the range you are using is within the standard pulse width range mentioned above.

Brandon

Hi Brandon,

thank you so much for your help this works perfect for me now!!!

I´ve changed the code a bit, now its doing exactly what i want.

goto main_loop    # Run the main loop when the script starts (see below).
 
# This subroutine returns 1 if the button is pressed, 0 otherwise.
# To convert the input value (0-1023) to a digital value (0 or 1) representing
# the state of the button, we make a comparison to an arbitrary threshold (500).
# This subroutine puts a logical value of 1 or a 0 on the stack, depending
# on whether the button is pressed or not.
sub button
  0 get_position 500 less_than
  return
 
# This subroutine uses the BUTTON subroutine above to wait for a button press,
# including a small delay to eliminate noise or bounces on the input.
sub wait_for_button_press

   0 5 servo
   0 4 servo
   0 3 servo
      

  wait_for_button_open_10ms
  wait_for_button_closed_10ms
  return
 
# Wait for the button to be NOT pressed for at least 10 ms.
sub wait_for_button_open_10ms
  get_ms # put the current time on the stack
  begin
    # reset the time on the stack if it is pressed
    button
    if
      drop get_ms
    else
      get_ms over minus 10 greater_than
      if drop return endif
    endif
  repeat
 
# Wait for the button to be pressed for at least 10 ms.
sub wait_for_button_closed_10ms
  get_ms
  begin
    # reset the time on the stack if it is not pressed
    button
    if
      get_ms over minus 10 greater_than
      if drop return endif
    else
      drop get_ms
    endif
  repeat
 
# An example of how to use wait_for_button_press is shown below:
 
# Uses WAIT_FOR_BUTTON_PRESS to allow a user to step through
# a sequence of positions on servo 1.2.3.4.5

main_loop:

500 0 0 8000 3968 8000 frame_1..5 # Frame 0

begin
# Sequence 0   


sub Sequence_0
  wait_for_button_press

  500 3968 8000 frame_3_4 # Frame 1
  500 2432 frame_5 # Frame 2

 #when button is pressed again move servo 3 adn 4, then move 5
  wait_for_button_press
  500 8000 3968 frame_3_4 
  500 8000 frame_5

  repeat

sub frame_1..5
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  delay
  return

sub frame_3_4
  4 servo
  3 servo
  delay
  return

sub frame_5
  5 servo
  delay
  return
1 Like