Servo Control For Robot Hand

I made the robot hand on the rendering and now I am trying to connect 6 servos to one Arduino Uno R3.

The power supply for the Servos is done. It provides 5 volts and can supply up to 15 Amps.

Question1: Can I actually control 6 individual servos with the PWM pins? (3,5,6,9,10,11) I read different answers.

Question2: At the moment the code turns one servo and then moves on to the next one. How can I have them all move at once?

Thank you for your time!

#include <Servo.h>

Servo servo1;  // create servo object to control a servo 
Servo servo2; // a maximum of eight servo objects can be created 
Servo servo3;
 
int delai = 20; //spelling is intended to avoid confusion with system comand

int ser1max = 1600;   //Max value in ° for Servo
int ser1min = 1200;    //Min value in ° for Servo
int serset1= 1050;     // Value that controlls Servo Position

int ser2max = 1600;   //Max value in ° for Servo
int ser2min = 1200;    //Min value in ° for Servo
int serset2= 1050;     // Value that controlls Servo Position

int ser3max = 1600;   //Max value in ° for Servo
int ser3min = 1200;    //Min value in ° for Servo
int serset3= 1050;     // Value that controlls Servo Position


void setup() 
{ 
  servo1.attach(9);  // attaches the servo on pin 9 to the servo object 
  servo2.attach (10);  
  servo3.attach (3);
} 
 
void loop() 
{ 
  for(serset1 = ser1min; serset1 < ser1max; serset1 += 10)  
  {                                  
    servo1.writeMicroseconds(serset1);              
    delay(delai);                       
  } 
  for(serset1 = ser1max ; serset1 > ser1min; serset1-= 10)      
  {                                
    servo1.writeMicroseconds(serset1);         
    delay(delai);                        
    
  } 
  //Servo 2 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
   for(serset2 = ser2min; serset2 < ser2max; serset2 += 10)  
  {                                  
    servo2.writeMicroseconds(serset2);              
    delay(delai);                       
  } 
  for(serset2 = ser2max ; serset2 > ser2min; serset2-= 10)      
  {                                
    servo2.writeMicroseconds(serset2);         
    delay(delai);                        
  } 
  //Servo 3 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
   for(serset3 = ser3min; serset3 < ser3max; serset3 += 10)  
  {                                  
    servo3.writeMicroseconds(serset3);              
    delay(delai);                       
  } 
  for(serset3 = ser3max ; serset3 > ser3min; serset3-= 10)      
  {                                
    servo3.writeMicroseconds(serset3);         
    delay(delai);                        
  } 
}

You can control 16 servos with the TLC5940NT

http://playground.arduino.cc/learning/TLC5940#.UyjMI_ldX_o

tlc5940.pdf (1.23 MB)

Question 1: are these standard R/C servos? If so, why do you think you need to use PWM pins?
Question 2: we can’t see your code

AWOL:
Question 1: are these standard R/C servos? If so, why do you think you need to use PWM pins?
Question 2: we can’t see your code

Question1: Yes standard R/C servos. A friend pointed at the PWM pins and said. Each of these can run one Servo.
Question2: I don’t know why. Hope you can see it here.

#include <Servo.h>

Servo servo1; // create servo object to control a servo
Servo servo2; // a maximum of eight servo objects can be created
Servo servo3;

int delai = 20; //spelling is intended to avoid confusion with system comand

int ser1max = 1600; //Max value in ° for Servo
int ser1min = 1200; //Min value in ° for Servo
int serset1= 1050; // Value that controlls Servo Position

int ser2max = 1600; //Max value in ° for Servo
int ser2min = 1200; //Min value in ° for Servo
int serset2= 1050; // Value that controlls Servo Position

int ser3max = 1600; //Max value in ° for Servo
int ser3min = 1200; //Min value in ° for Servo
int serset3= 1050; // Value that controlls Servo Position

void setup()
{
servo1.attach(9); // attaches the servo on pin 9 to the servo object
servo2.attach (10);
servo3.attach (3);
}

void loop()
{
for(serset1 = ser1min; serset1 < ser1max; serset1 += 10)
{
servo1.writeMicroseconds(serset1);
delay(delai);
}
for(serset1 = ser1max ; serset1 > ser1min; serset1-= 10)
{
servo1.writeMicroseconds(serset1);
delay(delai);

}
//Servo 2 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
for(serset2 = ser2min; serset2 < ser2max; serset2 += 10)
{
servo2.writeMicroseconds(serset2);
delay(delai);
}
for(serset2 = ser2max ; serset2 > ser2min; serset2-= 10)
{
servo2.writeMicroseconds(serset2);
delay(delai);
}
//Servo 3 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
for(serset3 = ser3min; serset3 < ser3max; serset3 += 10)
{
servo3.writeMicroseconds(serset3);
delay(delai);
}
for(serset3 = ser3max ; serset3 > ser3min; serset3-= 10)
{
servo3.writeMicroseconds(serset3);
delay(delai);
}
}

It's a shame your friend didn't read the spec of the PWM outputs, or better still, skip that nonsense and read about the Servo library.

Lose the for loops, gain some code tags.

spooner777:
Question1: Can I actually control 6 individual servos with the PWM pins? (3,5,6,9,10,11) I read different answers.

Question2: At the moment the code turns one servo and then moves on to the next one. How can I have them all move at once?

You can drive up to twelve servos on the UNO, using the Servo library.

If you want to control multiple servos concurrently then you need to design the control code to be non-blocking. It would need to have code to determine whether a given servo needed to be moved, and if so move it. You would run that code at regular intervals for each servo. The aspect you will need to think about os how you will define the sequence of movements that you want each servo to take - will it be defined in real time from some control input signals, or will you need to define it in code?

PeterH:

spooner777:
Question1: Can I actually control 6 individual servos with the PWM pins? (3,5,6,9,10,11) I read different answers.

Question2: At the moment the code turns one servo and then moves on to the next one. How can I have them all move at once?

You can drive up to twelve servos on the UNO, using the Servo library.

If you want to control multiple servos concurrently then you need to design the control code to be non-blocking. It would need to have code to determine whether a given servo needed to be moved, and if so move it. You would run that code at regular intervals for each servo. The aspect you will need to think about os how you will define the sequence of movements that you want each servo to take - will it be defined in real time from some control input signals, or will you need to define it in code?

It will be defined by the code since its just a demonstrator. Close hand - open hand - repeat.

spooner777:
It will be defined by the code since its just a demonstrator. Close hand - open hand - repeat.

If you can come up with a simple algorithm for these movements, such as following a sin wave or similar, that ought to be quite easy to code. It will get a bit more fiddly if you need each servo to follow an arbitrary pattern of movement since you'd need to hard-code these positions and times in the sketch.

One way to send individual commands to several servos.

//zoomkat 11-22-12 simple delimited ',' string parse 
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added 

String readString;
#include <Servo.h> 
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control 
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    }  
    else {     
      readString += c; //makes the string readString
    }
  }
}

It's a shame your friend didn't read the spec of the PWM outputs, or better still, skip that nonsense and read about the Servo library.

Are you saying the purpose of the servo library is to turn simple digital outputs into PWMs using S/W ?

raschemmel:
Are you saying the purpose of the servo library is to turn simple digital outputs into PWMs using S/W ?

The Servo library generates the right sort of signal to control a servo and can output it on any digital I/O pin - it isn't limited to the PWM-capable pins. It does it using a combination of hardware timers and software. This doesn't turn the digital outputs into general PWM-capable outputs but it does produce the specific type of signal that servos use.

I suspect the confusion arises because PWM is used to mean two different things.

Mostly, PWM means a square wave where the mark-space ratio is varied to give a different average output voltage - for example to vary the speed of an electric motor. When you use analogWrite() in an Arduino sketch it produces this sort of wave and only on the PWM capable pins.

PWM is also often used to describe the signal that is sent to a servo but it is a very different concept. The signal for a servo is a pulse whose width varies roughly from 1 to 2 millisecs and is repeated once every 20 msecs. The electronics within the servo "measure" the width of the pulse and use it to decide the position the servo arm should move to. This is the sort of signal the Arduino Servo library produces and it can do so on any pin.

...R

Excellent answer Robin2 ! I've seen this on the scope (as well as the PWM signals) and I noticed that the servo signal did vary, but in a much different way as you described, and I wondered if it was PWM or something else. Now I know.

I think it is a nice answer too, but is there any difference?

Both the analogWrite PWM and the Servo.write() PWM are fixed frequency, and vary the width of the pulse. Both encode an "analog signal" in the digital wave. Both make their magic by using timers and interrups so the waves are generated in the background.

The difference is that the mark-space ratio for "ordinary" PWM varies bewteen 0 to 100% and for the servo between 5 to 10%; the frquency is 430Hz on the analogWrite PWM and 50Hz on the Servo PWM.

The term PWM is correct for both, but "common use" in the Arduino land is the PWM is the analogWrite type.

I look forward to corrections and enhancment to my knowledge (not sure about the analogWrite frequency) - honestly! :slight_smile:

Msquare:
I think it is a nice answer too, but is there any difference?

Personally I think it is very unfortunate that there isn’t an alternative acronym for the servo signals. It would eliminate a tonne of confusion. Including the confusion that newbies have about the role of the PWM pins on the Arduino.

The real difference is that a servo signal is a means of information transfer whereas the PWM produced by analogWrite() is mostly used as a means of power control.

I know you can argue that the servo signal is just a regular PWM signal with a very limited duty cycle, but the reality is that it is used by the servo in a completely different way compared to how an electric motor or a dimmed LED uses a PWM signal generated by analogWrite().

…R

It's also unfortunate that the Arduino term chose the name analogWrite() for a function that does not write an analog value - it produces a pwm output. (This sort of poor naming crops up in many places in the Wiring API.)

At one time there was a custom here of using the name Pulse Position Modulation (PPM) to describe servo control signals. Although this is strictly wrong (the RF signal uses PPM, the servo interface doesn't), it does avoid the confusion between Arduino analog output PWM, and a servo control signal.

I agree the term analogWrite is a misnomer. I've seen many people try to use it to vary the voltage of their lcd backlight only to discover that if flickers wildly when they try it because they have never seen the signal on a scope.

PeterH:
At one time there was a custom here of using the name Pulse Position Modulation (PPM) to describe servo control signals. Although this is strictly wrong (the RF signal uses PPM, the servo interface doesn't), it does avoid the confusion between Arduino analog output PWM, and a servo control signal.

I reckon PPM isn't ideal for the RC signal either. Pulse Order Multiplexing is what's really going on.

...R

PPM is perfectly apt - it is the pulse's position relative to the start of the frame.

AWOL:
PPM is perfectly apt - it is the pulse's position relative to the start of the frame.

When its being transmitted by the R/C system it isn't modulating anything - it is just being sent (and received) as a multiplexed stream of data.

To the extent that it modulates anything that only happens when the receiver sends the de-multiplexed data to the servos.

...R