I have the following script that runs fine but I would like it to not run when the button is pressed momentarily and only run when the button is pressed for a longer period of time (i.e. 3 seconds). Any help would be appreciated.
begin
0 get_position #Check state of switch, number is the channel the switch is on
1 less_than #Check if switch is held, number is the amount of time the switch must be held before moving servo
if
sequence_0 #Run the move servo subroutine
endif
0 get_position #Check state of switch, 0 is the channel the switch is on
1 greater_than #Check if switch is released, number is the amount of time the switch must be released before moving servo
if
endif
repeat
return
### Sequence subroutines: ###
# Sequence 0
sub Sequence_0
500 5940 0 0 5800 0 frame_1..5 # Frame 0
1300 6400 6400 frame_1_4 # Frame 1
1300 delay # Frame 2
1300 delay # Frame 3
1300 delay # Frame 4
1300 delay # Frame 5
1300 delay # Frame 6
1300 delay # Frame 7
1300 5940 5800 frame_1_4 # Frame 8
return
sub frame_1..5
5 servo
4 servo
3 servo
2 servo
1 servo
delay
return
sub frame_1_4
4 servo
1 servo
delay
return
6500 4 servo
50 delay # added delay for 50 miliseconds
3000 4 servo
100 delay # added delay for 100 miliseconds
return
There are various ways to implement the type of feature you described. I would recommend merging the script example under the “Using a button or switch to control servos” heading in the “Example Scripts” section of the Maestro Servo Controller User’s Guide with your code and extend the button hold time from 10 ms to 3000 ms (3 seconds) in the wait_for_button_closed_10ms subroutine by changing:
get_ms over minus 10 greater_than
to
get_ms over minus 3000 greater_than
If you have trouble merging the two codes, you can post your modified script, and I would be happy to take a look.
By the way, I noticed in your script there are a few lines code that are incomplete. The code lines I am referring to are:
Thank you Amanda. I tried merging my code with the one in the example scripts last night. I haven’t been to get it to work yet but I will play with it some more this weekend. I’ll post my modified script if I’m still having troubles.
One question, do I get rid of my code I was using previously to monitor the button and replace it with the button monitoring code from the example script or do I use both codes?
I think I picked up the return from another example script and assumed I needed it. Good to know I don’t.
The last bit of code actually controls an LED output I assigned to servo 4.
So I have the code working so it only runs my script when I hold the button for 3 seconds but now it keeps running my code in a loop. I would like it to stop the script when the button is open. Here is the merged script.
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_3000ms
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 3000 ms.
sub wait_for_button_closed_3000ms
get_ms
begin
# reset the time on the stack if it is not pressed
button
if
get_ms over minus 3000 greater_than
if drop return endif
else
drop get_ms
endif
repeat
# Uses WAIT_FOR_BUTTON_PRESS to allow sequence_0 to run.
# Sequence 0
sub Sequence_0
begin
500 5940 0 0 5800 0 frame_1..5 # Frame 0
1300 6400 6400 frame_1_4 # Frame 1
1300 delay # Frame 2
1300 delay # Frame 3
1300 delay # Frame 4
1300 delay # Frame 5
1300 delay # Frame 6
1300 delay # Frame 7
1300 5940 5800 frame_1_4 # Frame 8
repeat
sub frame_1..5
5 servo
4 servo
3 servo
2 servo
1 servo
delay
return
main_loop:
sub frame
wait_for_button_press
sequence_0
sub frame_1_4
4 servo
1 servo
delay
return
Looking at your recent script, you have a begin/repeat block within your Sequence_0 subroutine, which is causing the program to repeat. One way to fix this problem is to remove the begin/repeat lines in Sequence_0 and use return instead (at the end of that subroutine). Then add begin/repeat lines around the code under main_loop. Like so:
Using return at the end of the Sequence_0 subroutine tells the program to return back to the point where the subroutine was last called, which prevents the program from falling through and executing frame_1..5. By encapsulating wait_for_button_press and Sequence_0 in a begin/repeat block under main_loop, the program will continually cycle between waiting for a button press (lasting for at least 3 seconds) and executing the movement sequence.
Since it seems that you are new to using the Maestro Scripting Language, I strongly recommend reading the “Command Reference” section of the Maestro Servo Controller User’s Guide to get a better understanding of the commands.
By the way, you mentioned in your previous post that the last bit of code actually controls an LED output that you assigned to servo 4, but in your original script, it does not look like the program will ever reach that section of code. If you can tell me what you are using the LED for, I might be able to offer suggestions on how you can implement that feature into your script.