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

Pololu Forum

Micro Maestro on button 0 won't work (Update)


#1

Hi,

i have little problem with my Micro Maestro 6 channel decoder.
Channel 0 is set as input.
If Button pressed, all works fine.
As long as i push the button the servo moves from left to right.
But when the button will be released, it should be 1 time trigger the end loop and go to the main loop.
I really don’t know how to realize that.
Can anybody help me?

#Sequence 0
1 # start with a 1 on the stack
10 1 acceleration
70 1 speed

goto main_loop
 
# 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_closed_10ms
#button_open
  return

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

sub button_open
begin
button
if equals 0 goto end_loop endif
repeat

main_loop:
begin
 1500 3968 frame_1 # Frame 1
 1500 8000 frame_1 # Frame 2
 1500 3968 frame_1 # Frame 3
 1500 8000 frame_1 # Frame 4
 repeat

sub frame_1
wait_for_button_press
  1 servo
  delay
return

end_loop:  
1 # start with a 1 on the stack

begin
dup
while
 1500 4516 frame_2# Frame 5
 1500 7001 frame_2 # Frame 6
 1500 5435 frame_2 # Frame 7
 1500 5964 frame_2 # Frame 8
1 minus
 repeat

sub frame_2
  1 servo
  delay
  return


Best regards

Peter


#2

Hello, Peter.

Thank you for posting your script. Can you describe how you want your code to function? Right now, it looks like it is staying in the main_loop portion of your script and will never reach the end_loop.

Brandon


#3

Hello Brandon,

yes, that’s exactly my problem. I don’t know how to realize my function.
It works fine when i press the button, but i need help to activate the last part when i release the button.
Here it should run for one time the end_loop, and if it’s ready it should be check the button again.

I think my “sub button_open” is completely wrong.
Maybe it have to be integrated in
"sub wait_for_button_closed_10ms"

Best regards

Peter


#4

There are a lot of ways something you could go about doing something like that, but since the Maestro does not support interrupts, you will need to actively poll the button channel to see if the button has been released. One way that might work for you is to put the servo sequence in your end loop into a subroutine instead and add some logic at the end of your frame_1 subroutine to see if the button is still being held. If the button has been released, you can call the subroutine with your ending sequence. I modified your code to do this and copied it below:

10 1 acceleration
70 1 speed

goto main_loop
 
sub button
  0 get_position 500 less_than
  return

sub wait_for_button_press
    wait_for_button_closed_10ms
  return

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

sub frame_1
wait_for_button_press
  1 servo
  delay
button if else end_sequence endif  #if button is released, run end_sequence
return

sub frame_2
  1 servo
  delay
return

main_loop:
begin
 1500 3968 frame_1 # Position 1
 1500 8000 frame_1 # Position 2
repeat

sub end_sequence
 1500 4516 frame_2
 1500 7001 frame_2
 1500 5435 frame_2
 1500 5964 frame_2
return

By the way, since your main loop was looping the same values twice, I simplified it in the script above. If you try that script and it does not function how you want, could you describe what it is doing differently?

Brandon


#5

Hello Brandon,

it works as i expect.
I only can say a big THANK YOU!
I really appreciate your help.

And now, as i see the solution, i understand it.
Sometimes you don’t see the forest because of the trees :wink:

Best regards

Peter


#6

Hello,

there is a small mistake in the program.
It depends on which moment i release the button.
Sometimes the servo stops for a second and will then go to the end_sequence.
Is there a possibility to fix that?

Best regards

Peter


#7

Your frame_1 subroutine has a delay in it, and the script is checking to see if the button is still being pressed at the end of the subroutine, so if you release the button during this delay, the script will not call the end sequence until the delay is over. without this delay, the script would continue and send the next servo position before the servo actually moves to the first position. Since the Maestro scripting does not support interrupts, the script needs to poll the button channel to get the state of it. If you need the script to react when the button is released during a delay, you might try writing a subroutine that loops for a certain amount of time (creating the desired delay) and also checks the button with each loop.

Brandon