Placing servos in groups

Hi,

I am using an Arduino Mega 2560 with a 2.4GHz transmitter/receiver with a common ground. The Mega and my receiver/servos are powered independently.

I am trying to place servos into different groups so that when I move a particular pot on my R/C transmitter it moves those servos at the same time. When I move a different pot it moves a different group of servos.

The below does not work, however, it shows what I am trying to achieve:

#include <VarSpeedServo.h>


const int numberOfServos = 2;                  //number of servos

VarSpeedServo servo[numberOfServos];   //create servo objects
int portNumberGroup1[numberOfServos] = {22}; //initalize input pin numbers
int portNumberGroup2[numberOfServos] = {23}; //initalize input pin numbers
int servoPinGroup1[numberOfServos] = {52};  //intialize output pins servos connect to
int servoPinGroup2[numberOfServos] = {53};  //intialize output pins servos connect to
int highvalue[numberOfServos] = {1600};  //control knob value high
int lowvalue[numberOfServos] = {1100};    //control knob value low
int closepos = {45};   //value (in degrees) for servo closed position value
int openpos =  {80};    //value (in degrees) for servo open postion
int mid = 90;         //value (in degrees) for servo mid postion



void setup()
{

  for (int i = 0; i < numberOfServos; i++)
  {
    servo[i].attach(servoPinGroup1[i]);        // attach servos to output pins
    servo[i].attach(servoPinGroup2[i]);         // attach servos to output pins
    pinMode (portNumberGroup1[i], INPUT);      //set up input pins
    pinMode (portNumberGroup2[i], INPUT);      //set up input pins
  }

}

void loop ()
{


  for (int i = 0; i < numberOfServos; i++) {
    if (pulseIn(portNumberGroup1[i],HIGH) > lowvalue[i])  //read all inputs and outputs servo.move commands

      servo[i].slowmove (openpos, 5);   // second arg is servo speed , 20 is about 3 seconds

    else

      servo[i].slowmove (closepos, 5);  // second arg is servo speed , 20 is about 3 seconds

    if (pulseIn(portNumberGroup2[i],HIGH) > lowvalue[i])  //read all inputs and outputs servo.move commands

      servo[i].slowmove (openpos, 10);   // second arg is servo speed , 20 is about 3 seconds

    else

      servo[i].slowmove (closepos, 10);  // second arg is servo speed , 20 is about 3 seconds

      
  }
}

Thank you for your help.

You create a bunch of two-element arrays and only initialize one of the elements. Why?!?

I believe this part is wrong:

    servo[i].attach(servoPinGroup1[i]);        // attach servos to output pins
    servo[i].attach(servoPinGroup2[i]);         // attach servos to output pins
    pinMode (portNumberGroup1[i], INPUT);      //set up input pins
    pinMode (portNumberGroup2[i], INPUT);      //set up input pins

But I don't know how to add both servoPinGroup1 and servoPinGroup2 together in both servo attach and pinMode.

const int numberOfServos = 2;                  //number of servos
...
int portNumberGroup1[numberOfServos] = {22}; //initalize input pin numbers

See reply#1

Ok, I can initalize all the servos in one line of code but then how do I put them into different groups?

tom_tom_go:
Ok, I can initalize all the servos in one line of code but then how do I put them into different groups?

I don't understand your use of "Ok" there. Can you explain, please?

The below works, however, this does not allow me to put servos into different groups to perform different movements depending on what pot on the controller I turn:

#include <VarSpeedServo.h>


const int numberOfServos = 2;                  //number of servos

VarSpeedServo servo[numberOfServos];   //create servo objects
int portNumber[numberOfServos] = {22,21,20}; //initalize input pin numbers
int servoPin[numberOfServos] = {52,51,50};  //intialize output pins servos connect to
int highvalue[numberOfServos] = {1600};  //control knob value high
int lowvalue[numberOfServos] = {1100};    //control knob value low
int closepos = {45};   //value (in degrees) for servo closed position value
int openpos =  {80};    //value (in degrees) for servo open postion
int mid = 90;         //value (in degrees) for servo mid postion



void setup()
{

  for (int i = 0; i < numberOfServos; i++)
  {
    servo[i].attach(servoPin[i]);        // attach servos to output pins
    pinMode (portNumber[i], INPUT);      //set up input pins
  }

}

void loop ()
{


  for (int i = 0; i < numberOfServos; i++) {
    if (pulseIn(portNumber[i],HIGH) > lowvalue[i])  //read all inputs and outputs servo.move commands

      servo[i].slowmove (openpos, 5);   // second arg is servo speed , 20 is about 3 seconds

    else

      servo[i].slowmove (closepos, 5);  // second arg is servo speed , 20 is about 3 seconds
  }
}

If I initialize all the servos then how do I next go about placing them into groups to associate with different pins on the Mega which are connected to my receiver?

const int numberOfServos = 2;                  //number of servos

int portNumber[numberOfServos] = {22,21,20};

3 into 2 doesn't go.

You have ONE group of servos (what most people properly call an array). There is no way to have ONE array and multiple groups.

Thank you for the clarification.

If I could have some suggestions please on how I might achieve what I am trying to do in code I would be grateful.

Assuming there is one group of servos for each receiver channel of interest and all of the servos in a group are connected to the same output pin:

