Skip to content

Commit a01d15c

Browse files
committed
Update
* Enable most pins as pwm capable. * More attach overload options. * New attachInvert function. * New servo easing examples. * Updated readme.
1 parent 8188a62 commit a01d15c

File tree

8 files changed

+215
-107
lines changed

8 files changed

+215
-107
lines changed

README.md

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ pwm.writeServo(servoPin3, pos3, speed3, 0.8); // move 90 deg, 180 deg/s, steep
2828

2929
##### **Examples:**
3030

31-
- [![Wokwi_badge](https://user-images.githubusercontent.com/63488701/212449119-a8510897-c860-4545-8c1a-794169547ba1.svg)](https://wokwi.com/projects/360276061783595009) [Servo Easing](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite/blob/main/examples/Servo-Easing/Servo-Easing.ino) Controls three servos with different easing settings
31+
- [![Wokwi_badge](https://user-images.githubusercontent.com/63488701/212449119-a8510897-c860-4545-8c1a-794169547ba1.svg)](https://wokwi.com/projects/360276061783595009) [Servo_Easing_Time](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite/blob/main/examples/Servo_Easing_Time/Servo_Easing_Time.ino) 3 servos with different easing constants and timed position control
32+
33+
- [![Wokwi_badge](https://user-images.githubusercontent.com/63488701/212449119-a8510897-c860-4545-8c1a-794169547ba1.svg)](https://wokwi.com/projects/361237697368753153) [Servo_Easing_Position](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite/blob/main/examples/Servo_Easing_Position/Servo_Easing_Position.ino) 3 servos with different easing constants and position feedback control
3234

3335
- [![Wokwi_badge](https://user-images.githubusercontent.com/63488701/212449119-a8510897-c860-4545-8c1a-794169547ba1.svg)](https://wokwi.com/projects/355852275661848577) [ESP32_C3_6_Servo_Knob](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite/blob/main/examples/ESP32_C3_6_Servo_Knob/ESP32_C3_6_Servo_Knob.ino) Potentiometer control of 6 servos on an ESP32-C3
3436

@@ -52,8 +54,6 @@ pwm.writeServo(servoPin3, pos3, speed3, 0.8); // move 90 deg, 180 deg/s, steep
5254

5355
- [![Wokwi_badge](https://user-images.githubusercontent.com/63488701/212449119-a8510897-c860-4545-8c1a-794169547ba1.svg)](https://wokwi.com/projects/349322326995632722) [2 Sync 300kHz](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite/blob/main/examples/ESP32_Sync2_300kHz/ESP32_Sync2_300kHz.ino) 2 synchronized PWM outputs using the same timer (channel pair)
5456

55-
- [![Wokwi_badge](https://user-images.githubusercontent.com/63488701/212449119-a8510897-c860-4545-8c1a-794169547ba1.svg)](https://wokwi.com/projects/349319723103552084) [8 Sync 20kHz](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite/blob/main/examples/ESP32_Sync8_20kHz/ESP32_Sync8_20kHz.ino) ESP32 8 Synchronized PWM Outputs (20kHz, 10-bit)
56-
5757
- [![Wokwi_badge](https://user-images.githubusercontent.com/63488701/212449119-a8510897-c860-4545-8c1a-794169547ba1.svg)](https://wokwi.com/projects/349336125753524820) [ESP32_3-Phase 40kHz](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite/blob/main/examples/ESP32_3phase_40kHz/ESP32_3phase_40kHz.ino) ESP32 3 Phase PWM Outputs (40kHz, 10-bit)
5858

5959
- [![Wokwi_badge](https://user-images.githubusercontent.com/63488701/212449119-a8510897-c860-4545-8c1a-794169547ba1.svg)](https://wokwi.com/projects/334722465700774482) [ESP32_3-Phase 10kHz](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite/blob/main/examples/ESP32_3phase_10kHz/ESP32_3phase_10kHz.ino) ESP32 3 Phase PWM Outputs (10kHz, 10-bit)
@@ -64,11 +64,11 @@ pwm.writeServo(servoPin3, pos3, speed3, 0.8); // move 90 deg, 180 deg/s, steep
6464

6565

6666

67-
| Board | PWM Pins | PWM, Duty and Phase Channels | Frequency and Resolution Channels |
68-
| -------- | ------------------------------------ | ---------------------------- | --------------------------------- |
69-
| ESP32 | 2, 4, 5, 12-19, 21-23, 25-27, 32, 33 | 16 | 8 |
70-
| ESP32‑S2 | 1- 14, 21, 33-42, 45 | 8 | 4 |
71-
| ESP32‑C3 | 0- 10, 18-21 | 6 | 3 |
67+
| Board | PWM Pins | PWM, Duty and Phase Channels | Frequency and Resolution Channels |
68+
| ----------- | ------------------------- | ---------------------------- | --------------------------------- |
69+
| ESP32 | 0-19, 21-23, 25-27, 32-39 | 16 | 8 |
70+
| ESP32‑S2/S3 | 0-21, 26, 33-45 | 8 | 4 |
71+
| ESP32‑C3 | 0- 10, 18-21 | 6 | 3 |
7272

7373
### PWM Channel Configuration
7474

@@ -153,7 +153,7 @@ The frequency and resolution values are shared by each channel pair. When any ch
153153

154154
**Attaching to free Channel**
155155

156-
This process is automatic - the servo pin will be attached to the next free channel. If you need to assign the servo pin(s) to specific channels or to set the minimum, default or maximum microsecond values, then call the `attach()`method first.
156+
This process is automatic - the servo pin will be attached to the next free channel. If you need to assign the servo pin(s) to specific channels or to set the minimum or maximum microsecond values, then call the `attach()`method first.
157157

158158
##### Syntax
159159

@@ -292,28 +292,27 @@ readMicroseconds(pin)
292292

293293
##### Description
294294

295-
This function allows auto-attaching a pin to the first available channel if only the pin is specified. To have the pin assigned to a specific channel, use both the pin and channel (ch) parameters. Additionally, there are parameters available for setting the servo timer values for minimum, default and maximum microseconds.
295+
This function allows auto-attaching a pin to the first available channel if only the pin is specified. To have the pin assigned to a specific channel, use both the pin and channel (ch) parameters. Additionally, there are parameters available for setting the servo timer values for minimum and maximum microseconds.
296296

297297
**Syntax**
298298

299299
```c++
300-
attach(pin) // auto attach to 1st free channel
301-
attach(pin, ch, invert) // attach to ch, optional invert
302-
attach(pin, minUs, defUs, maxUs) // auto attach incl servo timer values
303-
attach(pin, ch, minUs, defUs, maxUs) // attach to ch with servo limits
304-
attach(pin, ch, minUs, defUs, maxUs, speed, ke) // as above with speed, easing constant
305-
attach(pin, ch, minUs, defUs, maxUs, speed, ke, invert) // as above with invert
300+
attach(pin) // auto attach to 1st free channel
301+
attach(pin, ch) // attach to specified channel
302+
attach(pin, minUs, maxUs) // auto attach to free ch with servo limits
303+
attach(pin, ch, minUs, maxUs) // attach to specified ch with servo limits
304+
attach(pin, minUs, maxUs, speed, ke) // attach to free ch with speed and easing constant
305+
attach(pin, ch, minUs, maxUs, speed, ke) // as above but attaches to specified channel
306+
attach(pin, ch, minUs, maxUs, speed, ke, invert) // as above with invert
306307
```
307308
308309
##### Parameters
309310
310311
- **pin** The pin number *(uint8_t)*
311312
312-
- **channel** This optional parameter is used to attach the pin to a specific channel *(uint8_t)*)
313+
- **ch** This optional parameter is used to attach the pin to a specific channel *(uint8_t)*)
313314
314-
- **minUs** Minimum timer width in microseconds *(uint16_t)*
315-
316-
- **defUs** Default timer width in microseconds *(uint16_t)*
315+
- **minUs** Minimum timer width in microseconds *(uint16_t)
317316
318317
- **maxUs** Maximum timer width in microseconds *(uint16_t)*
319318
@@ -336,6 +335,33 @@ attach(pin, ch, minUs, defUs, maxUs, speed, ke, invert) // as above with invert
336335
337336
338337
338+
### attachInvert()
339+
340+
##### Description
341+
342+
This function allows auto-attaching a pin to the first available channel if only the pin is specified. To have the pin assigned to a specific channel, use both the pin and channel (ch) parameters. The pwm output will be inverted. The duty value represents the low period.
343+
344+
**Syntax**
345+
346+
```c++
347+
attachInvert(pin); // attach pin to next free channel with inverted pwm
348+
attachInvert(pin, ch); // attach to specified ch with inverted pwm
349+
```
350+
351+
##### Parameters
352+
353+
- **pin** The pin number *(uint8_t)*
354+
- **ch** This optional parameter is used to attach the pin to a specific channel *(uint8_t)*)
355+
356+
##### Returns
357+
358+
- If not a valid pin, 254 *(uint8_t)*
359+
- free channels exist, 253 *(uint8_t)*
360+
- If attached, the channel number (0-15) *(uint8_t)*
361+
- If not attached, 255 *(uint8_t)*
362+
363+
364+
339365
### attached()
340366

341367
##### Description
@@ -518,7 +544,7 @@ pwm.printDebug()
518544

519545
- serial report on serial monitor
520546

521-
![![image](https://user-images.githubusercontent.com/63488701/229374511-de75b97d-f91f-44d0-b103-0ca858d16727.png)
547+
![image](https://user-images.githubusercontent.com/63488701/229374511-de75b97d-f91f-44d0-b103-0ca858d16727.png)
522548

523549
```
524550
This Library is licensed under the MIT License

examples/ESP32_Sync8_20kHz/ESP32_Sync8_20kHz.ino

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
Controls three servos with different easing settings
3+
New position command after normalized output (ye) reaches set value.
4+
https://wokwi.com/projects/361237697368753153
5+
by dlloydev, March 2023.
6+
7+
⚪ The green servo moves from 0 to 90 deg at 70 deg/s with linear motion.
8+
⚪ The orange servo moves from 0 to 180 deg at 140 deg/s with sigmoid motion.
9+
⚪ The purple servo moves from 45 to 135 deg at 180 deg/s with steep sigmoid motion.
10+
*/
11+
12+
#include <pwmWrite.h>
13+
14+
const int servoPin1 = 18;
15+
const int servoPin2 = 19;
16+
const int servoPin3 = 21;
17+
18+
// units in degrees per second
19+
float speed1 = 70.0;
20+
float speed2 = 140.0;
21+
float speed3 = 180.0;
22+
23+
// When easing constant (ke) < 1.0, return value is normalized, when 1.0, returns pulse width (μs)
24+
// ke = 0.0 is linear, between 0.0 and 1.0 is tunable sigmoid, 1.0 is normal response
25+
// Normalized Tunable Sigmoid: https://www.desmos.com/calculator/ejkcwglzd1
26+
float ke1 = 0.0;
27+
float ke2 = 0.6;
28+
float ke3 = 0.8;
29+
30+
// go to position (degrees)
31+
uint8_t pos1 = 90;
32+
uint8_t pos2 = 180;
33+
uint8_t pos3 = 135;
34+
35+
float ye1, ye2, ye3;
36+
37+
Pwm pwm = Pwm();
38+
39+
void setup() {
40+
Serial.begin(115200);
41+
}
42+
43+
void loop() {
44+
45+
if (ye1 <= 0.0 ) pos1 = 90;
46+
else if (ye1 >= 1.0) pos1 = 0;
47+
48+
if (ye2 <= 0.0 ) pos2 = 180;
49+
else if (ye2 >= 1.0) pos2 = 0;
50+
51+
if (ye3 <= 0.0 ) pos3 = 135;
52+
else if (ye3 >= 1.0) pos3 = 45;
53+
54+
ye1 = pwm.writeServo(servoPin1, pos1, speed1, ke1);
55+
ye2 = pwm.writeServo(servoPin2, pos2, speed2, ke2);
56+
ye3 = pwm.writeServo(servoPin3, pos3, speed3, ke3);
57+
Serial.print(ye1);
58+
Serial.print(",");
59+
Serial.print(ye2);
60+
Serial.print(",");
61+
Serial.println(ye3);
62+
delay(6);
63+
}

examples/Servo-Easing/Servo-Easing.ino renamed to examples/Servo_Easing_Time/Servo_Easing_Time.ino

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
Controls three servos with different easing settings
3+
New position command after elapsed time based position change and speed.
34
https://wokwi.com/projects/360276061783595009
45
by dlloydev, March 2023.
56
@@ -10,23 +11,34 @@
1011

1112
#include <pwmWrite.h>
1213

13-
const int servoPin1 = 21;
14-
const int servoPin2 = 22;
15-
const int servoPin3 = 23;
14+
const int servoPin1 = 18;
15+
const int servoPin2 = 19;
16+
const int servoPin3 = 21;
1617

18+
// units in degrees per second
1719
float speed1 = 70.0;
1820
float speed2 = 140.0;
1921
float speed3 = 180.0;
2022

21-
uint32_t prevMs1, prevMs2, prevMs3;
23+
// When easing constant (ke) < 1.0, return value is normalized, when 1.0, returns pulse width (μs)
24+
// ke = 0.0 is linear, between 0.0 and 1.0 is tunable sigmoid, 1.0 is normal response
25+
// Normalized Tunable Sigmoid: https://www.desmos.com/calculator/ejkcwglzd1
26+
float ke1 = 0.0;
27+
float ke2 = 0.6;
28+
float ke3 = 0.8;
29+
30+
// go to position (degrees)
2231
uint8_t pos1 = 90;
2332
uint8_t pos2 = 180;
2433
uint8_t pos3 = 135;
2534

35+
// duration of travel in ms is degrees to move / speed * 1000
2636
float dur1 = 90.0 / speed1 * 1000.0;
2737
float dur2 = 180.0 / speed2 * 1000.0;
2838
float dur3 = 90.0 / speed3 * 1000.0;
2939

40+
uint32_t prevMs1, prevMs2, prevMs3;
41+
3042
Pwm pwm = Pwm();
3143

3244
void setup() {
@@ -51,9 +63,9 @@ void loop() {
5163
prevMs3 = ms3;
5264
pos3 = (pos3 == 45) ? 135 : 45;
5365
}
54-
ye1 = pwm.writeServo(servoPin1, pos1, speed1, 0.0);
55-
ye2 = pwm.writeServo(servoPin2, pos2, speed2, 0.6);
56-
ye3 = pwm.writeServo(servoPin3, pos3, speed3, 0.8);
66+
ye1 = pwm.writeServo(servoPin1, pos1, speed1, ke1);
67+
ye2 = pwm.writeServo(servoPin2, pos2, speed2, ke2);
68+
ye3 = pwm.writeServo(servoPin3, pos3, speed3, ke3);
5769
Serial.print(ye1);
5870
Serial.print(",");
5971
Serial.print(ye2);

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"keywords": "pwm, servo, tone, esp32, analogWrite, esp32-s2, esp32-s3, esp32-c3, ledc",
44
"description": "ESP32 PWM, Servo, Easing and Tone. Smart GPIO pin management and advanced control features.",
55
"license": "MIT",
6-
"version": "4.3.3",
6+
"version": "4.3.4",
77
"frameworks": "arduino",
88
"platforms": "espressif32",
99
"repository": {

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=ESP32 ESP32S2 AnalogWrite
2-
version=4.3.3
2+
version=4.3.4
33
author=David Lloyd
44
maintainer=David Lloyd <dlloydev@testcor.ca>
55
sentence=ESP32 PWM, Servo, Easing and Tone.

0 commit comments

Comments
 (0)