Go Down

Topic: Wave Shield + Mega + Multiple Servos (WAVHC + Servo Timer 2) (Read 1 time) previous topic - next topic

I'm having issues getting two servos to work with a MEGA + WAV Shield using WAVHC and Servo Timer 2 libraries. The libraries use separate timers, so there should not be any timer conflicts.

Basically I can get myservo1 to work fine, but issues arise when I add a second servo. I have two servos attached to pins 6, 7...If I call stepper2()...myservo2 will rotate fine...BUT if I call stepper1(), both servos rotate when it should only be myservo1 that rotates.

If I remove the WAV shield and upload this simplified sketch everything works fine. I can call each stepper function separately and rotate each servo independently.

Code: [Select]


#include <ServoTimer2.h>  // the servo library

ServoTimer2 myservo1;
ServoTimer2 myservo2;
int servoPin1 = 6;
int servoPin2 = 7;
int pos = 50;    // variable to store the servo position

void setup() {
 initServo();
}

void initServo()
{
 Serial.println("initServo");
 
 pinMode(servoPin1, OUTPUT);
 pinMode(servoPin2, OUTPUT);
 
 // set up servo pin
 myservo1.attach(servoPin1);
 myservo2.attach(servoPin2);
 
 stepper1();
 delay(5000);
 stepper2();
 delay(5000);
 stepper1();
 stepper2();
}

void loop()
{
 
}


int stepper1(){
 Serial.println("stepper1");

 for(pos = 1400; pos < 1700; pos += 15)  // goes from 0 degrees to 180 degrees
 {                                  // in steps of 1 degree
   myservo1.write(pos);              // tell servo to go to position in variable 'pos'
   delay(15);                       // waits 15ms for the servo to reach the position
 }
 for(pos = 1700; pos>=1400; pos -=15)     // goes from 180 degrees to 0 degrees
 {                                
   myservo1.write(pos);              // tell servo to go to position in variable 'pos'
   delay(15);                       // waits 15ms for the servo to reach the position
 }
}

int stepper2(){
 Serial.println("stepper2");

 for(pos = 1400; pos < 1700; pos += 15)  // goes from 0 degrees to 180 degrees
 {                                  // in steps of 1 degree
   myservo2.write(pos);              // tell servo to go to position in variable 'pos'
   delay(15);                       // waits 15ms for the servo to reach the position
 }
 for(pos = 1700; pos>=1400; pos -=15)     // goes from 180 degrees to 0 degrees
 {                                
   myservo2.write(pos);              // tell servo to go to position in variable 'pos'
   delay(15);                       // waits 15ms for the servo to reach the position
 }
}


If anyone has any tips and suggestions on how to get multiple servos working independently with this setup please let me know.

#1
Feb 03, 2013, 01:38 pm Last Edit: Feb 03, 2013, 03:43 pm by insultcomicdog Reason: 1
This is the sketch that is causing issues when I use the WAV shield:

http://pastebin.com/Ku7bXHFV

It excreeds maximum allowed length so I posted it on PasteBin.

What's curious is that this demo sketch uses the same hardware and libraries as me and appears to have no servo issues:

http://rayjk.com/sites/default/files/article-files/12-Halloween%20Pumpkin/HalloweenPumpkin.pde

holmes4

Which servos, provide a link. How are you powering the servos?

Mark

#3
Feb 03, 2013, 02:07 pm Last Edit: Feb 03, 2013, 02:08 pm by insultcomicdog Reason: 1
I tried using two different power sources for my Mega:

1) 9VDC 650 mAmp
2) 12VDC 2.5 A

which supply power to servos via 5V pin.


These are the servos:
http://fr.hobbytronics.co.uk/powerhd-3001hb

PaulS

A link to the ServoTimer2 library would be useful, too. The normal Servo::write() method expects a value in degrees, not a time in microseconds.

How are you powering the servos? Not from the Arduino, I hope. Oh, wait, I see that you are. Bad idea. Really bad.

Here are links to the ServoTimer2 library I'm using.

ServoTimer2.h
http://pastebin.com/tjFBRen4

ServoTimer2.cpp
http://pastebin.com/a1DQyNQq

I guess the next test is to power the servos externally.

I solved my issues with multiple servos by using an external 5 V 1 AMP alternating PSU. I can now rotate 4 servos independently.

The one thing I noticed is that I have four stepper functions to control each servo. If I call all stepper functions at the same time, each servo will rotate as if they are in a queue and not at the same time. Is this because you can only use one servo at a time because they use same Timer (Servo Timer 2 uses Timer 2)?

Here's my code:


Code: [Select]


ServoTimer2 myservo1;
ServoTimer2 myservo2;
ServoTimer2 myservo3;
ServoTimer2 myservo4;

int servoPin1 = 6;//9;
int servoPin2 = 7;//10;
int servoPin3 = 8;//10;
int servoPin4 = 9;//10;
#define degreesToUS( _degrees) (_degrees * 6 + 900) // macro to convert degrees to microseconds
int pos = 50;    // variable to store the servo position
//servo vars

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
  Serial.println("slave setup");
 
  initServo();
}

void initServo()
{
  Serial.println("initServo");
 
  pinMode(servoPin1, OUTPUT);
  pinMode(servoPin2, OUTPUT);
  pinMode(servoPin3, OUTPUT);
  pinMode(servoPin4, OUTPUT);

  // set up servo pin
  myservo1.attach(servoPin1);
  myservo2.attach(servoPin2);
  myservo3.attach(servoPin3);
  myservo4.attach(servoPin4);
 
  stepper1();
  stepper2();
  stepper3();
  stepper4();
}


int stepper1(){
  Serial.println("stepper1");

  for(pos = 1400; pos < 1700; pos += 15)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 1700; pos>=1400; pos -=15)     // goes from 180 degrees to 0 degrees
  {                               
    myservo1.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

int stepper2(){
  Serial.println("stepper2");

  for(pos = 1400; pos < 1700; pos += 15)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo2.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 1700; pos>=1400; pos -=15)     // goes from 180 degrees to 0 degrees
  {                               
    myservo2.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

int stepper3(){
  Serial.println("stepper3");

  for(pos = 1400; pos < 1700; pos += 15)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo3.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 1700; pos>=1400; pos -=15)     // goes from 180 degrees to 0 degrees
  {                               
    myservo3.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

int stepper4(){
  Serial.println("stepper4");

  for(pos = 1400; pos < 1700; pos += 15)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo4.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 1700; pos>=1400; pos -=15)     // goes from 180 degrees to 0 degrees
  {                               
    myservo4.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

PaulS

Why do you have multiple nearly identical functions?

Why are the functions to move the servos called stepperN?"

Quote
If I call all stepper functions at the same time

You can't call 4 functions at the same time.

Quote
Is this because you can only use one servo at a time because they use same Timer (Servo Timer 2 uses Timer 2)?

No, and I'll be back after a short delay() to explain why.

I now realize that the delay() in each function is probably causing issues, making the servos appear to rotate in queue. I'll use an interval AND millis() (http://arduino.cc/en/Tutorial/BlinkWithoutDelay) to set rotation and report back.

PaulS

Quote
I'll use an interval AND millis() (http://arduino.cc/en/Tutorial/BlinkWithoutDelay) to set rotation and report back.

I love when subtle hints work.  8)

Hehe...I need separate stepper functions b/c I'll likely have to calibrate each servo individually. I actually don't plan on using all servos at the same time. I was just doing a test in the init() to see what would happen, and was curious why I was getting this behaviour. It'll will be great to have the option to use all servos at the same time now.

PaulS

Quote
I need separate stepper functions b/c I'll likely have to calibrate each servo individually.

The range of the for loops as well as the servo instance to manipulate could all be inputs to one function.

(I'm going to keep hammering on this. There is no need for 4 nearly identical functions when one will suffice.)

Go Up