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

Pololu Forum

Auto start sequence but retaining existing script!


#1

Hi,

I have a script that moves servos once a button is pressed.
This all works really well.

I made a sequence for a separate servo on a separate channel but when I add this to the script it doesnt auto play.

Is this possible? I’ve seen people starting the sequence with a button but I would like this to auto play.

Thanks in advance.

begin

button_a if 1000 				#button_a = mouth
else 6000
endif
sequence_a

button_b if			            #if button_b is pressed

8000 8000 sequence_b	        	#move servos in one direction

else button_c if			   	 #if button_b is not pressed and button_c is

4000 4000 sequence_b  	    		#move servos in the other direction

 else				        	#if neither button is pressed

 6000 6000 sequence_b  			#move servos to center

endif

endif


repeat

sub button_a
  0 get_position 1 less_than
  return
 
sub button_b
  1 get_position 1 less_than
  return
 
sub button_c
  2 get_position 1 less_than
  return
 
sub sequence_a
 6 servo 10 delay
  return
   
sub sequence_b
  7 servo
  8 servo
  10 delay
return

### Sequence subroutines: ###

# BLINK
sub BLINK
  300 0 0 0 0 0 0 
  6615 0 0 frame_3..11 # Frame 0
  300 3392 frame_9 # Frame 1
  2000 6525 frame_9 # Frame 2
  400 3392 frame_9 # Frame 3
  6000 6466 frame_9 # Frame 4
  300 3392 frame_9 # Frame 5
  8000 6436 frame_9 # Frame 6
  300 3392 frame_9 # Frame 7
  200 6496 frame_9 # Frame 8
  200 3392 frame_9 # Frame 9
  200 delay # Frame 11
  200 6525 frame_9 # Frame 10
  6000 6555 frame_9 # Frame 12
  300 3392 frame_9 # Frame 13
  10000 6496 frame_9 # Frame 14
  300 3392 frame_9 # Frame 15
  20000 6525 frame_9 # Frame 16
  300 3392 frame_9 # Frame 17
  4000 6436 frame_9 # Frame 18
  return

sub frame_3..11
  11 servo
  10 servo
  9 servo
  8 servo
  7 servo
  6 servo
  5 servo
  4 servo
  3 servo
  delay
  return

sub frame_9
  9 servo
  delay
  return

#2

Hello.

The way your current script is set up, it looks like it will run either your sequence_a or sequence_b subroutine based on which buttons are pressed, but it will never execute your BLINK, frame_3..11, or frame_9 subroutines since your main BEGIN/REPEAT loop never calls them.

From your description, it sounds like you might be expecting two scripts to be running simultaneously. Please note that there is no way to do that; only one script can be ran at a time, so you would need to merge both of your scripts into one integrated script.

Brandon


#3

Hi Brandon,

Thanks for the reply.

What would be the easiest way to merge both of the scripts into one please?

Cheers,

Jon


#4

You will need to manually merge them.

If you try merging your scripts and have problems, can you describe how you want the two scripts to work together? If you can explain the kind of behavior are you trying to get, I might have some suggestions.

Brandon


#5

Hi Brandon,

Thanks for your help again.
I would like 3 servos to be operated by a button, which works perfectly thanks to your previous help. This is for operating eyes and a mouth on a puppet!

I would then like one servo to have “random” movement which would be the eyelids opening and closing at timed points without the operator having to use a button. Thats why I thought the sub blink routine would work. I didnt realise I couldnt put them both together :slight_smile:

Any help would be REALLY gratefully received.

Thanks,

Jon


#6

The Maestro does not support interrupts on its inputs, so in order to detect a button press, the Maestro must be actively polling the button channels. It will be tricky to monitor your buttons while the script is running through the sequence for the eyelid movements. Since the DELAY command is blocking, you would probably need to avoid using it. For example, instead of 5000 delay to wait 5 seconds, you could enter a while loop that uses GET_MS to measure how long it has been in the loop and break out after 5 seconds. Then, inside the loop, you can be checking for your button presses, which would interrupt the eyelid sequence if pressed.

Here is an example script that you might find helpful. It uses a nb_delay subroutine I wrote that can be used to do other things (like monitoring buttons) during a delay. It is set up to work like the normal delay command, so it takes 1 argument and delays for the specified time in microseconds. Unfortunately, since it uses the peek command, it will only work with Mini Maestro controllers (and not the Micro Maestro). If you have a Micro Maestro, let me know and I might be able to rework it so it can work with a Micro Maestro.

begin			#main sequence, just moving 1 servo back and forth
  4000 0 servo
    5000 nb_delay	#non-blocking delay subroutine (5000 = 5 seconds)
  8000 0 servo
    5000 nb_delay
repeat

sub nb_delay
  get_ms  		#save the time you entered the while loop
    begin dup get_ms swap minus 0 peek less_than   	#compare that to current time
      while		#this while loop is where you would do your button processing
        button_a if sequence_a endif 	#when button_a is pressed, it will run sequence_a, then return back to this spot
      repeat
  drop drop #empty the values on the stack before returning
return

sub button_a
1 get_position 500 less_than 
return

sub sequence_a	#simple example sequence - this sequence is blocking since it uses the normal delay command
  5000 0 servo
  500 delay
  7000 0 servo
  500 delay
return

Brandon


Servo Sequence triggert by Audio?
#7

Hi Brandon,

Thanks so much for the reply earlier this week, it has helped a lot but I’ve tried everything to try and get my other buttons working.

I have button 0 - which controls the mouth
button 1 makes both eyes look to the right
button 2 makes both eyes look to the left
and when theyre not pressed they return to the centre.

This was working perfectly so thanks for all your previous help.

Now I can get button 0 to operate the mouth and have the blink sequence at the same time but I cant get the other two buttons to work! my stupidity I know!! any help would be really graefully received thanks.

begin #main sequence, just moving eyelids back and forth for a blink

4000 9 servo #servo 9 = Blink
300 nb_delay #non-blocking delay subroutine
8000 9 servo
300 nb_delay
10000 nb_delay
4000 9 servo #servo 9 = Blink
300 nb_delay #non-blocking delay subroutine
8000 9 servo
300 nb_delay
20000 nb_delay

repeat

sub nb_delay
get_ms #save the time you entered the while loop
begin dup get_ms swap minus 0 peek less_than #compare that to current time
while #this while loop is where you would do your button processing
button_a if sequence_a endif #when button_a is pressed, it will run sequence_a, then return back to this spot
repeat
drop drop #empty the values on the stack before returning
return

button_b if #if button_b is pressed

8000 8000 sequence_b #move servos in one direction

else button_c if #if button_b is not pressed and button_c is

4000 4000 sequence_b #move servos in the other direction

else #if neither button is pressed

6000 6000 sequence_b #move servos to center

endif

endif

sub button_a
0 get_position 500 less_than #mouth button
return

sub button_b #eye right button
1 get_position 500 less_than
return

sub button_c #eye left button
2 get_position 500 less_than
return

sub sequence_a #sequence to move mouth
5000 6 servo
200 delay
7000 6 servo
200 delay

return

sub sequence_b #sequence to move both eyes
5000 7 servo
5000 8 servo
300 delay

return


#8

It looks like you have your button_a check in the right place (inside the while loop of the nb_delay subroutine), but your button_b and button_c checks were added after the return command, so the script will never reach them.

You should be able to get it to work by putting your button_b and button_c checks just after your button_a check (and before the repeat command of the while loop). I added some comments to your nb_delay subroutine below to indicate where:

sub nb_delay
  get_ms
   begin dup get_ms swap minus 0 peek less_than
      while
        button_a if sequence_a endif #when button_a is pressed, it will run sequence_a, then return back to this spot
        # place additional button processing code here
        repeat
   drop drop #empty the values on the stack before returning
return

Brandon