Pages: [1]   Go Down
Author Topic: Servo gone crazy: moves without me sending command.  (Read 2150 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I have two of these little servos: http://www.dealextreme.com/p/sg90-mini-servo-with-gears-and-parts-2kg-torque-35764

1- I tested them with the code bellow (from playground). They were working fine connected to an arduino:
2- Now that I almost fish assembling my robot and have them connected to a serial servo controleur, I started programing.
3- All my servos work fine expect for these two. They move like crazy without me sending any command.
4- I thought it might be some kind of incompatibility with the servo controller. But when I plug them back to a stock arduino with same code as before they keep moving continuously in one direction or alternatively.

May I have damaged them somehow? Here is the model of the serial controller I used: http://www.pololu.com/catalog/product/207/resources

Any help would be welcome!

Code:
#include <Servo.h>
int minPulse1     =  0;   // minimum servo position
int maxPulse1     =  180; // maximum servo position
int turnRate1     =  10;  // servo turn rate increment (larger value, faster rate)
int minPulse2     =  0;  // minimum servo position
int maxPulse2     =  180; // maximum servo position
int turnRate2     =  10;  // servo turn rate increment (larger value, faster rate)
int buttonPin     = 13;    // pin that the trigger will be connected to
/** The Arduino will calculate these values for you **/
int centerServo1;
int centerServo2;
int pulseWidth1;     // servo pulse width
int pulseWidth2;     // servo pulse width

Servo servo1;
Servo servo2;

void setup() {
  pinMode(buttonPin, OUTPUT);
  servo1.attach(4);
  servo2.attach(10);
  centerServo1 = maxPulse1 - ((maxPulse1 - minPulse1)/2);
  centerServo2 = maxPulse2 - ((maxPulse2 - minPulse2)/2);
  pulseWidth1 =  centerServo1;
  pulseWidth2 =  centerServo2;
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
  Serial.println(" Arduino Serial Servo Control");
  Serial.println("Press a, s, d, or w to move, spacebar to center, and f to fire");
  Serial.println();
}

void loop() {

  // check for serial input
  if (Serial.available() > 0) {

    int data = Serial.read(); // read the incoming byte:
    digitalWrite(buttonPin, LOW);  // turn the pin off on any incoming data
    switch(data)
    {
case 'a' :  pulseWidth1 = pulseWidth1 - turnRate1;  break;
case 'd' :  pulseWidth1 = pulseWidth1 + turnRate1;  break ;
case ' ' :  pulseWidth1 = pulseWidth2 = centerServo1;  break;
case 's' :  pulseWidth2 = pulseWidth2 - turnRate1;  break;
case 'w' :  pulseWidth2 = pulseWidth2 + turnRate1;  break ;
case 'f' :  digitalWrite(buttonPin, HIGH); delay (1000); digitalWrite(buttonPin, LOW); break;

    }
    // stop servo pulse at min and max
    if (pulseWidth1 > maxPulse1) { pulseWidth1 = maxPulse1; }
    if (pulseWidth1 < minPulse1) { pulseWidth1 = minPulse1; }

// stop servo pulse at min and max
    if (pulseWidth2 > maxPulse2) { pulseWidth2 = maxPulse2; }
    if (pulseWidth2 < minPulse2) { pulseWidth2 = minPulse2; }

     servo1.write(pulseWidth1);
     servo2.write(pulseWidth2);

    // print pulseWidth back to the Serial Monitor (uncomment to debug)
    Serial.print("Servo 1: ");
    Serial.print(pulseWidth1);
    Serial.print(" Servo 2: ");
    Serial.print(pulseWidth2);
    Serial.println("degrees");
  }
}
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8974
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you try connecting the 'bad' servos in place of two of the servos that 'work fine'?  If the 'bad' servos work fine when you put them in place of known working servos then either they were connected to bad channels on the controller or the software driving those channels is faulty.  If the servos misbehave with known good channels, the problem is the servos.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, Thanks for your answer,

Yes I did connect the 'bad' servos to the known to work channels: same issue, they move unexpectedly.
I don't know much about servos, but the only reasons I see is that there electronics went bad. Do you know any way to correct that ?

Thanks
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34724
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Now that I almost fish assembling my robot
I love the idea of fish assembling a robot, what sort of fish bass, bream or salmon?

The reason why a servo moves like this is that it's input line is floating. This can be due to not initialising the pins connecting the servo as an output. I see in your code you don't do this, so add those lines and try again.
Logged

0
Offline Offline
Tesla Member
***
Karma: 147
Posts: 9741
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Simple servo test code that can be used to test individual servos.

Code:
// zoomkat 10-14-11 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readString;
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(2000); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control
  Serial.println("servo-test-22"); // so I can keep track of what is loaded
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  // allow buffer to fill with next character
    }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string
    myservo.writeMicroseconds(readString.toInt()); //convert readString to number for servo
    //myservo.write(readString.toInt()); //for degees 0-180
    readString=""; //empty for next input
  }
}

Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Now that I almost fish assembling my robot
I love the idea of fish assembling a robot, what sort of fish bass, bream or salmon?

I meant 'finish', never mind my tuna brain smiley-grin

The reason why a servo moves like this is that it's input line is floating. This can be due to not initialising the pins connecting the servo as an output. I see in your code you don't do this, so add those lines and try again.

OK will try the code bellow. But though it use to work fine with this code. And I expect the servo controller to initialise the servo correctly.
Could you be more precise about what you mean by 'input line is floating'?

Thanks a lot for your help.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34724
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When a line is an input it is not exerting any voltage pull in any direction. Doing a digitalWrite() on an input pin turns on an off the 30K internal pull up resistor. This is too high an impedance for some of your servos (your bad ones) but it looks like it is just enough for your other servos, but it is not very good.

Quote
And I expect the servo controller to initialise the servo correctly
You might expect it but no.

For more on floating inputs, see:-
http://www.thebox.myzen.co.uk/Tutorial/Inputs.html
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8974
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
And I expect the servo controller to initialise the servo correctly
You might expect it but no.

That call to pinMode( pin, OUTPUT) in the Servo library looks like it should initialize the pin correctly:
Code:
uint8_t Servo::attach(int pin, int min, int max)
{
  if(this->servoIndex < MAX_SERVOS ) {
    pinMode( pin, OUTPUT) ;                                 // set servo pin to output
    servos[this->servoIndex].Pin.nbr = pin; 
    // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128
    this->min  = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS
    this->max  = (MAX_PULSE_WIDTH - max)/4;
    // initialize the timer if it has not already been initialized
    timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
    if(isTimerActive(timer) == false)
      initISR(timer);   
    servos[this->servoIndex].Pin.isActive = true;  // this must be set after the check for isTimerActive
  }
  return this->servoIndex ;
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

0
Offline Offline
Newbie
*
Karma: 0
Posts: 16
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When a line is an input it is not exerting any voltage pull in any direction. Doing a digitalWrite() on an input pin turns on an off the 30K internal pull up resistor. This is too high an impedance for some of your servos (your bad ones) but it looks like it is just enough for your other servos, but it is not very good.

Quote
And I expect the servo controller to initialise the servo correctly
You might expect it but no.

For more on floating inputs, see:-
http://www.thebox.myzen.co.uk/Tutorial/Inputs.html

Hmm not sure I understood this, to me I'm using an output which send a pulse of X ms to the servo and not an input.
Maybe it would help me if you tell me between which pin of the servo you advise to put a pull up resistor?

Thanks!
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34724
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
to me I'm using an output which send a pulse of X ms to the servo and not an input.
So initialise the pin as an output, you were not doing that in your code.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26619
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks like  a confusion of pulse widths ( microseconds) and angles.
Have a good read of the sources of the servo library, and get back when you understand the ranges of values involved.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

0
Offline Offline
Tesla Member
***
Karma: 147
Posts: 9741
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Servo test code that takes either angle input or microsecond input. In this code pin seven is used for the servo control signal. If this doesn't work, you probably have a power supply problem and/or the external power supply does not have a common ground with the arduino.

Code:
// zoomkat 10-22-11 serial servo test
// type servo position 0 to 180 in serial monitor
// or for writeMicroseconds, use a value like 1500
// for IDE 0022 and later
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);
  myservo.writeMicroseconds(1500); //set initial servo position if desired
  myservo.attach(7);  //the pin for the servo control
  Serial.println("servo-test-22-dual-input"); // so I can keep track of what is loaded
}

void loop() {
  while (Serial.available()) {
    char c = Serial.read();  //gets one byte from serial buffer
    readString += c; //makes the string readString
    delay(2);  //slow looping to allow buffer to fill with next character
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string
    int n = readString.toInt();  //convert readString into a number

    // auto select appropriate value, copied from someone elses code.
    if(n >= 500)
    {
      Serial.print("writing Microseconds: ");
      Serial.println(n);
      myservo.writeMicroseconds(n);
    }
    else
    {   
      Serial.print("writing Angle: ");
      Serial.println(n);
      myservo.write(n);
    }

    readString=""; //empty for next input
  }
}

Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

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

I have 4 of those servos, in 2 of the 4 the signal wire had come loose inside the servo,from new, causing it shimmy and shake and turn one direction hard against the stop. if you have a small screw driver and a soldering iron it is an easy 2 minute fix. Hope this helps.
Charley
Logged

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

Sorry, it wasn't the signal wire , it was a wire on the little pot inside the servo, i just remembered.
Charley
Logged

Pages: [1]   Go Up
Jump to: