1 #ifndef ServoDispatchDirect_h
2 #define ServoDispatchDirect_h
5 #define SERVO_DEBUG_PRINT(s) DEBUG_PRINT(s)
6 #define SERVO_DEBUG_PRINTLN(s) DEBUG_PRINTLN(s)
7 #define SERVO_DEBUG_PRINT_HEX(s) DEBUG_PRINT_HEX(s)
8 #define SERVO_DEBUG_PRINTLN_HEX(s) DEBUG_PRINTLN_HEX(s)
10 #define SERVO_DEBUG_PRINT(s)
11 #define SERVO_DEBUG_PRINTLN(s)
12 #define SERVO_DEBUG_PRINT_HEX(s)
13 #define SERVO_DEBUG_PRINTLN_HEX(s)
16 #ifdef USE_VERBOSE_SERVO_DEBUG
17 #define VERBOSE_SERVO_DEBUG_PRINT(s) DEBUG_PRINT(s)
18 #define VERBOSE_SERVO_DEBUG_PRINTLN(s) DEBUG_PRINTLN(s)
19 #define VERBOSE_SERVO_DEBUG_PRINT_HEX(s) DEBUG_PRINT_HEX(s)
20 #define VERBOSE_SERVO_DEBUG_PRINTLN_HEX(s) DEBUG_PRINTLN_HEX(s)
22 #define VERBOSE_SERVO_DEBUG_PRINT(s)
23 #define VERBOSE_SERVO_DEBUG_PRINTLN(s)
24 #define VERBOSE_SERVO_DEBUG_PRINT_HEX(s)
25 #define VERBOSE_SERVO_DEBUG_PRINTLN_HEX(s)
37 template <u
int8_t numServos>
40 #ifndef ARDUINO_ARCH_ESP32
41 ,
private ServoDispatchISR
48 #ifndef ARDUINO_ARCH_ESP32
49 const unsigned kDefaultPulseWidth = 1500;
50 auto priv = privates();
52 memset(fServos,
'\0',
sizeof(fServos));
53 for (uint16_t i = 0; i < numServos; i++)
55 ServoState* state = &fServos[i];
57 #ifndef ARDUINO_ARCH_ESP32
58 priv->pwm[i].ticks = convertMicrosecToTicks(kDefaultPulseWidth);
61 #ifndef ARDUINO_ARCH_ESP32
62 priv->ServoCount = numServos;
69 #ifndef ARDUINO_ARCH_ESP32
70 const unsigned kDefaultPulseWidth = 1500;
71 auto priv = privates();
73 memset(fServos,
'\0',
sizeof(fServos));
74 for (uint16_t i = 0; i < numServos; i++)
76 ServoState* state = &fServos[i];
77 uint8_t pin = pgm_read_uint16(&settings[i].pinNum);
78 #ifndef ARDUINO_ARCH_ESP32
82 state->startPulse = pgm_read_uint16(&settings[i].startPulse);
83 state->endPulse = pgm_read_uint16(&settings[i].endPulse);
85 state->neutralPulse = state->startPulse;
86 state->group = pgm_read_uint32(&settings[i].group);
87 state->posNow = state->neutralPulse;
88 #ifndef ARDUINO_ARCH_ESP32
89 priv->pwm[i].pin = pin;
90 priv->pwm[i].ticks = convertMicrosecToTicks(kDefaultPulseWidth);
92 state->pin = (ServoDispatchESP32::validPWM(pin)) ? pin : 0;
95 #ifndef ARDUINO_ARCH_ESP32
96 priv->ServoCount = numServos;
105 virtual uint8_t
getPin(uint16_t num)
override
109 #ifndef ARDUINO_ARCH_ESP32
110 auto priv = privates();
111 return priv->pwm[num].pin;
113 ServoState* state = &fServos[num];
122 return (num < numServos) ? fServos[num].startPulse : 0;
125 virtual uint16_t
getEnd(uint16_t num)
override
127 return (num < numServos) ? fServos[num].endPulse : 0;
132 return (num < numServos) ? fServos[num].getMinimum() : 0;
137 return (num < numServos) ? fServos[num].getNeutral() : 0;
142 return (num < numServos) ? fServos[num].getMaximum() : 0;
147 return (num < numServos) ? fServos[num].group : 0;
152 return (num < numServos) ? fServos[num].currentPos() : 0;
155 virtual void setServo(uint16_t num, uint8_t pin, uint16_t startPulse, uint16_t endPulse, uint16_t neutralPulse, uint32_t group)
override
157 #ifndef ARDUINO_ARCH_ESP32
158 const unsigned kDefaultPulseWidth = 1500;
159 auto priv = privates();
163 ServoState* state = &fServos[num];
164 #ifndef ARDUINO_ARCH_ESP32
165 pinMode(pin, OUTPUT);
167 state->channel = num;
168 state->startPulse = startPulse;
169 state->endPulse = endPulse;
170 state->neutralPulse = neutralPulse;
171 state->group = group;
172 state->posNow = state->neutralPulse;
173 #ifndef ARDUINO_ARCH_ESP32
174 priv->pwm[num].pin = pin;
175 priv->pwm[num].ticks = convertMicrosecToTicks(kDefaultPulseWidth);
177 state->pin = (ServoDispatchESP32::validPWM(pin)) ? pin : 0;
185 for (uint16_t i = 0; i < numServos; i++)
191 virtual uint16_t
scaleToPos(uint16_t num,
float scale)
override
196 scale = min(max(0.0f, scale), 1.0f);
197 uint16_t startPulse = fServos[num].startPulse;
198 uint16_t endPulse = fServos[num].endPulse;
199 if (startPulse < endPulse)
201 pos = startPulse + (endPulse - startPulse) * scale;
205 pos = startPulse - (startPulse - endPulse) * scale;
213 #ifdef ARDUINO_ARCH_ESP32
215 ServoDispatchESP32::configureTimer(0);
216 ServoDispatchESP32::configureTimer(1);
217 ServoDispatchESP32::configureTimer(2);
218 ServoDispatchESP32::configureTimer(3);
220 for (
int i = 0; i < numServos; i++)
222 ServoState* state = &fServos[i];
223 fPWM[i].attachPin(state->pin, REFRESH_CPS, DEFAULT_TIMER_WIDTH);
224 fPWM[i].detachPin(state->pin);
233 #ifndef ARDUINO_ARCH_ESP32
234 auto priv = privates();
235 return priv->pwm[num].isActive;
237 return fPWM[num].attached();
247 ServoState* state = &fServos[num];
249 #ifndef ARDUINO_ARCH_ESP32
250 auto priv = privates();
251 priv->pwm[num].isActive =
false;
252 digitalWrite(priv->pwm[num].pin, LOW);
254 if (fPWM[num].attached())
256 fPWM[num].detachPin(state->pin);
264 uint32_t now = millis();
265 if (fLastTime + 1 < now)
267 for (
int i = 0; i < numServos; i++)
269 ServoState* state = &fServos[i];
270 if (state->finishTime != 0)
272 state->move(
this, now);
274 else if (state->detachTime > 0 && state->detachTime < millis())
279 fLastTime = now = millis();
283 virtual void setPWM(uint16_t channel, uint16_t targetLength)
override
285 #ifndef ARDUINO_ARCH_ESP32
286 auto priv = privates();
289 if (!priv->pwm[channel].isActive)
291 initISR(fServos[channel].channel);
294 priv->pwm[channel].value = targetLength;
300 targetLength -= kTrimDuration;
301 targetLength = convertMicrosecToTicks(targetLength);
303 uint8_t oldSREG = SREG;
307 priv->pwm[channel].ticks = targetLength;
309 priv->pwm[channel].speed = 0;
320 if (fPWM[channel].attached())
322 uint32_t ticks = convertMicrosecToTicks(targetLength);
323 fPWM[channel].write(ticks);
332 kMinPulseWidth = 544,
333 kMaxPulseWidth = 2400,
346 return min(startPulse, endPulse);
356 return max(startPulse, endPulse);
363 if (timeNow < startTime)
367 else if (timeNow >= finishTime)
370 doMove(dispatch, timeNow);
372 detachTime = timeNow + 500;
374 else if (lastMoveTime != timeNow)
376 uint32_t timeSinceLastMove = timeNow - startTime;
377 uint32_t denominator = finishTime - startTime;
378 float (*useMethod)(float) = easingMethod;
379 if (useMethod ==
nullptr)
381 float fractionChange = useMethod(
float(timeSinceLastMove)/
float(denominator));
382 int distanceToMove = float(deltaPos) * fractionChange;
383 uint16_t newPos = startPosition + distanceToMove;
384 if (newPos != posNow)
386 posNow = startPosition + distanceToMove;
387 doMove(dispatch, timeNow);
395 uint32_t timeNow = millis();
397 startTime = startDelay + timeNow;
398 finishTime = moveTime + startTime;
400 posNow = startPosition = startPos;
401 deltaPos = finishPos - posNow;
402 doMove(dispatch, timeNow);
408 uint16_t neutralPulse;
411 uint32_t lastMoveTime;
413 uint16_t startPosition;
417 float (*easingMethod)(
float completion) =
nullptr;
418 #ifdef ARDUINO_ARCH_ESP32
425 #ifdef USE_SERVO_DEBUG
431 dispatch->
setPWM(channel, posNow);
440 lastMoveTime = timeNow;
454 virtual void _moveServoToPulse(uint16_t num, uint32_t startDelay, uint32_t moveTime, uint16_t startPos, uint16_t pos)
override
458 #ifndef ARDUINO_ARCH_ESP32
459 initISR(fServos[num].channel);
461 if (fServos[num].pin && !fPWM[num].attached())
463 fPWM[num].attachPin(fServos[num].pin, REFRESH_CPS, DEFAULT_TIMER_WIDTH);
464 SERVO_DEBUG_PRINTLN(
"Attaching servo : "+String(fServos[num].pin)+
" on PWM "+String(fPWM[num].getChannel())+
" PULSE "+pos);
467 fServos[num].moveToPulse(
this, startDelay, moveTime, startPos, pos);
475 virtual void _moveServosToPulse(uint32_t servoGroupMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax, uint16_t pos)
override
477 for (uint16_t i = 0; i < numServos; i++)
479 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
480 if ((fServos[i].group & servoGroupMask) != 0)
487 virtual void _moveServosByPulse(uint32_t servoGroupMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax, int16_t pos)
override
489 for (uint16_t i = 0; i < numServos; i++)
491 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
492 if ((fServos[i].group & servoGroupMask) != 0)
494 int16_t curpos = fServos[i].currentPos();
495 moveToPulse(i, startDelay, moveTime, curpos, curpos + pos);
502 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
505 for (uint16_t i = 0; i < numServos; i++)
507 if ((fServos[i].group & servoGroupMask) == 0)
509 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
510 bool on = ((servoSetMask & (1L<<bitShift)) != 0);
517 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
520 for (uint16_t i = 0; i < numServos; i++)
522 if ((fServos[i].group & servoGroupMask) == 0)
524 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
525 bool on = ((servoSetMask & (1L<<bitShift)) != 0);
526 int16_t curpos = fServos[i].currentPos();
527 moveToPulse(i, startDelay, moveTime, curpos, curpos + ((on) ? onPos : offPos));
535 virtual void _moveServosTo(uint32_t servoGroupMask, uint32_t startDelay, uint32_t moveTimeMin, uint32_t moveTimeMax,
float pos)
override
537 for (uint16_t i = 0; i < numServos; i++)
539 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
540 if ((fServos[i].group & servoGroupMask) != 0)
547 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
550 for (uint16_t i = 0; i < numServos; i++)
552 if ((fServos[i].group & servoGroupMask) == 0)
554 uint32_t moveTime = (moveTimeMin != moveTimeMax) ? random(moveTimeMin, moveTimeMax) : moveTimeMax;
555 bool on = ((servoSetMask & (1L<<bitShift)) != 0);
566 if (onEasingMethod !=
nullptr)
569 else if (offEasingMethod !=
nullptr)
581 virtual void _setServoEasingMethod(uint16_t num,
float (*easingMethod)(
float completion))
583 if (num < numServos && fServos[num].channel != 0)
585 fServos[num].easingMethod = easingMethod;
589 virtual void _setServosEasingMethod(uint32_t servoGroupMask,
float (*easingMethod)(
float completion))
591 for (uint16_t i = 0; i < numServos; i++)
593 if ((fServos[i].group & servoGroupMask) != 0)
595 fServos[i].easingMethod = easingMethod;
600 virtual void _setEasingMethod(
float (*easingMethod)(
float completion))
602 for (uint16_t i = 0; i < numServos; i++)
604 fServos[i].easingMethod = easingMethod;
611 ServoState fServos[numServos];
614 inline uint16_t pgm_read_uint16(
const uint16_t* p)
616 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || \
617 defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || \
618 defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
619 return pgm_read_word(p);
625 inline uint32_t pgm_read_uint32(
const uint32_t* p)
627 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || \
628 defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || \
629 defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
630 return pgm_read_dword(p);
636 #ifdef ARDUINO_ARCH_ESP32
637 const int REFRESH_CPS = 50;
638 const int REFRESH_USEC = 20000;
639 const int DEFAULT_TIMER_WIDTH = 16;
640 const int DEFAULT_TIMER_WIDTH_TICKS = 65536;
641 ServoDispatchESP32 fPWM[numServos];
642 int convertMicrosecToTicks(
int usec)
644 return (
int)((float)usec / ((
float)REFRESH_USEC / (float)DEFAULT_TIMER_WIDTH_TICKS)*(((float)REFRESH_CPS)/50.0));
647 int convertTicksToMicrosec(
int ticks)
649 return (
int)((float)ticks * ((
float)REFRESH_USEC / (float)DEFAULT_TIMER_WIDTH_TICKS)/(((float)REFRESH_CPS)/50.0));