For a real life project I am pursuing I have written a sketch to initially set all servos at a "MID" position in setup() - a START position. Using, as adviced, the Adafruit library.
In this example I then drive them from MAX to MIN alternatively using a variable array to fix their "actual" position to decide which direction to move them to. All fine.
EXCEPT! The first "movement" from MID to MAX (i.e. to SERVOMAX as defined by the library example) results in a reduced stunt approximately one fourth of the expected distance. ONLY ONCE!! Then it regains the "rhythm" and goes fine. I find it extremely puzzling.
I also tried to start the "for cycle" from MIN instead of actual position. The first step is always a stunt.
Can any one shed a light?
Thanks
Flavio
/* Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);
// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN 130 // This is the 'minimum' pulse length count (out of 4096) ***original 150
#define SERVOMAX 630 // This is the 'maximum' pulse length count (out of 4096) ***original 600
#define USMIN 520 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150 ***original 600
#define USMAX 2520 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600 ***original 2400
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
// our servo # counter
uint8_t servonum = 0;
uint16_t servo_pos = 0;
uint16_t pos[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
void setup() {
Serial.begin(9600);
Serial.println("PCA9685 MULTIchannel Servo test!");
pwm.begin();
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(SERVO_FREQ); // Analog servos run at ~50 Hz updates
delay(10);
servo_set_mid();
// Drive each servo one at a time using setPWM() to set MID position (90°)
delay(10000);
servonum = 0;
}
void loop() {
Serial.println(servonum); //DEBUG
if (pos[servonum] < SERVOMAX) {
for (servo_pos = pos[servonum]; servo_pos <= SERVOMAX; servo_pos++) {
pwm.setPWM(servonum, 0, servo_pos);
}
} else {
for (servo_pos = pos[servonum]; servo_pos >= SERVOMIN; servo_pos--) {
pwm.setPWM(servonum, 0, servo_pos);
}
}
pos[servonum] = servo_pos;
Serial.print("Servo "); //DEBUG
Serial.print(servonum); //DEBUG
Serial.print(" POS = "); //DEBUG
Serial.println(pos[servonum]); //DEBUG
delay(1500);
servonum++;
if (servonum > 4) servonum = 0; // Testing the first 4 servo channels
}
void servo_set_mid() {
for (servonum=0;servonum<8;servonum++){
for (servo_pos = SERVOMIN; servo_pos <= (SERVOMIN+SERVOMAX)/2; servo_pos++) {
pwm.setPWM(servonum, 0, servo_pos);
}
pos[servonum] = servo_pos;
Serial.print("Servo "); //DEBUG
Serial.print(servonum); //DEBUG
Serial.print(" POS = "); //DEBUG
Serial.println(pos[servonum]); //DEBUG
}
servonum = 0;
}