Micro Maestro 6-Channel USB Servo Controller speed control

Hello, BobbyS.

You can write a Maestro script that reads an analog input and uses it to set the speed of a servo channel. We do not have any specific examples to show how to do that, but it would look very similar to the “Using an analog input to control servos” example found in the “Example Scripts” section of the Maestro user’s guide, only you would likely want to change the scaling and instead of a servo command, you would use a speed command.

Brandon

Thank you Brandon! I will give that a look and see if I can get that to happen! So I should be able to write a script that allows it to see an analog input command?

Yes, Maestro channels 0-12 are analog, so if you configure any of them as an input in the “Channel Settings” tab of the Maestro Control Center, then the GET_POSITION script command will return a value from 0 to 1023 as the signal goes from 0V to 5V.

Brandon

Your help was right on target! Thank You!

What I am doing is moving a servo one direction a certain amount then the other direction to where it just moves back and forth. I have the parameters of movement in the frame and the speed in the script.

Why does the amount of rotation increase when I increase the speed. It does this whether I run the script and change speed with a pot or just change speed in the control center?

The speed value should just change how quickly the Maestro reaches the target position, so if you are seeing the servo’s range of motion change when you adjust the speed, I suspect it is limiting the speed enough that it doesn’t reach the target position before the new position is commanded. You can monitor the sliders in the “Status” tab to check this. The arrow on the slider shows the target position, and the circle shows the current position. If the circle does not reach the arrow before it changes to a new position, you will probably either need to increase the delay between frames or use higher speed values so it reaches the target value sooner.

If you want to post a copy of your settings file, I might be able to offer more specific suggestions. You can save a copy of your settings file from the “File” drop-down menu of the Maestro Control Center while the controller is connected.

Brandon

Yes that seems to be what is happening. The arrow gets to the target before the round ball. What is the best way to post the file here? I do not understand the scaling.

To upload a file, you can either use the upload button (shown in the image below) or drag the file directly into the text box:

As far as scaling, the analog input should read from 0-1023 over the 0-5V range and your script will need to scale that input to appropriate speed values. A speed of 0 means that speed limiting is disabled (i.e. the controller will immediately command the target position). A value of 1 is the slowest speed you can set and the speed increases from there (up to the maximum of 3968). You can find more information about the units of the speed variable in the “Channel Settings” section of the Maestro user’s guide. Ultimately, you will probably want to do some testing by just setting the speed in the status tab and moving the servo with the slider (i.e. not using a script) to find the speed range that work for your application, then you can scale the potentiometer input to that.

Brandon

Thanks for all the help Brandon! Put me on the right track. Just gotta work with stuff ya got lol. I found with the suggestions that you gave me along with adjusting the “Duration” got me closer to what I can use.

OK, here is the script I came up with. I am sure there is a better way to do it so:
maestro_settings.txt (3.5 KB)

Thank you for posting that settings file. While it looks like your script should work fine as-is, you are not moving the servo very far, so I suspect you will want to reduce the scaling factor so it sets the speed to much slower values.

For example, with the positions and delay times you are using, a speed of 5 is the lowest you can use that still allows the servo to reach the target, so that might be a good lower limit. For an upper limit, it will depend on your application, but something around 25 is probably a good starting point. To scale the 0-1023 reading to 5-25, you could replace your 1 times line of code with 50 divide 5 plus.

By the way, instead of updating the speed only once per cycle, it is possible to have it update all the time with some slightly more complicated modifications to your script. If you want to try that, let me know and I would be glad to give you some suggestions.

Brandon

Yes, I am moving it a small distance. This is for a guitar pickup winder. The width of the pickup coil is .5 inch, so the amount of movement at the servo will also be dependent on distance from servo to pickup bobbin. Yes I would be interested in updating speed all the time. thank You!

Edit: I changed the code and it works better. What is interesting is every 10 cycles the servo stops momentarily, then resumes. I noticed it do it before also. It looks like it starts out at given speed then gets a bit smoother and cycles a bit shorter on rotation each cycle, then stops, and starts again and repeats.

