Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

Stopping a sequence when letting go of button?


#1

I’m a prop builder at a theater and I am using a micro Maestro to control the hands on a clock. I’ve been able to use the button example to easily create a sequence that moves the minute hand, delays 60 seconds, moves hand, delays, etc. This sequence is 8 minutes long.

My problem is that during rehearsal I will need to stop the sequence in the middle and start it over from the beginning. I’ve spent quite a bit of time reading this forum and I have two ideas to make this happen but I haven’t been able to quit figure out how. The two ideas I have are:

  1. Script it so that the button must be held down to continue the sequence
  2. Use a second input that must remain “on” for the sequence to continue.

Can someone help guide me in the right direction?


#2

This is the script that I’ve been using.

`# When the Maestro script is not doing anything else,
# this loop will listen for button presses.  When a button
# is pressed it runs the corresponding sequence.
begin
  buttonA if sequenceA endif
  
  repeat
# This subroutine listens for the button to be pushed
#
sub buttonA
  3 get_position 500 less_than
  return


# This is the subroutine that runs the minute hand. 
sub sequenceA
    3308 0 servo
  1 delay_minutes  
    3200 0 servo
  1 delay_minutes
    3024 0 servo 
  1 delay_minutes
    2908 0 servo
  1 delay_minutes
    2760 0 servo
  1 delay_minutes
    2620 0 servo
  1 delay_minutes
    2484 0 servo 
  1 delay_minutes
    2352 0 servo 
  return

# delay by a specified number of seconds, up to 65535 s
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
 # delay by a specified number of minutes, up to 65535 min
sub delay_minutes
  begin dup while
    1 minus 60 delay_seconds # subtract one and delay 1min
  repeat
  drop return                # remove the 0 from the stack and return

`

#3

It sounds like the behavior you want is basically to reset your script with a button press. The simplest way to accomplish this is probably to reset the Maestro by connecting a button between the board reset pin (!RST) and GND. The !RST pin is connected to VDD on the Maestro via a pull-up resistor, so unlike adding a button or switch to the Maestro’s channels, you should not need to add any other components to your circuit to get the button or switch to work.

If that does not sound like it would work for you, or if you have trouble implementing it, you can post about it here and I would be happy to help.

-Jon


#4

Thanks for the quick reply. Your suggested method is actually what I used for the show last year. The problem it gave me was that when it got reset the servos snapped immediately into position and this motion was really rough on the mechanism.


#5

How about like this:

while (button is pressed)
{
  my_sequence();
 get button();
}

So if you get button off loop terminates, leaving motors
in last position.

Hope it helps.


#6

Without restructuring your code, one thing you might try to do is to check for a second button after each minute long delay. For example, you can set that button up on channel four with a separate subroutine like:

sub buttonB
  4 get_position 500 less_than
  return

and add the following conditional to sequenceA after every instance of 1 delay_minutes:

buttonB if 3308 0 servo
  return endif 

This sets up an environment where you can manually start your sequence over as long as the second input on channel four is active at the end of your minute long delays (i.e. after the servo has been at its position for an entire minute, but before the servo has started moving to a new position).

You can also extend this to check every second by adding the buttonB conditional after the 1 minus 1000 delay in your delay_seconds subroutine, except you also need to add a DROP command. For example:

buttonB if 3308 0 servo
  drop return endif 

-Jon


#7

Thanks Jon, this is exactly the solution that I needed. I’ve implemented some changes but I’m a little confused about extending it to check every second. I tried to use what you suggested but I’m having difficulties.

# delay by a specified number of seconds, up to 65535 s
sub delay_seconds
  begin dup while      # check if the count has reached zero
    1 minus 1000 delay # subtract one and delay 1s
  buttonB if 3308 0 servo 
  drop return endif  
repeat

I’m getting very weird results when trying this. The one minute counter is stuck at 59 and the servo is setting through it’s sequence very rapidly. Any ideas what I am doing wrong? I feel like it’s probably something simple I am overlooking.

Thanks
Grant


#8

Nevermind. I missed a line. It’s working perfectly now. Thanks again, Jon for pointing me in the right direction.