diff --git a/README.md b/README.md index 12dc447..0242db8 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Accurate determination of the inflection point was given high priority for this #### S-shaped Step Response -![Reaction Curve](https://user-images.githubusercontent.com/63488701/151797252-63b6c4d1-2781-459a-81f8-22f931a4a96b.png) +![Reaction Curve](https://user-images.githubusercontent.com/63488701/151890696-d574d77b-b849-4079-81e2-71e4ee416fa3.png) #### Configuration diff --git a/examples/MAX31856_PTC_SSR/Get_All_Tunings/Get_All_Tunings.ino b/examples/MAX31856_PTC_SSR/Get_All_Tunings/Get_All_Tunings.ino index 3e1842c..f744656 100644 --- a/examples/MAX31856_PTC_SSR/Get_All_Tunings/Get_All_Tunings.ino +++ b/examples/MAX31856_PTC_SSR/Get_All_Tunings/Get_All_Tunings.ino @@ -1,6 +1,7 @@ -/*************************************************************** +/***************************************************************************** sTune Get All Tunings Example (MAX31856, PTC Heater and SSR) - ***************************************************************/ + Reference: https://github.com/Dlloydev/sTune/wiki/Examples_MAX31856_PTC_SSR + ****************************************************************************/ #include #include diff --git a/examples/MAX31856_PTC_SSR/sTune_PID_v1/sTune_PID_v1.ino b/examples/MAX31856_PTC_SSR/sTune_PID_v1/sTune_PID_v1.ino index 2b7bd36..6fbdb9f 100644 --- a/examples/MAX31856_PTC_SSR/sTune_PID_v1/sTune_PID_v1.ino +++ b/examples/MAX31856_PTC_SSR/sTune_PID_v1/sTune_PID_v1.ino @@ -1,10 +1,11 @@ -/*************************************************************** +/**************************************************************************** sTune PID_v1 Example This sketch does on-the-fly tunning and PID SSR control of a PTC heater. Tunning parameters are quickly determined and applied during the temperature ramp-up to setpoint. Open the serial plotter to view the graphical results. - ***************************************************************/ + Reference: https://github.com/Dlloydev/sTune/wiki/Examples_MAX31856_PTC_SSR + ****************************************************************************/ #include #include @@ -32,7 +33,7 @@ float Input, Output, Setpoint = 50, Kp, Ki, Kd; // sTune Adafruit_MAX31856 maxthermo = Adafruit_MAX31856(10); //SPI sTune tuner = sTune(&Input, &Output, tuner.ZN_PID, tuner.directIP, tuner.printOFF); -PID myPID(&input, &output, &setpoint, 0, 0, 0, P_ON_M, DIRECT); +PID myPID(&input, &output, &setpoint, kp, ki, kd, P_ON_M, DIRECT); void setup() { pinMode(drdyPin, INPUT); @@ -64,15 +65,18 @@ void loop() { myPID.SetOutputLimits(0, outputSpan * 0.1); myPID.SetSampleTime(outputSpan * 0.4); debounce = 0; // switch to SSR optimum cycle mode - output = outputStep, kp = Kp, ki = Ki, kd = Kd; + setpoint = Setpoint, output = outputStep, kp = Kp, ki = Ki, kd = Kd; myPID.SetMode(AUTOMATIC); // the PID is turned on + output = outputStep; + Output = output; myPID.SetTunings(kp, ki, kd); // update PID with the new tunings break; case tuner.runPid: // active once per sample after tunings - if (!digitalRead(drdyPin)) input = maxthermo.readThermocoupleTemperature(); + if (!digitalRead(drdyPin)) Input = maxthermo.readThermocoupleTemperature(); + input = Input; myPID.Compute(); - Input = input, Output = output; + Output = output; tuner.plotter(Input, optimumOutput, Setpoint, 1, 3); break; } diff --git a/examples/MAX31856_PTC_SSR/sTune_QuickPID/sTune_QuickPID.ino b/examples/MAX31856_PTC_SSR/sTune_QuickPID/sTune_QuickPID.ino index d47825e..3c61e4a 100644 --- a/examples/MAX31856_PTC_SSR/sTune_QuickPID/sTune_QuickPID.ino +++ b/examples/MAX31856_PTC_SSR/sTune_QuickPID/sTune_QuickPID.ino @@ -1,10 +1,11 @@ -/************************************************************** +/*************************************************************************** sTune QuickPID Example This sketch does on-the-fly tunning and PID SSR control of a PTC heater. Tunning parameters are quickly determined and applied during the temperature ramp-up to setpoint. Open the serial plotter to view the graphical results. - *************************************************************/ + Reference: https://github.com/Dlloydev/sTune/wiki/Examples_MAX31856_PTC_SSR + ***************************************************************************/ #include #include diff --git a/examples/MAX6675_PTC_SSR/Get_All_Tunings/Get_All_Tunings.ino b/examples/MAX6675_PTC_SSR/Get_All_Tunings/Get_All_Tunings.ino new file mode 100644 index 0000000..8084961 --- /dev/null +++ b/examples/MAX6675_PTC_SSR/Get_All_Tunings/Get_All_Tunings.ino @@ -0,0 +1,74 @@ +/*************************************************************************** + sTune Get All Tunings Example (MAX6675, PTC Heater and SSR) + Reference: https://github.com/Dlloydev/sTune/wiki/Examples_MAX6675_PTC_SSR + ***************************************************************************/ + +#include +#include + +// pins +const uint8_t inputPin = 0; +const uint8_t relayPin = 3; +const uint8_t drdyPin = 5; +const uint8_t SO = 12; +const uint8_t CS = 10; +const uint8_t sck = 13; + +// user settings +uint32_t settleTimeSec = 10; +uint32_t testTimeSec = 500; +const uint16_t samples = 500; +const float inputSpan = 220; +const float outputSpan = 1000; +float outputStart = 0; +float outputStep = 50; +float tempLimit = 100; + +// variables +float Input, Output; + +MAX6675 module(sck, CS, SO); //SPI +sTune tuner = sTune(&Input, &Output, tuner.ZN_PID, tuner.directIP, tuner.printALL); + +void setup() { + pinMode(drdyPin, INPUT); + pinMode(relayPin, OUTPUT); + Serial.begin(115200); + while (!Serial) delay(10); + delay(3000); + Output = 0; + tuner.Configure(inputSpan, outputSpan, outputStart, outputStep, testTimeSec, settleTimeSec, samples); + tuner.SetEmergencyStop(tempLimit); +} + +void loop() { + tuner.softPwm(relayPin, Input, Output, 0, outputSpan, 1); + + switch (tuner.Run()) { + case tuner.sample: // active once per sample during test + Input = module.readCelsius(); + break; + + case tuner.tunings: // active just once when sTune is done + Output = 0; + tuner.SetTuningMethod(tuner.TuningMethod::DampedOsc_PID); + tuner.printTunings(); + tuner.SetTuningMethod(tuner.TuningMethod::NoOvershoot_PID); + tuner.printTunings(); + tuner.SetTuningMethod(tuner.TuningMethod::CohenCoon_PID); + tuner.printTunings(); + tuner.SetTuningMethod(tuner.TuningMethod::Mixed_PID); + tuner.printTunings(); + tuner.SetTuningMethod(tuner.TuningMethod::ZN_PI); + tuner.printTunings(); + tuner.SetTuningMethod(tuner.TuningMethod::DampedOsc_PI); + tuner.printTunings(); + tuner.SetTuningMethod(tuner.TuningMethod::NoOvershoot_PI); + tuner.printTunings(); + tuner.SetTuningMethod(tuner.TuningMethod::CohenCoon_PI); + tuner.printTunings(); + tuner.SetTuningMethod(tuner.TuningMethod::Mixed_PI); + tuner.printTunings(); + break; + } +} diff --git a/examples/MAX6675_PTC_SSR/README.txt b/examples/MAX6675_PTC_SSR/README.txt deleted file mode 100644 index dd196f1..0000000 --- a/examples/MAX6675_PTC_SSR/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -1/31/2022 -Awaiting delivery of a MAX6675 module. Should have example files created, tested and published within the next week or so. \ No newline at end of file diff --git a/examples/MAX6675_PTC_SSR/sTune_PID_v1/sTune_PID_v1.ino b/examples/MAX6675_PTC_SSR/sTune_PID_v1/sTune_PID_v1.ino new file mode 100644 index 0000000..3b29c74 --- /dev/null +++ b/examples/MAX6675_PTC_SSR/sTune_PID_v1/sTune_PID_v1.ino @@ -0,0 +1,80 @@ +/*************************************************************************** + sTune PID_v1 Example + This sketch does on-the-fly tunning and PID SSR control of a + PTC heater. Tunning parameters are quickly determined and + applied during the temperature ramp-up to setpoint. Open + Reference: https://github.com/Dlloydev/sTune/wiki/Examples_MAX6675_PTC_SSR + ***************************************************************************/ + +#include +#include +#include + +// pins +const uint8_t inputPin = 0; +const uint8_t relayPin = 3; +const uint8_t drdyPin = 5; +const uint8_t SO = 12; +const uint8_t CS = 10; +const uint8_t sck = 13; + +// user settings +uint32_t settleTimeSec = 10; +uint32_t testTimeSec = 500; +const uint16_t samples = 500; +const float inputSpan = 200; +const float outputSpan = 1000; +float outputStart = 0; +float outputStep = 30; +float tempLimit = 75; +uint8_t debounce = 1; + +// variables +double input, output, setpoint = 50, kp, ki, kd; // PID_v1 +float Input, Output, Setpoint = 50, Kp, Ki, Kd; // sTune + +MAX6675 module(sck, CS, SO); //SPI +sTune tuner = sTune(&Input, &Output, tuner.ZN_PID, tuner.directIP, tuner.printOFF); +PID myPID(&input, &output, &setpoint, kp, ki, kd, P_ON_M, DIRECT); + +void setup() { + pinMode(drdyPin, INPUT); + pinMode(relayPin, OUTPUT); + Serial.begin(115200); + while (!Serial) delay(10); + delay(3000); + Output = 0; + tuner.Configure(inputSpan, outputSpan, outputStart, outputStep, testTimeSec, settleTimeSec, samples); + tuner.SetEmergencyStop(tempLimit); +} + +void loop() { + float optimumOutput = tuner.softPwm(relayPin, Input, Output, Setpoint, outputSpan, debounce); + + switch (tuner.Run()) { + case tuner.sample: // active once per sample during test + Input = module.readCelsius(); + tuner.plotter(Input, Output, Setpoint, 1, 3); + break; + + case tuner.tunings: // active just once when sTune is done + tuner.GetAutoTunings(&Kp, &Ki, &Kd); // sketch variables updated by sTune + myPID.SetOutputLimits(0, outputSpan * 0.1); + myPID.SetSampleTime(outputSpan * 0.2); + debounce = 0; // switch to SSR optimum cycle mode + setpoint = Setpoint, output = outputStep, kp = Kp, ki = Ki, kd = Kd; + myPID.SetMode(AUTOMATIC); // the PID is turned on + output = outputStep; + Output = output; + myPID.SetTunings(kp, ki, kd); // update PID with the new tunings + break; + + case tuner.runPid: // active once per sample after tunings + Input = module.readCelsius(); + input = Input; + myPID.Compute(); + Output = output; + tuner.plotter(Input, optimumOutput, Setpoint, 1, 3); + break; + } +} diff --git a/examples/MAX6675_PTC_SSR/sTune_QuickPID/sTune_QuickPID.ino b/examples/MAX6675_PTC_SSR/sTune_QuickPID/sTune_QuickPID.ino new file mode 100644 index 0000000..18ade1c --- /dev/null +++ b/examples/MAX6675_PTC_SSR/sTune_QuickPID/sTune_QuickPID.ino @@ -0,0 +1,77 @@ +/*************************************************************************** + sTune QuickPID Example + This sketch does on-the-fly tunning and PID SSR control of a + PTC heater. Tunning parameters are quickly determined and + applied during the temperature ramp-up to setpoint. Open + the serial plotter to view the graphical results. + Reference: https://github.com/Dlloydev/sTune/wiki/Examples_MAX6675_PTC_SSR + ***************************************************************************/ + +#include +#include +#include + +// pins +const uint8_t inputPin = 0; +const uint8_t relayPin = 3; +const uint8_t drdyPin = 5; +const uint8_t SO = 12; +const uint8_t CS = 10; +const uint8_t sck = 13; + +// user settings +uint32_t settleTimeSec = 10; +uint32_t testTimeSec = 500; +const uint16_t samples = 500; +const float inputSpan = 200; +const float outputSpan = 1000; +float outputStart = 0; +float outputStep = 30; +float tempLimit = 75; +uint8_t debounce = 1; + +// variables +float Input, Output, Setpoint = 50, Kp, Ki, Kd; + +MAX6675 module(sck, CS, SO); //SPI +sTune tuner = sTune(&Input, &Output, tuner.ZN_PID, tuner.directIP, tuner.printOFF); +QuickPID myPID(&Input, &Output, &Setpoint); + +void setup() { + pinMode(drdyPin, INPUT); + pinMode(relayPin, OUTPUT); + Serial.begin(115200); + while (!Serial) delay(10); + delay(3000); + Output = 0; + tuner.Configure(inputSpan, outputSpan, outputStart, outputStep, testTimeSec, settleTimeSec, samples); + tuner.SetEmergencyStop(tempLimit); +} + +void loop() { + float optimumOutput = tuner.softPwm(relayPin, Input, Output, Setpoint, outputSpan, debounce); + + switch (tuner.Run()) { + case tuner.sample: // active once per sample during test + Input = module.readCelsius(); + tuner.plotter(Input, Output, Setpoint, 1, 3); + break; + + case tuner.tunings: // active just once when sTune is done + tuner.GetAutoTunings(&Kp, &Ki, &Kd); // sketch variables updated by sTune + myPID.SetOutputLimits(0, outputSpan * 0.1); + myPID.SetSampleTimeUs(outputSpan * 1000 * 0.2); + debounce = 0; // switch to SSR optimum cycle mode + myPID.SetMode(myPID.Control::automatic); // the PID is turned on + myPID.SetProportionalMode(myPID.pMode::pOnMeas); + myPID.SetAntiWindupMode(myPID.iAwMode::iAwClamp); + myPID.SetTunings(Kp, Ki, Kd); // update PID with the new tunings + break; + + case tuner.runPid: // active once per sample after tunings + Input = module.readCelsius(); + myPID.Compute(); + tuner.plotter(Input, optimumOutput, Setpoint, 1, 3); + break; + } +} diff --git a/library.json b/library.json index d036424..0058983 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "sTune", - "version": "2.3.0", + "version": "2.3.1", "description": "Open loop PID autotuner using a novel s-curve inflection point test method. Tuning parameters are determined in about ½Tau on a first-order system with time delay. Full 5Tau testing and multiple serial output options are provided.", "keywords": "PID, autotune, autotuner, tuner, tune, stune, inflection, step", "repository": diff --git a/library.properties b/library.properties index d808b0d..8dfa626 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=sTune -version=2.3.0 +version=2.3.1 author=David Lloyd maintainer=David Lloyd sentence=Open loop PID autotuner using a novel s-curve inflection point test method. diff --git a/src/sTune.cpp b/src/sTune.cpp index 24c6fdb..37e525d 100644 --- a/src/sTune.cpp +++ b/src/sTune.cpp @@ -1,5 +1,5 @@ /**************************************************************************************** - sTune Library for Arduino - Version 2.3.0 + sTune Library for Arduino - Version 2.3.1 by dlloydev https://github.com/Dlloydev/sTune Licensed under the MIT License.