Detecting servo end points to operate a relay

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