Problem with sample script

Hello

I am using a micro maestro 6channel servo controller I am trying to start a script to move 3 servos with a button press below is the script that woks fine alone. I have coppied most of the example script and changed some of the values to get used to some of the aspects of the code I am new to code. I have made up the pull up resistor swich assembly per the users guide and connected it to 0 servo and changed the 0 servo to input per users guide and tested the assembly in the status portion of the of the control center and it works properly. I copied the example script under USING A BUTTON OR SWITCH TO CONTROL SERVOS but a error appears about the SUB WAIT_FOR_BUTTON_PRESS line of the code. Can some help me with why I get an error with example script?

Thanks
Bob

begin
5000 1 servo
500 delay
5000 2 servo
500 delay
5000 3 servo
500 delay
7000 1 servo
500 delay
7000 2 servo
500 delay
7000 3 servo
500 delay
repeat

The example script you cite includes this code:

# Uses WAIT_FOR_BUTTON_PRESS to allow a user to step through a sequence  
# of positions on servo 0.  
begin  
   4000 frame  
   5000 frame  
   6000 frame  
   7000 frame  
   8000 frame  
repeat  
   
sub frame  
   wait_for_button_press  
   0 servo  
   return

Did you remember to put that code at the top of your program?

If you need more help, please post your entire code here, and tell us specifically what error message you are seeing.

–David

Hello

I am using a micro maestro 6 channel servo controller I am trying to start a script with a button. I have coppied most of the example script and changed some of the values to get used to some of the aspects of the code I am new to code. I have made up the pull up resistor swich assembly per the users guide and connected it to 0 servo and changed the 0 servo to input per users guide and tested the assembly in the status portion of the of the control center and it works properly. I copied the example script under USING A BUTTON OR SWITCH TO CONTROL SERVOS but a error appears 0x0080 and it does not run through the script. My servo is connected to channel 1. It looks like the servo is on channel 0 in the sample script and the input is 1. The script does not specify which channel is input and which channel is the servo I tried the script the way it is copied and also changing servo to 1 and the get_position command to 0 it did not work either way. I also changed the input to channel 1 and servo to 0 on the micro maestro and have same 0x0080 error, I also changed the mode of channel 1 to input and channel 0 back to servo and ran the program as copied and same 0x0080 error. Can some one help me with why I get an error with example script? I have read the user guide several times and not seeing MY error I must be doing something wrong. Below is the coppied code

Thanks
Bob

# Returns 1 if the button is pressed, 0 otherwise.
sub button
1 get_position 500 less_than 
return 


# Waits for a button press, with debouncing.    
# (Requires the BUTTON subroutine.) 
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 
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 pressed 
button 
if 
get_ms over minus 10 greater_than 
if drop return endif 
else 
drop get_ms 
endif 
repeat 


# Uses WAIT_FOR_BUTTON_PRESS to allow a user to step through a sequence 
# of positions on servo 1. 
begin 
4000 frame 
5000 frame 
6000 frame 
7000 frame 
8000 frame 
repeat 
sub frame 
wait_for_button_press 
0 servo 
return

Hello Bobby. I have merged your new topic in to the old topic because you were asking the same question in both of them. Please reply to this topic instead of creating new ones.

Channel 0 is the servo channel and channel 1 is the input.

Your script is incomplete because you don’t have any kind of loop at the top of the script to actually do anything. You just have some subroutines at the top. Therefore, when the script starts running, it will just execute the first subroutine. When it gets to the “return” statement, there will be a call stack underflow because there is no place to return to. You could have discovered this by stepping through your program in the Maestro control center.

Please read my previous response because it tells you how to fix this.

–David

David
Thank you

Hello
Thanks for your help
My questions are
#1 From the script below In this line of script (1 get_position 500 less_than) does the 1 mean it is looking for an input from channel 1?

#2 How do you start this script not connected to the computer with the button press?

Thanks
Bobby

# Uses WAIT_FOR_BUTTON_PRESS to allow a user to step through a sequence  
# of positions on servo 0.  
begin  
   4000 frame  
   5000 frame  
   6000 frame  
   7000 frame  
   8000 frame  
repeat  
   
sub frame  
   wait_for_button_press  
   0 servo  
   return

# Returns 1 if the button is pressed, 0 otherwise.
sub button
1 get_position 500 less_than 
return 


# Waits for a button press, with debouncing. 
# (Requires the BUTTON subroutine.) 
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 
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 pressed 
button 
if 
get_ms over minus 10 greater_than 
if drop return endif 
else 
drop get_ms 
endif 
repeat 



# Uses WAIT_FOR_BUTTON_PRESS to allow a user to step through a sequence  
# of positions on servo 0.  
begin  
   4000 frame  
   5000 frame  
   6000 frame  
   7000 frame  
   8000 frame  
repeat  
   
sub frame  
   wait_for_button_press  
   0 servo  
   return

# Returns 1 if the button is pressed, 0 otherwise.
sub button
1 get_position 500 less_than 
return 


