How many servos on an Arduino Uno

by robothand on Mon Dec 03, 2012 8:49 am

I am using an Arduino Uno w/328 to operate 5 flex sensors and 5 servos. The 5 flex sensors and the five servos are plugin on one bread board.

One one side of the bread board the five flex sensors are powered by the Arduino's 5v and each flex sensor has a 10k resistor . On the other side of the bread board the 5 servos is powered by battery 4 pack delivering 6v.

I am using the Arduino's 5 analog inputs A0-A4 and attaching it the servos using digital output pins 2,3,4,5 and 7

When I bend flex A0 Servo2 moves independently

When I bend flex A1 Servos 3,4,5 and 7 moves simultaneous and not independently as I as had hope.

Any thoughts as to what is wrong

Can the Arduino Uno support operating 5 servos on 5 separate pins independently. or is the Arduino mega better suited for this project?

Another thing is this..two servos will work fine. When that three servo is added A0 and Servo2 works but when the third servo is added A1 operates Servos 2 and 3 simultaneous and A2 does not operate any of the servos.

pins A2-A4 don't work when everything is put together but they do work when tested by it self

Code: Select all | TOGGLE FULL SIZE
#include <Servo.h>

int flexpin=A0;
int flexpin1=A1;
int flexpin2=A2;
int flexpin3=A3;
int flexpin4=A4;


int pos=0;
int pos1=0;
int pos2=0;
int pos3=0;
int pos4=0;



Servo myservo;
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;


int flex[20];
int flex1[20];
int flex2[20];
int flex3[20];
int flex4[20];



int flexsum=0;
int flexsum1=0;
int flexsum2=0;
int flexsum3=0;
int flexsum4=0;


void setup()
{
myservo.attach(2);
myservo1.attach(3);
myservo2.attach(4);
myservo3.attach(5);
myservo4.attach(7);

Serial.begin(9600);
}

void loop()
{
for(int x=0; x<20; x++)
{
flex[x]=analogRead(flexpin);
flex1[x]=analogRead(flexpin1);
flex2[x]=analogRead(flexpin2);
flex3[x]=analogRead(flexpin3);
flex4[x]=analogRead(flexpin4);


flexsum=flexsum+analogRead(flexpin);
flexsum1=flexsum1+analogRead(flexpin1);
flexsum2=flexsum1+analogRead(flexpin2);
flexsum3=flexsum1+analogRead(flexpin3);
flexsum4=flexsum1+analogRead(flexpin4);



delayMicroseconds(14);
}
flexsum=flexsum/20;
flexsum1=flexsum1/20;
flexsum2=flexsum2/20;
flexsum3=flexsum3/20;
flexsum4=flexsum4/20;

if(Serial.available())
{
Serial.println(flexsum);
Serial.println(flexsum1);
Serial.println(flexsum2);
Serial.println(flexsum3);
Serial.println(flexsum4);

delay(100);
}
pos=map(flexsum,870,800,0,180);
pos1=map(flexsum1,870,800,0,180);
pos2=map(flexsum2,870,800,0,180);
pos3=map(flexsum3,870,800,0,180);
pos4=map(flexsum4,870,800,0,180);

myservo.write(pos);
myservo1.write(pos1);
myservo2.write(pos2);
myservo3.write(pos3);
myservo4.write(pos4);

delay(200);
}
robothand
 
Posts: 18
Joined: Mon Oct 15, 2012 1:48 pm

Re: How many servos on an Arduino Uno

by adafruit_support_bill on Mon Dec 03, 2012 9:26 am

What do you see for the flex sensor values on the serial output?

I suspect what is happening is that analog reads do not have sufficient time to settle. This is a well known phenomenon of the Arduino. The ADC is multiplexed between the analog pins, so the first reading on a given pin is often no good. It is better to read one pin 21 times and throw away the first reading, then repeat for the other pins.
User avatar
adafruit_support_bill
 
Posts: 28161
Joined: Sat Feb 07, 2009 9:11 am

Re: How many servos on an Arduino Uno

by robothand on Mon Dec 03, 2012 10:27 am

So two things (1) Your saying the Arduino Uno borad is designed to handle 5 servos indendently (2) What do I need to change in my coding to do what you are say?

Thanks for your help.
robothand
 
Posts: 18
Joined: Mon Oct 15, 2012 1:48 pm

Re: How many servos on an Arduino Uno

by adafruit_support_bill on Mon Dec 03, 2012 11:27 am

I've done projects with 8 servos before. The Servo library will handle up to 12 servos.

To solve the analog pin settling time problem, I use the following function. It takes one reading and throws it away. Then waits 1 mS for the signal to settle. Then it takes a number of readings and returns the average as the result. You can change the number of samples taken by modifying "sampleSize".

