how to attach and drive servos with arrays..?

I’ve got zero programming/Arduino experience, but I’ve been doing a fair bit of reading around them recently…

My ultimate goal’s to build a small hexapod using my Arduino Mega 2560 (r2, I think?), but I’m starting small and trying to make 4-leg, 2DOF per leg walking thing to figure out how to do some of what I may need…

I’ve got the thing skuttling around the floor, driven by single characters sent from a BT terminal app on my (android) Desire Z.

It’s currently simply running through a list of servo movements for forwards, back, left and right, like this:

void Walk(){
  LegServo5.write(90);                
  LegServo6.write(90);                
  delay(Delay);
  LegServo4.write(0);                
  LegServo7.write(0);                
  delay(Delay);
  LegServo0.write(45);                
  LegServo1.write(0);                
  LegServo2.write(135);                               
  LegServo3.write(180);                  
  delay(Delay);

but I like the idea of both attaching and driving the servos from arrays. I think this could let me include the number of legs and servos and have my code work out what servos go where from there… (so I change a couple of numbers to go from my 4-leg/8servo to a 6-leg/18 servo when the servos turn up!).

This is how I’ve been trying to attach them:

const int NoLegServos = 8;                 // number of servos in legs
int LegServoPins[NoLegServos] =    // Servo pins, starting at servo0
{43,42,12,49,44,45,53,8};

void setup():
  for (int thisServo = 0; thisServo < NoLegServos; thisServo++) {
  LegServo(thisServo).attach(LegServoPins[thisServo]);
  delay(Delay);
}

I’m trying to end up with the loop running
LegServo0.attach(43)
LegServo1.attach(42)
etc …

but I’m doing something wrong, it wont compile giving:
Sketch.cpp: In function ‘void setup()’:
Sketch:77: error: ‘LegServo’ was not declared in this scope

can anyone comment on whether using arrays is a good move at all and how I might be able to if it is please?

thanks in advance!

'tunes

You're almost there, but the shape of the brackets for LegServo array (which isn't defined), is wrong.

Thanks for your quick reply AWOL, nice one ;)

I think I may still be 'a bit off the mark' though. I wasn't thinking of LegServo as an array at all, just trying to 'build' the lines starting with LegServo using the servo numbers (0-7 atm) and the pin they're attached to from the LegServoPins array. As the servos are numbered 0 upwards, I was trying to use the number in thisServo, to get LegServo0, LegServo1 etc..

Does LegServo have to be an array to do what I'm trying? If it does, it'd need to contain 0,1,2,3, up to the number of servos I've got. Would populating it with a loop be the way to go, or would that just be moving the same problem elsewhere?

...do you think arrays are a sensible direction to be heading in for the bots actual moves? (I'd like to go the full-on IK route, but thats way beyond me atm)

thanks again.

'tunes

You can create an array of servo objects. Something like…

#include <Servo.h>

const int NoLegServos = 8;                 // number of servos in legs

Servo LegServo[NoLegServos];      // Define servo array

int LegServoPins[NoLegServos] =    // Servo pins, starting at servo0
{43,42,12,49,44,45,53,8};

void setup()
{
  for (int thisServo = 0; thisServo < NoLegServos; thisServo++) 
  {
    LegServo[thisServo].attach(LegServoPins[thisServo]);
  }
}

20 mins:20 secs -- watch and see, amazing robots from analysis of nature http://www.ted.com/talks/robert_full_on_engineering_and_evolution.html

dxw00d:
You can create an array of servo objects. Something like…

#include <Servo.h>

const int NoLegServos = 8;                 // number of servos in legs

Servo LegServo[NoLegServos];      // Define servo array

int LegServoPins[NoLegServos] =    // Servo pins, starting at servo0
{43,42,12,49,44,45,53,8};

void setup()
{
  for (int thisServo = 0; thisServo < NoLegServos; thisServo++)
  {
    LegServo[thisServo].attach(LegServoPins[thisServo]);
  }
}

thanksa lot dxw00d. That’s just where I was heading in my thinking. It compiles just fine like you’ve written, but I’m not sure I understand the logic behind it… how’s an array (which doesn’t contain anything, but is the right length to hold a list of my servos) produce the numbers 0 to NoLegServos?

(I guess I’m at that annoying stage in my learning where even giving the answer raises more questions!)

thanks again

It does contain something, it contains 8 servo objects.

Servo myServo;

defines a single servo object.

Servo LegServo[NoLegServos];

defines NoLegServos (8 in your case) servo objects, which are referenced through the array.

It's not annoying, because you are trying to do it yourself, and weren't far off with your first attempt.

Not sure about what you mean by "doesn't contain anything"; it is an array of Servos, of length NoLegsServos, and the indices run from zero to NoLegsServos - 1.

AWOL: Not sure about what you mean by "doesn't contain anything"; it is an array of Servos, of length NoLegsServos, and the indices run from zero to NoLegsServos - 1.

I was missing a couple of the finer details of defining the LegServos array.. mentioning it being empty came from it not being populated like I had done here: int LegServoPins[NoLegServos] = // Servo pins, starting at servo0 {43,42,12,49,44,45,53,8};

but, it seems that doesn't mean it's empty! I've obviously got a lot more reading to do.

Thanks to both of you for your help, I'd have been swearing at it (and myself) for ages otherwise. It's good to see I wasn't miles away from what was needed too.

Do you (anyone) think using arrays to hold servo moves is a reasonable next step in my botts development, or could you suggest a better/different approach?

OK, I thought I understood, but somehow don’t.

I’ve put the additional servo array into my sketch and have got them attaching OK using the loop.
I’d like to do the same thing when creating the servo objects, effectively replacing these existing lines:
Servo LegServo0; // hipFL
Servo LegServo1; // hipFR
Servo LegServo2; // hipBL
Servo LegServo3; // hipBR
Servo LegServo4; // kneeFL
Servo LegServo5; // kneeFR
Servo LegServo6; // kneeBL
Servo LegServo7; // kneeBR

if I try to do the same as with attaching them:
//create servo objects
for (int thisServo = 0; thisServo < NoLegServos; thisServo++)
{
Servo LegServo[thisServo];
}

with the loop doing so before setup() (starting at line 46), I get:
Sketch:45: error: expected unqualified-id before ‘for’
Sketch:45: error: expected constructor, destructor, or type conversion before ‘<’ token
Sketch:45: error: expected constructor, destructor, or type conversion before ‘++’ token

if I put the loop into setup(), it compiles OK until I try to do anything with a servo, with:
error: ‘LegServo0’ was not declared in this scope

so it compiles but isnt creating the servo objects as I hoped.

can anyone see what (probably very basic thing) am I missing please?

This is exactly the kind of thing you don’t do when you’re trying to drive servos with array(s)

Servo LegServo0; // hipFL
Servo LegServo1; // hipFR
Servo LegServo2; // hipBL
Servo LegServo3; // hipBR
Servo LegServo4; // kneeFL
Servo LegServo5; // kneeFR
Servo LegServo6; // kneeBL
Servo LegServo7; // kneeBR

GoForSmoke: This is exactly the kind of thing you don't do when you're trying to drive servos with array(s)

Servo LegServo0; // hipFL Servo LegServo1; // hipFR Servo LegServo2; // hipBL Servo LegServo3; // hipBR Servo LegServo4; // kneeFL Servo LegServo5; // kneeFR Servo LegServo6; // kneeBL Servo LegServo7; // kneeBR

please, share any further thoughts.

Put them in an array, like dxw00d showed. Then you can address the one(s) you want in a general manner instead of needing special lines for each one.

It's quite possible that you should learn and practice more C before taking on any complex project. Your approach will certainly benefit. You know, Dick and Jane before War and Peace?

GoForSmoke: Put them in an array, like dxw00d showed. Then you can address the one(s) you want in a general manner instead of needing special lines for each one.

I'm trying to do it using an array, so I can then go on to deal with collections of servos/legs/moves rather than servo0 go here, servo1 there etc. Is that the same as you mean?

The 'LegServo?.Attach(?)' section now does just what I was after-thanks. Applying the same logic in replacement of the (somehow wrong?) 'exactly the kind of thing you don't do' section wont do the same though.

GoForSmoke: It's quite possible that you should learn and practice more C before taking on any complex project. Your approach will certainly benefit. You know, Dick and Jane before War and Peace?

I completely agree. That's what I'm trying to do, I'm just asking for a couple of pointers along the way. Can servos and arrays be much more basic than getting the combination of the two to move a servo?

I understand I've got something *dumb*wrong, could anyone be kind enough to let me know what/how please?

This bit...

Servo LegServo[NoLegServos];

replaces...

Servo LegServo0;  // hipFL
Servo LegServo1;  // hipFR
Servo LegServo2;  // hipBL
Servo LegServo3;  // hipBR
Servo LegServo4;  // kneeFL
Servo LegServo5;  // kneeFR
Servo LegServo6;  // kneeBL
Servo LegServo7;  // kneeBR

It defines all 8 Servos at the same time.

You could use constants (or #defines) to associate a label to each servo array instance.

const byte hipFL = 0;
const byte hipFR = 1;
const byte hipBL = 2;
const byte hipBR = 3;
const byte kneeFL = 4;
const byte kneeFR = 5;
const byte kneeBL = 6;
const byte kneeBR = 7;

This would allow you to do...

void Walk(){
  LegServo[kneeFR].write(90);                
  LegServo[kneeBL].write(90);                
  delay(Delay);
  LegServo[kneeFL].write(0);                
  LegServo[kneeBR].write(0);
...

thanks dxw00d

dxw00d:
This bit…

Servo LegServo[NoLegServos];

replaces…

Servo LegServo0;  // hipFL

Servo LegServo1;  // hipFR
Servo LegServo2;  // hipBL
Servo LegServo3;  // hipBR
Servo LegServo4;  // kneeFL
Servo LegServo5;  // kneeFR
Servo LegServo6;  // kneeBL
Servo LegServo7;  // kneeBR

If I comment out my old Servo LegServo0;  // hipFL lines and leave Servo LegServo[NoLegServos];, I then get ‘:200: error: ‘LegServo0’ was not declared in this scope’ when trying to use the servos (LegServo0.write(90)).

If I comment out the Servo LegServo[NoLegServos]; and leave Servo LegServo0;  // hipFL etc..., I can use the servos OK

What I’m aiming for is something along the lines of:

const int NoLegServos = 8;
int LegServoPins[NoLegServos]={43,42,12,49,44,45,53,8};

replace this:

Servo LegServo0;
Servo LegServo1;
Servo LegServo2;
Servo LegServo3;
Servo LegServo4;
Servo LegServo5;
Servo LegServo6;
Servo LegServo7;

with something like:
Servo LegServo[NoLegServos];??

something like this to attach the servos:

for (int thisServo = 0; thisServo < NoLegServos; thisServo++) 
{
  LegServo[thisServo].attach(LegServoPins[thisServo]);
}

and eventually something like this to read arrays of moves and make them happen:

    for (int thisServo = 0; thisServo < NoLegServos; thisServo++) {
      LegServo(thisServo).write(WalkMoves[thisServo][thisServo]);
      delay(Delay);
    }

…so, to add more servos, all I would have to do is change NoLegServos and set their pins in LegServoPins.

I’ve attached my main .ino, in case it helps out. I know it’ll probably make experienced Arduino-ers cringe, but it’s my first fumble at making something move, which I’m trying to improve on.

What I’m missing?

Plank_B_0_006.ino (8.39 KB)

You're missing the difference between () and []

We seem to have gone backwards a bit.

If I comment out my old Code:

Servo LegServo0; // hipFL

lines and leave Code:

Servo LegServo[NoLegServos];

, I then get ':200: error: 'LegServo0' was not declared in this scope' when trying to use the servos (LegServo0.write(90)).

You want to use

LegServo[0].write(90);

instead. Or define the consts, as I suggested earlier, then use

LegServo[hipFL].write(90);

There will be a way to use an array to define your walk patterns.

dxw00d: You want to use

LegServo[0].write(90);

instead.

I think that made the penny drop. When putting the changes into the beginning of my sketch, I hadn't changed my: LegServo?.write(90); lines to LegServo[?].write(90); further on in the sketch.

dxw00d: Or define the consts, as I suggested earlier, then use

LegServo[hipFL].write(90);

I was going to refer to the servos by just a number (LegServo[number]), does creating the constants do anything other than provide a label? (if not, I can see this being of use slightly later on, but I'll stick with 0-7 for now).

I'll get them changed and make sure all's good, then hopefully switch the lists of moves into arrays.

Thanks again for your help (re-reading this thread makes much more sense to me now!)

The constants do just provide labels.