Hello,
I am new to this and can not seem to figure out how to get the script to work for my purpose.
I got it partialy working with one servo and one button and it does what I want.
Now I want to add 2 extra servo’s and buttons.
But the second one does not work.
It seems dat the end of the script is missing something to make it work.
I searched other threads, the example scripts and the manual.
Below my script that I used and are tweaking.
Any help would really help.
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_a
6 get_position 500 less_than
return
sub button_b
7 get_position 500 less_than
return
sub button_c
8 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_a
wait_for_button_open_10ms_a
wait_for_button_closed_10ms_a
return
sub wait_for_button_press_b
wait_for_button_open_10ms_b
wait_for_button_closed_10ms_b
return
# Wait for the button to be NOT pressed for at least 10 ms.
sub wait_for_button_open_10ms_a
get_ms # put the current time on the stack
begin
# reset the time on the stack if it is pressed
button_a
if
drop get_ms
else
get_ms over minus 10 greater_than
if drop return endif
endif
repeat
# Wait for the button to be NOT pressed for at least 10 ms.
sub wait_for_button_open_10ms_b
get_ms # put the current time on the stack
begin
# reset the time on the stack if it is pressed
button_b
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_a
get_ms
begin
# reset the time on the stack if it is not pressed
button_a
if
get_ms over minus 10 greater_than
if drop return endif
else
drop get_ms
endif
repeat
# Wait for the button to be pressed for at least 10 ms.
sub wait_for_button_closed_10ms_b
get_ms
begin
# reset the time on the stack if it is not pressed
button_b
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
6000 frame_1
4000 frame_1
repeat
begin
6000 frame_2
4000 frame_2
repeat
sub frame_1
wait_for_button_press_a
1 servo
return
sub frame_2
wait_for_button_press_b
2 servo
return
Hello.
There could be a couple problems with the way your script is written depending on how you want the system to behave. The biggest problem (and the reason why the second button doesn’t work) is that there are two completely isolated ‘BEGIN/REPEAT’ loops. Once the script enters the first one, it will never reach the second one:
main_loop:
begin #Start of loop
6000 frame_1
4000 frame_1
repeat #Returns to start of loop
begin #This BEGIN/REPEAT loop will never be reached
6000 frame_2
4000 frame_2
repeat
One way to fix this is to put them all in a single BEGIN/REPEAT
loop:
begin
6000 frame_1
4000 frame_1
6000 frame_2
4000 frame_2
repeat
However, please note that your ‘wait_for_button_press_a’ and ‘wait_for_button_press_b’ subroutines are blocking code, so the script will be stuck waiting for those buttons when it enters them. This means that your script will require the user to push the buttons in alternating orders to continue. If that is not how you want the system to work, you can post more details about what you are trying to do and I would be glad to give you suggestions.
Brandon
Hello Brandon,
I tried the second portion of the script you provided and does not give me the correct behavior.
That creates behavior that the button_b can only be used if button_a is used two times.
I need every button to behave the same and independent from each other.
Every button must go to the servo first position on one touch and the servo second position on the second touch, and back again to first position on the touch after that.
I want to use it to open/close three doors.
Addional it would be nice to light up a led if the servo is second position.
I hope I explained it clearly
You will need to change how your code works to get that kind of behavior. As I mentioned before the wait_for_button_press
subroutines are blocking, so you will not be able to use them as-is to have any of the buttons work at all times.
One way around this is to use the method shown in the “Using multiple buttons or switches to control servos” example found in the “Example Scripts” section of the Maestro user’s guide. However, note that this example dose not do any debouncing for the buttons, so it might trigger multiple times when you press the button once. A simple (but not very elegant) way to solve this is to add a small delay before returning from your subroutine. Also, since you want the same button to do different things each time it is pressed, you will need to add some separate logic for that. One way to do it would be to have your subroutine check what position the servo is in before deciding what the new position should be. For example, if you want a servo on channel 0 to swap between 1000us and 2000us, it might look like this:
sub moveServo0
0 get_position #get the position of the servo
6000 less_than if #if it is less than 6000 (1500us)
8000 0 servo #set the position to 8000 (2000us)
else #otherwise,
4000 0 servo #set the position to 4000 (1000us)
endif
500 delay #small delay to prevent debouncing problems
return
If you have enough Maestro channels still available, you could use them to control LEDs. You would need a separate channel for each of your 3 LEDs to be controlled independently. Instructions for connecting LEDs can be found in the “LED” section of the “Attaching Servos and Peripherals” section of the user’s guide. Once the channels are configured as outputs and the LEDs are connected, you can add commands to toggle them inside the IF
statement in the example subroutine above to have them indicate the servo position.
Brandon
1 Like
Thank you Brandon.
Maybe it is easier if I use switches with a fixed position instead of push moment buttons.
Could that help?
You could use either a switch or a button. The way you would handle the button in your script is fairly similar, only instead of checking the servo position after the button is pressed, you could just check the switch position directly, so it takes out one step. For example, here is the previous code modified to work with a switch:
begin
1 get_position #get the position of the switch on channel 1
512 less_than if #if it is low (0V)
8000 0 servo #set the position to 8000 (2000us)
else #otherwise,
4000 0 servo #set the position to 4000 (1000us)
endif
50 delay #small delay
repeat
Brandon
1 Like