Code: Select all | TOGGLE FULL SIZE
#define sampleSize 20

//
// Read "sampleSize" samples and report the average
//
int ReadAnalog(int Pin)
{
  long reading = 0;
  analogRead(Pin);
  delay(1);
  for (int i = 0; i < sampleSize; i++)
  {
    reading += analogRead(Pin);
  }
  return reading/sampleSize;
}


So you can replace all this:
Code: Select all | TOGGLE FULL SIZE
for(int x=0; x<20; x++)
{
flex[x]=analogRead(flexpin);
flex1[x]=analogRead(flexpin1);
flex2[x]=analogRead(flexpin2);
flex3[x]=analogRead(flexpin3);
flex4[x]=analogRead(flexpin4);


flexsum=flexsum+analogRead(flexpin);
flexsum1=flexsum1+analogRead(flexpin1);
flexsum2=flexsum1+analogRead(flexpin2);
flexsum3=flexsum1+analogRead(flexpin3);
flexsum4=flexsum1+analogRead(flexpin4);



delayMicroseconds(14);
}
flexsum=flexsum/20;
flexsum1=flexsum1/20;
flexsum2=flexsum2/20;
flexsum3=flexsum3/20;
flexsum4=flexsum4/20;


with this:
Code: Select all | TOGGLE FULL SIZE
flexsum = ReadAnalog(flexpin);
flexsum1 = ReadAnalog(flexpin1);
flexsum2 = ReadAnalog(flexpin2);
flexsum3 = ReadAnalog(flexpin3);
flexsum4 = ReadAnalog(flexpin4);
User avatar
adafruit_support_bill
 
Posts: 28161
Joined: Sat Feb 07, 2009 9:11 am

Re: How many servos on an Arduino Uno

by robothand on Mon Dec 03, 2012 3:37 pm

Thanks for much for your advice. I will give this a try.

One question regarding this coding:
Code: Select all | TOGGLE FULL SIZE
#define sampleSize 20

//
// Read "sampleSize" samples and report the average
//
int ReadAnalog(int Pin)
{
  long reading = 0;
  analogRead(Pin);
  delay(1);
  for (int i = 0; i < sampleSize; i++)
  {
    reading += analogRead(Pin);
  }
  return reading/sampleSize;
}


Do I insert this code before the Void setup?

Thanks again.
robothand
 
Posts: 18
Joined: Mon Oct 15, 2012 1:48 pm

Re: How many servos on an Arduino Uno

by adafruit_support_bill on Mon Dec 03, 2012 3:46 pm

Either there, or at the very end should work.
User avatar
adafruit_support_bill
 
Posts: 28161
Joined: Sat Feb 07, 2009 9:11 am

Re: How many servos on an Arduino Uno

by robothand on Mon Dec 03, 2012 4:18 pm

Not sure is I understand this line of code

reading += analogRead(Pin);

(1) Should I change pin to read flexpin ?
(2) What is += function?
(3) Do I need to add addition lines for flexpin1, flexpin2... for the remaining flex sensors

I am not a programmer and this is new to me. Thanks for understanding.
robothand
 
Posts: 18
Joined: Mon Oct 15, 2012 1:48 pm

Re: How many servos on an Arduino Uno

by adafruit_support_bill on Mon Dec 03, 2012 4:25 pm

(1) Should I change pin to read flexpin ?

"Pin" is the name of the parameter that you pass to the call.
If you call it this way:
Code: Select all | TOGGLE FULL SIZE
flexsum = ReadAnalog(flexpin);

Pin is equal to "flexpin"
If you call it this way:
Code: Select all | TOGGLE FULL SIZE
flexsum1 = ReadAnalog(flexpin1);

Pin is equal to "flexpin1"
etc...
(2) What is += function?

That is a shorthand way of writing:
Code: Select all | TOGGLE FULL SIZE
reading = reading + analogRead(Pin);

(3) Do I need to add addition lines for flexpin1, flexpin2... for the remaining flex sensors

No, just call the function with the different pin numbers to read the different pins. :)
User avatar
adafruit_support_bill
 
Posts: 28161
Joined: Sat Feb 07, 2009 9:11 am

Re: How many servos on an Arduino Uno

by robothand on Mon Dec 03, 2012 5:08 pm

So should my program read

Code: Select all | TOGGLE FULL SIZE
#include <Servo.h>

int flexpin=A0;
int flexpin1=A1;
int flexpin2=A2;
int flexpin3=A3;
int flexpin4=A4;


int pos=0;
int pos1=0;
int pos2=0;
int pos3=0;
int pos4=0;



Servo myservo;
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;


int flex[20];
int flex1[20];
int flex2[20];
int flex3[20];
int flex4[20];



int flexsum=0;
int flexsum1=0;
int flexsum2=0;
int flexsum3=0;
int flexsum4=0;


