generated from BrandonElectronic/ESP-COMPONENT-TEMPLATE
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add explanation of bang bang and PID
- Loading branch information
Showing
1 changed file
with
54 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,64 @@ | ||
# _Sample project_ | ||
In the `AutoPID` algorithm, the decision to use bang-bang control or PID control is based on the current error relative to the set bang-bang thresholds. | ||
|
||
(See the README.md file in the upper level 'examples' directory for more information about examples.) | ||
### Bang-Bang Control | ||
|
||
This is the simplest buildable example. The example is used by command `idf.py create-project` | ||
that copies the project to user specified path and set it's name. For more information follow the [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project) | ||
Bang-bang control is used when the error between the setpoint and the input is outside the defined bang-bang thresholds. Specifically: | ||
|
||
- **Bang-On Threshold**: If the error is greater than the `_bangOn` threshold, the output is set to `_outputMax`. | ||
- **Bang-Off Threshold**: If the error is greater than the `_bangOff` threshold, but in the opposite direction, the output is set to `_outputMin`. | ||
|
||
### PID Control | ||
|
||
## How to use example | ||
We encourage the users to use the example as a template for the new projects. | ||
A recommended way is to follow the instructions on a [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project). | ||
PID control is used when the error is within the bang-bang thresholds. This means that the system is close enough to the setpoint that finer control is required. In this case, the PID calculations are performed to adjust the output. | ||
|
||
## Example folder contents | ||
### Detailed Breakdown | ||
|
||
The project **sample_project** contains one source file in C language [main.c](main/main.c). The file is located in folder [main](main). | ||
1. **Bang-Bang On Control**: | ||
- If the difference between the setpoint and the input (`*_setpoint - *_input`) is greater than `_bangOn`, the output is set to `_outputMax`. | ||
|
||
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` | ||
files that provide set of directives and instructions describing the project's source files and targets | ||
(executable, library, or both). | ||
```cpp | ||
if (_bangOn && ((*_setpoint - *_input) > _bangOn)) { | ||
*_output = _outputMax; | ||
_lastStep = esp_timer_get_time() / 1000; | ||
} | ||
``` | ||
Below is short explanation of remaining files in the project folder. | ||
2. **Bang-Bang Off Control**: | ||
- If the difference between the input and the setpoint (`*_input - *_setpoint`) is greater than `_bangOff`, the output is set to `_outputMin`. | ||
``` | ||
├── CMakeLists.txt | ||
├── main | ||
│ ├── CMakeLists.txt | ||
│ └── main.c | ||
└── README.md This is the file you are currently reading | ||
``` | ||
Additionally, the sample project contains Makefile and component.mk files, used for the legacy Make based build system. | ||
They are not used or needed when building with CMake and idf.py. | ||
```cpp | ||
else if (_bangOff && ((*_input - *_setpoint) > _bangOff)) { | ||
*_output = _outputMin; | ||
_lastStep = esp_timer_get_time() / 1000; | ||
} | ||
``` | ||
|
||
3. **PID Control**: | ||
- If the error is within the bang-bang thresholds, PID control is used. The time step `_dT` is checked to see if enough time has passed since the last update. If so, PID calculations are performed: | ||
|
||
```cpp | ||
else { //otherwise use PID control | ||
unsigned long _dT = (esp_timer_get_time() / 1000) - _lastStep; //calculate time since last update | ||
if (_dT >= _timeStep) { //if long enough, do PID calculations | ||
_lastStep = esp_timer_get_time() / 1000; | ||
double _error = *_setpoint - *_input; | ||
_integral += (_error + _previousError) / 2 * _dT / 1000.0; //Riemann sum integral | ||
double _dError = (_error - _previousError) / _dT / 1000.0; //derivative | ||
_previousError = _error; | ||
double PID = (_Kp * _error) + (_Ki * _integral) + (_Kd * _dError); | ||
*_output = std::clamp(PID, _outputMin, _outputMax); | ||
} | ||
} | ||
``` | ||
### Summary | ||
- **Bang-Bang Control**: | ||
- Used when the error is outside the bang-bang thresholds (`_bangOn` or `_bangOff`). | ||
- Provides a simple on/off control by setting the output to `_outputMax` or `_outputMin`. | ||
- **PID Control**: | ||
- Used when the error is within the bang-bang thresholds. | ||
- Provides finer control by calculating the output using the PID algorithm. | ||
This hybrid approach allows the `AutoPID` algorithm to quickly react when the error is large (using bang-bang control) and finely adjust the output when the error is small (using PID control). |