Go Down

Topic: controlling an array of 10 servos (Read 4601 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]);
The art of getting good answers lies in asking good questions.

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.
The art of getting good answers lies in asking good questions.

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
  }
}

Go Up