Hello,
Stupid issue here with a simple maestro script. I only have 2 sequences (“Sequence 1” and “Sequence 2”) and only 2 inputs (Channel 22 and 23 on maestro, momentary SPST push-button switch). My monkey brain cannot figure out what is wrong with the script, I bet you can see it immediately. Please help! TIA!
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
22 get_position 500 less_than
return
#me
sub button_2
23 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_10ms
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
#me
button_2
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
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
#me
button_2
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
wait_for_button_press # call subroutine before executing sequence
500 5184 5376 6336 5632 6272 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 frame_0..21 # Frame 0
500 6784 frame_0 # Frame 1
500 8000 frame_1 # Frame 2
500 8384 frame_2 # Frame 3
500 8000 frame_3 # Frame 4
500 8192 frame_4 # Frame 5
500 6272 frame_4 # Frame 6
500 5632 frame_3 # Frame 7
500 6336 frame_2 # Frame 8
500 5376 frame_1 # Frame 9
500 5184 frame_0 # Frame 10
2000 6784 8000 8384 8000 8192 frame_0..4 # Frame 11
1000 5184 5376 6336 5632 6272 frame_0..4 # Frame 12
1500 6784 8000 8384 8000 8192 frame_0..4 # Frame 13
1500 5184 5376 6336 5632 6272 frame_0..4 # Frame 14
500 6784 8000 frame_0_1 # Frame 15
500 5376 8384 frame_1_2 # Frame 16
500 6336 8000 frame_2_3 # Frame 17
500 5632 8192 frame_3_4 # Frame 18
500 6272 frame_4 # Frame 19
500 6826 7460 6923 7326 frame_1..4 # Frame 20
1000 5376 6336 5632 6272 frame_1..4 # Frame 21
1000 8000 8384 8000 8192 frame_1..4 # Frame 22
1000 6750 7423 6880 7284 frame_1..4 # Frame 23
200 5376 frame_1 # Frame 24
200 6336 frame_2 # Frame 25
200 5632 frame_3 # Frame 26
200 6272 frame_4 # Frame 27
repeat
#sub Sequence_0
# wait_for_button_press
1 servo
return
#PERCY PROGRAMS
### Sequence subroutines: ###
# Sequence 0
sub Sequence_0
500 5184 5632 3584 3904 5245 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 frame_0..21 # Frame 0
500 6784 frame_0 # Frame 1
500 7104 frame_1 # Frame 2
500 6592 frame_2 # Frame 3
500 6400 frame_3 # Frame 4
500 7296 frame_4 # Frame 6
return
# Sequence 1
sub Sequence_1
500 5184 5376 6336 5632 6272 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 frame_0..21 # Frame 0
500 6784 frame_0 # Frame 1
500 8000 frame_1 # Frame 2
500 8384 frame_2 # Frame 3
500 8000 frame_3 # Frame 4
500 8192 frame_4 # Frame 5
500 6272 frame_4 # Frame 6
500 5632 frame_3 # Frame 7
500 6336 frame_2 # Frame 8
500 5376 frame_1 # Frame 9
500 5184 frame_0 # Frame 10
2000 6784 8000 8384 8000 8192 frame_0..4 # Frame 11
1000 5184 5376 6336 5632 6272 frame_0..4 # Frame 12
1500 6784 8000 8384 8000 8192 frame_0..4 # Frame 13
1500 5184 5376 6336 5632 6272 frame_0..4 # Frame 14
500 6784 8000 frame_0_1 # Frame 15
500 5376 8384 frame_1_2 # Frame 16
500 6336 8000 frame_2_3 # Frame 17
500 5632 8192 frame_3_4 # Frame 18
500 6272 frame_4 # Frame 19
500 6826 7460 6923 7326 frame_1..4 # Frame 20
1000 5376 6336 5632 6272 frame_1..4 # Frame 21
1000 8000 8384 8000 8192 frame_1..4 # Frame 22
1000 6750 7423 6880 7284 frame_1..4 # Frame 23
200 5376 frame_1 # Frame 24
200 6336 frame_2 # Frame 25
200 5632 frame_3 # Frame 26
200 6272 frame_4 # Frame 27
return
# Sequence 2
sub Sequence_2
500 5184 5376 6336 5632 6272 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 frame_0..21 # Frame 0
500 7228 frame_4 # Frame 1
500 6785 frame_3 # Frame 2
500 7326 frame_2 # Frame 3
500 6673 frame_1 # Frame 4
500 5981 frame_0 # Frame 5
500 6784 frame_0 # Frame 6
500 8000 frame_1 # Frame 7
500 8384 frame_2 # Frame 8
500 8000 frame_3 # Frame 9
5000 8192 frame_4 # Frame 10
5000 5184 5376 6336 5632 6272 frame_0..4 # Frame 11
3000 6784 8000 8384 8000 8192 frame_0..4 # Frame 12
4000 5184 5376 frame_0_1 # Frame 13
4000 6784 frame_0 # Frame 14
4000 8000 frame_1 # Frame 15
1500 5184 5376 6336 5632 6272 frame_0..4 # Frame 16
return
sub frame_0..21
21 servo
20 servo
19 servo
18 servo
17 servo
16 servo
15 servo
14 servo
13 servo
12 servo
11 servo
10 servo
9 servo
8 servo
7 servo
6 servo
5 servo
4 servo
3 servo
2 servo
1 servo
0 servo
delay
return
sub frame_0
0 servo
delay
return
sub frame_1
1 servo
delay
return
sub frame_2
2 servo
delay
return
sub frame_3
3 servo
delay
return
sub frame_4
4 servo
delay
return
sub frame_0..4
4 servo
3 servo
2 servo
1 servo
0 servo
delay
return
sub frame_0_1
1 servo
0 servo
delay
return
sub frame_1_2
2 servo
1 servo
delay
return
sub frame_2_3
3 servo
2 servo
delay
return
sub frame_3_4
4 servo
3 servo
delay
return
sub frame_1..4
4 servo
3 servo
2 servo
1 servo
delay
return
Hello.
Can you describe what you are trying to have your script do, and what it is actually doing right now? How do you want the buttons to function? It looks like you added some logic for your second button to the wait_for_button_press
, wait_for_button_open_10ms
and wait_for_button_closed_10ms
, but it is not clear if you want to wait for either button to be pressed, or if you want the buttons to work independently in some way.
Brandon
Hi Brandon,
Thanks for your help. All I need this script to do is:
- wait for either button to be pressed
- if button 1 is pressed Sequence 1 plays
- if button 2 is pressed Sequence 2 plays
- after either Sequence is finished system goes back to the top, waiting for a button press
Stupid simple, I know…
Cheers
It looks like you based your script off of the “Using a button or switch to control servos” example in the “Example Scripts” section of the Maestro user’s guide. The method shown in the “Using multiple buttons or switches to control servos” example is probably a better starting point for what you are doing. This example monitors three buttons, each triggering a different subroutine before returning to monitoring the buttons again, so you would need to remove one button and sequence combination since you only have two.
Brandon
Hi Brandon,
Yes, you are correct. I didn’t see the multiple button example underneath it, thank you.
I have been staring at the screen now for waaaay too long and still am getting errors. Can you spot them? There are 5 servos taking up channel 0-4 on the maestro. TIA!
goto main_loop # Run the main loop when the script starts (see below).
sub wait_for_button_press
wait_for_button_open_10ms
wait_for_button_closed_10ms
return
# When the script is not doing anything else,
# this loop will listen for button presses. When a button
# is pressed it runs the corresponding sequence.
begin
button_a if Sequence_1 endif
button_b if Sequence_2 endif
repeat
# These subroutines each return 1 if the corresponding
# button is pressed, and return 0 otherwise.
# Currently button_a is assigned to channel 0,
# button_b is assigned to channel 1, and
# button_c is assigned to channel 2.
# These channels must be configured as Inputs in the
# Channel Settings tab.
sub button_a
22 get_position 500 less_than #button_a is ch22 on maestro
return
sub button_b
23 get_position 500 less_than #button_b is ch23 on maestro
return
# These subroutines each perform an arbitrary sequence
# of servo movements. You should change these to fit
# your application.
sub Sequence_1
500 6784 frame_0 # Frame 1
500 8000 frame_1 # Frame 2
500 8384 frame_2 # Frame 3
500 8000 frame_3 # Frame 4
500 8192 frame_4 # Frame 5
500 6272 frame_4 # Frame 6
500 5632 frame_3 # Frame 7
500 6336 frame_2 # Frame 8
500 5376 frame_1 # Frame 9
500 5184 frame_0 # Frame 10
2000 6784 8000 8384 8000 8192 frame_0..4 # Frame 11
1000 5184 5376 6336 5632 6272 frame_0..4 # Frame 12
1500 6784 8000 8384 8000 8192 frame_0..4 # Frame 13
1500 5184 5376 6336 5632 6272 frame_0..4 # Frame 14
500 6784 8000 frame_0_1 # Frame 15
500 5376 8384 frame_1_2 # Frame 16
500 6336 8000 frame_2_3 # Frame 17
500 5632 8192 frame_3_4 # Frame 18
500 6272 frame_4 # Frame 19
500 6826 7460 6923 7326 frame_1..4 # Frame 20
1000 5376 6336 5632 6272 frame_1..4 # Frame 21
1000 8000 8384 8000 8192 frame_1..4 # Frame 22
1000 6750 7423 6880 7284 frame_1..4 # Frame 23
200 5376 frame_1 # Frame 24
200 6336 frame_2 # Frame 25
200 5632 frame_3 # Frame 26
200 6272 frame_4 # Frame 27
return
sub Sequence_2
500 7228 frame_4 # Frame 1
500 6785 frame_3 # Frame 2
500 7326 frame_2 # Frame 3
500 6673 frame_1 # Frame 4
500 5981 frame_0 # Frame 5
500 6784 frame_0 # Frame 6
500 8000 frame_1 # Frame 7
500 8384 frame_2 # Frame 8
500 8000 frame_3 # Frame 9
5000 8192 frame_4 # Frame 10
5000 5184 5376 6336 5632 6272 frame_0..4 # Frame 11
3000 6784 8000 8384 8000 8192 frame_0..4 # Frame 12
4000 5184 5376 frame_0_1 # Frame 13
4000 6784 frame_0 # Frame 14
4000 8000 frame_1 # Frame 15
1500 5184 5376 6336 5632 6272 frame_0..4 # Frame 16
return
# 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
wait_for_button_press # call subroutine before executing sequence
repeat
# wait_for_button_press
1 servo
return
#PERCY PROGRAMS
### Sequence subroutines: ###
# Sequence 1
sub Sequence_1
500 5184 5376 6336 5632 6272 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 frame_0..21 # Frame 0
500 6784 frame_0 # Frame 1
500 8000 frame_1 # Frame 2
500 8384 frame_2 # Frame 3
500 8000 frame_3 # Frame 4
500 8192 frame_4 # Frame 5
500 6272 frame_4 # Frame 6
500 5632 frame_3 # Frame 7
500 6336 frame_2 # Frame 8
500 5376 frame_1 # Frame 9
500 5184 frame_0 # Frame 10
2000 6784 8000 8384 8000 8192 frame_0..4 # Frame 11
1000 5184 5376 6336 5632 6272 frame_0..4 # Frame 12
1500 6784 8000 8384 8000 8192 frame_0..4 # Frame 13
1500 5184 5376 6336 5632 6272 frame_0..4 # Frame 14
500 6784 8000 frame_0_1 # Frame 15
500 5376 8384 frame_1_2 # Frame 16
500 6336 8000 frame_2_3 # Frame 17
500 5632 8192 frame_3_4 # Frame 18
500 6272 frame_4 # Frame 19
500 6826 7460 6923 7326 frame_1..4 # Frame 20
1000 5376 6336 5632 6272 frame_1..4 # Frame 21
1000 8000 8384 8000 8192 frame_1..4 # Frame 22
1000 6750 7423 6880 7284 frame_1..4 # Frame 23
200 5376 frame_1 # Frame 24
200 6336 frame_2 # Frame 25
200 5632 frame_3 # Frame 26
200 6272 frame_4 # Frame 27
return
# Sequence 2
sub Sequence_2
500 5184 5376 6336 5632 6272 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 frame_0..21 # Frame 0
500 7228 frame_4 # Frame 1
500 6785 frame_3 # Frame 2
500 7326 frame_2 # Frame 3
500 6673 frame_1 # Frame 4
500 5981 frame_0 # Frame 5
500 6784 frame_0 # Frame 6
500 8000 frame_1 # Frame 7
500 8384 frame_2 # Frame 8
500 8000 frame_3 # Frame 9
5000 8192 frame_4 # Frame 10
5000 5184 5376 6336 5632 6272 frame_0..4 # Frame 11
3000 6784 8000 8384 8000 8192 frame_0..4 # Frame 12
4000 5184 5376 frame_0_1 # Frame 13
4000 6784 frame_0 # Frame 14
4000 8000 frame_1 # Frame 15
1500 5184 5376 6336 5632 6272 frame_0..4 # Frame 16
return
sub frame_0..21
21 servo
20 servo
19 servo
18 servo
17 servo
16 servo
15 servo
14 servo
13 servo
12 servo
11 servo
10 servo
9 servo
8 servo
7 servo
6 servo
5 servo
4 servo
3 servo
2 servo
1 servo
0 servo
delay
return
sub frame_0
0 servo
delay
return
sub frame_1
1 servo
delay
return
sub frame_2
2 servo
delay
return
sub frame_3
3 servo
delay
return
sub frame_4
4 servo
delay
return
sub frame_0..4
4 servo
3 servo
2 servo
1 servo
0 servo
delay
return
sub frame_0_1
1 servo
0 servo
delay
return
sub frame_1_2
2 servo
1 servo
delay
return
sub frame_2_3
3 servo
2 servo
delay
return
sub frame_3_4
4 servo
3 servo
delay
return
sub frame_1..4
4 servo
3 servo
2 servo
1 servo
delay
return
Thank you for posting your updated code. It looks like you still have a lot of code left over from your original script that is causing problems. For example, because your code starts with the goto main_loop
command your script never reaches your new BEGIN/REPEAT
loop that checks your two buttons. You should remove the following portions of leftover code:
goto main_loop # Run the main loop when the script starts (see below).
sub wait_for_button_press
wait_for_button_open_10ms
wait_for_button_closed_10ms
return
and
main_loop:
begin
wait_for_button_press # call subroutine before executing sequence
repeat
# wait_for_button_press
1 servo
return
Additionally, you now have sub Sequence_1
and sub Sequence_2
each defined twice. If you intended to have 4 different subroutines, they should all have unique identifiers. Otherwise, you should determine which of these are the intended subroutines and remove or comment out the two others.
Brandon
Brandon, you are a steely-eyed-missile man! That did it, thanks again for the help.
Quick question: program is working fine but input (ch 22 and 23, push buttons, simple) is very, very sensitive. To the point where without attaching anything to those pins but simply touching them with my finger give a noisy spazm that shows in the control center status window.
My guess is I am missing a known tip (that I can’t find) on using a resistor of a known value to calm this input down.
Help!
And thank you!
From your description it sounds like you might have connected your buttons in a way that doesn’t use pull-up resistors, as shown in the “Button or switch” heading of the “Attaching Servos and Peripherals” section in the Maestro user’s guide. If you did connect your buttons per the instructions in the user’s guide, and it is still very sensitive, can you post some pictures that show your connections?
Alternatively, since you have a 24-channel Maestro, you could check the “Enable pull-ups on channels 18-20” check box in the “Channel Settings” tab of the Maestro Control Center to use internal pull-up resistors and move your buttons to two of those channels, connecting between the signal pin and ground. Please note that you would need to change the pin numbers to reflect this change in your script as well.
Brandon
By the looks of it, grayfxman is trying to accomplish the same as I am.
I have a 24 channel Maestro set up to control two servos, using two scripts, triggered by two buttons.
My problem is, that I’m encountering some outside interference, which sometimes triggers the inputs.
I’ve been trying to overcome this by adding a debounce routine as mentioned in the “Using a button or switch to control servos” example to the “Using multiple buttons or switches to control servos” example. But I keep getting error messages.
Could you please steer me in the right direction in how to debounce multiple buttons?
I just followed Brandon’s advice (used channel 19 and 20 in my case) and it worked perfectly.
Yes, but you took out most of the debouncing in your second attempt and Brandon told you to take out what was left of it. I tried to include the debouncing code and make it work for two buttons, but couldn’t get it to work.
Hello, Micropuller.
There are probably multiple ways you could go about doing something like that. If you want the subroutines to wait for a specific button to be pressed, one option might be to duplicate the button
, wait_for_button_press
, wait_for_button_open_10ms
, and wait_for_button_closed_10ms
subroutines in the “Using a button or switch to control servos” example script and modified the duplicates to work for a button on a different channel (please note that you would need to modify the names of the duplicate subroutines as well). It might be more efficient to try modifying those subroutines so you can pass them a channel number, so you could use the same subroutines for both buttons. However, if you want to monitor both buttons and run a different sequence depending on which button is pressed (essentially behaving like the Using multiple buttons or switches to control servos
example, but with debouncing), you will likely need a different approach.
I came up with the subroutine below to check an input channel for a button press and do some debouncing. It needs to be passed the channel number of the button, so you can use this same subroutine for both of your inputs (e.g. 0 button_debounce
would check the input on channel 0). This subroutine should return 1 if the button has been pressed for the debouncing time (I used 100 in the sample), and 0 if the button is released before that time. Please note that the program will stay in the subroutine for the duration of the debouncing time if the button is being pushed the whole time.
sub button_debounce
get_ms #get current time and put it on stack
begin
swap dup get_position 500 less_than #check if specified button is pressed
if
swap get_ms over minus 100 greater_than #return 1 if it has been pressed for 100ms+
if drop drop 1 return endif
else #if button is released before specified time return 0
drop drop 0 return
endif
repeat #if button is still being held and it has not been 100ms repeat subroutine
Brandon
Thanks! I’ll try that tomorrow!
Brandon, I can’t thank you enough, that worked a treat!
1 Like