Pages: [1]   Go Down
Author Topic: Wave Shield + Mega + Multiple Servos (WAVHC + Servo Timer 2)  (Read 902 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

#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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: February 03, 2013, 09:43:42 am by insultcomicdog » Logged

Poole, Dorset, UK
Offline Offline
Edison Member
*
Karma: 52
Posts: 2316
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Mark
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: February 03, 2013, 08:08:42 am by insultcomicdog » Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 616
Posts: 49433
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

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

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 616
Posts: 49433
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 616
Posts: 49433
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.  smiley-cool
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 32
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 616
Posts: 49433
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.)
Logged

Pages: [1]   Go Up
Jump to: