Servo Library

Hi,
this is "Squarenut" again with a very elementary problem.
Two servos are moving the wheels of my Arduino carriage.
Since the servos are mounted mirror image to each other, to make the carriage go straight one servo has to turn clockwise and the other counterclockwise.
I start my sketch including the Servo library and defining the output pins as follows:

*/
#include <Servo.h>
Servo servoLeft; // Define left servo
Servo servoRight; // Define right servo
void setup()
{
servoLeft.attach(10); // Set left servo to digital pin 10
servoRight.attach(9); // Set right servo to digital pin 9
}

Then, I need to create the subroutines for going forward(), reverse(), turnRight(), turnLeft(), and stopRobot().
One example of code I found loops the subroutines as follows:

void loop() // Loop through motion tests
{
forward(); // Example: move forward
delay(2000); // Wait 2000 milliseconds (2 seconds)
reverse();
delay(2000);
turnRight();
delay(2000);
turnLeft();
delay(2000);
stopRobot();
delay(2000);
}

As an example, the forward() and reverse() routines are defined as follows:

// Motion routines for forward, reverse, turns, and stop
void forward()
{
servoLeft.write(0);
servoRight.write(180);
}
void reverse()
{
servoLeft.write(180);
servoRight.write(0);
}

Low and behold the carriage moves forward, then reverses and I get totally confused.
Why the carriage goes forward (both wheels turn in the appropriate direction for 180 deg) when the code tells the left Servo to stay still?[servoLeft.write(0)]
And viceversa for the reverse()?
Are there some commands in the library that I do not understand?
Where can I learn the commands that are in the Servo.h library?
I feel stupid, but I hope is normal for a newbie.
Thanks.

servoLeft.write(0)]

That doesn't tell it to stay still, it tells a servo to turn to its zero degree position.

You don't have a servo, you have an ex-servo that has lost the ability to turn to a specific angle, so "servoLeft.write(0)" tells the servo to move in the direction it would turn had it still been able to turn to the zero degree position.

Thank you very much AWOL

please, stay with me on this.
I now understand the servoWrite() standard methods.
The library reference says:

write(int)
* Set the angle of the servo in degrees, 0 to 180.*

However, the Arduino web site says:
This library allows an Arduino board to control RC (hobby) servo motors.
Servos have integrated gears and a shaft that can be precisely controlled.
Standard servos allow the shaft to be positioned at various angles, usually between 0 and 180 degrees.
Continuous rotation servos allow the rotation of the shaft to be set to various speeds.

I presume this means that a continuous rotation servo is not limited to 180 deg.
This is where I need help.
I understand my servos are of the continuous rotation type (SPRINGRC SM-S4303R)
What's the correct code to instruct a continuous rotation servo to run indefinitely and to reverse motion and to set different rotation speeds?

Thanks again for your help.

There is no "correct" code - it depends on the ex-servo.
An "angle" of 90 should cause it to stop, with +/- about 10 "degrees" either side of this being the range where speed may be controlled; beyond this, the ex-servo will probably run at maximum speed.

Sometimes, the only way to find the stop point is by experimentation, sometimes the ex-servo has a trim-pot to allow you to set it. zoomkat often posts simple servo code to allow you to set values via the serial monitor.
If you find that there is no single value, and it creeps in one direction or the other, you can try using "writeMicroseconds" which gives slightly finer control.

Thanks,
I'll keep experimenting by trial and error.

I am new to arduino but I'm planning to build a small cart also. I recently purchased a number of Spring RC servos, including two of the SM-S4315R high torque continuous rotation servos. I calibrated each of the servos manually using the writeMicroseconds command from the servo library.

Plug random numbers between ~540 to ~2400 into writeMicroseconds() and then count the number of revolutions in 60 seconds for each number you plug in. If you graph this data you will see that you can correlate writeMicroseconds() values to specific values of RPM.

Note that if you change the voltage to the servos, this may change the curve slightly.

At ~5.3 V, here is the curve I got for my two servos:

Notice from the graph that there is a 'dead band' in the center where I will get 0 RPM over a range of writeMicroseconds() values. I will probably want to write software that collapses this zone. Otherwise, I could end up writing a program that expects the cart to move very slowly, yet the cart doesn't move at all.

Also notice in the graph that there is a range in which the Microseconds and the RPM are pretty much linear, but at high and low RPMs the graph starts to curve and levels off at the max/min RPM.

Hope this helps!

If you graph this data you will see that you can correlate writeMicroseconds() values to specific values of RPM

how does the graph look if you load the ex-servo?

That's a rather complicated question. I'd imagine that depends on what the load is and what voltage you're running the servo at.

I don't have any sophisticated servo test equipment so I'm not sure. I guess I could try attaching a spool with a weight hanging from a string to get consistent load, but my power supply probably isn't regulated sufficiently to make that experiment repeatable. (I'm using an old 5V 700ma cell phone charger with the connector cut off. This powers the servos while the Arduino runs on USB. The cell phone charger voltage fluctuates up to ~0.3 V and I'm using 4000uF of spare capacitors to try to smooth out the pulses.) I have a LiPo battery and a 4A UBEC coming in the mail so maybe I can follow up later on when I have better toys.

That's a rather complicated question.

And it is a question which, I'm sorry, probably makes your graph pointless.

Squarenut:

Have you followed this series of articles in Servo Magazine? You do need to subscribe...

Is there anything there that might help?

I have most of the series -- I will try to look later. But if you have already seen them and they don't help, there is no point.

And it is a question which, I'm sorry, probably makes your graph pointless.

Perhaps I gave the wrong impression in my post. My intent was to illustrate a cheap way for a beginner to start using a continuous rotation servo without having to buy any expensive equipment.

The exact numbers in the graph are only representative of a single servo with one set of environmental conditions. I was assuming that most people would realize that, but that may be a bad assumption.

I admit I'm new here and making things up as I go along based on my engineering experience in other fields. Do you know or can recommend any alternative methods for a beginner to learn to characterize continuous rotation servo performance?

Do you know or can recommend any alternative methods for a beginner to learn to characterize continuous rotation servo performance?

The problem (as I see it) is that there are lots of vendors of servos for various different (usually modelling) puposes.

They'll often have different electronics, motors and mechanics.

How they are used, and how are they are loaded in use will vary immensely.

Your approach is useful, but you need to tell people how to do it for themselves, not simply provide potentially limited, specific results.

Do you know or can recommend any alternative methods for a beginner to learn to characterize continuous rotation servo performance?

I think you have a good handle of the task at hand and understand what you are dealing with. It's very frustrating to try an explain to some beginners that their shiny new continuous rotation 'servo' was only a servo before it was modified for continuous rotation, and that now it's a 'former servo' and now it's only a bi-direction, variable speed, geared DC motor drive unit that happens to use servo PPM commands to command it's direction and speed variables.

The fact that the original servo was not designed to be a bidirectional, variable speed, geared motor drive means the users now has to deal with unknown linearity, unknown deadband and may even find that even two identical modified 'servos' may not even respond identically to the same PPM command values. If two such 'servos' were used to drive a small vehicle (a common desired application) it's probably a good thing that there is some decent deadband in the center of the control line as hoping that two different 'servos' would both be stopped at the same exact microsecond value would likely be most problematic to deal with.

So you are on the right track. But that track will never end with a set of numbers one can pass on to someone else and have it correct all the problems for their specific modified continuous rotation 'servo' for their specific application. At best you can show them a 'road-map' of how you characterized your units and what the final results looks like for your specific application.

By the way nice graphing, and it sure bears out that one good picture is worth a thousand words?

Lefty

Thanks for the help guys. It probably would have been better to eliminate the numbers on the two axes in order to stress that the values I obtained won't be valuable to anyone else, and that every continuous rotation servo will have to be checked individually. I also forgot to mention in my previous post that I had to very carefully tweak the set point of the second servo using the pot in order to get its deadband to match up with the deadband of the first one, which will give the false impression that all SM-S4315R will have the same deadband.

Dealing with continuous rotation servos seems to be a common issue as I've found numerous youtube videos of Arduino cars that don't drive in a straight line. I have a few more ideas on how to add some rigor to the "trial and error" method of dealing with continuous rotation servos.

For me, the biggest initial challenge was determining the domain of uS values over which the speed will be relatively linear, and then mapping the uS domain to a domain that is easier to deal with, such as % of full speed which could range from (-100 to 100). Then comes the part of load vs no-load, which for many projects would not be necessary to characterize.

Would there be any value to putting together some kind of tutorial for beginners to produce a graph of their own? I looked around and didn't find anything like this, but it might already be out there.

Thanks

About the best thing for someone new to continous rotation servos is 1) how standard servos work and how they are made into continous rotation servos, 2) the "stopped" deadband is generally +-5us around the center "stopped" us value, 3) full rotation from "stopped" is generally 100us, 4) various things can make the center "stopped" us position (and full rotation values) change from a little to a lot, and 5) "identical" servos can behave differently to a certain degree. If the continous rotation servo still uses the origional servo pot, substituting a little 15 turn trim pot for it may make adjusting the stopped center point us value easier.