Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
Detaching a pin will now occur when the pwm signal is low for jitterless detach.

Fixed a few ambiguous overload attach functions. Required changing pin, ch, munUs and maxUs parameters to int and speed and ke parameters to double.
  • Loading branch information
Dlloydev committed May 31, 2023
1 parent 1629e70 commit b3be0df
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 160 deletions.
44 changes: 22 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,15 @@ myservo.write(pin, value, speed, ke)

##### Parameters

- **pin** The pin number which (if necessary) will be attached to the next free channel *(uint8_t)*
- **value** This value is converted to the pwm duty. See above table for range and units *(float)
- **speed** This value has units degrees/second (float). For example, if `speed` is set to 100 deg/s and the servo position value is changed from 0 to 180 deg, then the servo will take 1.8 sec (1800 ms) to complete its travel. Its motion (response) will be determined by `ke`,
- **pin** The pin number which (if necessary) will be attached to the next free channel *(int)*
- **value** This value is converted to the pwm duty. See above table for range and units *(double)
- **speed** This value has units degrees/second (double). For example, if `speed` is set to 100 deg/s and the servo position value is changed from 0 to 180 deg, then the servo will take 1.8 sec (1800 ms) to complete its travel. Its motion (response) will be determined by `ke`,
- **ke** Servo easing constant for a [Normalized Tunable Sigmoid](https://www.desmos.com/calculator/ejkcwglzd1). A `ke` value of 0.0 represents a linear response. As you increase `ke`, this increases the steepness of a sigmoid response. When `ke` is 1.0, normal "instantaneous" servo response is enabled and the speed parameter is ignored.

##### Returns

- If the servo easing constant `ke` is 1.0 (default) then the pwm duty value *(uint32_t)* is returned.
- If `ke` is less than 1.0, then a normalized float value (0.0 to 1.0) is returned. This represents the programmed servo position from start to stop as it moves over time. When the returned value reaches 0.5, this represents both 50% travel and 50% time duration, no matter what easing constant is set.
- If `ke` is less than 1.0, then a normalized double value (0.0 to 1.0) is returned. This represents the programmed servo position from start to stop as it moves over time. When the returned value reaches 0.5, this represents both 50% travel and 50% time duration, no matter what easing constant is set.

</details>

Expand Down Expand Up @@ -256,7 +256,7 @@ myservo.read(pin)

##### Parameters

- **pin** The pin number *(uint8_t)
- **pin** The pin number (int)

##### Returns

Expand All @@ -280,7 +280,7 @@ myservo.readMicroseconds(pin)

##### Parameters

- **pin** The pin number *(uint8_t)
- **pin** The pin number (int)

##### Returns

Expand Down Expand Up @@ -313,15 +313,15 @@ myservo.attach(pin, ch, minUs, maxUs, speed, ke, invert) // as above with inver

##### Parameters

- **pin** The pin number *(uint8_t)*
- **pin** The pin number *(int)*

- **ch** This optional parameter is used to attach the pin to a specific channel *(uint8_t)*)
- **ch** This optional parameter is used to attach the pin to a specific channel *(int)*)

- **minUs** Minimum timer width in microseconds *(uint16_t)
- **minUs** Minimum timer width in microseconds *(int)*

- **maxUs** Maximum timer width in microseconds *(uint16_t)*
- **maxUs** Maximum timer width in microseconds *(int)*

- **speed** This servo easing parameter has units degrees/second (float). For example, if `speed` is set to 100 deg/s and the servo position value is changed from 0 to 180 deg, then the servo will take 1.8 sec (1800 ms) to complete its travel. Its motion (response) will be determined by `ke`,
- **speed** This servo easing parameter has units degrees/second (double). For example, if `speed` is set to 100 deg/s and the servo position value is changed from 0 to 180 deg, then the servo will take 1.8 sec (1800 ms) to complete its travel. Its motion (response) will be determined by `ke`,

- **ke** Servo easing constant for a [Normalized Tunable Sigmoid](https://www.desmos.com/calculator/ejkcwglzd1). A `ke` value of 0.0 represents a linear response. As you increase `ke`, this increases the steepness of a sigmoid response. When `ke` is 1.0, normal "instantaneous" servo response is enabled and the speed parameter is ignored.

Expand Down Expand Up @@ -357,7 +357,7 @@ myservo.attach(pin, ch) // attach to specified channel

##### Parameters

- **pin** The pin number *(uint8_t)
- **pin** The pin number *(int)*

##### Returns

Expand All @@ -384,7 +384,7 @@ myservo.attached(pin)

##### Parameters

- **pin** The pin number *(uint8_t)
- **pin** The pin number *(int)*

##### Returns

Expand Down Expand Up @@ -412,8 +412,8 @@ myservo.attachInvert(pin, ch); // attach to specified ch with inverted pwm

##### Parameters

- **pin** The pin number *(uint8_t)*
- **ch** This optional parameter is used to attach the pin to a specific channel *(uint8_t)*)
- **pin** The pin number *(int)*
- **ch** This optional parameter is used to attach the pin to a specific channel *(int)*

