Newbie in need of advice about servo controlling

Hi! I’m completely new in robotics. I come from the bicycle world and that’s what brought me here.

Bicycles, above all, MTB’s are becoming more and more complex these days, this resulting in the fact that you can have as many controls in your handlebars as in a car’s dashboard.

To name a few: front shifting (2 levers), rear shifting (2 levers), front suspension control (1 lever for lock, 1 more fo travel, sometimes a knob for other adjustments), rear suspension control (this is just one lever).

All this is a mess and a perfect source of mistakes and mechanical failure since all of these controls are purely mechanical.

I think it is possible to get rid of all this mess using servos to move the mechanical systems in place, instead of using a mechanical control connected with the systeme itself by a cable.

So, my idea is to use servos, first of all to make the most complex task, which is also the one that is used more often: gear shifting.

What I think is that attaching a servo to a rear derailleur and transfering motion by a push rod you have something far more realiable and simple than the complex index system we all ride today.

The problem is I’m fairly competent on mechanics but have no idea of robotics. So, the question:

How do I and what do I need to control a servo that is able to stop in 9, 10 o 11 diferent positions (each one for a sprocket)?

I thought using a Futaba servo controlled by a Pololu Micro Serial Servo Controller would do the job… but how do I program the different positions I need the servo to stop in? Any software needed, can the controller be connected to a PC?

As you can see, very basic doubts…

Once I get the rear shifting to work, I would try to control the rest of the stuff using more servos as I understand this controller can handle up to 8 servos and the rest of the task are asier to do, usually implying just 2 stops.

I hope my message is clear. Thank you in advance for your help

Hello,

Instead of the Micro Serial Servo Controller, I’d recommend our new Micro Maestro Servo Controller. The Micro Maestro has a PC application that lets you control your servos while it is connected to your computer via USB. The program also has a sequencer, which would let you set up the ten different servo positions. You need to make sure that your servo has the range of motion (and resolution) that will let you accurately command it to go to the different positions. How far does the push rod move between gears? How far does it need to move to cover all 11 positions? Does the circular motion of the servo work for actuating the push rod, or do you need some other linkage there?

Another feature the Maestro has is that you can use some of the servo channels as analog inputs. You could attach a potentiometer to the analog input and then write a small script (stored on the Maestro) that would go to the correct position based on that input.

Does this answer your questions?

- Ryan

Yes, it does. Thank you very much!

After writing the post I saw the new Maestro controller. That makes much more sene to me since I have no idea of programming language and although I could learn some and I really want to do it as soon as possible, I would like to test the “electronic shifting” in the next two months to take a decision on if racing it this year or not.

The mechanical part of the system is the one I have thought more about, and I think it is more than feasible. I need around 50º from the servo. 10 positions is fine. It’ll be connected just by a push rod or maybe, if the servo itslf is not too bulky, I can attach it directly to the paralelogram arm it has to move on the shifting mechanism of the bike itself (what we call derailleur).

In terms of accuracy, all I need is +1º/-1º, that’s part of the advantage of servo controlled system, I think. A cable actuated mechanical system is far from the accuracy a servo can deliver.

Just a couple of questions more:

Once the servo gets to a selected position, I suppose that if the mechanical system suffers a physical input that tends to move it from the selected position, the servo will react to correct the position back. Am I wrong?

I would need to have two input buttons: one that select one step clockwise in the circular motion and another that does just the opposite. It would be a sequential control: one click in one button means one position clockwise, two clicks, two positions clockwise… and the same but countrclockwise for the other button. Is that possible? Too complicated? If so, any other suggestion for the “human interface”?

Oh, I lied, there’s a third question ;). Does the controller have a software to program it from the PC or do I need something else?

Thank you again.

Sounds like you have a good grasp on the mechanical aspects of a servo, and whether it will work for you.

  1. You are right that a servo will try to correct its position. This can be a problem if the servo has weak gears that cannot withstand the forces generated by the motor and the environment. (Plastic servo gears break often when people try to strain against the servo.) I suggest you try to see roughly how much torque the derailleur will be putting on the servo and get a servo that is rated for much more than that much torque.

  2. Your two input button approach is possible with the Micro Maestro, and it’s not “too complicated.” The human interface I mentioned in my last post might be nice: use a potentiometer to control the servo position. Using a potentiometer would only require using one of your servo channels as inputs (the button approach would require two).

  3. Our website has a free PC application that you can download that programs the Maestro via USB (you will need to buy the USB cable). You can download and install the application before buying the Maestro to get a sense for what it is like.

- Ryan

That was of great help.

I had thought about the “Power HD Mini Digital Servo HD-1810MG”. If I understood something after all I have read about servos reciently, digital means more torque and metal gears is advisable for the kind of enviroment this thing is going to be submitted to.

3.9 kg cm is a lot. If the derailleur has to deal with more something is going really wrong and most likely the chain will snap before the servo does… So I think the specifications are all right.

And the idea of the potentiometer is growing on me. Seems very user friendly.

Thank you very much for your advice. I’ll keep posting as soon as I have started to build. If everything goes fine, I’ll try t control front shifting and suspension using servos too.

You’re welcome for the help.

If you are eying the HD-1810MG, you should really consider the Power HD High-Torque Servo HD-1501MG. About the same price, a lot stronger, and it has these blue rubber bands that help seal the servo. It’s not an all-weather servo by any means, but every little bit helps. Another thing to consider, though, is that it will definitely draw more power than the smaller HD-1810MG.

We would love to hear about anything you make using our products. We will post cool projects on our community projects page.

- Ryan

I`ll take your advice. And will keep you informed. Thank you again.

So far the mechanics are done. Time for programing. I’ve been testing the system in the harsh conditions typical of a full suspension mtb like the one in the video, 5.75" of rear travel, and everything works just fine. By now i’m controlling it using a potentiometer.

Now I will try to write a srcipt based on the example “using a button or switch to control servos” to control it using a button to upshift and another to downshift, as usually happens with mechanical derailleurs.

Any suggestion will be appreciated.

Thank you.

Great to see that it is working! I would love to see some closeups of the mechanism that show how the parts connect together. And we would be happy to help you if you get stuck with your Maestro code.

-Paul

Here are the pics that show how everything is screw together:

I got to make it work using the Maestro control Center or a servo tester. Now I’d like to make it as user friendly as possible.

To do so i’d like to have a user interface as similar as possible to the one of a normal bicycle. Usually bicyce gears are controlled by two levers. One of them shifts to a lower gear, the other shifts to a higher one.

Problem is I’m new in programming. I’m using your example on “Resources » Pololu Micro Maestro Servo Controller User’s Guide » 6. The Maestro Scripting Language> Example Scripts>Using a button or switch to control servos”.

By now I was able to change the values before the “frame” subroutine so the derailleur engages the cogs just perfect. I’ve put 9 different values, so it engages all the 9 cogs the bike has.

Problem is using this script I can only “upshift”, this is, going to the next frame on the sequence when I push a button that I’m calling “+”. But I need the system to “downshift” (going to the former frame on the sequence) everytime I push another button called “-”.

Up to now i’ve been unable to do so.

Any help would be appreciated.

Thank you.

Okay, that is going to be a pretty major change to the structure of the example program, so you should take it one step at a time. Here is what I recommend.

  • Write subroutines button0 and button1, for your two buttons, equivalent to the original button.[
  • Write a wait_for_both_buttons_open_10ms that waits for both buttons to NOT be pressed for at least 10ms. You will probably need to use the OR command. You can test it by temporarily changing the 10ms to 10000ms.
  • Similarly, write wait_for_either_button_closed_10ms, which will also require the OR command.
  • Modify wait_for_button_press to leave a value on the stack that indicates the number of the button. You can do this simply by checking whether button 1 is pressed - just add a button1 command at the end of the function, and you will get a 1 if it was that one that was pressed; a 0 otherwise. (There is a small chance that the button will no longer be pressed when this code is run, which would result in a brief button 1 press being interpreted as a button 0 press - make a note to yourself to improve this if you ever run into problems.)
  • Modify your main code - either with a counter or a bunch of goto statements, so that it goes through the frames the way you want it to!

If you get stuck along the way, let me know exactly where you are and post some of the code you tried - I am sure I can help you make it work!

-Paul

Thank you very much!

That las post was really helpful. Will try to write some code in the next two days and then post the result.

It seems I’m making some progress…

Not a great video, I know :), but I got to make it work using 2 microswitches, one for upshift, one for downshift.

I wrote some code following your advices: Basicly I follow the button example structure but there are some tweaks.

The subroutine wait_for_button_open now has:

begin
button+ logical_or button-

Both button+ and - subroutines are identical and the same as in the example.

Then in the subroutine wait_for_button_closed everything has changed:

begin
button+
if
1 0 get_position over 480 times plus
0 servo
drop
500 delay #here I will comment later
0 get_position 100 minus
0 servo
500 delay
else …

Comments: the first 500 delay line tries to create an “overshift”, I mean, the derailleur is moved towards a position further than it reamins later so the chain jumps more quickly. After the chain has jumped, it returns to a positon where it makes no noise. I tried a delay of 3000 ms, buy strangely it seemed not to hold the “overshift” three seconds but just delay three seconds the response to a new button push. Any idea why?


button-
if
0 get_position
5200 less_than if -1 0 get_position over 300 times plus
0 servo
500 delay # this delay here is to avoid incidental multiple shifts by a button that’s been pushed for too long. It happened a couple of times and I don`t know if there’s a better solution.
else
-1 0 get_position over 550 times plus
0 servo
500 delay # again we have overshifted and after 500 ms we’re back to the position where the sytem makes no noise
0 get_position 120 plus
0 servo
500 delay
endif
else
endif
endif
repeat

As I said, the buton+ and button- subroutines reamin unchanged, they’re identical to the button subroutine in the example.

Any comments? I suppose this is very improvable since is the first time I ever program something. I’ve just understood how the Stack works by using the “Step script” function.

I need to test it further and out of the bench, but up to now only flaws is sometimes I get a stack overflow, I think because I’m missing a “drop” somewhere, but I can’t see where.

