Skip to content

Commit cc6a7bc

Browse files
committed
Update
Organize functions in pwmWrite.cpp
1 parent b3be0df commit cc6a7bc

File tree

3 files changed

+89
-84
lines changed

3 files changed

+89
-84
lines changed

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": "5.0.1",
6+
"version": "5.0.2",
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=5.0.1
2+
version=5.0.2
33
author=David Lloyd
44
maintainer=David Lloyd <[email protected]>
55
sentence=ESP32 PWM, Servo, Easing and Tone.

src/pwmWrite.cpp

Lines changed: 87 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
ESP32 PWM, SERVO and TONE Library, Version 5.0.1
2+
ESP32 PWM, SERVO and TONE Library, Version 5.0.2
33
by dlloydev https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite
44
License: MIT
55
*/
@@ -45,90 +45,20 @@ float Pwm::write(int pin, uint32_t duty, uint32_t frequency, uint8_t resolution,
4545
return mem[ch].frequency;
4646
}
4747

48-
float Pwm::writeServo(int pin, float value, double speed, double ke) {
49-
uint8_t ch = attached(pin);
50-
wr_servo(pin, value, speed, ke);
51-
return mem[ch].ye; // normalized easing position (0.0 - 1.0)
52-
}
53-
54-
float Pwm::writeServo(int pin, float value) {
48+
uint8_t Pwm::attach(int pin) {
5549
uint8_t ch = attached(pin);
5650
if (ch == 253) { // free channels exist
5751
for (uint8_t c = 0; c < chMax; c++) {
5852
if (mem[c].pin == 255 && ch == 253) { //first free ch
5953
mem[c].pin = pin;
6054
ch = c;
61-
if (mem[ch].frequency < 40 || mem[ch].frequency > 900) mem[ch].frequency = 50;
62-
if (mem[ch].resolution > widthMax) mem[ch].resolution = widthMax;
63-
else if (mem[ch].resolution < 14 && widthMax == 20) mem[ch].resolution = 16;
64-
else if (mem[ch].resolution < 14) mem[ch].resolution = 14;
6555
ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
6656
if (sync) pause(ch);
6757
ledcAttachPin(pin, ch);
58+
return ch;
6859
}
6960
}
7061
}
71-
wr_servo(pin, value, mem[ch].speed, mem[ch].ke);
72-
return mem[ch].ye; // normalized easing position (0.0 - 1.0)
73-
}
74-
75-
void Pwm::tone(int pin, uint32_t frequency, uint16_t duration, uint16_t interval) {
76-
uint8_t ch = attach(pin);
77-
if (ch < chMax) {
78-
uint32_t ms = millis();
79-
static bool durDone = false;
80-
#if defined(CONFIG_IDF_TARGET_ESP32C3)
81-
if (frequency < 153) frequency = 153;
82-
#else
83-
if (frequency < 4) frequency = 4;
84-
#endif
85-
if (!durDone) {
86-
if (frequency != mem[ch].frequency && (ms - mem[ch].startMs > interval)) {
87-
mem[ch].startMs = ms;
88-
mem[ch].frequency = frequency;
89-
ledcChangeFrequency(ch, frequency, mem[ch].resolution);
90-
write(pin, 127, frequency, 8);
91-
resume(ch);
92-
}
93-
if ((duration && ((ms - mem[ch].startMs) > duration)) || (duration == 0)) {
94-
mem[ch].startMs = ms;
95-
durDone = true;
96-
if (duration < 0xffff) pause(ch);
97-
}
98-
} else if (ms - mem[ch].startMs > interval) durDone = false;
99-
}
100-
}
101-
102-
void Pwm::note(int pin, note_t note, uint8_t octave, uint16_t duration, uint16_t interval) {
103-
const uint16_t noteFrequencyBase[12] = {
104-
// C C# D Eb E F F# G G# A Bb B
105-
4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902
106-
};
107-
uint32_t noteFreq = (uint32_t)noteFrequencyBase[note] / (uint32_t)(1 << (8 - octave));
108-
if (octave <= 8 || note <= NOTE_MAX) tone(pin, noteFreq, duration, interval);
109-
}
110-
111-
float Pwm::read(int pin) {
112-
uint8_t ch = attached(pin);
113-
if (ch < chMax) {
114-
float deg = (readMicroseconds(pin) - mem[ch].servoMinUs) / (mem[ch].servoMaxUs - mem[ch].servoMinUs) * 180.0;
115-
return deg < 0 ? 0 : deg;
116-
}
117-
else return 0;
118-
}
119-
120-
float Pwm::readMicroseconds(int pin) {
121-
uint8_t ch = attached(pin);
122-
if (ch < chMax) return mem[ch].duty * ((1000000.0 / mem[ch].frequency) / ((1 << mem[ch].resolution) - 1.0)); // μs
123-
else return 0;
124-
}
125-
126-
uint8_t Pwm::attach(int pin) {
127-
uint8_t ch = firstFreeCh();
128-
if (ch < chMax) mem[ch].pin = pin;
129-
ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
130-
if (sync) pause(ch);
131-
ledcAttachPin(pin, ch);
13262
return ch;
13363
}
13464

@@ -180,8 +110,7 @@ uint8_t Pwm::attachServo(int pin, int ch) {
180110

181111
uint8_t Pwm::attachServo(int pin, int ch, bool invert) {
182112
if (ch < chMax) config_servo(ch, mem[ch].servoMinUs, mem[ch].servoMaxUs);
183-
uint8_t chan = (invert) ? attachInvert(pin, ch) : attach(pin, ch);
184-
return chan;
113+
return (invert) ? attachInvert(pin, ch) : attach(pin, ch);
185114
}
186115

187116
uint8_t Pwm::attachServo(int pin, int minUs, int maxUs) {
@@ -197,8 +126,7 @@ uint8_t Pwm::attachServo(int pin, int ch, int minUs, int maxUs) {
197126

198127
uint8_t Pwm::attachServo(int pin, int ch, int minUs, int maxUs, bool invert) {
199128
config_servo(ch, minUs, maxUs);
200-
uint8_t chan = (invert) ? attachInvert(pin, ch) : attach(pin, ch);
201-
return chan;
129+
return (invert) ? attachInvert(pin, ch) : attach(pin, ch);
202130
}
203131

204132
uint8_t Pwm::attachServo(int pin, int minUs, int maxUs, double speed, double ke) {
@@ -214,8 +142,85 @@ uint8_t Pwm::attachServo(int pin, int ch, int minUs, int maxUs, double speed, do
214142

215143
uint8_t Pwm::attachServo(int pin, int ch, int minUs, int maxUs, double speed, double ke, bool invert) {
216144
config_servo(ch, minUs, maxUs, speed, ke);
217-
uint8_t chan = (invert) ? attachInvert(pin, ch) : attach(pin, ch);
218-
return chan;
145+
return (invert) ? attachInvert(pin, ch) : attach(pin, ch);
146+
}
147+
148+
float Pwm::read(int pin) {
149+
uint8_t ch = attached(pin);
150+
if (ch < chMax) {
151+
float deg = (readMicroseconds(pin) - mem[ch].servoMinUs) / (mem[ch].servoMaxUs - mem[ch].servoMinUs) * 180.0;
152+
return deg < 0 ? 0 : deg;
153+
}
154+
else return 0;
155+
}
156+
157+
float Pwm::readMicroseconds(int pin) {
158+
uint8_t ch = attached(pin);
159+
if (ch < chMax) return mem[ch].duty * ((1000000.0 / mem[ch].frequency) / ((1 << mem[ch].resolution) - 1.0)); // μs
160+
else return 0;
161+
}
162+
163+
float Pwm::writeServo(int pin, float value, double speed, double ke) {
164+
uint8_t ch = attached(pin);
165+
wr_servo(pin, value, speed, ke);
166+
return mem[ch].ye; // normalized easing position (0.0 - 1.0)
167+
}
168+
169+
float Pwm::writeServo(int pin, float value) {
170+
uint8_t ch = attached(pin);
171+
if (ch == 253) { // free channels exist
172+
for (uint8_t c = 0; c < chMax; c++) {
173+
if (mem[c].pin == 255 && ch == 253) { //first free ch
174+
mem[c].pin = pin;
175+
ch = c;
176+
if (mem[ch].frequency < 40 || mem[ch].frequency > 900) mem[ch].frequency = 50;
177+
if (mem[ch].resolution > widthMax) mem[ch].resolution = widthMax;
178+
else if (mem[ch].resolution < 14 && widthMax == 20) mem[ch].resolution = 16;
179+
else if (mem[ch].resolution < 14) mem[ch].resolution = 14;
180+
ledcSetup(ch, mem[ch].frequency, mem[ch].resolution);
181+
if (sync) pause(ch);
182+
ledcAttachPin(pin, ch);
183+
}
184+
}
185+
}
186+
wr_servo(pin, value, mem[ch].speed, mem[ch].ke);
187+
return mem[ch].ye; // normalized easing position (0.0 - 1.0)
188+
}
189+
190+
void Pwm::tone(int pin, uint32_t frequency, uint16_t duration, uint16_t interval) {
191+
uint8_t ch = attach(pin);
192+
if (ch < chMax) {
193+
uint32_t ms = millis();
194+
static bool durDone = false;
195+
#if defined(CONFIG_IDF_TARGET_ESP32C3)
196+
if (frequency < 153) frequency = 153;
197+
#else
198+
if (frequency < 4) frequency = 4;
199+
#endif
200+
if (!durDone) {
201+
if (frequency != mem[ch].frequency && (ms - mem[ch].startMs > interval)) {
202+
mem[ch].startMs = ms;
203+
mem[ch].frequency = frequency;
204+
ledcChangeFrequency(ch, frequency, mem[ch].resolution);
205+
write(pin, 127, frequency, 8);
206+
resume(ch);
207+
}
208+
if ((duration && ((ms - mem[ch].startMs) > duration)) || (duration == 0)) {
209+
mem[ch].startMs = ms;
210+
durDone = true;
211+
if (duration < 0xffff) pause(ch);
212+
}
213+
} else if (ms - mem[ch].startMs > interval) durDone = false;
214+
}
215+
}
216+
217+
void Pwm::note(int pin, note_t note, uint8_t octave, uint16_t duration, uint16_t interval) {
218+
const uint16_t noteFrequencyBase[12] = {
219+
// C C# D Eb E F F# G G# A Bb B
220+
4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902
221+
};
222+
uint32_t noteFreq = (uint32_t)noteFrequencyBase[note] / (uint32_t)(1 << (8 - octave));
223+
if (octave <= 8 || note <= NOTE_MAX) tone(pin, noteFreq, duration, interval);
219224
}
220225

221226
uint8_t Pwm::attached(int pin) {
@@ -243,9 +248,9 @@ void Pwm::detach(int pin) {
243248
uint8_t ch = attached(pin);
244249
if (ch < chMax) {
245250
reset_fields(ch);
246-
if (digitalRead(pin) == HIGH) delay (3); // wait until low
247-
ledcWrite(ch, 4); // minimal duty for jitterless detach
248-
ledcDetachPin(mem[ch].pin);
251+
if (digitalRead(pin) == HIGH) delayMicroseconds(mem[ch].servoMaxUs); // wait until LOW
252+
ledcWrite(ch, 4); // set minimal duty
253+
ledcDetachPin(mem[ch].pin); // jitterless
249254
REG_SET_FIELD(GPIO_PIN_MUX_REG[pin], MCU_SEL, GPIO_MODE_DEF_DISABLE);
250255
}
251256
}

0 commit comments

Comments
 (0)