You Saved me, This works perfect for what I Need
this is how I modified it to do all 15 servos, could you let me know if I did it correctly?
/***************************************************
This is an example for our Adafruit 16-channel PWM & Servo driver
Servo test - this will drive 16 servos, one after the other
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/815
These displays use I2C to communicate, 2 pins are required to
interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
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);
// 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 150 // this is the 'minimum' pulse length count (out of 4096)
//#define SERVOMAX 400 // this is the 'maximum' pulse length count (out of 4096)
const unsigned long FREQUENCY = 50; // Adafruit used 60Hz. JR RC radios use about 45Hz. 50Hz is the most common (I think).
// The larger the frequecy value, the more precise the servo control.
const unsigned long MICROSECONDS_PER_SECOND = 1000000;
const unsigned long REFRESH_PERIOD_US = MICROSECONDS_PER_SECOND / FREQUENCY; //20,000 @ 50Hz
// ****** Change These Values To Match Your Servos ******
const unsigned long SERVO_MIN_US = 610; // Based on initial values from Adafruit demo.
const unsigned long SERVO_MAX_US = 1500;
const unsigned long DEFAULT_SERVO_MIN = SERVO_MIN_US * 4096 / REFRESH_PERIOD_US; // 610 * 4096 / 20000 = 124
const unsigned long DEFAULT_SERVO_MAX = SERVO_MAX_US * 4096 / REFRESH_PERIOD_US; // 2442 * 4096 / 20000 = 500
const int SERVOS_IN_USE = 15;
const int MAX_SERVO_INDEX = SERVOS_IN_USE - 1;
const unsigned long DEFAULT_PERIOD = 2 * FREQUENCY;
const unsigned long FOURTY_PERIOD = 47 * FREQUENCY;
const unsigned long THREEMIN_PERIOD = 190 * FREQUENCY;
unsigned long servoPeriodCycles[] = {DEFAULT_PERIOD, DEFAULT_PERIOD, DEFAULT_PERIOD, DEFAULT_PERIOD, DEFAULT_PERIOD, FOURTY_PERIOD, FOURTY_PERIOD, FOURTY_PERIOD, FOURTY_PERIOD, FOURTY_PERIOD, THREEMIN_PERIOD, THREEMIN_PERIOD, THREEMIN_PERIOD, THREEMIN_PERIOD, THREEMIN_PERIOD};
unsigned long servoPhase[] = {0, DEFAULT_PERIOD / SERVOS_IN_USE, 2 * DEFAULT_PERIOD / SERVOS_IN_USE, 3 * DEFAULT_PERIOD / SERVOS_IN_USE, 4 * DEFAULT_PERIOD / SERVOS_IN_USE, 5 * FOURTY_PERIOD / SERVOS_IN_USE, 6 * FOURTY_PERIOD / SERVOS_IN_USE, 7 * FOURTY_PERIOD / SERVOS_IN_USE, 8 * FOURTY_PERIOD / SERVOS_IN_USE, 9 * FOURTY_PERIOD / SERVOS_IN_USE, 10 * THREEMIN_PERIOD / SERVOS_IN_USE, 11 * THREEMIN_PERIOD / SERVOS_IN_USE, 12 * THREEMIN_PERIOD / SERVOS_IN_USE, 13 * THREEMIN_PERIOD / SERVOS_IN_USE, 14 * THREEMIN_PERIOD / SERVOS_IN_USE};
unsigned long servoPulseMin[] = {DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN, DEFAULT_SERVO_MIN};
unsigned long servoPulseMax[] = {DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX, DEFAULT_SERVO_MAX};
unsigned long servoPulseRange[SERVOS_IN_USE];
unsigned long lastRefreshTime;
void setup()
{
Serial.begin(9600);
Serial.print(SERVOS_IN_USE);
Serial.println(" Channel Servo Test");
Serial.println("Servo Ranges:");
for (byte i = 0; i < SERVOS_IN_USE; i++)
{
servoPulseRange[i] = servoPulseMax[i] - servoPulseMin[i];
Serial.print("channel # ");
Serial.print(i);
Serial.print(", min = ");
Serial.print(servoPulseMin[i]);
Serial.print(", max ");
Serial.print(servoPulseMax[i]);
Serial.print(", range = ");
Serial.println(servoPulseRange[i]);
}
pwm.begin();
pwm.setPWMFreq(FREQUENCY); // Analog servos run at ~50 Hz updates
yield();
lastRefreshTime = micros();
}
void loop()
{
checkServoTime();
}
void checkServoTime()
{
if (micros() - lastRefreshTime >= REFRESH_PERIOD_US)
{
lastRefreshTime += REFRESH_PERIOD_US;
driveServosLinear(0, MAX_SERVO_INDEX);
}
}
void driveServosLinear(uint8_t firstServo, uint8_t lastServo)
{
for (uint8_t servoIndex = firstServo; servoIndex <= lastServo; servoIndex++)
{
if (++servoPhase[servoIndex] >= servoPeriodCycles[servoIndex])
{
servoPhase[servoIndex] = 0;
//Serial.print("zero phase of channel # ");
//Serial.println(servoIndex);
}
driveServoLinear(servoIndex, servoPeriodCycles[servoIndex], servoPhase[servoIndex], servoPulseMin[servoIndex], servoPulseRange[servoIndex]);
}
}
void driveServoLinear(uint8_t servoIndex, unsigned long period, unsigned long phase, unsigned long minPulse, unsigned long range)
{
unsigned long halfPeriod = period >> 1;
if (phase >= halfPeriod)
{
phase = period - phase;
}
pwm.setPWM(servoIndex, 0, (phase * range / halfPeriod) + minPulse);
//debugServo(servoIndex, period, phase, minPulse, range);
}
void debugServo(uint8_t servoIndex, unsigned long period, unsigned long pseudoPhase, unsigned long minPulse, unsigned long range)
{
Serial.print("channel # ");
Serial.print(servoIndex);
Serial.print(", min = ");
Serial.print(minPulse);
Serial.print(", max ");
Serial.print(range + minPulse);
Serial.print(", range = ");
Serial.print(range);
Serial.print(", pseudoPhase/period = ");
Serial.print(pseudoPhase); // It's a "pseudo" because it has been altered by "driveServoLinear" if the phase was greater than or equal to half the period.
Serial.print(" / ");
Serial.print(period);
Serial.print(", active pulse = ");
Serial.println((pseudoPhase * range / (period >> 1)) + minPulse);
}