// Receiver channels
const int CHANNELS = 3;
const int ChannelPins[CHANNELS] = {22, 21, 20}; //initalize input pin numbers
const int CHANNEL_MAX = {1600};  //control knob value max (microseconds)
const int CHANNEL_MIN = {1100};  //control knob value min (microseconds)

// Output Servos
#include <VarSpeedServo.h>
const int SERVOGROUPS = CHANNELS;         //number of servo groups
VarSpeedServo ServoGroups[CHANNELS];   //create servo objects
const int ServoGroupPins[CHANNELS] = {52, 51, 50}; //intialize output pins servos connect to
const int SERVO_CLOSE = 45;   //value (in degrees) for servo closed position value
const int SERVO_OPEN =  80;   //value (in degrees) for servo open postion
const int SERVO_MIDDLE = 90;    //value (in degrees) for servo mid postion

void setup() {
  for (int i = 0; i < CHANNELS; i++) {
    pinMode (ChannelPins[i], INPUT);      //set up input pins
    ServoGroups[i].attach(ServoGroupPins[i]);        // attach servos to output pins
  }
}

void loop () {
  for (int i = 0; i < CHANNELS; i++)  {
    int channelValue = pulseIn(ChannelPins[i], HIGH);
    int servoPosition = map(channelValue, CHANNEL_MIN, CHANNEL_MAX, SERVO_OPEN, SERVO_CLOSE);
    ServoGroups[i].slowmove(servoPosition, 5);
  }
}

I’m not sure that’s what was asked for.
I read it as an input channel could fan-out to multiple servos - you’d need a second, nested for loop for the group, I think.

AWOL:
I'm not sure that's what was asked for.

Neither am I, which is why I stated my assumptions at the top. I'm not even sure that the OP knows what he or she was asking for. :slight_smile:
Yes, you could connect each servo to a separate output pin and add arrays to associate servo pins with groups and groups with input channels but since each group can use a single output pin it doesn't really make sense to use separate pins.

I would like to be able to operate a group of servos, for example, on channel 3 (all connected to the same signal pin on the Mega, i.e. 22) to perform a certain movement, however, have another group of servos on channel 4 to perform a different movement connected to signal pin 23.

In the example that John posted (thank you), can I not add more channels which would be my servo groups?

tom_tom_go:
In the example that John posted (thank you), can I not add more channels which would be my servo groups?

Yes. You can add more channel input pins and servo output pins as long as you add them together. I don't know about the VarSpeedServo library but the standard Servo library can support 48 servo outputs on the Arduino Mega. I doubt that your RF receiver has 48 channels but you can have more than one receiver.

But how do I get different channels to use different loops because CHANNELS is set to all pins which would mean the servos still all follow the same command?

For example, I want to have two or loops that perform different movements but only certain servos use one loop while other use the other loop:

void loop () {
  for (int i = 0; i < CHANNELS; i++)  {
    int channelValue = pulseIn(ChannelPins[i], HIGH);
    int servoPosition = map(channelValue, CHANNEL_MIN, CHANNEL_MAX, SERVO_OPEN, SERVO_CLOSE);
    ServoGroups[i].slowmove(servoPosition, 5);

void loop () {
  for (int i = 0; i < CHANNELS; i++)  {
    int channelValue = pulseIn(ChannelPins[i], HIGH);
    int servoPosition = map(channelValue, CHANNEL_MIN, CHANNEL_MAX, SERVO_OPEN, SERVO_CLOSE);
    ServoGroups[i].slowmove(servoPosition, 20);

You cannot have different functions both called "loop"

You want different groups of servos to run at different speeds? Easy:

// Receiver channels
const int CHANNELS = 3;
const int ChannelPins[CHANNELS] = {22, 21, 20}; //initalize input pin numbers
const int CHANNEL_MAX = 1600;  //control knob value max (microseconds)
const int CHANNEL_MIN = 1100;  //control knob value min (microseconds)

// Output Servos
#include <VarSpeedServo.h>
const int SERVOGROUPS = CHANNELS;         //number of servo groups
VarSpeedServo ServoGroups[CHANNELS];   //create servo objects
const int ServoGroupPins[CHANNELS] = {52, 51, 50}; //intialize output pins servos connect to
const int ServoGroupSpeeds[CHANNELS] = {5, 20, 15};
const int SERVO_CLOSE = 45;   //value (in degrees) for servo closed position value
const int SERVO_OPEN =  80;   //value (in degrees) for servo open postion
const int SERVO_MIDDLE = 90;    //value (in degrees) for servo mid postion

void setup() {
  for (int i = 0; i < CHANNELS; i++) {
    pinMode (ChannelPins[i], INPUT);      //set up input pins
    ServoGroups[i].attach(ServoGroupPins[i]);        // attach servos to output pins
  }
}

void loop () {
  for (int i = 0; i < CHANNELS; i++)  {
    int channelValue = pulseIn(ChannelPins[i], HIGH);
    int servoPosition = map(channelValue, CHANNEL_MIN, CHANNEL_MAX, SERVO_OPEN, SERVO_CLOSE);
    ServoGroups[i].slowmove(servoPosition, ServoGroupSpeeds[i]);
  }
}

Thanks John, that's great.

But what if I want to do more than just speed?

I would like all the servos connected to pin 51, for example, to open and close at different points rather than just do one open or close.

I would like all the servos connected to pin 51, for example, to open and close at different points rather than just do one open or close.

You don't understand how servos work, do you?