The main thing that needs to be worked around is the DELAY command, which is a blocking command. So, instead of using DELAY, you can write a subroutine that stays in a while loop for the duration of the delay. Inside of the while loop, you can put your code for reading the potentiometer and updating the speed.

The nb_delay subroutine that I show in this forum post is basically what we want, but instead of reading a button in the while loop (i.e. button_a if sequence_a endif) you can put your code for updating the speed. To make it easier to read, you could put the code for updating the speed in its own subroutine as well. The last thing you would need to do is change all of the DELAY commands to call nb_delay instead. All together, those changes to your script would look something like this:

begin
  1200 6218 0 0 0 0 0 0 0 0 0 0 frame_0_1_3..11 # Frame 0
  1200 5709 frame_0 # Frame 1
repeat


#non-breaking delay subroutine:
sub nb_delay
  get_ms  		#save the time you entered the while loop
    begin dup get_ms swap minus 0 peek less_than   	#compare that to current time
      while		#this while loop runs during the "delay"
        update_speed
      repeat
  drop drop #empty the values on the stack before returning
return


#Subroutine for reading the pot on channel 2 and updating the speed of servo 1
sub update_speed
  2 get_position  #get the value of the pot, 0-1023
  50 divide 5 plus  #scale it 
  0 speed #set speed of servo 0 based to the value
return


sub frame_0_1_3..11
  11 servo
  10 servo
  9 servo
  8 servo
  7 servo
  6 servo
  5 servo
  4 servo
  3 servo
  1 servo
  0 servo
  nb_delay
  return

sub frame_0
  0 servo
  nb_delay
  return

By the way, that sounds like a neat project! If you are willing to share more about it after you get it working, you might consider posting details in the share your projects section of our forum; it would be neat to see a video of it in action!

Brandon

Thank you Brandon! This works now like I wanted it too! Now I can see how the scaling and how the code works. Yes when I get this project finished I will post in the share projects for sure.

1 Like

I want to put a small script in to set the servo to center only at startup, a one shot. Would I be able to put a sub routine in just before the while loop?

It sounds like what you are describing is correct. The REPEAT command makes the code return to the BEGIN command, so if you want some code to run only once on startup, you can put it at the top of your script before the BEGIN command. Please note that it does not need to be a separate subroutine (generally, the benefit of subroutines is that you can call them from multiple places within your script without having to re-write the same code, but they can also be used to make the code more readable).

Brandon

What is odd when I run the servo it will creep one direction. The swing is the same but the servo creeps so then my target center isn’t where I want it. Also it jitters in the same spot as it moves back and forth, maybe the pot in the servo is wonkey? A servo may not hold precision enough, I might have to use a stepper motor.

I suspect that kind of problem is probably coming from your servo (since your script was using hard-coded values that should not drift). For example, something in the mechanical system might be slipping (e.g. an internal gear, the feedback potentiometer, the servo horn). Has it always drifted, and has the problem gotten worse over time? You might try replacing it with a different servo before redesigning your system to accommodate a stepper motor.

Brandon

OK, so what I am going to try is: I have a 12vdc geared motor that I am going to try. Maestro 12 will not energize a 5 vdc relay directly from an OUT. Do I need to build a trigger circuit with say a 2n2222A?

Thanks!

In general, if your relay cannot be triggered directly from a Maestro channel configured as an output, you could try using a MOSFET to trigger it like you described.

By the way, it is not clear to me how you are planning on using a gear motor and relay to replace your servo. Is your servo a continuous rotation servo?

Brandon

No it is a regular hobby servo FS5106b. I had purchased 2 of them but one does not work. What I am going to do is the gear motor is not real fast and I have a speed control for it also. I am going to use the same script as before but use it as an output instead of a servo. This way I can use the on/off of the out put to energize a DPDT relay. In the off state the motor will turn one direction and energized it will reverse. With the same script it should oscillate back and forth. I am just trying to use parts I have already laying around. If it doesn’t work then I will probably go stepper. Of course the electronic Gremlins that hang out around one’s workbench may intervene :woozy_face: too!