Controlling servos with a Phototransistor

This is my first project using a Pololu product, and I am using a Maestro 6 channell USB servo controller to control two servos. What I would like to do is connect a phototransistor to an input channel as a switch that initializes the servo sequence when it detects infrared light and returns to neutral state when there is no light present. I think I know how to set up the board physically for this to happen from reading the following directions: pololu.com/docs/0J40/7.b . However, I am totally lost on how to properly script this so that it functions properly. Any help or input would be greatly appreciated. Thanks

Hello,

Take a look at the example code I posted for another Maestro user. You application should be very similar. If you still have questions after that, see if you can ask something more specific.

-Paul

By the way, a good way to go in general is to break up your project into manageable steps and see where you get stuck:

  1. Wire the sensor to your Maestro and verify that it works in the Maestro Control Center.
  2. Write a function called DETECTOR that returns 1 if something is detected, 0 if not. You can test this function by putting “DETECTOR QUIT” as the first line of your program, running it interactively, and seeing what value ends up on the stack.
  3. Write a function called SEQUENCE that runs your sequence - test it in a similar way.
  4. Combine these two functions using a BEGIN…REPEAT loop and an IF…END condition.
  5. Step through your code to debug it until it works!

-Paul

Hello,

I know this thread is a bit old, but I’m completely new at this and am trying to learn. I have a Micro Maestro 6-Channel USB Servo Controller and am trying to understand this coding stuff. I want to use a phototransistor as a switch to control my servo. I didn’t really quite understand your code in the example you posted, nor the detector function you explained, but it seems like it’s exactly what I want to do. I am really new sorry :frowning: In the Maestro Control Center, what I’ve basically done is set/saved two frames to put the servo in the position and speeds I want (channel 1). I have also wired the phototransistor as a button/switch, in accordance with the user manual and have set the channel to “Input” (channel 5). Next when I “copy sequence to script” I get the code below. Now my question is how do I incorporate the switch(phototransistor) into this code to be able to play one frame (door open) when it is on (light present) and the other frame (door closed) when it is off (no light). Any help will be greatly appreciated. Thanks for your time.

# Sequence 1
begin
  3500 0 8896 0 0 0 frame_0..4 # Door Open
  3500 2368 frame_1 # Door Closed
repeat

sub frame_0..4
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

sub frame_1
  1 servo
  delay
  return

Hello.

It sounds like you are on the right track with what you have started. From there, I would suggest using the Maestro Control Center to see the input values you are getting from your phototransistor (on channel 5), so you can get an idea of where you want the threshold to be. Note that the input values range from 0 to 255, but in your script this corresponds to 0 to 1023. You should be able to use the get_position command to read the phototransistor’s input value and greater_than or less_than commands compare that to the threshold. If its on one side of the threshold, run your “door open” frame, and if it is on the other side, run your “door closed” frame. For example, it could look something like this (using an arbitrary threshold value of 125):

begin
	 
	5 get_position   
	
	500 greater_than   #Threshold of 125 corresponds to about 500
	if 
	led_off  #run your close door frame

	else 
	led_on  #run your open door frame

	endif

repeat

-Brandon

Hi Brandon,

Thanks for the reply. I was able to get it to work! Soo excited. :smiley: Only question I have is that when I run the script, the red led is on during one frame and then turns off during the next frame. After some research, I found that the red led means that there is an error in the script? But I also found the the “led_on” command turns the red led on. I’m not finding any errors showing up under the error tab in the Maestro Control Center. Can I safely assume that the red led on because of the led_on command that I’m using? Other than that, it works great! Thank you so much for you help.

-John

Yes, the led_on and led_off commands in the code I provided were just meant to be place holders for your “close door” and “open door” frames. The led_on and led_off commands control the same red LED on the board that designates an error, so if you are not receiving any errors in the Maestro Control Center, it is working properly.

-Brandon

I have a 6 channel maestro controller. I plunged a photo transistor as an input signal to turn on a continuous servo motor clock wise for a given value else turn counter clock detection.

I need the servo to run for a give time interval and speed which i get from sliding the interface slider then I adjust the run time to meet the operation, then I need to go to its stopped position. The script goes something like this from your example;

begin
5 get_position

500 greater_than #Threshold of 125 corresponds to about 500
if
led_off #run close curtain frame

else
led_on #run open curtain frame

endif

repeat

I have a problem to make the servo go to its stop position after it runs either frame. I need to run the servo then followed by a stop position within the if/else statements. Any suggestions how to write the script.

Thanks for your help.

Hello.

Have you tried putting a command after calling a frame that sends a neutral target position (6000)? You might also try adding delays.

The Maestro might be cycling through your script so fast that it is reading the sensor and running the frame again before you have a chance to see the servo stop. Could you post your script so I can see what it is doing?

-Brandon

My project is to close a house curtain during the hot sun period and open it in the afternoon when it’s cooler.

Here is the script but i can’t get the continuous servo to stop after the initial run.

### Sequence subroutines: ###

# Sequence 0
begin
  1 get_position 
	
1000 less_than 

if
sub Sequence_0
  5000 0 0 0 0 6649 frame_0_2..5 # clockwise Frame 0
  500 5984 frame_5 # stop rotation Frame 1
else
sub sequence_1  
5000 5514 frame_5 # counter clockwise Frame 2
  500 5944 frame_5 # stop rotation Frame 3
  
endif
repeat


sub frame_0_2..5
  5 servo
  4 servo
  3 servo
  2 servo
  0 servo
  delay
  return

sub frame_5
  5 servo
  delay
  return

The way your script is right now, when the sensor reads less than 1000, the servo on channel 5 will turn for 5 seconds (frame_0_2. .5), then this servo should stop for half of a second (frame_5). After this, the script will cycle through and read the sensor again, and move the servo again. Is that what is happening when you run the script?

If you are trying to have the servo only react to an initial change in brightness once, and then monitor the light to see when to change back, you might try adding a number to the stack that acts as a state variable. I tried adding a state variable to your script as an example:

1  #Sets an initial state
begin

    dup
    if   #If state is 1, check the sensor to move the servo clockwise

        3 get_position
        650 less_than 
        if
            5000 6649 frame_5 #Turn clockwise for 5 seconds		
            drop  #Change the state to 0
            0
        endif
    
    else #If state is 0, check the sensor to move the servo counter clockwise

        3 get_position
        650 greater_than 
        if
            5000 5514 frame_5 #Turn counter clockwise for 5 seconds
            drop  #Change the state to 1
            1
        endif

    endif

500 5944 frame_5 #Stop rotation

repeat

sub frame_5
  5 servo
  delay
  return

By the way, you were testing your sensor to see if it was returning a value less than 1000, which is nearly the maximum value the sensor would output (1023). I am not sure if this was intentional and works for your application, but I found 650 to be a more appropriate value for my test.

Also, I am not sure what you were trying to do in frame_0_2…5. It looked like it was setting the servos on channels 0, 2, 3, and 4 to stop sending pulses (target position of 0), but channel 3 is being used as an input and channels 0, 2, and 4 are not being used anywhere else. For this example, I took out frame_0_2…5 and just used a single servo on channel 5.

-Brandon

The script you provided works great. It’s exactly what i was looking for this operation. I did adjust the servo neutral position to 6000 and corrected the photo values and channel.

Thank you for the timely response. I like to commend you and all the staff at Pololu for the great support on this and other projects.