So there's a presentation on controlling a basic servo at ITP on the very subject: class 3 (communication, servos, and pwm). As luck would have it, I have a continuous rotation servo, which functions a bit differently than the servo described in the presentation. In short, both types of servos use pulse width modulation (PWM) but the continuous rotation servo operates in terms of a "set point" and left and right rotation. You can also control speed.
UPDATE 2008-8-3: We ended up using "normal" (i.e. non-continuous) servos. So things work a bit differently now.
The servo is pictured above. I found a pdf with specifications and Basic Stamp code on Parallax's web site. From the instructions I figured out the important numbers. The servo wants intervals of 20ms and pulse widths of 1.5ms if it's going to do nothing. Widths greater than 1.5ms turn the servo counterclockwise, widths lower than 1.5ms turn the servo clockwise. When the servo is receiving 1.5ms width pulses, it's possible to adjust the set point with a tiny Phillips screw driver.
Here's my translation of BASIC Stamp 1 code into Arduino. The code should make the servo stay still, rotate left, rotate right (and repeat).
Basic Stamp 1 code
SYMBOL Temp = W0 'Work space for FOR NEXT
SYMBOL Servo_pin = 0 'I/O pin that is connected to servo
FOR temp = 0 TO 200 '
PULSOUT Servo_pin,150
PAUSE 20
NEXT
FOR temp = 0 TO 200
PULSOUT Servo_pin,180
PAUSE 20
NEXT
FOR temp = 0 TO 200
PULSOUT Servo_pin,120
PAUSE 20
NEXT
Stop
Arduino
int servoPin = 7;
void setup()
{
pinMode(servoPin,OUTPUT);
}
void loop()
{
int temp;
for (temp = 0; temp <= 200; temp++)
{
digitalWrite(servoPin,HIGH);
delayMicroseconds(1500); // 1.5ms
digitalWrite(servoPin,LOW);
delay(20); // 20ms
}
for (temp = 0; temp <= 200; temp++)
{
digitalWrite(servoPin,HIGH);
delayMicroseconds(1800); // 1.8ms
digitalWrite(servoPin,LOW);
delay(20); // 20ms
}
for (temp = 0; temp <= 200; temp++)
{
digitalWrite(servoPin,HIGH);
delayMicroseconds(1200); // 1.2ms
digitalWrite(servoPin,LOW);
delay(20); // 20ms
}
}
That's it!
Hey!
If I am not mistaken, the frequency at which pulses should be given is 50Hz, which is 20ms as you pointed out.
So, if the pulse is HIGH for 1.5ms, it should be low for 18.5ms, giving a total of 20ms. And then this process repeats to give a 1.5ms pulse at 50Hz.
In your code, you give a 1.5ms pulse and then wait for 20ms which would give a period of 21.5ms instead of 20ms.
Though not a problem, as servos still work, but just to be precise
Thanks!
I just try and it works very well
Thanks
very simple works great. thanks a lot.
can someone help me with writing a code for servo rotation in C Language.
thanx
Thanks, but I was unable to control rotation speed by changing pulse width.
Parallax CR servo.
Are you sure that this servos can change speed in respond to change of pulse width?
If yes – it means that either I do something wrong, or my servos are in bad condition.
@amdei, I don’t think I ever managed to control the speed of rotation (i.e. fast or slow). I think it was either left rotation, right rotation, or off. Good luck getting yours to work.
PLease try this one (it is working fo a Parallax CR Servo):
orfeus, that code didn’t work quite right for me…
I am playing with the CR (continuous rotation) servos from adafruit, and what I’m noticing is that first of all- I had to calibrate the servos to actually operate at a 1500 stop…
Then I have started some testing (just got some new equip, so I didn’t play with it too long yet…), but here’s the code I’m using. The key for me was to start with setting my pulse to 1500, then putting a philips jeweler screwdriver into the calibration port of the servo, and turning until I got no movement, then I played with the code to get this going.
It requires either Arduino 017, or the ServoLibrary btw:
#include
Servo srv0;
void setup()
{
srv0.attach(9);
}
int ctr = 1500;
int sspacer = 200;
int smin = ctr-sspacer;
int smax = ctr+sspacer;
int step = 10;
int s0 = ctr;
int n0 = -1;
void loop()
{
s0 = (s0 + n0*step);
if ((s0 = smax))
n0 = n0 * -1;
srv0.write(s0);
delay(100);
}
PLease try this one (it is working fo a Parallax CR Servo) (I posted again but I had wrong email sorry, maybe that is why it is not validated) Please delete the above.
/*
* Serial Port Continuous Rotation Servo – Movement and Speed Control
* ————–
*
* Alteration of the control interface to use keys
* to slew the servo horn left and right. Works best with
* the Linux/Mac terminal “screen” program.
*
* Created 10 December 2007
* copyleft 2007 Brian D. Wendt
* http://principialabs.com/
*
* Adapted from code by Tom Igoe
* http://itp.nyu.edu/physcomp/Labs/Servo
*
* Adapted for Continuous Rotation Servo (Parallax)
* by Orfeus (for http://www.grobot.gr)
* v.200910211932
*
* For Serial Port Terminal on Windows I used PuTTY SSH Client
* ( freeware at http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html )
*/
/** Adjust these values for your servo and setup, if necessary **/
int servoPin = 2; // control pin for servo motor
int minPulse = 1170; // minimum servo position
int maxPulse = 1770; // maximum servo position
int turnRate = 75; // servo turn rate increment (larger value, faster rate)
int refreshTime = 20; // time (ms) between pulses (50Hz)
/** The Arduino will calculate these values for you **/
int centerServo; // center servo position
int pulseWidth; // servo pulse width
int moveServo; // raw user input
long lastPulse = 0; // recorded time (ms) of the last pulse
void setup() {
pinMode(servoPin, OUTPUT); // Set servo pin as an output pin
centerServo = maxPulse – ((maxPulse – minPulse)/2);
pulseWidth = centerServo; // Give the servo a stop command
Serial.begin(115200);
Serial.println(“Arduino Serial Continuous Rotation Servo Control”);
Serial.println(” by Orfeus for GRobot.gr”);
Serial.println(” Press to move, spacebar to center”);
Serial.println();
}
void loop() {
// wait for serial input
if (Serial.available() > 0) {
// read the incoming byte:
moveServo = Serial.read();
// ASCII ” is 46 (comma and period, really)
if (moveServo == 44) { pulseWidth = pulseWidth + turnRate; }
if (moveServo == 46) { pulseWidth = pulseWidth – turnRate; }
if (moveServo == 32) { pulseWidth = centerServo; }
// stop servo pulse at min and max
if (pulseWidth > maxPulse) { pulseWidth = maxPulse; }
if (pulseWidth = refreshTime) {
digitalWrite(servoPin, HIGH); // start the pulse
delayMicroseconds(pulseWidth); // pulse width
digitalWrite(servoPin, LOW); // stop the pulse
lastPulse = millis(); // save the time of the last pulse
}
}
/* Orfeus 200910212001 */
Sorry to all, it seems that I can’t post all the sketch. You can find it here : http://www.grobot.gr/phpBB3/viewtopic.php?f=23&t=333
Use a small turnRate to find your CR Servo “zero” point (so you dont have to use a screwdriver – mine didnt have such a control).
There is a simple video showing the result (in low quality unfortunately).
Thnx
orfeus
HI, can any1 help on using c language control 2 Parallax CR Servo
hello,
mine doesn’t work it wouldn’t turn.
i just want that it turns when my potmeter gives like 1023 or so.
can anyone help me please
tnx
Howdy,
Here’s a quick and simple play on the original post that gradually speeds up and slows down with a continuous motion servo. Thanks for sharing your post!
int servoPin = 7;
int fullCounter = 1200; // 1.2ms
int stopped = 1500; // 1.5ms
int fullClock = 1800; // 1.8ms
int dirInt = 1500; //stopped to start
int dir = 1; //add 1 ms per loop untill hitting 1800, then -1 until 1200
void setup()
{
pinMode(servoPin,OUTPUT);
}
void loop()
{
digitalWrite(servoPin,HIGH);
delayMicroseconds(dirInt);
digitalWrite(servoPin,LOW);
delay(20); // 20ms
dirInt += dir;
if(dirInt >= fullClock)
{
dir = -1;
} else if(dirInt <= fullCounter) {
dir = 1;
}
}
If you use the above code and “0″ all the “1″ you can change “int dirInt = 1500; ” to find the nul point for your servo. for my servo int dirInt = 1410 worked and then I replaced the “0″ with “1’s” again, and then run the program again with dirInt=1410 and it worked great. Some servos are hard to adjust the nul point. I then write the nul point on the servo, and use it to plug into other programs.
Hi, recently I am doing a project with a parallax servo and a distance sensor. I m trying to use the servo as a winch, so that if the sensor sense something, it moves to right for some rotation and stop. On other hand, if sensor didnt sense anything then it moves to left for some rotation and stop.
I have been trying different codes but just cant get the servo to stop.
Can anyone help me with coding on arduino?
THANKS