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 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 */
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