# Waits for a button press, with debouncing. 
# (Requires the BUTTON subroutine.) 
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 
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 pressed 
button 
if 
get_ms over minus 10 greater_than 
if drop return endif 
else 
drop get_ms 
endif 
repeat

Hello, Bobby.

Please use the “code” tags when posting code, to make the code easier to read (just select the code and click the ‘code’ button at the top of the post composer). Also, you accidentally pasted the same script twice.

#1: Yes

#2: You should check the “Run script on startup” checkbox in the “Script” tab. Then your script will start running (and start waiting for a button press) whenever you supply power to the Maestro.

–David

Thanks David

So if from your last reply i can change

1 get_position 500 less_than 

To

0 get_position 500 less_than 

and change

0 servo 

to

1 servo

and change channel 0 to input and channel 1 to servo in the Maestro control center and apply and connect the switch to channel 0 and servo to channel 1

Bobby

# Uses WAIT_FOR_BUTTON_PRESS to allow a user to step through a sequence 
# of positions on servo 0. 
begin 
4000 frame 
5000 frame 
6000 frame 
7000 frame 
8000 frame 
repeat 

sub frame 
wait_for_button_press 
0 servo 
return

# Returns 1 if the button is pressed, 0 otherwise.
sub button
1 get_position 500 less_than 
return 


# Waits for a button press, with debouncing. 
# (Requires the BUTTON subroutine.) 
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 
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 pressed 
button 
if 
get_ms over minus 10 greater_than 
if drop return endif 
else 
drop get_ms 
endif 
repeat 

Yes, the procedure you describe should work. You should also check the “Run script on startup” box before clicking “Apply Settings” so that your script actually runs.

It sounds like you are not very comfortable with the Maestro scripting language though, so I would recommend just getting the original script to work before you modify it. Is there some reason you need the button to be on channel 0 and the servo to be on channel 1?

–David

David
You are correct I dont have a clue what I am doing but your answeres are helping me to understand the code a bit. I have got your code to work with your help putting things in the proper order. I am a mechanical guy who has an electronics problem I am trying to solve you are great help, thanks. I can use channel 1 as the input and channel o as the servo just trying to understand how it works. What I am trying to accomplish is move 4 servos about 20 degrees 1 at a time with separate signals from the button. Push the button servo 0 moves next button push move servo 2, next button push move servo 3, next button push move servo 4. Then the next part of the problem is after the servo moves I need them to not hold their position so a spring can return them later. Any help you can give me with this problem would be most appretiated.

Thanks again
Bobby

First I recommend removing the “frame” subroutine and refactoring the top of your code a little so it looks like this:

begin
wait_for_button_press
4000 0 servo
wait_for_button_press
5000 0 servo
wait_for_button_press
6000 0 servo
wait_for_button_press
7000 0 servo
wait_for_button_press
8000 0 servo
repeat

#(the wait_for_button_press subroutine needs to be defined below for this script to work)

After making that change, your script should behave the same way (except that the position gets added to the stack later). But now it is easier to see what is going on, and it should be easy to see how you would modify the script about to move a different servo after each button press (just change the the numbers before the “servo” commands).

By default, the servo should holds its position until you send another command. If you want it to not hold position, you have to stop sending pulses to a servo. You can do that by setting the target/position to zero after the servo has reached its new position (a delay is required). For example:

7000 0 servo   # tell servo 0 to start moving
500 delay       # give it enough time to get there (0.5 seconds; you'll need to tune the exact time for your application)
0 0 servo       # stop sending pulses to servo 0

If your servos have a speed or acceleration limit, then you could write a little loop that uses the “GET_MOVING_STATE” command to wait until they are done moving (you would do this instead of “500 delay”).

However, beware that some servos might not allow you to back drive them this way, and they might break.

–David

Thanks David Iwill try it

David this works exactly how I hoped it would, see code below, but I have another question, the RX line. I am going to start and activate the controller with a radio that puts out a 500ms pulse of 6-8 volts DC. I can replace the switch I am using to test with with a relay and take the pulse from my radio to switch a relay (mechanical device to fail sometime). Or can I put a voltage divider in between my radio and the RX line to use 500ms pulse of 3-4 volts to replace my switch and start and run script with through the RX line? When I made the changes we talked about earlier
about switching the button to channel 0 and servo the channel 1 it did not work for me not real important now.

Thanks for all your help
Bobby

# Uses WAIT_FOR_BUTTON_PRESS to allow a user to step through a sequence 
# of positions on servo 2,3,4,5 
 

begin
wait_for_button_press
7000 2 servo
350 delay
0 2 servo
wait_for_button_press
7000 3 servo
350 delay
0 3 servo
wait_for_button_press
7000 4 servo
350 delay
0 4 servo
wait_for_button_press
7000 5 servo
350 delay
0 5 servo
repeat




# Returns 1 if the button is pressed, 0 otherwise.   
sub button
1 get_position 500 less_than 
return 



# Waits for a button press, with debouncing.     
# (Requires the BUTTON subroutine.) 
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 
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 pressed 
button 
if 
get_ms over minus 10 greater_than 
if drop return endif 
else 
drop get_ms 
endif 
repeat