Go Down

Topic: controlling an array of 10 servos (Read 6172 times) previous topic - next topic

Ghost_Rider

Hello All,

I want to control an array of 10 servo motors.I am using Arduino mega 2560 r3 and I will be accessing only 1 servo at a particular moment

Code: [Select]
#include <Servo.h>
 
Servo absrv[10]={};  // create servo object to control a servo
Servo myserv;                // twelve servo objects can be created on most boards
 
//int pos = 0;    // variable to store the servo position
 
void setup()
{
 Serial.begin(9600);
 absrv[0].attach(22);
absrv[1].attach(23);
absrv[2].attach(24);
absrv[3].attach(25);
absrv[4].attach(26);
absrv[5].attach(27);
absrv[6].attach(28);
absrv[7].attach(29);
absrv[8].attach(30);
absrv[9].attach(31);
 // attaches the servo on pin 9 to the servo object
//myserv.attach(31);
}
 
 void sweep(int pos,Servo lserv)
{
  int i;
 for(i = 0; i <= pos; i += 1) // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    lserv.write(i);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}
 
 
void loop()
{
  int i;
  for(i=0;i<10;i++)
  {
    delay(1000);
    Serial.println(i);
    if(!absrv[i].attached())
    {
      Serial.print("error");
      myserv.write(60);
    }
   sweep(120,absrv[i]);
   delay(1000);
  }
 // myserv.write(60);
}




it only works when the number of servos are less than or equal to 6

CrossRoads

Can you try changing this line
Code: [Select]

Servo absrv[10]={};  // create servo object to control a servo

to
Code: [Select]

Servo absrv[]={22,23,24,25,26,27,28,29,30,31};  // create servo object to control a servo
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

PaulS

Quote
Can you try changing this line...to...
That is not going to work. You can't assign an array of ints to a Servo array.
Code: [Select]
Servo movingThings[10];

   movingThings[0].attach(servoPin[0]);

   movingThings[0].write(servoPos[0]);

Ghost_Rider

@CrossRoads the code is giving a compilation error owing to the fact it needs to be initialised with a servo object instead of an int type.

The main thing is can Arduino mega handle 10 servo motor pins on its digital pins???

PaulS

Quote
The main thing is can Arduino mega handle 10 servo motor pins on its digital pins???
Yes, it can!!! Hopefully, the extra punctuation helps.

MartinL

#5
Dec 29, 2016, 01:31 pm Last Edit: Jan 03, 2018, 05:49 pm by MartinL
Hi Ghost_Rider,

Yes the Mega is capable of controlling 12 servos.

If you don't mind using up all the 16-bit timers, then it's possible to control 12 servos using hardware PWM. Using hardware PWM offers the benefit of 14-bit resolution at 50Hz and the fact that the timers require no intervention from the CPU, apart from loading the duty-cycle (OCRxx) register for each output.

The code below uses the Mega's 16-bit timers: 1, 3, 4 & 5, each with 3 outputs: A, B and C. The setup() portion of the code sets the timers up in phase and frequency correct mode, with an output frequency of 50Hz.

The loop() portion just centers each servo, then moves them to lower and higher positions. To move the servos just load the appropriate pOCRxxReg[] array with a value similar to the servo.writeMicroseconds() function: 1500 = center, 1000 = minimum, 2000 maximum:

Code: [Select]
// On the Arduino Mega there are 4 16 bit timers: 1, 3, 4 & 5, each with three outputs: A, B & C
// Store the addresses of the PWM timer compare (duty-cycle) registers
volatile uint16_t* pOCRxxReg[] = { &OCR1A, &OCR1B, &OCR1C, &OCR3A, &OCR3B, &OCR3C, &OCR4A, &OCR4B, &OCR4C, &OCR5A, &OCR5B, &OCR5C };

void setup() {
  // Set PWM pins as outputs
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(46, OUTPUT);
  pinMode(45, OUTPUT);
  pinMode(44, OUTPUT);

  // Initialise timers 1, 3, 4 and 5 for phase and frequency correct PWM
  TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1C1);         // Enable the PWM outputs OC1A, OC1B and OC1C on digital pins 11, 12 and 13
  TCCR1B = _BV(WGM13) | _BV(CS11);                          // Set phase and frequency correct PWM and prescaler of 8 on timer 1
  TCCR3A = _BV(COM3A1) | _BV(COM3B1) | _BV(COM3C1);         // Enable the PWM output OC3A, OC3B and OC3C on digital pins 5, 2 and 3
  TCCR3B = _BV(WGM33) | _BV(CS31);                          // Set phase and frequency correct PWM and prescaler of 8 on timer 3
  TCCR4A = _BV(COM4A1) | _BV(COM4B1) | _BV(COM4C1);         // Enable the PWM outputs OC4A, OC4B and OC4C on digital pins 6, 7 and 8
  TCCR4B = _BV(WGM43) | _BV(CS41);                          // Set phase and frequency correct PWM and prescaler of 8 on timer 4
  TCCR5A = _BV(COM5A1) | _BV(COM5B1) | _BV(COM5C1);         // Enable the PWM outputs OC5A, OC5B and OC5C on digital pins 46, 45 and 44
  TCCR5B = _BV(WGM53) | _BV(CS51);                          // Set phase and frequency correct PWM and prescaler of 8 on timer 5
  ICR1 = 20000;                                             // Set the timer 1 frequency to 50Hz
  ICR3 = 20000;                                             // Set the timer 3 frequency to 50Hz
  ICR4 = 20000;                                             // Set the timer 4 frequency to 50Hz
  ICR5 = 20000;                                             // Set the timer 5 frequency to 50Hz
}

void loop() {
  for (uint8_t i = 0; i < 12; i++)                          // Iterate through the 12 servos
  {
    *(pOCRxxReg[i]) = 1500;                                 // Centre the specified servo
    delay(500);                                             // Wait half a second
  }
  for (uint8_t i = 0; i < 12; i++)                          // Iterate through the 12 servos
  {
    *(pOCRxxReg[i]) = 1200;                                 // Move the specified servo to a lower position
    delay(500);                                             // Wait half a second
  }
  for (uint8_t i = 0; i < 12; i++)                          // Iterate through the 12 servos
  {
    *(pOCRxxReg[i]) = 1800;                                 // Move the specified servo to a higher position
    delay(500);                                             // Wait half a second
  }
}

zelda546

#6
Sep 12, 2020, 09:59 am Last Edit: Sep 12, 2020, 10:00 am by zelda546
yes you can control array of servos
try something like this

Code: [Select]


#define NO_OF_SERVOS 6

// Declare Servos
Servo servo1; 
Servo servo2;
Servo servo3; 
Servo servo4;
Servo servo5;
Servo servo6;

// Servo Array
Servo servo_array[NO_OF_SERVOS] = {servo1, servo2, servo3, servo4, servo5, servo6};

// Input here Servo pins
int servo_pins[NO_OF_SERVOS] = {2,7,8,3,11,4};
// DEFAULT angles of servos
int angle_init[NO_OF_SERVOS]  = {90, 70, 120, 90, 90, 0};

// setup
setup(){
 
 // set pwm pins to output and attach servos
 for(int i = 0; i < NO_OF_SERVOS; i++){
      // set pwm pin to output
      pinMode(servo_pins[i], OUTPUT);
      // attach servo to pin
      servo_array[i].attach(servo_pins[i]);


 // move servo to default position
       delay(50);
       servo_array[i].write(angle_init[i]);   
       delay(50);

 } // for end
 
 
} // setup end

// Loop
loop(){
 
} // loop end


vilmabergmann

#7
Sep 16, 2020, 01:20 pm Last Edit: Sep 16, 2020, 01:28 pm by vilmabergmann
try something like this
Or better yet, this, which levels up the use of arrays and replaces this approach:

Code: [Select]
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;


... with this thinking:

Code: [Select]
Servo myServos[8];

... as already shown by the same author in #2 of this thread almost 4y ago.

And, servo pins don't need to be pwm pins, nor do you need to pinMode() them as you did here:

Code: [Select]
// set pwm pin to output
      pinMode(servo_pins[i], OUTPUT);


(edit) Servo pins are pinMode()-ed in Servo.cpp, btw:

Code: [Select]
uint8_t Servo::attach(int pin, int min, int max)
{
  if(this->servoIndex < MAX_SERVOS ) {
    pinMode( pin, OUTPUT) ;                                   // set servo pin to output



Go Up