#define sampleSize 20

//
// Read "sampleSize" samples and report the average
//
int ReadAnalog(int Pin)
{
  long reading = 0;
  analogRead(Pin);
  delay(1);
  for (int i = 0; i < sampleSize; i++)
  {
    reading += analogRead(Pin);
  }
  return reading/sampleSize;
}

void setup()
{
myservo.attach(2);
myservo1.attach(3);
myservo2.attach(4);
myservo3.attach(5);
myservo4.attach(7);

Serial.begin(9600);
}

void loop()
{
flexsum = ReadAnalog(flexpin);
flexsum1 = ReadAnalog(flexpin1);
flexsum2 = ReadAnalog(flexpin2);
flexsum3 = ReadAnalog(flexpin3);
flexsum4 = ReadAnalog(flexpin4);

if(Serial.available())
{
Serial.println(flexsum);
Serial.println(flexsum1);
Serial.println(flexsum2);
Serial.println(flexsum3);
Serial.println(flexsum4);

delay(100);
}
pos=map(flexsum,870,800,0,180);
pos1=map(flexsum1,870,800,0,180);
pos2=map(flexsum2,870,800,0,180);
pos3=map(flexsum3,870,800,0,180);
pos4=map(flexsum4,870,800,0,180);

myservo.write(pos);
myservo1.write(pos1);
myservo2.write(pos2);
myservo3.write(pos3);
myservo4.write(pos4);

delay(200);
}
robothand
 
Posts: 18
Joined: Mon Oct 15, 2012 1:48 pm

Re: How many servos on an Arduino Uno

by adafruit_support_bill on Mon Dec 03, 2012 5:16 pm

You can get rid of these arrays since they are not used anymore:

Code: Select all | TOGGLE FULL SIZE
    int flex[20];
    int flex1[20];
    int flex2[20];
    int flex3[20];
    int flex4[20];
User avatar
adafruit_support_bill
 
Posts: 28161
Joined: Sat Feb 07, 2009 9:11 am

Re: How many servos on an Arduino Uno

by robothand on Tue Dec 04, 2012 6:24 am

YOU ROCK. The program change worked great. Thanks so much for your help.
robothand
 
Posts: 18
Joined: Mon Oct 15, 2012 1:48 pm

Re: How many servos on an Arduino Uno

by robothand on Tue Dec 04, 2012 7:30 am

Very last question. We couldn't get the serial print to work with the serial monitor. Do you see anything in the program that is wrong. Is there a way to print finger1 finger2 on the monitor in a column format?

Thanks again.
robothand
 
Posts: 18
Joined: Mon Oct 15, 2012 1:48 pm

Re: How many servos on an Arduino Uno

by adafruit_support_bill on Tue Dec 04, 2012 8:47 am

Code: Select all | TOGGLE FULL SIZE
    if(Serial.available())
    {
    Serial.println(flexsum);
    Serial.println(flexsum1);
    Serial.println(flexsum2);
    Serial.println(flexsum3);
    Serial.println(flexsum4);

    delay(100);
    }


'if(Serial.available()' is only true if you are sending characters to the Arduino from the serial monitor. If you want it to print unconditionally, remove that test.

To print in columns, use 'print' instead or 'println' and insert tab after each value. Something like this should work:

Code: Select all | TOGGLE FULL SIZE
    Serial.print(flexsum);
    Serial.print("\t");
    Serial.print(flexsum1);
    Serial.print("\t");
    Serial.print(flexsum2);
    Serial.print("\t");
    Serial.print(flexsum3);
    Serial.print("\t");
    Serial.println(flexsum4);

    delay(100);
 
User avatar
adafruit_support_bill
 
Posts: 28161
Joined: Sat Feb 07, 2009 9:11 am

Re: How many servos on an Arduino Uno

by robothand on Fri Dec 07, 2012 4:33 pm

I am now trying to separate the program below into a transmitting and receiving program . This is my main program
Code: Select all | TOGGLE FULL SIZE
#include <Servo.h>

int flexpin=A0;    // Analog input pin that the flex sensor is attached to
int flexpin1=A1;
int flexpin2=A2;
int flexpin3=A3;
int flexpin4=A4;


int pos=0;   // variable to store the servo position
int pos1=0;
int pos2=0;
int pos3=0;
int pos4=0;



"Servo myservo;  // create servo object to control a servo
"
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;



int flexsum=0;
int flexsum1=0;
int flexsum2=0;
int flexsum3=0;
int flexsum4=0;

#define sampleSize 20

//
// Read "sampleSize" samples and report the average
//
int ReadAnalog(int Pin)
{
  long reading = 0;
  analogRead(Pin);    // read the analog in value:
  delay(1);          // waits 1ms for the between each analog pin reads
  for (int i = 0; i < sampleSize; i++)
  {
    reading += analogRead(Pin);
  }
  return reading/sampleSize;
}

void setup()
{
myservo.attach(2);    // attaches the servo on pin 2 to the servo object
myservo1.attach(3);
myservo2.attach(4);
myservo3.attach(5);
myservo4.attach(7);

Serial.begin(9600); // initialize serial communications at 9600 bps:
}

void loop()
{
flexsum = ReadAnalog(flexpin);
flexsum1 = ReadAnalog(flexpin1);
flexsum2 = ReadAnalog(flexpin2);
flexsum3 = ReadAnalog(flexpin3);
flexsum4 = ReadAnalog(flexpin4);


{
Serial.println(flexsum);
Serial.println(flexsum1);
Serial.println(flexsum2);
Serial.println(flexsum3);
Serial.println(flexsum4);

delay(100);
}
pos=map(flexsum,870,800,0,180);
pos1=map(flexsum1,870,800,0,180);
pos2=map(flexsum2,870,800,0,180);
pos3=map(flexsum3,870,800,0,180);
pos4=map(flexsum4,870,800,0,180);

myservo.write(pos);      // tell servo to go to position in variable 'pos
myservo1.write(pos1);
myservo2.write(pos2);
myservo3.write(pos3);
myservo4.write(pos4);

delay(200);   // stop the program for some time
}



This my glove program

Code: Select all | TOGGLE FULL SIZE
int flexpin=A0;    // Analog input pin that the flex sensor is attached to
int flexpin1=A1;
int flexpin2=A2;
int flexpin3=A3;
int flexpin4=A4;


int pos=0;   // variable to store the servo position
int pos1=0;
int pos2=0;
int pos3=0;
int pos4=0;

int flexsum=0;  // Set the flexsum to zero
int flexsum1=0;
int flexsum2=0;
int flexsum3=0;
int flexsum4=0;

#define sampleSize 20

//
// Read "sampleSize" samples and report the average
//
int ReadAnalog(int Pin)
{
  long reading = 0;
  analogRead(Pin);    // read the analog in value:
  delay(1);          // waits 1ms for the between each analog pin reads
  for (int i = 0; i < sampleSize; i++)
  {
    reading += analogRead(Pin);
  }
  return reading/sampleSize;
}


void setup()
{

Serial.begin(9600); // initialize serial communications at 9600 bps:
}


void loop()
{
flexsum = ReadAnalog(flexpin);
flexsum1 = ReadAnalog(flexpin1);
flexsum2 = ReadAnalog(flexpin2);
flexsum3 = ReadAnalog(flexpin3);
flexsum4 = ReadAnalog(flexpin4);


{

Serial.print(flexsum);
Serial.print("\t");
Serial.print(flexsum1);
Serial.print("\t");
Serial.print(flexsum2);
Serial.print("\t");
Serial.print(flexsum3);
Serial.print("\t");
Serial.println(flexsum4);

    delay(100);

delay(100);
}
pos=map(flexsum,870,800,0,180);
pos1=map(flexsum1,870,800,0,180);
pos2=map(flexsum2,870,800,0,180);
pos3=map(flexsum3,870,800,0,180);
pos4=map(flexsum4,870,800,0,180);

delay(100);
}


This is my servo code

Code: Select all | TOGGLE FULL SIZE
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
Servo myservo1;
Servo myservo2;
Servo myservo3;
Servo myservo4;

int pos=0;   // variable to store the servo position
int pos1=0;
int pos2=0;
int pos3=0;
int pos4=0;



void setup()
{

Serial.begin(9600); // initialize serial communications at 9600 bps:


myservo.attach(2);    // attaches the servo on pin 2 to the servo object
myservo1.attach(3);
myservo2.attach(4);
myservo3.attach(5);
myservo4.attach(7);

}


void loop()
{
myservo.write(pos); // tells servo to go to position based on finger position
myservo1.write(pos1);
myservo2.write(pos2);
myservo3.write(pos3);
myservo4.write(pos4);


Serial.println(pos);
Serial.println(pos1);
Serial.println(pos2);
Serial.println(pos3);
Serial.println(pos4);

delay(200);   // stop the program for some time

}


Was this done correctly? Thanks
robothand
 
Posts: 18
Joined: Mon Oct 15, 2012 1:48 pm

Re: How many servos on an Arduino Uno

by adafruit_support_bill on Sat Dec 08, 2012 6:11 am

So far it looks good. You just need the communication part.

On the transmit side, you may find that shorter delays will make the glove more responsive. On the receive side, I'd eliminate the delays altogether and have the loop run as fast as the data is received.
User avatar
adafruit_support_bill
 
Posts: 28161
Joined: Sat Feb 07, 2009 9:11 am