diff --git a/libraries/Servo/src/Servo.cpp b/libraries/Servo/src/Servo.cpp index 3dc2c7753e..aff9afebbe 100644 --- a/libraries/Servo/src/Servo.cpp +++ b/libraries/Servo/src/Servo.cpp @@ -27,15 +27,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA uint32_t Servo::_servoMap = 0; // similiar to map but will have increased accuracy that provides a more -// symetric api (call it and use result to reverse will provide the original value) +// symmetrical api (call it and use result to reverse will provide the original value) int improved_map(int value, int minIn, int maxIn, int minOut, int maxOut) { const int rangeIn = maxIn - minIn; const int rangeOut = maxOut - minOut; const int deltaIn = value - minIn; // fixed point math constants to improve accurancy of divide and rounding - const int fixedHalfDecimal = 1; - const int fixedDecimal = fixedHalfDecimal * 2; + constexpr int fixedHalfDecimal = 1; + constexpr int fixedDecimal = fixedHalfDecimal * 2; return ((deltaIn * rangeOut * fixedDecimal) / (rangeIn) + fixedHalfDecimal) / fixedDecimal + minOut; } @@ -46,9 +46,9 @@ int improved_map(int value, int minIn, int maxIn, int minOut, int maxOut) Servo::Servo() { _attached = false; - _valueUs = DEFAULT_PULSE_WIDTH; - _minUs = MIN_PULSE_WIDTH; - _maxUs = MAX_PULSE_WIDTH; + _valueUs = DEFAULT_NEUTRAL_PULSE_WIDTH; + _minUs = DEFAULT_MIN_PULSE_WIDTH; + _maxUs = DEFAULT_MAX_PULSE_WIDTH; } Servo::~Servo() { @@ -58,10 +58,15 @@ Servo::~Servo() { uint8_t Servo::attach(int pin) { - return attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); + return attach(pin, DEFAULT_MIN_PULSE_WIDTH, DEFAULT_MAX_PULSE_WIDTH); } uint8_t Servo::attach(int pin, uint16_t minUs, uint16_t maxUs) +{ + return attach(pin, minUs, maxUs, _valueUs); +} + +uint8_t Servo::attach(int pin, uint16_t minUs, uint16_t maxUs, int value) { if (!_attached) { digitalWrite(pin, LOW); @@ -76,7 +81,7 @@ uint8_t Servo::attach(int pin, uint16_t minUs, uint16_t maxUs) _maxUs = max((uint16_t)250, min((uint16_t)3000, maxUs)); _minUs = max((uint16_t)200, min(_maxUs, minUs)); - write(_valueUs); + write(value); return pin; } @@ -85,20 +90,20 @@ void Servo::detach() { if (_attached) { _servoMap &= ~(1 << _pin); + startWaveform(_pin, 0, REFRESH_INTERVAL, 1); + delay(REFRESH_INTERVAL / 1000); // long enough to complete active period under all circumstances. stopWaveform(_pin); _attached = false; - digitalWrite(_pin, LOW); + _valueUs = DEFAULT_NEUTRAL_PULSE_WIDTH; } } void Servo::write(int value) { - // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) - if (value < _minUs) { + // treat any value less than 200 as angle in degrees (values equal or larger are handled as microseconds) + if (value < 200) { // assumed to be 0-180 degrees servo value = constrain(value, 0, 180); - // writeMicroseconds will contrain the calculated value for us - // for any user defined min and max, but we must use default min max value = improved_map(value, 0, 180, _minUs, _maxUs); } writeMicroseconds(value); @@ -106,6 +111,7 @@ void Servo::write(int value) void Servo::writeMicroseconds(int value) { + value = constrain(value, _minUs, _maxUs); _valueUs = value; if (_attached) { _servoMap &= ~(1 << _pin); @@ -117,8 +123,7 @@ void Servo::writeMicroseconds(int value) int Servo::read() // return the value as degrees { - // read returns the angle for an assumed 0-180, so we calculate using - // the normal min/max constants and not user defined ones + // read returns the angle for an assumed 0-180 return improved_map(readMicroseconds(), _minUs, _maxUs, 0, 180); } diff --git a/libraries/Servo/src/Servo.h b/libraries/Servo/src/Servo.h index 45f593c0d8..38d78709a4 100644 --- a/libraries/Servo/src/Servo.h +++ b/libraries/Servo/src/Servo.h @@ -27,9 +27,9 @@ // // Servo - Class for manipulating servo motors connected to Arduino pins. // -// attach(pin ) - Attaches a servo motor to an i/o pin. -// attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds -// default min is 544, max is 2400 +// attach(pin) - Attaches a servo motor to an i/o pin. +// attach(pin, min, max) - Attaches to a pin setting min and max values in microseconds +// default min is 1000, max is 2000 // // write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) // writeMicroseconds() - Sets the servo pulse width in microseconds @@ -44,13 +44,17 @@ #include -// the following are in us (microseconds) -// -#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo -#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo -#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached -#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds -#define MAX_SERVOS 12 +// The following values are in us (microseconds). +// Since the defaults can be overwritten in the new attach() member function, +// they were modified from the Arduino AVR defaults to be in the safe range +// of publically available specifications. While this implies that many 180° +// servos do not operate the full 0° to 180° sweep using these, it also prevents +// unsuspecting damage. For Arduino AVR, the same change is being discussed. +#define DEFAULT_MIN_PULSE_WIDTH 1000 // uncalibrated default, the shortest duty cycle sent to a servo +#define DEFAULT_MAX_PULSE_WIDTH 2000 // uncalibrated default, the longest duty cycle sent to a servo +#define DEFAULT_NEUTRAL_PULSE_WIDTH 1500 // default duty cycle when servo is attached +#define REFRESH_INTERVAL 20000 // classic default period to refresh servos in microseconds +#define MAX_SERVOS 9 // D0-D8 #if !defined(ESP8266) @@ -63,8 +67,16 @@ class Servo public: Servo(); ~Servo(); - uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure - uint8_t attach(int pin, uint16_t min, uint16_t max); // as above but also sets min and max values for writes. + // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure. + // returns channel number or 0 if failure. + uint8_t attach(int pin); + // attach the given pin to the next free channel, sets pinMode, min, and max values for write(). + // returns channel number or 0 if failure. + uint8_t attach(int pin, uint16_t min, uint16_t max); + // attach the given pin to the next free channel, sets pinMode, min, and max values for write(), + // and sets the initial value, the same as write(). + // returns channel number or 0 if failure. + uint8_t attach(int pin, uint16_t min, uint16_t max, int value); void detach(); void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds void writeMicroseconds(int value); // Write pulse width in microseconds pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy