1 #ifndef ServoDispatchPCA9685_h
2 #define ServoDispatchPCA9685_h
8 #define SERVO_DEBUG_PRINT(s) DEBUG_PRINT(s)
9 #define SERVO_DEBUG_PRINTLN(s) DEBUG_PRINTLN(s)
10 #define SERVO_DEBUG_PRINT_HEX(s) DEBUG_PRINT_HEX(s)
11 #define SERVO_DEBUG_PRINTLN_HEX(s) DEBUG_PRINTLN_HEX(s)
13 #define SERVO_DEBUG_PRINT(s)
14 #define SERVO_DEBUG_PRINTLN(s)
15 #define SERVO_DEBUG_PRINT_HEX(s)
16 #define SERVO_DEBUG_PRINTLN_HEX(s)
19 #ifdef USE_VERBOSE_SERVO_DEBUG
20 #define VERBOSE_SERVO_DEBUG_PRINT(s) DEBUG_PRINT(s)
21 #define VERBOSE_SERVO_DEBUG_PRINTLN(s) DEBUG_PRINTLN(s)
22 #define VERBOSE_SERVO_DEBUG_PRINT_HEX(s) DEBUG_PRINT_HEX(s)
23 #define VERBOSE_SERVO_DEBUG_PRINTLN_HEX(s) DEBUG_PRINTLN_HEX(s)
25 #define VERBOSE_SERVO_DEBUG_PRINT(s)
26 #define VERBOSE_SERVO_DEBUG_PRINTLN(s)
27 #define VERBOSE_SERVO_DEBUG_PRINT_HEX(s)
28 #define VERBOSE_SERVO_DEBUG_PRINTLN_HEX(s)
34 #define PCA9685_MODE1 0x00
35 #define PCA9685_MODE2 0x01
36 #define PCA9685_SWRST_ADDR 0X00
37 #define PCA9685_SWRST_ACK 0x06
38 #define PCA9685_SWRST_NOACK 0x00
39 #define PCA9685_AI 0x20
40 #define PCA9685_ALLCALL 0x01
41 #define PCA9685_PRESCALE 0xFE
42 #define PCA9685_SLEEP 0x10
43 #define PCA9685_ALLCALLADR 0x70
44 #define PCA9685_ALL_LED_ON_L 0xFA
45 #define PCA9685_ALL_LED_ON_H 0xFB
46 #define PCA9685_ALL_LED_OFF_L 0xFC
47 #define PCA9685_ALL_LED_OFF_H 0xFD
48 #define PCA9685_DEFAULT_PRESCALE_VALUE 0x1A
49 #define LED0_ON_L 0x06
50 #define LED0_ON_H 0x07
51 #define LED0_OFF_L 0x08
52 #define LED0_OFF_H 0x09
53 #define LED_FULL_OFF_L 0x00
54 #define LED_FULL_OFF_H 0x10
56 #define POPULATED_CHANNEL_NUMBER 32
57 #define MIN_PWM_LENGTH 500
58 #define MAX_PWM_LENGTH 2500
59 #define DEFAULT_CHANNEL_STAGGERING false
60 #define CHANNEL_OFFSET_STEP 50 //in us. This value should not extend the last channel off timing to exceed the 4095 limit.
61 #define NOMINATED_ROOM_TEMPERATURE 25
62 #define DEFAULT_TEMPERATURE_CORRECTION 40 //per 30 degrees change in temperature
63 #define DEFAULT_SERVO_PWM_LENGTH 1500
64 #define NOMINAL_CLOCK_FREQUENCY 25000000
65 #define DEFAULT_UPDATE_FREQUENCY 50
66 #define TEMPERATURE_CORRECTION_COEFFICIENT 0.00020
67 #define TEMPERATURE_CORRECTION_STEP 128
68 #define TEMPERATURE_CORRECTION_POINTS ((MAX_PWM_LENGTH-MIN_PWM_LENGTH)/TEMPERATURE_CORRECTION_STEP)
82 template <u
int16_t numServos,
byte defaultOEValue = HIGH>
95 fOutputEnabled(false),
96 fOutputExpireMillis(0),
101 fI2CAddress[chip] = startAddress + chip;
105 memset(fServos,
'\0',
sizeof(fServos));
106 for (uint8_t servoChannel = 0; servoChannel <
SizeOfArray(fLastLength); servoChannel++)
117 fOutputEnablePin(-1),
118 fOutputAutoOff(true),
119 fOutputEnabled(false),
120 fOutputExpireMillis(0),
125 fI2CAddress[chip] = startAddress + chip;
129 memset(fServos,
'\0',
sizeof(fServos));
130 for (uint8_t servoChannel = 0; servoChannel <
SizeOfArray(fLastLength); servoChannel++)
134 for (uint16_t i = 0; i < numServos; i++)
136 ServoState* state = &fServos[i];
137 state->channel = pgm_read_word(&settings[i].pinNum);
138 state->group = pgm_read_dword(&settings[i].group);
139 state->startPulse = pgm_read_word(&settings[i].startPulse);
141 state->neutralPulse = state->startPulse;
142 state->endPulse = pgm_read_word(&settings[i].endPulse);
143 fLastLength[state->channel - 1] = state->startPulse;
144 state->posNow = state->startPulse;
153 #ifdef ARDUINO_SAM_DUE
165 #ifdef ARDUINO_SAM_DUE
175 return numServos / 16 + 1;
188 if (fOutputEnablePin != -1)
190 digitalWrite(fOutputEnablePin, defaultOEValue);
192 fOutputEnabled =
false;
204 if (fOutputEnablePin != -1)
206 digitalWrite(fOutputEnablePin, !defaultOEValue);
208 fOutputEnabled =
true;
215 fOutputEnablePin = outputEnablePin;
216 fOutputAutoOff = outputAutoOff;
217 pinMode(fOutputEnablePin, OUTPUT);
218 digitalWrite(fOutputEnablePin, defaultOEValue);
225 fClocks[i] = clock[i];
229 virtual uint8_t
getPin(uint16_t num)
override
231 return (num < numServos) ? fServos[num].channel : 0;
236 return (num < numServos) ? fServos[num].startPulse : 0;
239 virtual uint16_t
getEnd(uint16_t num)
override
241 return (num < numServos) ? fServos[num].endPulse : 0;
246 return (num < numServos) ? fServos[num].getMinimum() : 0;
251 return (num < numServos) ? fServos[num].getNeutral() : 0;
256 return (num < numServos) ? fServos[num].getMaximum() : 0;
261 return (num < numServos) ? fServos[num].group : 0;
266 return (num < numServos) ? fServos[num].currentPos() : 0;
269 virtual void setPin(uint16_t num, uint16_t pin)
override
271 if (num < numServos) {
272 ServoState* state = &fServos[num];
273 state->channel = pin;
278 virtual void setNeutral(uint16_t num, uint16_t neutralPulse)
override
281 fServos[num].neutralPulse = neutralPulse;
284 virtual void setStart(uint16_t num, uint16_t startPulse)
override
286 if (num < numServos) {
287 ServoState* state = &fServos[num];
288 state->startPulse = startPulse;
289 if (state->channel != 0)
290 fLastLength[state->channel - 1] = state->startPulse;
294 virtual void setEnd(uint16_t num, uint16_t endPulse)
override
297 fServos[num].endPulse = endPulse;
300 virtual void setServo(uint16_t num, uint8_t pin, uint16_t startPulse, uint16_t endPulse, uint16_t neutralPulse, uint32_t group)
override
304 ServoState* state = &fServos[num];
305 state->channel = pin;
306 state->group = group;
307 state->startPulse = startPulse;
308 state->neutralPulse = neutralPulse;
309 state->endPulse = endPulse;
310 if (state->channel != 0)
311 fLastLength[state->channel - 1] = state->startPulse;
312 state->posNow = state->startPulse;
320 for (uint16_t i = 0; i < numServos; i++)
326 virtual uint16_t
scaleToPos(uint16_t num,
float scale)
override
331 scale = min(max(0.0f, scale), 1.0f);
332 uint16_t startPulse = fServos[num].startPulse;
333 uint16_t endPulse = fServos[num].endPulse;
334 if (startPulse < endPulse)
336 pos = startPulse + (endPulse - startPulse) * scale;
340 pos = startPulse - (startPulse - endPulse) * scale;
358 for (uint8_t i = 0; i <
SizeOfArray(fTemperatureCorrectionArray); i++)
360 fTemperatureCorrectionArray[i] = 0;
372 return (num < numServos && fOutputEnabled) ? fServos[num].isActive() :
false;
387 uint32_t now = millis();
388 if (fLastTime + 1 < now)
390 for (
unsigned i = 0; i < numServos; i++)
392 if (fServos[i].channel != 0)
393 fServos[i].move(
this, now);
395 fLastTime = now = millis();
397 if (fOutputAutoOff && now > fOutputExpireMillis)
413 setPWM(servoChannel, fLastLength[servoChannel - 1]);
424 uint8_t chip = (servoChannel - 1) / 16;
425 uint8_t channel = (servoChannel - 1) % 16;
426 fI2C->beginTransmission(fI2CAddress[chip]);
430 fI2C->endTransmission();
472 for (uint16_t index = 0; index <
SizeOfArray(fChannelOffset); index++)
480 float nominalUpdateFrequency;
481 nominalUpdateFrequency = (float)clockFrequency / (
float)(((uint32_t)(prescale+1)) << 12);
482 return nominalUpdateFrequency;
489 fClocks[chip] = clocks[chip];
497 fTargetUpdateFrequency[chip] = targetUpdateFrequency[chip];
523 fCalculatedUpdateFrequency[chip] = fClocks[chip] / (float)(((uint32_t)prescale + 1) << 12);
524 fCalculatedResolution[chip] = 1000000.0 / (fCalculatedUpdateFrequency[chip] * 4096);
534 uint32_t calculatedPrescale;
535 calculatedPrescale = (float)calculatedClockFrequency * 100.0 / (4096.0 * targetUpdateFrequency);
536 if ((calculatedPrescale % 100) >= 50)
537 calculatedPrescale += 100;
538 calculatedPrescale = (calculatedPrescale / 100) - 1;
539 return (uint8_t)calculatedPrescale;
544 return (chip <
numberOfPCA9685Chips()) ? (targetLength / fCalculatedResolution[chip]) + 0.5 : 0;
554 uint8_t fI2CAddress[(numServos/16)+1];
555 float fCalculatedUpdateFrequency[(numServos/16)+1];
556 uint32_t fClocks[(numServos/16)+1];
557 float fTargetUpdateFrequency[(numServos/16)+1];
558 float fCalculatedResolution[(numServos/16)+1];
559 int8_t fDeltaTemperature = 0;
562 uint16_t fChannelOffset[((numServos/16)+1)*16];
563 uint16_t fLastLength[((numServos/16)+1)*16];
565 int fOutputEnablePin;
568 uint32_t fOutputExpireMillis;
580 return min(startPulse, endPulse);
585 return max(startPulse, endPulse);
595 float (*useMethod)(float) = easingMethod;
596 if (useMethod == NULL)
600 if (timeNow < startTime)
604 else if (timeNow >= finishTime)
615 doMove(dispatch, timeNow);
617 uint32_t savedOffTime = offTime;
619 offTime = savedOffTime;
621 else if (lastMoveTime != timeNow)
623 uint32_t timeSinceLastMove = timeNow - startTime;
624 uint32_t denominator = finishTime - startTime;
627 float fractionChange = useMethod(
float(timeSinceLastMove)/
float(denominator));
628 int distanceToMove = float(deltaPos) * fractionChange;
629 uint16_t newPos = startPosition + distanceToMove;
630 if (newPos != posNow)
632 posNow = startPosition + distanceToMove;
633 doMove(dispatch, timeNow);
639 doMove(dispatch, timeNow);
643 else if (offTime != 0 && timeNow >= offTime)
652 uint32_t timeNow = millis();
654 startTime = startDelay + timeNow;
655 finishTime = moveTime + startTime;
656 offTime = finishTime;
660 posNow = startPosition = startPos;
661 deltaPos = finishPos - posNow;
662 doMove(dispatch, timeNow);
669 uint16_t neutralPulse;
672 uint32_t lastMoveTime;
675 uint16_t startPosition;
678 float (*easingMethod)(
float completion) = NULL;
687 dispatch->
setPWM(channel, posNow);
696 lastMoveTime = timeNow;
701 return (finishTime != 0 || lastMoveTime != 0 || finishPos != 0);
713 ServoState fServos[numServos];
717 virtual void _moveServoToPulse(uint16_t num, uint32_t startDelay, uint32_t moveTime, uint16_t startPos, uint16_t pos)
override
719 if (num < numServos && fServos[num].channel != 0)
722 fServos[num].moveToPulse(
this, startDelay, moveTime, startPos, pos);
723 fOutputExpireMillis = max(fOutputExpireMillis, uint32_t(millis() + startDelay + moveTime + 500));
731 virtual void _moveServosToPulse(uint32_t servoGroupMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax, uint16_t pos)
override
733 for (uint16_t i = 0; i < numServos; i++)
735 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
736 if ((fServos[i].group & servoGroupMask) != 0)
743 virtual void _moveServosByPulse(uint32_t servoGroupMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax, int16_t pos)
override
745 for (uint16_t i = 0; i < numServos; i++)
747 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
748 if ((fServos[i].group & servoGroupMask) != 0)
750 int16_t curpos = fServos[i].currentPos();
751 moveToPulse(i, startDelay, moveTime, curpos, curpos + pos);
758 virtual void _moveServoSetToPulse(uint32_t servoGroupMask, uint32_t servoSetMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax, uint16_t onPos, uint16_t offPos)
override
761 for (uint16_t i = 0; i < numServos; i++)
763 if ((fServos[i].group & servoGroupMask) == 0)
765 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
766 bool on = ((servoSetMask & (1L<<bitShift)) != 0);
773 virtual void _moveServoSetByPulse(uint32_t servoGroupMask, uint32_t servoSetMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax, int16_t onPos, int16_t offPos)
override
776 for (uint16_t i = 0; i < numServos; i++)
778 if ((fServos[i].group & servoGroupMask) == 0)
780 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
781 bool on = ((servoSetMask & (1L<<bitShift)) != 0);
782 int16_t curpos = fServos[i].currentPos();
783 moveToPulse(i, startDelay, moveTime, curpos, curpos + ((on) ? onPos : offPos));
791 virtual void _moveServosTo(uint32_t servoGroupMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax,
float pos)
override
793 for (uint16_t i = 0; i < numServos; i++)
795 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
796 if ((fServos[i].group & servoGroupMask) != 0)
803 virtual void _moveServoSetTo(uint32_t servoGroupMask, uint32_t servoSetMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax,
float onPos,
float offPos,
float (*onEasingMethod)(
float),
float (*offEasingMethod)(
float))
override
806 for (uint16_t i = 0; i < numServos; i++)
808 if ((fServos[i].group & servoGroupMask) == 0)
810 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
811 bool on = ((servoSetMask & (1L<<bitShift)) != 0);
822 if (onEasingMethod != NULL)
825 else if (offEasingMethod != NULL)
837 virtual void _setServoEasingMethod(uint16_t num,
float (*easingMethod)(
float completion))
839 if (num < numServos && fServos[num].channel != 0)
841 fServos[num].easingMethod = easingMethod;
845 virtual void _setServosEasingMethod(uint32_t servoGroupMask,
float (*easingMethod)(
float completion))
847 for (uint16_t i = 0; i < numServos; i++)
849 if ((fServos[i].group & servoGroupMask) != 0)
851 fServos[i].easingMethod = easingMethod;
856 virtual void _setEasingMethod(
float (*easingMethod)(
float completion))
858 for (uint16_t i = 0; i < numServos; i++)
860 fServos[i].easingMethod = easingMethod;
866 uint8_t readRegister(uint8_t chipNumber, uint8_t registerAddress)
868 fI2C->beginTransmission(fI2CAddress[chipNumber]);
869 fI2C->write(registerAddress);
870 fI2C->endTransmission();
871 fI2C->requestFrom(fI2CAddress[chipNumber], (uint8_t)1);
875 void writeRegister(uint8_t chipNumber, uint8_t registerAddress, uint8_t value)
877 fI2C->beginTransmission(fI2CAddress[chipNumber]);
878 fI2C->write(registerAddress);
880 fI2C->endTransmission();
888 fI2C->endTransmission();
897 setPWM(servoChannel, 4096, 0);
906 setPWM(servoChannel, 0, 4096);
910 void setPWM(uint16_t servoChannel, uint16_t on, uint16_t off)
914 uint8_t chip = (servoChannel - 1) / 16;
915 uint8_t channel = (servoChannel - 1) % 16;
925 fI2C->beginTransmission(fI2CAddress[chip]);
928 fI2C->write(on >> 8);
930 fI2C->write(off >> 8);
931 fI2C->endTransmission();
943 void setPWM(uint16_t servoChannel, uint16_t targetLength)
956 fLastLength[servoChannel - 1] = targetLength;
959 uint8_t chip = (servoChannel - 1) / 16;
960 uint16_t temperatureCorrectedTargetLength = targetLength +
962 uint16_t calibratedSteps =
getCalibratedSteps(chip, temperatureCorrectedTargetLength);
964 uint16_t on = fChannelOffset[servoChannel - 1];
965 uint16_t off = on + calibratedSteps;
967 setPWM(servoChannel, on, off);
979 uint16_t off = targetLength +
980 fTemperatureCorrectionArray[(targetLength -
MIN_PWM_LENGTH) >> 7];
982 uint8_t servoChannel = 1;
990 for (uint8_t i = 0; i < 16; i++, servoChannel++)
992 uint16_t channelOn = on;
994 fI2C->beginTransmission(fI2CAddress[chip]);
996 fI2C->write(channelOn);
997 fI2C->write(channelOn >> 8);
998 fI2C->write(channelOff);
999 fI2C->write(channelOff >> 8);
1000 fI2C->endTransmission();
1001 fLastLength[i] = off - on;
1016 fI2C->write(on >> 8);
1018 fI2C->write(off >> 8);
1019 fI2C->endTransmission();
1027 for (uint16_t servoChannel = 1; servoChannel <= numServos; servoChannel++)
1029 setPWM(servoChannel, fLastLength[servoChannel - 1]);
1038 fI2C->endTransmission();
1047 double pulselength = 4.521;
1049 pulse = microseconds/pulselength;
1063 template <u
int16_t numServos>