Apart from that, an electronic controlled derailleur allows you functions that are plain impossible on mechanical systems like the “overshift”.

It is great that you are getting it to work! Anyway, to debug your code, I would recommend simplifying eveyrthing as much as possible - unplug your Maestro from the servos and just leave the buttons connected to it, then step through the program within the Maestro Control Center. If there is a problem, you should be able to identify exactly which line it occurs on. If you can’t, try removing unnecessary lines of code until you have the simplest possible script that demonstrates the problem - for example, just

0 get_position 480 plus
500 delay
0 get_position 100 minus
0 servo

(I have removed all of the button commands, and the OVER, TIMES, and DROP commands did not seem to be doing anything useful anyway.)

Run it in the Control Center and see whether it does what you want. Then try adding features back in until you find the source of the problem.

By the way, you are not following the steps in my recommendation - the whole point of the button debouncing in the example I was building on is to eliminate the final 500 ms delay. If you get this thing working the way you are doing it now, you should take another look at what I suggested.

Good luck!

-Paul

Again, very, very helpful. I really thank you because it would be impossible for me alone to get all this thing working.

I consider myself a fairly competent bicycle mechanic, but as I said before, I have no idea of programming, that’s why I’m sure I’m doing a lot of things wrong.

In those lines of code you post, I get nothing on the stack after the button+ and button- subroutines, so first i put an 1 or -1 on the stack, then get the position, then put the 1 or -1 on top and multiply it by a number to increment the position of the servo.

I will try your code to see if the fact that until now i’ve been stepping through the code with a servo connected is confusing me.

I’ll try too to build in your debounce strategy. I confess I don’t know exactly how it works.

I will check my code and try to follow your advices, and then post the results.

Anyway, here are two more videos (my rushed low quality videos :slight_smile: ) that show the shifter I built and how the system works in real mtb conditions.


Thank you again

Hello,

It is great to see how well the shifting is working!

Anyway, the lines of code I posted did not include “button+” or “button-”, so I am not exactly sure what problem you are having. But the following two lines:

-1 0 get_position over 300 times
0 get_position -300

should be exactly equivalent. Do you have any problem replacing the more complicated one by the simpler one?

The general idea with debouncing is to make sure that the button is held in a consistent state before moving to the next step - for example, it must be released for > 10ms, then pressed for > 10ms to register as a button press. But I think you should get your version working first before moving onto that, as it is a bit more complicated.

-Paul

I’ve been checking the debouncing code and now I see how it works.

I’ve just written the following script:

begin
wfbo10
wfbc10
repeat

sub wfbo10
get_ms
 begin
  button+ logical_or button-
  if 
    drop get_ms
  else
    get_ms over minus 10 greater_than
    if drop return endif
  endif
 repeat

sub wfbc10
 get_ms
 begin
  button+
   if
    get_ms over minus 10 greater_than
    if drop goto up follow: return endif
   else
    drop get_ms
    button-
    if
     get_ms over minus 10 greater_than
     if drop goto down follow1: return endif
     else
     drop get_ms
    endif
   endif
  repeat

up:  
    1 0 get_position over 520 times plus
    0 servo
    1000 delay
    0 get_position 120 minus
    0 servo
    drop
    goto follow
    
  
down:
    0 get_position 6400 greater_than 
    if
    -1 0 get_position over 850 times plus
    0 servo
    1000 delay
    0 get_position 100 plus
    drop
    else
    -1 0 get_position over 350 times plus 
    0 servo
    1000 delay
    else 
    drop endif
    drop
    endif
    goto follow1
   
sub button+
  1 get_position 500 less_than
  return

sub button-
  2 get_position 500 less_than
  return

Long and complicated but depending on the po

It works when I press the “+” button, but it doesn´t when I press “-”. And strangely it does work for both if I step the script manually, so I think what you told me some posts ago is happening. Anyway I’ve just thought of splitting wait_for_button_close in two subroutines: wfb+c10 and wfb-c10 and see how it works.

I will try to follow your advices on the last post as soon as possible.

Again, your help is being really appreciated and helpful. I’m learning a lot.

Hello,

Glad you are learning. It is not easy to write such complicated programs in the Maestro script language! By the way, if you use the Code button when posting your code, it will look a lot more readable. I have updated your latest post in that way.

Anyway, it looks like you have not finished with the second step in the step-by-step plan I suggested. Your function wfbo10 clearly will not work. Did you test it? The problem is that you need to run both BUTTON+ and BUTTON- before you do the LOGICAL_OR. I am also confused about wfbc10, which seems to do a lot more than just waiting for a button to be closed.

-Paul

BTW, I’m so sorry I can’t get screenshot in this computer.

I’m trying to take your advices step by step, and I feel i’m really making progress. I have used the bicycle this weekend and it is amazing how the “robotic shifting” performs.

I will post soon a new version of my code I’m finishing following your advices, but after this weekend I’d like to improve the quality of the servos I’m using because I think they are the weakest link now.

Is it possible to use digital servos with the Micro Maestro? I suppose this is a very basic question, but I want to be sure before I take the step of movng towards better and more exoensive servos.

Thank you again.