Using Pololu Maestro micro controller and this example script to move two servos in opposite directions when a button is pushed.
I want to be able to detect when one of the servos is near its end point to turn ON and OFF a relay connected to spare Maestro micro controller output.
Thanks
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
18 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
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
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
4000 frame
8000 frame
repeat
sub frame
wait_for_button_press
1 servo
return
Hello.
Could you post a more detailed description of what are trying to do? The example script you posted toggles a single servo channel between two positions when a button is pressed, not two servos like you mentioned. Are you asking for help modifying it to handle two servos? Do you want to have two relay outputs (one for each servo), or just a single relay output?
Also, you mentioned wanting to be able to detect when one of the servos is near its end point; are you using any acceleration or speed limits on your servo channels?
Brandon
Thanks Brandon
I modified the example code from the “Pololu Maestro Servo Controller User’s Guide page 84” to add 2 servos and also removed the additional servo steps - nothing else.
begin
4000 8000 frame
8000 4000 frame
repeat
sub frame
wait_for_button_press
1 servo
2 servo
return
The 2 servos are used to open and close a box - one at each side one working clockwise the other anti clockwise. When the box is open I want to switch something ON (via a relay) and OFF when the box is closed. I thought it would be neat to “read” the end position of one of the servos to do this. I only need to detect when one servo when its reached its limit (or near its limit).to drive one relay.
Thanks
Since your code is directly setting the target position of the servos to only 2 positions, I’m not sure I understand why you want to detect when the servo reaches its limit; you could just add your digital output channel to the code like this:
begin
8000 4000 8000 frame #the first value, 8000, is send to servo channel 3 to toggle the digital output high
4000 8000 4000 frame #the first value, 4000, is send to servo channel 3 to toggle the digital output low
repeat
sub frame
wait_for_button_press
1 servo
2 servo
3 servo #this channel should be configured as "output" to send a simple high/low digital signal
return
Please note that Maestro channels configured as outputs will send a high signal when the target position is greater than or equal to 1500 and a low signal when it is below 1500 µs.
To clarify, the Maestro does not have access to the servo’s internal feedback potentiometer, and has no way to detect the actual position of the servo (which is left up to the servo’s internal control circuitry). You could add a small delay before sending the target position to your digital output channel if you want to give the servo time to reach its target. Alternatively, if you are using a non-zero speed or acceleration limit on those servo channels, the Maestro essentially breaks the movement up into many small movements, and you could use the GET_MOVING_STATE command detect when the Maestro channels are outputting their commanded target positions. For example:
sub frame
wait_for_button_press
1 servo
2 servo
begin 50 delay get_moving_state while repeat #wait until servo channels have reached their target positions
3 servo #toggle digital output on channel 3
return
Brandon