Skip to content

Commit 5aa4c33

Browse files
committed
Update compatibility with ESP32
1 parent b6c2873 commit 5aa4c33

File tree

6 files changed

+189
-162
lines changed

6 files changed

+189
-162
lines changed

QuickPID.cpp

Lines changed: 16 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**********************************************************************************
2-
QuickPID Library for Arduino - Version 2.2.2
2+
QuickPID Library for Arduino - Version 2.2.3
33
by dlloydev https://github.com/Dlloydev/QuickPID
44
Based on the Arduino PID Library by Brett Beauregard
55
@@ -53,8 +53,7 @@ QuickPID::QuickPID(int* Input, int* Output, int* Setpoint,
5353
PID Output needs to be computed. Returns true when the output is computed,
5454
false when nothing has been done.
5555
**********************************************************************************/
56-
bool QuickPID::Compute()
57-
{
56+
bool QuickPID::Compute() {
5857
if (!inAuto) return false;
5958
uint32_t now = micros();
6059
uint32_t timeChange = (now - lastTime);
@@ -67,7 +66,7 @@ bool QuickPID::Compute()
6766
if (kpi < 31 && kpd < 31) outputSum += FX_MUL(FL_FX(kpi) , error) - FX_MUL(FL_FX(kpd), dInput); // fixed-point
6867
else outputSum += (kpi * error) - (kpd * dInput); // floating-point
6968

70-
outputSum = QuickPID::Saturate(outputSum);
69+
outputSum = CONSTRAIN(outputSum, outMin, outMax);
7170
*myOutput = outputSum;
7271

7372
lastInput = input;
@@ -157,10 +156,8 @@ void QuickPID::AutoTune(int inputPin, int outputPin, int tuningRule, int Print =
157156
it's called automatically from the constructor, but tunings can also
158157
be adjusted on the fly during normal operation
159158
******************************************************************************/
160-
void QuickPID::SetTunings(float Kp, float Ki, float Kd, float POn = 1)
161-
{
159+
void QuickPID::SetTunings(float Kp, float Ki, float Kd, float POn = 1) {
162160
if (Kp < 0 || Ki < 0 || Kd < 0) return;
163-
164161
pOn = POn;
165162
dispKp = Kp; dispKi = Ki; dispKd = Kd;
166163

@@ -171,8 +168,7 @@ void QuickPID::SetTunings(float Kp, float Ki, float Kd, float POn = 1)
171168
kpi = (kp * pOn) + ki;
172169
kpd = (kp * (1 - pOn)) + kd;
173170

174-
if (controllerDirection == REVERSE)
175-
{
171+
if (controllerDirection == REVERSE) {
176172
kp = (0 - kp);
177173
ki = (0 - ki);
178174
kd = (0 - kd);
@@ -189,8 +185,7 @@ void QuickPID::SetTunings(float Kp, float Ki, float Kd) {
189185
/* SetSampleTime(...) *********************************************************
190186
Sets the period, in microseconds, at which the calculation is performed
191187
******************************************************************************/
192-
void QuickPID::SetSampleTimeUs(uint32_t NewSampleTimeUs)
193-
{
188+
void QuickPID::SetSampleTimeUs(uint32_t NewSampleTimeUs) {
194189
if (NewSampleTimeUs > 0) {
195190
float ratio = (float)NewSampleTimeUs / (float)sampleTimeUs;
196191
ki *= ratio;
@@ -203,16 +198,14 @@ void QuickPID::SetSampleTimeUs(uint32_t NewSampleTimeUs)
203198
The PID controller is designed to vary its output within a given range.
204199
By default this range is 0-255, the Arduino PWM range.
205200
******************************************************************************/
206-
void QuickPID::SetOutputLimits(int Min, int Max)
207-
{
201+
void QuickPID::SetOutputLimits(int Min, int Max) {
208202
if (Min >= Max) return;
209203
outMin = Min;
210204
outMax = Max;
211205

212-
if (inAuto)
213-
{
214-
*myOutput = QuickPID::Saturate(*myOutput);
215-
outputSum = QuickPID::Saturate(outputSum);
206+
if (inAuto) {
207+
*myOutput = CONSTRAIN(*myOutput, outMin, outMax);
208+
outputSum = CONSTRAIN(outputSum, outMin, outMax);
216209
}
217210
}
218211

@@ -221,11 +214,9 @@ void QuickPID::SetOutputLimits(int Min, int Max)
221214
when the transition from manual to auto occurs, the controller is
222215
automatically initialized
223216
******************************************************************************/
224-
void QuickPID::SetMode(uint8_t Mode)
225-
{
217+
void QuickPID::SetMode(uint8_t Mode) {
226218
bool newAuto = (Mode == AUTOMATIC);
227-
if (newAuto && !inAuto)
228-
{ /*we just went from manual to auto*/
219+
if (newAuto && !inAuto) { //we just went from manual to auto
229220
QuickPID::Initialize();
230221
}
231222
inAuto = newAuto;
@@ -235,11 +226,10 @@ void QuickPID::SetMode(uint8_t Mode)
235226
Does all the things that need to happen to ensure a bumpless transfer
236227
from manual to automatic mode.
237228
******************************************************************************/
238-
void QuickPID::Initialize()
239-
{
229+
void QuickPID::Initialize() {
240230
outputSum = *myOutput;
241231
lastInput = *myInput;
242-
outputSum = QuickPID::Saturate(outputSum);
232+
outputSum = CONSTRAIN(outputSum, outMin, outMax);
243233
}
244234

245235
/* SetControllerDirection(...)*************************************************
@@ -248,10 +238,8 @@ void QuickPID::Initialize()
248238
know which one, because otherwise we may increase the output when we should
249239
be decreasing. This is called from the constructor.
250240
******************************************************************************/
251-
void QuickPID::SetControllerDirection(uint8_t Direction)
252-
{
253-
if (inAuto && Direction != controllerDirection)
254-
{
241+
void QuickPID::SetControllerDirection(uint8_t Direction) {
242+
if (inAuto && Direction != controllerDirection) {
255243
kp = (0 - kp);
256244
ki = (0 - ki);
257245
kd = (0 - kd);
@@ -328,12 +316,6 @@ float QuickPID::analogReadAvg(int ADCpin) {
328316
return (float)sum / 16.0;
329317
}
330318

331-
int QuickPID::Saturate(int Out) {
332-
if (Out > outMax) Out = outMax;
333-
else if (Out < outMin) Out = outMin;
334-
return Out;
335-
}
336-
337319
void QuickPID::CheckPeak(int inputPin) {
338320
float rdAvg = analogReadAvg(inputPin);
339321
if (rdAvg > peakHigh) peakHigh = rdAvg;
@@ -359,65 +341,3 @@ void QuickPID::Stabilize(int inputPin, int outputPin, uint32_t timeout) {
359341
while ((analogReadAvg(inputPin) < atSetpoint) && (millis() <= timeout));
360342
analogWrite(outputPin, atOutput);
361343
}
362-
363-
#if defined(ESP32)
364-
// Adds support for analogWrite() for up to 9 PWM pins plus pins DAC1 and DAC2 which are 8-bit true analog outputs.
365-
// Also adds support for changing the PWM frequency (5000 Hz default) and timer resolution (13-bit default).
366-
367-
analog_write_channel_t _analog_write_channels[9] = { { 2, 5000, 13}, //LED_BUILTIN
368-
{ 4, 5000, 13}, { 13, 5000, 13}, { 14, 5000, 13}, { 16, 5000, 13}, { 17, 5000, 13}, { 27, 5000, 13}, { 32, 5000, 13}, { 33, 5000, 13}
369-
};
370-
371-
void analogWriteFrequency(float frequency) {
372-
for (uint8_t i = 0; i < 9; i++) {
373-
_analog_write_channels[i].frequency = frequency;
374-
if (frequency < 0.0001) {
375-
ledcDetachPin(_analog_write_channels[i].pin);
376-
pinMode(_analog_write_channels[i].pin, INPUT);
377-
}
378-
}
379-
}
380-
381-
void analogWriteFrequency(uint8_t pin, float frequency) {
382-
for (uint8_t i = 0; i < 9; i++) {
383-
if (_analog_write_channels[i].pin == pin) {
384-
_analog_write_channels[i].frequency = frequency;
385-
if (frequency < 0.0001) {
386-
ledcDetachPin(_analog_write_channels[i].pin);
387-
pinMode(_analog_write_channels[i].pin, INPUT);
388-
}
389-
}
390-
}
391-
}
392-
393-
void analogWriteResolution(uint8_t resolution) {
394-
for (uint8_t i = 0; i < 9; i++) {
395-
_analog_write_channels[i].resolution = resolution;
396-
}
397-
}
398-
399-
void analogWriteResolution(uint8_t pin, uint8_t resolution) {
400-
for (uint8_t i = 0; i < 9; i++) {
401-
if (_analog_write_channels[i].pin == pin) {
402-
_analog_write_channels[i].resolution = resolution;
403-
ledcSetup(i, _analog_write_channels[i].frequency, resolution);
404-
ledcAttachPin(_analog_write_channels[i].pin, i);
405-
}
406-
}
407-
}
408-
409-
void analogWrite(uint8_t pin, uint32_t value) {
410-
for (uint8_t i = 0; i < 9; i++) {
411-
if (_analog_write_channels[i].pin == pin) {
412-
uint8_t resolution = _analog_write_channels[i].resolution;
413-
uint32_t valueMax = (pow(2, resolution)) - 1;
414-
if (value > valueMax) value = valueMax;
415-
ledcWrite(i, value);
416-
}
417-
if (pin == DAC1 || pin == DAC2) {
418-
if (value > 255) value = 255;
419-
dacWrite(pin, value);
420-
}
421-
}
422-
}
423-
#endif

QuickPID.h

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ class QuickPID
66

77
public:
88

9-
//Constants used in some of the functions below
9+
//Constants and macros
1010
#define AUTOMATIC 1
1111
#define MANUAL 0
1212
#define DIRECT 0
1313
#define REVERSE 1
1414

1515
#define FL_FX(a) (int32_t)(a*256.0) // float to fixed point
1616
#define FX_MUL(a,b) ((a*b)>>8) // fixed point multiply
17+
#define CONSTRAIN(x,lower,upper) ((x)<(lower)?(lower):((x)>(upper)?(upper):(x)))
1718

1819
// commonly used functions ************************************************************************************
1920

@@ -68,7 +69,6 @@ class QuickPID
6869

6970
private:
7071
void Initialize();
71-
int Saturate(int);
7272
void CheckPeak(int);
7373
void StepUp(int, int, uint32_t);
7474
void StepDown(int, int, uint32_t);
@@ -110,19 +110,7 @@ class QuickPID
110110
};
111111

112112
#if defined(ESP32)
113-
// Adds support for analogWrite() for up to 9 PWM pins plus pins DAC1 and DAC2 which are 8-bit true analog outputs.
114-
// Also adds support for changing the PWM frequency (5000 Hz default) and timer resolution (13-bit default).
115-
116-
typedef struct analog_write_channel {
117-
int8_t pin;
118-
double frequency;
119-
uint8_t resolution;
120-
} analog_write_channel_t;
121-
122-
void analogWriteFrequency(float frequency = 5000);
123-
void analogWriteFrequency(uint8_t pin, float frequency = 5000);
124-
void analogWriteResolution(uint8_t resolution = 13);
125-
void analogWriteResolution(uint8_t pin, uint8_t resolution = 13);
126-
void analogWrite(uint8_t pin, uint32_t value = 0);
113+
#include "utility/analogWrite.h"
127114
#endif
115+
128116
#endif //QuickPID.h

README.md

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Development began with a fork of the Arduino PID Library. Modifications and new
1616
- `POn` parameter controls the setpoint weighting and mix of Proportional on Error to Proportional on Measurement
1717
- Reorganized and more efficient PID algorithm, faster analog read function, micros() timing resolution
1818
- Runs a complete PID cycle (*read-compute-write*) faster than just an `analogRead()` command in Arduino
19-
- Includes a complete`analogWrite()`function for ESP32 boards. This controls up to 9 independent PWM pins and 2 DAC pins.
19+
- Includes a complete [analogWrite function for ESP32](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite) boards. This controls up to 8 independent PWM pins and 2 DAC pins.
2020

2121
### Performance
2222

@@ -172,60 +172,18 @@ int QuickPID::analogReadFast(int ADCpin)
172172
173173
A faster configuration of `analogRead()`where a preset of 32 is used. If the architecture definition isn't found, normal `analogRead()`is used to return a value.
174174
175-
#### AnalogWrite (PWM and DAC) for ESP32
175+
#### [AnalogWrite (PWM and DAC) for ESP32](https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite)
176176
177-
```c++
178-
void analogWrite(uint8_t pin, uint32_t value)
179-
```
180-
181-
Call this function just like in the standard Arduino framework. It controls up to 9 independent PWM outputs and 2 DAC outputs. The controllable GPIO pins are 2, 4, 13, 14, 16, 17, 27, 32 and 33 for PWM and DAC0 (GPIO25) and DAC1 (GPIO26) for true analog outputs. The default PWM frequency is 5000 Hz and the default resolution is 13-bit (0-8191).
182-
183-
#### AnalogWrite Configuration Functions for ESP32
184-
185-
```c++
186-
void analogWriteFrequency(float frequency = 5000);
187-
void analogWriteFrequency(uint8_t pin, float frequency = 5000);
188-
void analogWriteResolution(uint8_t resolution = 13);
189-
void analogWriteResolution(uint8_t pin, uint8_t resolution = 13);
190-
```
191-
192-
Calling `analogWriteFrequency(frequency)`will set the PWM frequency for all 8 assigned pins. Using `analogWriteFrequency(0)`will detach the 9 assigned pins and set them as input.
193-
194-
To independently assign a unique frequency to each PWM pin, use the `analogWriteFrequency(pin, frequency)` function. If the frequency is set to 0, this function will detach the referenced pin and configure it as an input.
195-
196-
Calling `analogWriteResolution(resolution)` will set the resolution for all 9 assigned pins. Read more about the [Supported Range of Frequency and Duty Resolution](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ledc.html#ledc-api-supported-range-frequency-duty-resolution) here.
177+
#### Change Log
197178
198-
To independently assign a unique frequency to each PWM pin, use the `analogWriteResolution(pin, resolution)` function. Note that it is required to call this function once prior to using AnalogWrite as this will automatically setup and attach (initialize) the pin.
199-
200-
#### Fade Example for ESP32
201-
202-
```c++
203-
#include "QuickPID.h"
204-
205-
#define LED_BUILTIN 2
206-
int brightness = 0;
207-
int step = 1;
208-
209-
void setup() {
210-
analogWriteResolution(LED_BUILTIN, 10);
211-
}
212-
213-
void loop() {
214-
analogWrite(LED_BUILTIN, brightness);
215-
216-
brightness += step;
217-
if ( brightness >= 1023) step = -1;
218-
if ( brightness <= 0) step = 1;
219-
delay(1);
220-
}
221-
```
179+
#### [![arduino-library-badge](https://www.ardu-badge.com/badge/QuickPID.svg?)](https://www.ardu-badge.com/QuickPID)
222180
223-
### Change Log
181+
- Updated compatibility with the ESP32 Arduino framework
224182
225-
#### [![arduino-library-badge](https://www.ardu-badge.com/badge/QuickPID.svg?)](https://www.ardu-badge.com/QuickPID)
183+
#### Version 2.2.2
226184
227185
- Added compatibility with the ESP32 Arduino framework
228-
- Added full featured AnalogWrite methods for ESP32 to control up to 9 PWM and 2 DAC signals
186+
- Added full featured AnalogWrite methods for ESP32 and ESP32S2
229187
230188
#### Version 2.2.1
231189

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=QuickPID
2-
version=2.2.2
2+
version=2.2.3
33
author=David Lloyd
44
maintainer=David Lloyd <[email protected]>
55
sentence=A fast fixed/floating point PID controller with AutoTune and 9 tuning rules to choose from.

0 commit comments

Comments
 (0)