One Button Script Initiate Sequence, Stop Sequence and Restart Script

I am almost there!

I want to initiate a single button contact to move a servo tilt head from a down (home position) to an up position with ~ 7 second delay and then back to down (home position) and then stop until the button is pushed again. When I initiate a Frame_0, Frame_1 and Frame_2 play sequence using the Maestro Control Center GUI this is exactly what happens each time I select play.

I used Copy Sequence to Script and added a loop for the switch to initiate the sequence. When I select Run Script and push the momentary push button switch the sequence begins but when the tilt head returns to the home position the sequence starts all over again in a loop until I select Stop Script.

I want the sequence to stop with the tilt head at the home position and not begin again until I initiate a switch to start the sequence. See the script below for whatever script needs to be modified or added to accomplish this.

# Sequence 0
begin  
  0 get_position 200 greater_than while #wait in while loop until button connected to channel 0 is pushed
repeat
begin
  500 7616 0 0 0 0 0 
  0 0 0 0 0 frame_1..11 # Frame 0
  8000 3968 frame_1 # Frame 1
  500 7616 frame_1 # Frame 2
repeat

sub frame_1..11
  11 servo
  10 servo
  9 servo
  8 servo
  7 servo
  6 servo
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  delay
  return

sub frame_1
  1 servo
  delay
  return

Hello.

Thank you for posting your script. You are very close to getting the behavior you’re describing! Essentially, right now you have 2 separate BEGIN/REPEAT loops, so once your script exits the button’s WHILE loop, it never returns to it. All you need to do to fix this is move the second BEGIN command before the WHILE loop. So it would look like this:

begin    #this is where begin was moved to

begin  
  0 get_position 200 greater_than while #wait in while loop until button connected to channel 0 is pushed
repeat
	#this is where begin used to be
  500 7616 0 0 0 0 0 
  0 0 0 0 0 frame_1..11 # Frame 0
  8000 3968 frame_1 # Frame 1
  500 7616 frame_1 # Frame 2
repeat

Brandon

Thanks Brandon.

Also modifying the button script exercise in the Pololu Maestro User Guide along with YouTube help from… https://www.youtube.com/watch?v=7nFg1cm-UFs

I was able to get the functionality I was looking for.

Thanks again!

Brandon,
Thanks for all your help.

The following script below does everything we want except we need to delay the servo from activating ~ 1/2 second from the button press. When I add a 500 with space prefix to delay below…

sub frame_1..11
  wait_for_button_press
  1 servo
  delay
  return

I get a 1/2 second delay but the speed of the servo changes to maximum for all subsequent button presses rather than the speed (16) applied under channel settings. Please advise an edit to allow a button press delay without effecting the servo speed.


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.
main_loop:
begin
# Sequence 0

sub Sequence_0
  500 7616 0 0 0 0 0 
  0 0 0 0 0 frame_1..11 # Frame 0
  8000 3968 frame_1 # Frame 1
  500 7616 frame_1 # Frame 2
  repeat

sub frame_1..11
  wait_for_button_press
  1 servo
  delay
  return

sub frame_1
  1 servo
  delay
  return

Hello.

I noticed you started a separate thread asking this exact same question. I have deleted the separate thread since you already have one dedicated to the issue.

There is a larger problem with your code; it looks like you might have edited the frame_1..11 subroutine so it will not work as intended. Right now, it is putting 12 values on the stack, then only using 2 of them. This will end up slowly leaving more values on the stack until it overflows and causes an error. Additionally, because 0 is the last value put on the stack, that’s the value being used for servo 1, which disables the output. When a servo output is disabled, speed and acceleration limits will not work because the Maestro needs to know the current position to calculate the next.

To fix these problems, you should be able to just remove the 0 values after 500 7616

Additionally, it looks like you are not actually using your Sequence_0 subroutine as a subroutine, so you can just remove the sub Sequence_0 so it functions as your main loop instead of a subroutine.

With those changes, your main loop would look like this:

begin
  500 7616 frame_1..11
  8000 3968 frame_1 # Frame 1
  500 7616 frame_1 # Frame 2
  repeat

If you try that and it does not function as intended, can you describe what it is doing and post a copy of your settings file? You can save your settings file by selecting the “Save settings file…” option within the “File” drop-down menu of the Maestro Control Center with the Maestro connected.

Brandon

Thanks Brandon.

Sorry for the double entry.

Do you think adding 500 before the delay line of the script below will add ~ ½ second delay before the start of the sequence?

sub frame_1..11
wait_for_button_press
1 servo
delay
**return**

That delay is being specified by the values being placed on the stack before you call the subroutine. Without any other changes, adding a 500 there will eventually cause errors, and before then likely a lot of intended behavior.

In my previous post, you can see that two values are put on the stack before calling frame_1..11:

begin
  500 7616 frame_1..11
  . . .

Since 500 is being placed on the stack first, 7616 ends up on top of it. So, when we call frame_1..11, and the 1 servo command in it is consuming the top value (7616). This leaves 500 on the stack. Then, frame_1..11 reaches the delay command, and uses the next value on the stack (500). So, you can change the value in that main code to specify how long you want the delay. For example, if you change it to 2000 7616 frame_1..11, it will delay for 2 seconds after commanding the servo to move.

Brandon

Copy.

Thanks Brandon

Ed

1 Like