Pages: [1]   Go Down
Author Topic: controling 3 servos via serial comunication  (Read 381 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

HI
I'm trying to program an arm with 3 servos. The first 2 servos control the movement/position and the 3rd one is for a grabber.
I won't have my arduino until next week but I have to present some code before. Since this is my first project I would like to know if this code could work.
A better description:
-First I want to get the data from a computer via the serial connection.
-Then the two position servos move to the desired position.
-When in position the grabber servo grab an object
-Then a new position is provided and the arm is moved to the new position and the grabber release the object
-If there are no commands from the computer the arm wait in a special position

Code:
#include <Servo.h>

//Holds the servo ID
char bigChannel=0;
char smallChannel=1;

//switch for gripper
char i=0;

//These are the objects for each servo.
Servo servoBig
Servo servoSmall
Servo servoGripper

//This is the space that will hold data from the Serial port.
char serialChar=0;

//Attach servos to pins and give starting positions
void setup(){
  servoBig.attach(2);
  servoSmall.attach(3);
  servoGripper.attach(4);
 
  servoBig.write(90);
  servoSmall.write(90);
  servoGripper.write(0);
 
  Serial.begin(9600);  //Set up serial connection for 9600 bps.
  Serial.write("Power On")
}

void loop()]{
  while(Serial.available() >= 0){     //Wait for data on the serial port.
  serialChar = Serial.read();         //Copy one byte from serial buffert
  if(serialChar == bigChannel){      //Check to se if the character is the servo ID
    while(Serial.available() >= 0);   //wait for the second byte 
    servoBig.write(Serial.read());     //set the Big motor to the recived position
    i=i+1;
  }
  else if(serialChar == smallChannel){
    while(Serial.available() >= 0);
    servoSmall.write(Serial.read());
    i=i+1;
  }
  if(i == 2 ){                        //gripper closes
    delay(3000);
    servoGripper.write(180);
     }
  else if (i == 4){                   //gripper open
    delay(3000)
    servoGripper.write(0);       
    i=0;
  }
 }
 while(Serial.available() < 0){      //Arm to neutral position
   if servoBig != 90;{
   servoBig.write(90);
   }
   if servoSmall != 90; {
   servosmall.write(90);
   }
 }
}

One more question: the position of the servos, do i calculate it from the movement divided by the time it move or could i just send an angle?

Thanks in advance
/youknow
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 240
Posts: 24424
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
while(Serial.available() >= 0);   //wait for the second byte
Think about it.

Code:
while(Serial.available() < 0){    
Useful reading

How do you know which command is intended for which servo?
« Last Edit: November 14, 2012, 03:23:17 am by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Code:
while(Serial.available() >= 0);   //wait for the second byte
Think about it.

Code:
while(Serial.available() < 0){     
Useful reading


I guess this could make more sense?
Code:
if(Serial.available() > 0){     //Wait for data on the serial port.
  serialChar = Serial.read();         //Copy one byte from serial buffert
  if(serialChar == bigChannel){      //Check to se if the character is the servo ID
    servoBig.write(Serial.read());     //set the Big motor to the recived position
    i=i+1;
  }
  else if(serialChar == smallChannel){   //Check to se if the character is the servo ID
    servoSmall.write(Serial.read());     //set the small motor to the recived position
    i=i+1;

Quote
How do you know which command is intended for which servo?

My intension is to first send a byte with the servo ID
Code:
//Holds the servo ID
char bigChannel=0;
char smallChannel=1;

and then check
Code:
if(serialChar == bigChannel){      //Check to se if the character is the servo ID
.
.
 else if(serialChar == smallChannel){
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 240
Posts: 24424
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I guess this could make more sense?
Code:

if(Serial.available() > 0){     //Wait for data on the serial port.
  serialChar = Serial.read();         //Copy one byte from serial buffert
  if(serialChar == bigChannel){      //Check to se if the character is the servo ID
    servoBig.write(Serial.read());
It could, but it doesn't.
Think - you decide that there is at least one character to read, then read two of them.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

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

Code:
char i=0;
One letter global variable names, especially the ubiquitous i, is not a good idea.

Code:
//Holds the servo ID
char bigChannel=0;
char smallChannel=1;
One for each of the three servos, huh?

Quote
I guess this could make more sense?
No. Determining that there is one byte to read, and then reading 2 is never a good idea.

Just be patient. You mentioned serial data and servos in the same post. Zoomkat will be along shortly to post code for you. Or, if you aren't patient, you could use the search field and figure out that you aren't the first person to try to read serial data, or to use that serial data to control a servo.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for all the feedback.
I have tried to think about what you said and here is my result:
Code:
#include <Servo.h>

//Holds the servo ID
char bigChannel=0;
char smallChannel=1;
char gripperChar=0;

//These are the objects for each servo.
Servo servoBig
Servo servoSmall
Servo servoGripper

//This is the space that will hold data from the Serial port.
char serialChar=0;

//Attach servos to pins and give starting positions
void setup(){
  servoBig.attach(2);
  servoSmall.attach(3);
  servoGripper.attach(4);
 
  servoBig.write(90);
  servoSmall.write(90);
  servoGripper.write(0);
 
  Serial.begin(9600);  //Set up serial connection for 9600 btp.
  Serial.write("Power On")
}

void loop()]{
  if(Serial.available() > 1){     //Wait for data on the serial port.
  serialChar = Serial.read();         //Copy one byte from serial buffert
  if(serialChar == bigChannel){      //Check to see if the character is the servo ID
    servoBig.write(Serial.read());     //set the Big motor to the recived position
    gripperChar=gripperChar+1;      //tell the gripper one servo have been moved
  }
  else if(serialChar == smallChannel){   //Check to see if the character is the servo ID
    servoSmall.write(Serial.read());
    gripperChar=gripperChar+1;
  }
  if(gripperChar == 2 ){                 //gripper closes if the other servos have made 2 moves
    delay(3000);                           //wait for the arm to be in position
    servoGripper.write(180);
   delay(2000);                            //wait for the gripper to make its move
     }
  else if (gripperChar == 4){            //gripper open when the other servos done another 2 moves
    delay(3000)
    servoGripper.write(0);
    delay(2000);
    gripperChar=0;                     //resets the gripperChar so the gripper will close after the next two moves             
  }
 }
 else{                        //Arm to neutral position if there is no data waiting
   if servoBig != 90;{
   servoBig.write(90);
   }
   if servoSmall != 90; {
   servosmall.write(90);
   }
 }
}

Logged

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

What is sending the serial data? Is the data sent in binary form?

Code:
//Holds the servo ID
char bigChannel=0;
char smallChannel=1;
char gripperChar=0;
Is gripperChar really a servo ID? How is the Arduino supposed to distinguish between two servos with the same ID?

Code:
  if(gripperChar == 2 ){                 //gripper closes if the other servos have made 2 moves
No. It does something if one of the other servos has made two moves or if each of the other servos has made a move. If you are going to have silly comments, you should make them correct.

Code:
    delay(3000);                           //wait for the arm to be in position
    servoGripper.write(180);
   delay(2000);   
You must have the worlds slowest servos.

Code:
else{                        //Arm to neutral position if there is no data waiting
   if servoBig != 90;{
   servoBig.write(90);
   }
   if servoSmall != 90; {
   servosmall.write(90);
   }
Why are you nearly constantly setting these positions back to 90? Your arm will never accomplish anything.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 184
Posts: 11195
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's polite to get your code to at least compile before you post it for review. You will need to make several changes before this compiles:

Code:
else{                        //Arm to neutral position if there is no data waiting
   if servoBig != 90;{
   servoBig.write(90);
   }
   if servoSmall != 90; {
   servosmall.write(90);
   }
 }

Your code layout is all over the place and will make it hard to spot mistakes in your control structure. I suggest you get into the habit of putting each { and } on lines on their own with matching pairs indented by the same amount and the code between them indented one extra level.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

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

Simple servo test code for controlling two servos, which could be expanded to three. Lots of different ways to code to do basically the same thing. myservo1.write(n1) could be used instead of myservo1.writeMicroseconds(n1) to use degrees instead of microseconds if desired. This code should allow you to test your hardware wiring.

Code:
// zoomkat 11-22-10 serial servo (2) test
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.
// two servo setup with two servo commands
// send eight character string like 15001500 or 14501550

#include <Servo.h>
String readString, servo1, servo2;
Servo myservo1;  // create servo object to control a servo
Servo myservo2;

void setup() {
  Serial.begin(9600);
  myservo1.attach(6);  //the pin for the servo control
  myservo2.attach(7);
  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); //see what was received
     
      // expect a string like 07002100 containing the two servo positions     
      servo1 = readString.substring(0, 4); //get the first four characters
      servo2 = readString.substring(4, 8); //get the next four characters
     
      Serial.println(servo1);  //print to serial monitor to see results
      Serial.println(servo2);
     
      int n1; //declare as number 
      int n2;
     
      int n1 = servo1.toInt();
      int n2 = servo2.toInt();
     
      /*char carray1[6]; //magic needed to convert string to a number
      servo1.toCharArray(carray1, sizeof(carray1));
      n1 = atoi(carray1);
     
      char carray2[6];
      servo2.toCharArray(carray2, sizeof(carray2));
      n2 = atoi(carray2); */
     
      myservo1.writeMicroseconds(n1); //set servo position
      myservo2.writeMicroseconds(n2);
    readString="";
  }
}

Logged

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

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Code:
   if servoBig != 90;{

Just a tip. You can download the Arduino software right now from this site (for free). Before your board arrives. Then you can get rid of the syntax errors from your code at least.
Logged

Pages: [1]   Go Up
Jump to: