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.
#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");
}
}
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.
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 ?
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.
Simple servo test code that can be used to test individual servos.
// 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
}
}
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
Grumpy_Mike:
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'?
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.
And I expect the servo controller to initialise the servo correctly
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:
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 ;
}
Grumpy_Mike:
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.
And I expect the servo controller to initialise the servo correctly
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?
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.
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.
// 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
}
}
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