Pages: [1]   Go Down
Author Topic: Interfacing a servo with Serial  (Read 513 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I just got an Arduino card, and I have got a servo too.
I'm trying to do a little sketch to control the position of the servo, through the library, just by sending a % into the Serial port, and the servo mooves consequently.
Here is my sketch : What do you think about it ?

Code:
#include <Servo.h>
Servo myservo;
 
void setup()
{
  myservo.attach(9);
  Serial.begin(9600);
}
 
void loop()
{
  byte pos;
  if(Serial.available())
  {
    pos = Serial.read();
    pos = pos/179*100;
    Serial.println(pos, DEC);
  myservo.write(pos);
  delay(15);
  }
}
With this one, when I send for the first time a value through Serial, the servo goes to the opposite side, and stay there (if i enter a 2 or a 98, it's the same !). Then, when I shut the Serial window, the servo goes to the previous value he was at start, and thats's all :'(
I can't fix that problem. What can I do ? :smiley
Thanks, and I hope you will be able to fix my beginner problem...

PS : Sorry for my bad english, it's hard to read me  smiley-wink
« Last Edit: November 26, 2010, 07:24:46 pm by jo.vuitton » Logged

0
Offline Offline
Tesla Member
***
Karma: 118
Posts: 8962
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Some servo control code that might be useful.

Code:
// 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.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(10);  
    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="";
  }
}

Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi !

Thank you very much, it works very good with your code.
Can you tell me what's wrong in mine please ?


When I modify your code to that :
Code:
// 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.attach(3);  //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(10);
    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);
    n = (n/179)*100;
    myservo.write(n); //for degees 0-180
    readString="";
  }
}
( I just added this line before writing to the servo the position) :     n = (n/179)*100; so that I could have a %, but it doesn't works ? How can I fix that problem ?

Thaks !
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 551
Posts: 46248
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When you type a number into the Serial Monitor, like 50, that number is sent, as a series of characters, to the Arduino ('5' and '0').

Your code reads the 1st character ('5'), on each pass through loop(), and treats it like it were the value entered in the serial monitor. The character has an ASCII collating sequence value associated with it ('0' = 48, '1' = 49, etc.). It is that value (an integer) that is used to calculate the position to move the servo to, which is, of course, not what you want.

zoomkat's code reads the whole collection of characters sent, assembles them in a string, extracts the character array from the string ('5', '0', NULL), and converts that NULL terminated character array to an integer (50), and that integer is used to calculate the position to move the servo to, which is closer to what you want.

The problem with zoomkat's code is that it expects you to send something other than a %-age. It expects you to send a value that drives a continuous rotation servo.

In your modification, you are now taking the %-age (an integer value between 0 and 100) and dividing it by 179 (another integer) resulting in 0, which you then multiply by 100, resulting in 0.

Do the multiplication first, then the division. Or, use the map function:
Code:
n = map(n, 0, 100, 0, 179);
Logged

Pages: [1]   Go Up
Jump to: