Cant control servos outside pin 9(Servo/MegaServ)

Hey All,

I am new to the arduino, and today was my first try at it.
I got a standard futaba servo up and running on pin 9 (external power supply), but when I try pin 6.. it does not work anymore, not even with the MegaServo library.

Please, what can I do to resolve this problem?, because some Arduino-Specialist dude at the Maker Faire, San Fransisco this year promised me that up to 12 servos would work on the Arduino Duemilanov.

Cheers,

NLStitch

Code:

#include <Servo.h>

Servo steering;
Servo gear;
Servo throttle;

void setup()
{
  steering.attach(5);
  gear.attach(6);
  throttle.attach(7);
  
  //Get all axes to their initial position
  steering.write(80);
  gear.write(160);
  throttle.write(0);
  
  Serial.begin(9600);
  Serial.print("Ready for driving commands.");
}

void loop()
{


  if ( Serial.available() > 0) {
    
    byte incomingByte = Serial.read();
    int cmd = int(incomingByte); //Incoming byte gets converted to an int

    if(cmd == 102){ //Forward
      Serial.print("Going Forward");
      gear.write(110);
      
    }else if(cmd == 98){ //Backward
      Serial.print("Going Backward");
      gear.write(90);
      
    }else if(cmd == 108){ //Turn Left
      Serial.print("Turning left");
      steering.write(160);
      
    }else if(cmd == 114){ //Turn Right
      Serial.print("turning Right");
      steering.write(0);
      
    }else if(cmd == 99){ //Steering Center
      Serial.print("Centering");
      steering.write(80);
      
    }else if(cmd == 109){ // Throttle 0%
      Serial.print("T: 0%");
      throttle.write(0);
      
    }else if(cmd == 110){ //Throttle 25%
      Serial.print("T: 25%");
      throttle.write(36);
      
    }else if(cmd == 111){ //Throttle 50%
      Serial.print("T:50%");
      throttle.write(72);
      
    }else if(cmd == 112){ //Throttle 75%
      Serial.print("T: 75%");
      throttle.write(108);
      
    }else if(cmd == 113){ //Throttle 100%
      Serial.print("T: 100%");
      throttle.write(160);
      
    }
 
  }

}

and MegaServo:

#include <MegaServo.h>

MegaServo steering;
MegaServo gear;
MegaServo throttle;

void setup()
{
  steering.attach(5);
  gear.attach(6);
  throttle.attach(7);
  
  //Get all axes to their initial position
  steering.write(80);
  gear.write(160);
  throttle.write(0);
  
  Serial.begin(9600);
  Serial.print("Ready for driving commands.");
}

void loop()
{


  if ( Serial.available() > 0) {
    
    byte incomingByte = Serial.read();
    int cmd = int(incomingByte); //Incoming byte gets converted to an int

    if(cmd == 102){ //Forward
      Serial.print("Going Forward");
      gear.write(110);
      
    }else if(cmd == 98){ //Backward
      Serial.print("Going Backward");
      gear.write(90);
      
    }else if(cmd == 108){ //Turn Left
      Serial.print("Turning left");
      steering.write(160);
      
    }else if(cmd == 114){ //Turn Right
      Serial.print("turning Right");
      steering.write(0);
      
    }else if(cmd == 99){ //Steering Center
      Serial.print("Centering");
      steering.write(80);
      
    }else if(cmd == 109){ // Throttle 0%
      Serial.print("T: 0%");
      throttle.write(0);
      
    }else if(cmd == 110){ //Throttle 25%
      Serial.print("T: 25%");
      throttle.write(36);
      
    }else if(cmd == 111){ //Throttle 50%
      Serial.print("T:50%");
      throttle.write(72);
      
    }else if(cmd == 112){ //Throttle 75%
      Serial.print("T: 75%");
      throttle.write(108);
      
    }else if(cmd == 113){ //Throttle 100%
      Serial.print("T: 100%");
      throttle.write(160);
      
    }
 
  }

}

And standard code from the arduino website doesn't work:

#include <MegaServo.h>
#define NBR_SERVOS 4  // the number of servos, up to 48 for Mega, 12 for other boards
#define FIRST_SERVO_PIN 5 

MegaServo Servos[NBR_SERVOS] ; // max servos is 48 for mega, 12 for other boards

int pos = 0;      // variable to store the servo position 
int potPin = 0;   // connect a pot to this pin.

void setup()
{
  for( int i =0; i < NBR_SERVOS; i++)
    Servos[i].attach( FIRST_SERVO_PIN +i, 800, 2200);
}
void loop()
{ 
  pos = analogRead(potPin);   // read a value from 0 to 1023
  for( int i =0; i <NBR_SERVOS; i++) 
    Servos[i].write(90);   
  delay(15);   
}

What do you expect to happen? Your last sketch reads the pot value but its not used, so the servos will not move once they are centered. Why not try the example sketch that comes with MegaServo. (change the value of FIRST_SERVO_PIN to 4) You should see the servo(s) sweep once then move to follow the pot value on analog pin 0

Okay..Thanks!! I now have multiple servo's, but they are "shocking/jibbering".

here is the code:

#include <MegaServo.h>
#define NBR_SERVOS 7  // the number of servos, up to 48 for Mega, 12 for other boards
#define FIRST_SERVO_PIN 5 

MegaServo Servos[NBR_SERVOS] ; // max servos is 48 for mega, 12 for other boards

int pos = 0;      // variable to store the servo position 
int potPin = 0;   // connect a pot to this pin.

void setup()
{
  for( int i =0; i < NBR_SERVOS; i++)
    Servos[i].attach( FIRST_SERVO_PIN +i, 800, 2200); //pin 5/0 is steering, pin 6/1 = gear, pin 7/2 = throttle
  
  Serial.begin(9600);
  Serial.print("Ready for driving commands.");
}

void loop()
{


  if ( Serial.available() > 0) {
    
    byte incomingByte = Serial.read();
    int cmd = int(incomingByte); //Incoming byte gets converted to an int

    if(cmd == 102){ //Forward
      Serial.print("Going Forward");
      Servos[1].write(180);
      
    }else if(cmd == 98){ //Backward
      Serial.print("Going Backward");
      Servos[1].write(0);
      
    }else if(cmd == 108){ //Turn Left
      Serial.print("Turning left");
      Servos[0].write(170);
      
    }else if(cmd == 114){ //Turn Right
      Serial.print("turning Right");
      Servos[0].write(0);
      
    }else if(cmd == 99){ //Steering Center
      Serial.print("Centering");
      Servos[0].write(80);
      
    }else if(cmd == 109){ // Throttle 0%
      Serial.print("T: 0%");
      Servos[2].write(180);
      
    }else if(cmd == 110){ //Throttle 25%
      Serial.print("T: 25%");
      Servos[2].write(108);
      
    }else if(cmd == 111){ //Throttle 50%
      Serial.print("T:50%");
      Servos[2].write(72);
      
    }else if(cmd == 112){ //Throttle 75%
      Serial.print("T: 75%");
      Servos[2].write(36);
      
    }else if(cmd == 113){ //Throttle 100%
      Serial.print("T: 100%");
      Servos[2].write(0);
      
    }
 
  }

}

I now have multiple servo's, but they are "shocking/jibbering

I'm guessing you don't have them on a separate power supply.

Hi NLStitch, “shocking/jibbering” are not words I have ever heard used to describe servo behavior, can you say more about what the servos are doing?

You may want to try reducing the range of movement in your attach function call just in case there is some mechanical binding at the extreme range. You can test if this is causing a problem by adding a command that centers all the servos :
for( int i =0; i < NBR_SERVOS; i++)
Servos*.write(90);*
If the servos center correctly then you need to fix the problem at the extremes of movement

Instead of:

if(cmd == 102){ //Forward
      Serial.print("Going Forward");
      Servos[1].write(180);

    }else if(cmd == 98){ //Backward
      Serial.print("Going Backward");
      Servos[1].write(0);

    }else if(cmd == 108){

Can I suggest:

 if('f' == cmd){ //Forward
      Serial.print("Going Forward");
      Servos[1].write(180);

    }else if('b' == cmd){ //Backward
      Serial.print("Going Backward");
      Servos[1].write(0);

    }else if('l' == cmd){

or even:

switch (cmd) {
    case 'f' :      
        Serial.print("Going Forward");
        Servos[1].write(180);
        break;

    case 'b' :
        Serial.print("Going Backward");
        Servos[1].write(0);
        break;

   case 'l': 
etc.

Just makes it easier to see what's going on.

AWOL is giving good advice, as usual, but the form in the first suggestion
if('f' == cmd)
is not intuitive for a beginner and benefits from some explanation.

This expression does the same thing as the more obvious:
if(cmd == 'f' )

but putting the constant 'f' before the == allows the compiler to detect the common mistake of using a sign equals sign (setting the left hand side to be equal to the right) where an equality test was intended (testing to see if the left and right sides are equal). The compiler will report an error if you accidently do
if('f' = cmd) // error: single equal sign where == was intended
because 'f' is a constant (its equal to 102) and cannot be set equal to the value of the cmd variable.

Hi,

Since I can only send my strings to the device using byte format in Java, I can't cast them back to strings in the Arduino to parse them like you suggested.(Or I missed something somewhere) That's why I am using numbers, because the Bytes received by the arduino can still be used as Integers. I know.. it looks like a really dirty hack and wrong way to accept and process data.. sigh .

What I meant with shocking of the servo's means that the servo's do "want" to get to their position at , let's say, 180, but its like they struggle to get there, and they only get there half if the wheel of the robot is on the ground, and full if the wheel is lifted from the ground.In both of these cases, it looks like they want to get back to there center as wel, like a clock or wristwatch that has an empty battery, going from left to right or right to left and only coming there half way.

The weird thing is, is when I used one with the Servo library at pin 9, it wasn't a problem.

NOTE: The 3 servo's ARE hooked up to a usb port of my laptop, and are therefore on a external power supply. So that should not be the problem.

That should be clear enough =). I hope you can help me.

Cheers,

NLStitch

Since I can only send my strings to the device using byte format in Java, I can't cast them back to strings in the Arduino

'f' is not a string - it is a single character (byte) - the quotes are single quotes.
A string - "f" - uses double quotes and would consist of two characters, the character 'f and the character '\0'.

The 3 servo's ARE hooked up to a usb port of my laptop, and are therefore on a external power supply.

Then you need to put them on a supply capable of supplying sufficient current. Don't forget to connect the grounds.

Changed the code to recognise 'f', etc., but it is still a bit "struggling", even if I am not giving any commands.

#include <MegaServo.h>
#define NBR_SERVOS 7  // the number of servos, up to 48 for Mega, 12 for other boards
#define FIRST_SERVO_PIN 5 

MegaServo Servos[NBR_SERVOS] ; // max servos is 48 for mega, 12 for other boards

int pos = 0;      // variable to store the servo position 

void setup()
{
  //Attach the Servos
  for( int i =0; i < NBR_SERVOS; i++){
    Servos[i].attach( FIRST_SERVO_PIN +i, 800, 1500); //pin 5/0 is steering, pin 6/1 = gear, pin 7/2 = throttle
  }
  
  
  Serial.begin(9600);
  Serial.print("Ready for driving commands.");
}

void loop()
{


  if ( Serial.available() > 0) {
    
    char cmd = Serial.read();
    //int cmd = constrain(int(incomingByte),0,180); //Incoming byte gets converted to an int

    if(cmd == 'f'){ //Forward
      Serial.print("Going Forward");
      Servos[1].write(180);
      
    }else if(cmd == 'b'){ //Backward
      Serial.print("Going Backward");
      Servos[1].write(0);
      
    }else if(cmd == 'l'){ //Turn Left
      Serial.print("Turning left");
      Servos[0].write(170);
      
    }else if(cmd == 'r'){ //Turn Right
      Serial.print("turning Right");
      Servos[0].write(0);
      
    }else if(cmd == 'c'){ //Steering Center
      Serial.print("Centering");
      Servos[0].write(80);
      
    }else if(cmd == 'm'){ // Throttle 0%
      Serial.print("T: 0%");
      Servos[2].write(180);
      
    }else if(cmd == 'n'){ //Throttle 25%
      Serial.print("T: 25%");
      Servos[2].write(108);
      
    }else if(cmd == 'o'){ //Throttle 50%
      Serial.print("T:50%");
      Servos[2].write(72);
      
    }else if(cmd == 'p'){ //Throttle 75%
      Serial.print("T: 75%");
      Servos[2].write(36);
      
    }else if(cmd == 'q'){ //Throttle 100%
      Serial.print("T: 100%");
      Servos[2].write(0);
      
    }
 
  }

}

The 'f', 'b' etc stuff was never going to cure the stuttering of the servos, just make your code easier to read.

If you've got a four-pack of fresh AA batteries or a bench supply capable of at least one amp at six volts, you could try powering the servos off those. Don't forget to common the grounds. (I wish I had a quid for every time I've typed that!)

Common the grounds? Sorry, I am not the electro type of guy..

You need to connect the Ground (0V or -ve terminal of a battery) of your external supply (batteries, whatever) to the ground (Gnd) pin on your Arduino.

okay, that grounding changed some things, but did not solve all the problems.. yet.

The steering servo is still jittering all the time, and the other servo's jitter when they position themselves or have to pull or push to "heavy" , (but these servo's are strong enough.. I had them on my R/C plane before.)

I have uploaded a small video that shows what this jittering means.. But the results are different, (see above) then showed in the vid. All servo's are working but are jittering when they adjust, and the steering servo is jittering all the time.

Video could still be processing, because it's new. Here it is:

Cheers,

NLStitch

P.S: The piece that connects all the + and - to the battery has an additional wire as well(and is not showed in the vid).. this wire is going from the ground there to a ground of the arduino.

The video was still processing when I tried to look but I concur with AWOL, it sounds like you need a more powerful power supply.

OK, I have now seen the video. Can you try swapping the servo connections between the one that is jittering and one that is working ok. If the same servo jitters then try to actually swap the servos to see if it is problem with mechanical load.

You could also try disconnecting the mechanical load from all the servos and see if that stops the jittering.

Okay, rechecked all the wiring, all the servo's are working now but they are jittering when they want to get to their goal position.

I will try powering one servo with the power supply. If it works then I know that this power supply is not going to get all the servos working.

I do think it's strange if its the power supply, because this 4,8 volt pack worked like a charm powering -> 4 <- of these servo's in my r/c plane. I'm confused.

Cheers,

NLStitch

okay.. I tested 1 servo on my power supply (Steering only, power supply is arduino).

This code doesn't work, motor jittering etc. :

#include <MegaServo.h>
#define NBR_SERVOS 7  // the number of servos, up to 48 for Mega, 12 for other boards
#define FIRST_SERVO_PIN 5 

MegaServo Servos[NBR_SERVOS] ; // max servos is 48 for mega, 12 for other boards

int pos = 0;      // variable to store the servo position 

void setup()
{
  //Attach the Servos
  for( int i =0; i < NBR_SERVOS; i++){
    Servos[i].attach( FIRST_SERVO_PIN +i, 800, 1500); //pin 5/0 is steering, pin 6/1 = gear, pin 7/2 = throttle
  }
  
  
  Serial.begin(9600);
  Serial.print("Ready for driving commands.");
}

void loop()
{


  if ( Serial.available() > 0) {
    
    char cmd = Serial.read();
    //int cmd = constrain(int(incomingByte),0,180); //Incoming byte gets converted to an int

    if(cmd == 'f'){ //Forward
      Serial.print("Going Forward");
      Servos[1].write(180);
      
    }else if(cmd == 'b'){ //Backward
      Serial.print("Going Backward");
      Servos[1].write(0);
      
    }else if(cmd == 'l'){ //Turn Left
      Serial.print("Turning left");
      Servos[0].write(170);
      
    }else if(cmd == 'r'){ //Turn Right
      Serial.print("turning Right");
      Servos[0].write(0);
      
    }else if(cmd == 'c'){ //Steering Center
      Serial.print("Centering");
      Servos[0].write(80);
      
    }else if(cmd == 'm'){ // Throttle 0%
      Serial.print("T: 0%");
      Servos[2].write(180);
      
    }else if(cmd == 'n'){ //Throttle 25%
      Serial.print("T: 25%");
      Servos[2].write(108);
      
    }else if(cmd == 'o'){ //Throttle 50%
      Serial.print("T:50%");
      Servos[2].write(72);
      
    }else if(cmd == 'p'){ //Throttle 75%
      Serial.print("T: 75%");
      Servos[2].write(36);
      
    }else if(cmd == 'q'){ //Throttle 100%
      Serial.print("T: 100%");
      Servos[2].write(0);
      
    }
 
  }

}

This code DOES, using the Servo library, instead of MegaServo:
(using steering only, power supply is arduino).

#include <Servo.h>

Servo myservo;
int pos=90;

void setup()
{
myservo.attach(9);
}

void loop()
{
myservo.write(pos);

delay(100);



pos++;

if(pos > 170){
pos = 0;
}

}

So, it's either a code problem, or a problem with the library. The servo is not jittering at all when using the Servo library.Both of these tests had the same power supply and the same servo(steering).

Cheers,

NLStitch

Just out of interest, what happens with the MegaServo sketch if you set NBR_SERVOS to one?

Same result.