##### Returns

Expand Down Expand Up @@ -441,7 +441,7 @@ myservo.attachedPin(ch)

##### Parameters

- **pin** The pin number *(uint8_t)
- **pin** The pin number *(int)*

##### Returns

Expand Down Expand Up @@ -470,7 +470,7 @@ myservo.writePwm(pin, duty, frequency, resolution, phase)

##### Parameters

- **pin** The pin number which (if necessary) will be attached to the next free channel *(uint8_t)*
- **pin** The pin number which (if necessary) will be attached to the next free channel *(int)*
- **duty** This sets the pwm duty. The range is 0 to (2**resolution) - 1 *(uint32_t)*
- **frequency** The pwm timer frequency (Hz). The frequency and resolution limits are interdependent *(uint32_t)*. For more details, see [Supported Range of Frequency and Duty Resolutions](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html#ledc-api-supported-range-frequency-duty-resolution).
- **resolution** The bit resolution of the pwm duty *(uint8_t)*
Expand Down Expand Up @@ -498,7 +498,7 @@ myservo.detachPin(pin)

##### Parameters

- **pin** The pin number *(uint8_t)*
- **pin** The pin number *(int)*

##### Returns

Expand Down Expand Up @@ -572,7 +572,7 @@ myservo.setFrequency(pin, frequency)

##### Parameters

- **pin** The pin number (uint8_t) If the pin is detached (free) and there's a free channel available, the pin will be attached to the first free channel that's found *(uint8_t)*
- **pin** The pin number *(int)* If the pin is detached (free) and there's a free channel available, the pin will be attached to the first free channel that's found *(int)*
- **frequency** The frequency in Hz. The default is 1000 Hz *(uint32_t)*

##### Returns
Expand All @@ -597,7 +597,7 @@ myservo.setResolution(pin, resolution)

##### Parameters

- **pin** The pin number (uint8_t) If the pin is detached (free) and there's a free channel available, the pin will be attached to the first free channel that's found *(uint8_t)*
- **pin** The pin number *(int)* If the pin is detached (free) and there's a free channel available, the pin will be attached to the first free channel that's found *(int)*
- **resolution** The PWM resolution can be set from 1-bit to 16-bit, default is 8-bit *(uint8_t)*

##### Returns
Expand Down Expand Up @@ -631,7 +631,7 @@ myservo.tone(pin, frequency, duration, interval)

##### Parameters

- **pin** The pin number which (if necessary) will be attached to the next free channel *(uint8_t)*
- **pin** The pin number which (if necessary) will be attached to the next free channel *(int)*
- **frequency** The tone frequency (Hz) with range 1-65535 *(uint16_t)*.
- **duration** The duration in milliseconds with range 0-65535 *(uint16_t)*, where 0 is off (default) and 65535 is always on.
- **interval** This optional parameter specifies the pause time in milliseconds before the next call to tone becomes ready. *(uint16_t)*, range 0-65535, default = 0.
Expand Down Expand Up @@ -666,7 +666,7 @@ pwm.note(pin, note, octave, duration, interval)

##### Parameters

- **pin** The pin number which (if necessary) will be attached to the next free channel *(uint8_t)*
- **pin** The pin number which (if necessary) will be attached to the next free channel *(int)*
- **note** The type is defined in [esp32-hal-ledc.h](https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-ledc.h) *(note_t)*.
- **octave** There are 8 octaves available, 1 to 8 *(uint8_t)*
- **duration** The duration in milliseconds with range 0-65535 *(uint16_t)*, where 0 is off (default) and 65535 is always on.
Expand Down
4 changes: 2 additions & 2 deletions examples/Servo_Easing_Interrupt/Servo_Easing_Interrupt.ino
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
#include <Servo.h>

const int servoPin = 8;
volatile float ke = 0.0; // easing curve
volatile float speed = 100; // speed control (degrees/second)
volatile double ke = 0.0; // easing curve
volatile double speed = 100; // speed control (degrees/second)
volatile float pos = 90; // servo position (degrees)
volatile float ye; // calculated servo position (normalized)

Expand Down
12 changes: 6 additions & 6 deletions examples/Servo_Easing_Position/Servo_Easing_Position.ino
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ const int servoPin2 = 19;
const int servoPin3 = 21;

// units in degrees per second
float speed1 = 70.0;
float speed2 = 140.0;
float speed3 = 180.0;
double speed1 = 70.0;
double speed2 = 140.0;
double speed3 = 180.0;

// When easing constant (ke) < 1.0, return value is normalized, when 1.0, returns pulse width (μs)
// ke = 0.0 is linear, between 0.0 and 1.0 is tunable sigmoid, 1.0 is normal response
// Normalized Tunable Sigmoid: https://www.desmos.com/calculator/ejkcwglzd1
float ke1 = 0.0;
float ke2 = 0.6;
float ke3 = 0.8;
double ke1 = 0.0;
double ke2 = 0.6;
double ke3 = 0.8;

// go to position (degrees)
uint8_t pos1 = 90;
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"keywords": "pwm, servo, tone, esp32, analogWrite, esp32-s2, esp32-s3, esp32-c3, ledc",
"description": "ESP32 PWM, Servo, Easing and Tone. Smart GPIO pin management and advanced control features.",
"license": "MIT",
"version": "5.0.0",
"version": "5.0.1",
"frameworks": "arduino",
"platforms": "espressif32",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=ESP32 ESP32S2 AnalogWrite
version=5.0.0
version=5.0.1
author=David Lloyd
maintainer=David Lloyd <[email protected]>
sentence=ESP32 PWM, Servo, Easing and Tone.
Expand Down
72 changes: 36 additions & 36 deletions src/Servo.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,153 +16,153 @@ class Servo

// servo

uint8_t attach(uint8_t pin) {
uint8_t attach(int pin) {
return pwm.attachServo(pin);
};

uint8_t attach(uint8_t pin, bool invert) {
uint8_t attach(int pin, bool invert) {
return pwm.attachServo(pin, invert);
};

uint8_t attach(uint8_t pin, uint8_t ch) {
uint8_t attach(int pin, int ch) {
return pwm.attachServo(pin, ch);
};

uint8_t attach(uint8_t pin, uint8_t ch, bool invert) {
uint8_t attach(int pin, int ch, bool invert) {
return pwm.attachServo(pin, ch, invert);
};

uint8_t attach(uint8_t pin, uint16_t minUs, uint16_t maxUs) {
uint8_t attach(int pin, int minUs, int maxUs) {
return pwm.attachServo(pin, minUs, maxUs);
};

uint8_t attach(uint8_t pin, uint8_t ch, uint16_t minUs, uint16_t maxUs) {
uint8_t attach(int pin, int ch, int minUs, int maxUs) {
return pwm.attachServo(pin, ch, minUs, maxUs);
};

uint8_t attach(uint8_t pin, uint8_t ch, uint16_t minUs, uint16_t maxUs, bool invert) {
uint8_t attach(int pin, int ch, int minUs, int maxUs, bool invert) {
return pwm.attachServo(pin, ch, minUs, maxUs, invert);
};

uint8_t attach(uint8_t pin, uint16_t minUs, uint16_t maxUs, float speed, float ke) {
uint8_t attach(int pin, int minUs, int maxUs, double speed, double ke) {
return pwm.attachServo(pin, minUs, maxUs, speed, ke);
};

uint8_t attach(uint8_t pin, uint8_t ch, uint16_t minUs, uint16_t maxUs, float speed, float ke) {
uint8_t attach(int pin, int ch, int minUs, int maxUs, double speed, double ke) {
return pwm.attachServo(pin, ch, minUs, maxUs, speed, ke);
};

uint8_t attach(uint8_t pin, uint8_t ch, uint16_t minUs, uint16_t maxUs, float speed, float ke, bool invert) {
uint8_t attach(int pin, int ch, int minUs, int maxUs, double speed, double ke, bool invert) {
return pwm.attachServo(pin, ch, minUs, maxUs, speed, ke, invert);
};

float read(uint8_t pin) {
float read(int pin) {
return pwm.read(pin);
};

float readMicroseconds(uint8_t pin) {
float readMicroseconds(int pin) {
return pwm.readMicroseconds(pin);
};

float write(uint8_t pin, float value) {
float write(int pin, float value) {
return pwm.writeServo(pin, value);
};

float writeMicroseconds(uint8_t pin, float value) {
float writeMicroseconds(int pin, float value) {
return pwm.writeServo(pin, value);
};

float write(uint8_t pin, float value, float speed, float ke) {
float write(int pin, float value, double speed, double ke) {
return pwm.writeServo(pin, value, speed, ke);
};

float writeMicroseconds(uint8_t pin, float value, float speed, float ke) {
float writeMicroseconds(int pin, float value, double speed, double ke) {
return pwm.writeServo(pin, value, speed, ke);
};

// common

uint8_t attached(uint8_t pin) { // check if pin is attached
uint8_t attached(int pin) { // check if pin is attached
return pwm.attached(pin);
};

uint8_t attachedPin(uint8_t ch) { // get pin on specified channel
uint8_t attachedPin(int ch) { // get pin on specified channel
return pwm.attachedPin(ch);
};

uint8_t firstFreeCh(void) { // get first free channel
uint8_t firstFreeCh(void) { // get first free channel
return pwm.firstFreeCh();
};

void detach(uint8_t pin) { // detach pin
void detach(int pin) { // detach pin
pwm.detach(pin);
};

bool detached(uint8_t pin) { // check if pin is detached
bool detached(int pin) { // check if pin is detached
return pwm.detached(pin);
};

void pause(uint8_t ch = 255) { // pause timer on all or specified channel
void pause(int ch = 255) { // pause timer on all or specified channel
pwm.pause(ch);
};

void resume(uint8_t ch = 255) { // resume timer on all or specified channel
void resume(int ch = 255) { // resume timer on all or specified channel
pwm.resume(ch);
};

void printDebug(void) { // print the status of all channels
void printDebug(void) { // print the status of all channels
pwm.printDebug();
};

float setFrequency(uint8_t pin, uint32_t frequency = 1000) {
float setFrequency(int pin, uint32_t frequency = 1000) {
return pwm.setFrequency(pin, frequency);
};

uint8_t setResolution(uint8_t pin, uint8_t resolution = 10) {
uint8_t setResolution(int pin, uint8_t resolution = 10) {
return pwm.setResolution(pin, resolution);
};

// pwm

float writePwm(uint8_t pin, uint32_t duty) {
float writePwm(int pin, uint32_t duty) {
return pwm.write(pin, duty);
};

float writePwm(uint8_t pin, uint32_t duty, uint32_t frequency) {
float writePwm(int pin, uint32_t duty, uint32_t frequency) {
return pwm.write(pin, duty, frequency);
};

float writePwm(uint8_t pin, uint32_t duty, uint32_t frequency, uint8_t resolution) {
float writePwm(int pin, uint32_t duty, uint32_t frequency, uint8_t resolution) {
return pwm.write(pin, duty, frequency, resolution);
};

float writePwm(uint8_t pin, uint32_t duty, uint32_t frequency, uint8_t resolution, uint32_t phase) {
float writePwm(int pin, uint32_t duty, uint32_t frequency, uint8_t resolution, uint32_t phase) {
return pwm.write(pin, duty, frequency, resolution, phase);
};

uint8_t attachPwm(uint8_t pin) { // attach pin to next free channel
uint8_t attachPwm(int pin) { // attach pin to next free channel
return pwm.attach(pin);
};

uint8_t attachPwm(uint8_t pin, uint8_t ch) { // attach to specified channel
uint8_t attachPwm(int pin, int ch) { // attach to specified channel
return pwm.attach(pin, ch);
};

uint8_t attachInvert(uint8_t pin) { // attach pin to next free channel with inverted pwm
uint8_t attachInvert(int pin) { // attach pin to next free channel with inverted pwm
return pwm.attachInvert(pin);
};

uint8_t attachInvert(uint8_t pin, uint8_t ch) { // attach to specified ch with inverted pwm
uint8_t attachInvert(int pin, int ch) { // attach to specified ch with inverted pwm
return pwm.attachInvert(pin, ch);
};

// tone and note

void tone(uint8_t pin, uint32_t frequency, uint16_t duration = 500, uint16_t interval = 0) {
void tone(int pin, uint32_t frequency, uint16_t duration = 500, uint16_t interval = 0) {
pwm.tone(pin, frequency, duration, interval);
};

void note(uint8_t pin, note_t note, uint8_t octave, uint16_t duration, uint16_t interval) {
void note(int pin, note_t note, uint8_t octave, uint16_t duration, uint16_t interval) {
pwm.note(pin, note, octave, duration, interval);
};

Expand Down
Loading

0 comments on commit b3be0df

Please sign in to comment.