Controlling multiple servos through serial

Hi

I want to control several servos through serial port but I can control only one servo at a time, I know that an servo object needs to be created for each servo and then attached to a pin, but how to send to each servo a different value.

case 41 does the position writing, the rest communicates with a program.
What needs to change to control several servos? The command through serial is write(pin,val) when a servo position is set and another is send the first servo loose its position, and the second servo goes into position.

   #include <Servo.h> 
Servo myservo;

void setup() {
	
  int i;
  for (i=0;i<20;i++) {
    pinMode(i,INPUT);
    digitalWrite(i,0);
  }
  Serial.begin(9600);
}



void loop() {
  
  /* variables declaration and initialization                */
  
  static int  s   = -1;    /* state                          */
  static int  pin = 9;    /* generic pin number             */
  int  val =  0;           /* generic value read from serial */
  int  agv =  0;           /* generic analog value           */
  int  dgv =  0;           /* generic digital value          */

  if (Serial.available() >0) {
    val = Serial.read();
    
    switch (s) {
		
      /* s=-1 means NOTHING RECEIVED YET ******************* */
 case -1:      

      /* calculate next state                                */
      if (val>47 && val<58) {
	/* the first received value indicates the mode       
           49 is ascii for 1, ... 90 is ascii for Z          
           s=0 is change-pin mode
           s=10 is DI;  s=20 is DO;  s=30 is AI;  s=40 is AO; 
           s=50 is servo status; s=60 is aervo attach/detach;  
           s=70 is servo read;   s=80 is servo write         
           s=90 is query script type (1 basic, 2 motor)         
                                                             */                                                             
        s=10*(val-48);
      }
      break; /* s=-1 (initial state) taken care of       */
	  
     
      /* s=0 or 1 means CHANGE PIN MODE                      */



      case 41:   
      /*  writing position*/


      	  myservo.attach(pin);
      	   myservo.write(val);
      
      
      s=-1;  /* we are done with this so next state is -1    */
      break; 
      
      
      
      
      
      
      
      
      
      case 90:
      if (val==57) { 
        /* if string sent is 99  send script type via serial */
        Serial.println(1);
      }
      s=-1;  /* we are done with this so next state is -1    */
      break; /* s=90 taken care of                           */

    } /* end switch on state s                               */

  } /* end if serial available                               */
  
} /* end loop statement                                      */

I know that an servo object needs to be created for each servo and then attached to a pin, but how to send to each servo a different value.

You only have one servo object.

Servo myservo;
      if (val>47 && val<58) {

How about making it more readable?

      if (val >= '0' && val <= '9') {

You don’t need to confuse yourself with all these numbers, the C language can do the conversions for you.

I made the code simpler and added 3 objects, but how to write a value to a specified servos while maintaining the other servo position?

 #include <Servo.h> 
Servo myservo1;
Servo myservo2;
Servo myservo3;

void setup() {
	
  int i;
  for (i=0;i<20;i++) {
    pinMode(i,INPUT);
    digitalWrite(i,0);
  }
  Serial.begin(9600);
  
  
        myservo1.attach(9);
      	myservo2.attach(10);
      	myservo3.attach(11);
}



void loop() {
  
 static int  s   = -1;    /* state                          */
  static int  pin = 9;    /* generic pin number             */
  int  val =  0;           /* generic value read from serial */


  if (Serial.available() >0) {
    val = Serial.read();
    
    switch (s) {
		


      case 41:   
      /*  writing position*/



      	   myservo1.write(val);
      
      
      s=-1;  /* we are done with this so next state is -1    */
      break; 
           
      


    } /* end switch on state s                               */

  } /* end if serial available                               */
  
} /* end loop statement                                      */

SpaceOne: case 41:     /*  writing position*/   myservo1.write(val);

Well that looks better. At least you have 3 servos now. :-)

How do you imagine you would do it? This could be one way:

case 41:   
  /*  writing position*/
  if (pin == 9)
    myservo1.write(val);
  else if (pin == 10)
    myservo2.write(val);
  else if (pin == 11)
    myservo3.write(val);

There are fancier ways, but I am just trying to show the general idea.

There is nothing that I can see in what you are passing to the Arduino that defines WHICH servo the value is for. I guess you could pick a random servo to write the value to.

Where does s get a value? As your code is now, no case will ever match s, so nothing will ever happen.

Below is how I control two servos. You probably could modify it to do what you need.

// 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;
      
      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="";
  } 
}

Using conditions if the servo get into the right position and stay there, but when the program starts all the servo go dangerously fast at 120 degrees, and delay has no effect on the movements speed.

The last version published here doesn't get to 41 because it is "simpler", the first version should get to 41