Arduino-PID-AutoTune-Library
Arduino-PID-AutoTune-Library copied to clipboard
Autotune should be a method for class PID
It seems desirable to me to have the entire PID object passed to the auto tune function rather than the individual variables. Probably not possible since I don't see a way to do this that would not break existing programs.
I can definitely see benefit to something like a hard-link between the PID and Autotune. at the same time, there's a little dance that happens between pid and autotune when the "autotune" button is pressed, and I don't think that dance will be the same in every application. having a them separate allows for some flexibility on that front.
maybe the solution is a LinkedAutotune class that inherits from the autotuner. it could get passed all the same constructors, along with a pointer to a pid object.
I'll probably code something up in a fork. It may not be for everybody, like you say.
Here is the class I'm using, which combine PID and PID_ATune. Set autoTune = true, and it will adapt the tuned parameters automatically when the tuning process is completed.
` #ifndef PID_enhanced_H #define PID_enhanced_H
#include <PID_v1.h> #include <PID_AutoTune_v0.h>
class PID_enhanced: public PID, public PID_ATune {
private:
byte currentMode = 2;
public:
double Input, Output, Setpoint = 0;
bool autoTune = false;
PID_enhanced(double Kp = 2, double Ki = 5, double Kd = 1,
int ControllerDirection = DIRECT,
int SampleTime = 100,
double OutputLimit_min = 0, double OutputLimit_max = 255,
int controlType = 0)
: PID(&this->Input, &this->Output, &this->Setpoint, Kp, Ki, Kd, ControllerDirection),
PID_ATune(&this->Input, &this->Output){
SetOutputLimits(OutputLimit_min, OutputLimit_max);
SetSampleTime(SampleTime);
SetControlType(controlType);
}
void setup() {
SetMode(AUTOMATIC);
backupMode();
Cancel();
}
int tune() {
int result = 0;
if (autoTune) {
result = PID_ATune::Runtime();
if (result !=0) {
adaptTunedParameters();
Cancel();
autoTune = false;
}
}
return result;
}
int tuneAndCompute() {
if (autoTune) {
return tune();
} else {
Compute();
return 0;
}
}
void backupMode() {
currentMode = GetMode();
}
void restoreMode() {
SetMode(currentMode);
}
double GetOperatingKp()
{
return PID::GetKp();
}
double GetOperatingKi()
{
return PID::GetKi();
}
double GetOperatingKd()
{
return PID::GetKd();
}
double GetTunedKp()
{
return PID_ATune::GetKp();
}
double GetTunedKi()
{
return PID_ATune::GetKi();
}
double GetTunedKd()
{
return PID_ATune::GetKd();
}
void adaptTunedParameters() {
SetTunings(GetTunedKp(), GetTunedKi(), GetTunedKd());
Serial.println("Parameters set to: ");
Serial.print("Kp: ");Serial.print(GetOperatingKp());Serial.print("; ");
Serial.print("Ki: ");Serial.print(GetOperatingKi());Serial.print("; ");
Serial.print("Kd: ");Serial.print(GetOperatingKd());Serial.print("; ");
Serial.println();
}
};
#endif
`
I tried using your code, Wei1234c, but it returns me this error:
Archiving built core (caching) in: C:\Users\EDUARD~1\AppData\Local\Temp\arduino_cache_379640\core\core_arduino_avr_uno_0c812875ac70eb4a9b385d8fb077f54c.a
C:\Users\EDUARD~1\AppData\Local\Temp\ccGD3Nq5.ltrans0.ltrans.o: In function `main':
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:43: undefined reference to `setup'
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:46: undefined reference to `loop'
collect2.exe: error: ld returned 1 exit status
exit status 1
Has anyone got it to work?
Thanks!