Servo Problem

Hi,
New to the board. This is my first post… here goes. I’m using an Arduino Mega Board, trying to control a servo. I have wired it to digital pin 22. It is the only thing attached. My first question is: How do I use a PWM pin to control a servo? Should I use the digital pin instead?

Secondly- I got the servo working more or less. However, when it travels in one direction, it skips in 5 degree intervals and it takes forever. Can anyone enlighten me? This is the code I’m using.

#include <Servo.h>

Servo myservo; // create servo object to control a servo

void setup()
{
myservo.attach(22); // attaches the servo on pin 22 to the servo object
}

void loop()
{
myservo.write(0); // sets the servo position according to a value
delay(15); // waits for the servo to get there
}

When I use another program to try to control it via a serial connection, I still get next to no movement in one direction. This code waits for a user input from the serial monitor. It turns in one direction just fine, but when I prompt it to turn the other way, it still skips and the prompt displays itself again on the monitor like it is on crack. Here is the code:

#include <Servo.h>

/** Adjust these values for your servo and setup, if necessary **/
int servoPin = 22; // control pin for servo motor
int minPulse = 600; // minimum servo position
int maxPulse = 2400; // maximum servo position
int turnRate = 200; // 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 starting point (or it floats)
Serial.begin(9600);
Serial.println(" Arduino Serial Servo Control");
Serial.println(“Press < or > 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 44, 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 < minPulse) { pulseWidth = minPulse; }

Serial.print("Pulse Width: ");
Serial.print(pulseWidth);
Serial.println(“us”); // microseconds
}

// pulse the servo every 20 ms (refreshTime) with current pulseWidth
// this will hold the servo’s position if unchanged, or move it if changed
if (millis() - lastPulse >= 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
}
}

There is probably a very simple solution to this. I have checked all over arduino’s website and googled it to no avail. I need the helps.

Well one thing you can remove is this:

 // pulse the servo every 20 ms (refreshTime) with current pulseWidth
 // this will hold the servo's position if unchanged, or move it if changed
 if (millis() - lastPulse >= 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
 }

The servo library already handles the refreshing of the last valid command.

Lefty

Thanks for the advice.

I removed this code

// pulse the servo every 20 ms (refreshTime) with current pulseWidth
 // this will hold the servo's position if unchanged, or move it if changed
 if (millis() - lastPulse >= 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
 }

And the servo stopped responding altogether. I don't know why that is happening. I also tried just taking the last line out of the code. That made the servo respond, but still hops.

I may have missed something...

EDIT- Now I have the servo on 9v. It is working now. It is still slower in one direction but it moves at a reasonable pace. Could lack of voltage have been the problem?

Low voltage was causing me issues with my servos, so it certainly could be the cause of your grief. Even a small 5V servo didn't like Arduino-provided 5V power supply - once I moved to external power it all went along happily.

Cheers,

Even a small 5V servo didn't like Arduino-provided 5V

You've got it the wrong way round - the Arduino didn't like the servo dragging down its 5V supply.