Arduino Forum

Topics => Robotics => Topic started by: rzrshrp on Jul 20, 2011, 08:01 pm

Title: Servo motor interfacing
Post by: rzrshrp on Jul 20, 2011, 08:01 pm
I'm new to Arduino.  Got a vts 05B today and don't know how to control it. I tried out the sweep example but once the motor arm turns through 180 degrees, it doesn't return to its original position. I've tried changing the position limits in the example.

Code: [Select]
void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}


void loop()
{
  for(pos = 0; pos < 5; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(100);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 5; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                               
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(100);                       // waits 15ms for the servo to reach the position
  }
}
Title: Re: Servo motor interfacing
Post by: AWOL on Jul 20, 2011, 09:42 pm
Code: [Select]
 for(pos = 0; pos < 5; pos += 1)  // goes from 0 degrees to 180 degrees

Clearly, it does no such thing.

Code: [Select]
delay(100);                       // waits 15ms for the servo to reach the position
Hmmm.

Can you describe what you  observe, and how that differs from what you expect to observe?

Quote
Got a vts 05B today

What's that?
Title: Re: Servo motor interfacing
Post by: rzrshrp on Jul 21, 2011, 07:13 am
It was originally the example code and the values were modified.
Even though I set the pos limit as 5, my servo still rotates through 180 degrees.

The delay is 100ms. Forgot to change the comment when I modified the value.

VTS 05b is the servo motor
Title: Re: Servo motor interfacing
Post by: mem on Jul 22, 2011, 06:53 pm
Are you sure you have uploaded the changed code?

perhaps add some Serial.print statement to show the value being written to pos.
(don't forget to add a Serial.begin statement in setup)
Title: Re: Servo motor interfacing
Post by: zoomkat on Jul 24, 2011, 01:19 am
Simple servo test code for use with standard hobby servos.

Code: [Select]

// zoomkat 10-4-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readString;
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(2000); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1); 
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string
    int n;
    char carray[6]; //converting string to number
    readString.toCharArray(carray, sizeof(carray));
    n = atoi(carray);
    myservo.writeMicroseconds(n); // for microseconds
    //myservo.write(n); //for degees 0-180
    readString="";
  }
}

Title: Re: Servo motor interfacing
Post by: mem on Jul 24, 2011, 03:45 am
it looks like the sketch above relies on a delay to determine the end of the serial message. The tester below checks for a character that is not a digit to terminate the message.

You can set the Serial Monitor line ending dropdown to NewLine to automatically terminate a message with a NewLine character when the send button is pressed.

Code: [Select]
// Serial Servo Tester
// Use the Serial Monitor to write a value from 0 to 180
// Set Serial Monitor line ending to Newline
// for writeMicroseconds, use values from  544 to 2400

#include <Servo.h>

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

void setup()
{
 Serial.begin(9600);
 myservo.attach(9);  //the pin for the servo control
 Serial.println("Enter angle between 0 and 180 (values from 544 written as Microseconds)");  
}

void loop() {

 while (Serial.available()> 0) {
   int inChar = Serial.read();
   if (isDigit(inChar))
   {
     // if the incoming character is a digit, add it to the string
     inString += (char)inChar;
   }
   else
   {
     // here on the first character that is not a digit  
     int value = inString.toInt();
     if(value >= 544)
     {
       Serial.print("writing Microseconds: ");
       Serial.println(value);
       myservo.writeMicroseconds(value);
     }
     else
     {  
       Serial.print("writing Angle: ");
       Serial.println(value);
       myservo.write(value);
     }
     // clear the string for new input:
     inString = "";  
   }
 }
}


edit: fixed a typo in a comment
Title: Re: Servo motor interfacing
Post by: zoomkat on Jul 24, 2011, 07:34 am
My compiler has an issue with the below line.

    if (isDigit(inChar))
Title: Re: Servo motor interfacing
Post by: mem on Jul 24, 2011, 10:11 am
You are probably not running the latest Arduino release

replace if(isDigit(inChar)) with: if (inChar >= '0' && inChar <= '9')

This version will compile on earlier Arduino releases
Code: [Select]
// Serial Servo Tester
// Use the Serial Monitor to write a value from 0 to 180
// Set Serial Monitor line ending to Newline
// for writeMicroseconds, use values from  544 to 2400

#include <Servo.h>

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

void setup()
{
  Serial.begin(9600);
  myservo.attach(9);  //the pin for the servo control
  Serial.println("Enter angle between 0 and 180 (values from 544 written as Microseconds)"); 
}

void loop() {

  while (Serial.available()> 0) {
    int inChar = Serial.read();
    if (inChar >= '0' && inChar <= '9')
    {
      // if the incoming character is a digit, add it to the string
      inString += (char)inChar;
    }
    else
    {
      // here on the first character that is not a digit   
      int value = inString.toInt();
      if(value >= 544)
      {
        Serial.print("writeing Microseconds: ");
        Serial.println(value);
        myservo.writeMicroseconds(value);
      }
      else
      {   
        Serial.print("writing Angle: ");
        Serial.println(value);
        myservo.write(value);
      }
      // clear the string for new input:
      inString = "";   
    }
  }
}
Title: Re: Servo motor interfacing
Post by: AWOL on Jul 24, 2011, 03:23 pm
Quote
if(value >= 544)

Doesn't the "Servo.write" method already do this for you?
Title: Re: Servo motor interfacing
Post by: mem on Jul 24, 2011, 05:33 pm

Quote
if(value >= 544)

Doesn't the "Servo.write" method already do this for you?

Yes, values equal to or greater than  544 are  handled by Servo.write as microseconds. However the code as posted does the same thing and is preferred because its function is clearer.