Thanks to visit codestin.com
Credit goes to github.com

Skip to content

How to set the parameters of "sTune" correctly #43

@m-etc

Description

@m-etc

I am making a 3D printing filament drying box, using ESP32, Arduino programming, PTC heating plate for heating, and SSR to control the heating plate. I hope that this box can have the function of PID automatic tuning, so that the temperature inside the box can quickly reach the set target temperature, and the actual temperature will not exceed the set target temperature. I tried to use the <PID_AutoTune_v0.h> library before, but it didn't work. Later, I used <sTune.h>, but it still didn't work. I don't know the parameters in the <sTune.h> library. Can you explain their practical application?

settleTimeSec:is used to provide additional settling time prior to starting the test.
I don't quite understand what is considered "stable"? Does it mean that the temperature remains at a certain value and no longer rises or falls?
Is there any connection between stable temperature and "Setpoint"? "Setpoint=50", so what degree Celsius should the stable temperature be?
I set "outputStart = 150, outputSpan = 1000", but in fact, the temperature is still rising, about 0.01-0.02 per second.

inputSpan
If the target temperature is 60 °C, what should the "inputSpan" be? Or is there no relationship between "inputSpan" and "Setpoint"? Then, how to determine the value of "inputSpan"?

testTimeSec、samples
How should these two parameters be set? For example, if I control the SSR with 10% output, observe the temperature rise inside the box, then shut off the SSR output, and observe the temperature drop inside the box, can I calculate these two values?

outputStep
How should this value be set? Because the drying box has a very good insulation effect, the heating and cooling process is very slow, and the temperature overshoot is also very large, so should "outputStep" be set to a larger value of 50% ("outputSpan")? Or a smaller value of 10% ("outputSpan").


#include <Arduino.h>
#include <sTune.h>
#include <Wire.h>
#include <AHT20.h>
#include <PID_v1.h>

AHT20 aht20;

#define SSR_PIN 2 // SSR

// user settings
uint32_t settleTimeSec = 600;

uint32_t testTimeSec = 1800;

const uint16_t samples = 1800;

const float inputSpan = 45;

const float outputSpan = 1000;

float outputStart = 150;

float outputStep = 250;

float tempLimit = 85;

uint8_t debounce = 0;

// PID_v1
double input, output, setpoint = 50, kp, ki, kd;

// sTune
float Input, Output, Setpoint = 50, Kp, Ki, Kd;

sTune tuner = sTune(&Input, &Output, tuner.ZN_PID, tuner.directIP, tuner.printOFF);
/* ZN_PID directIP serialOFF
DampedOsc_PID direct5T printALL
NoOvershoot_PID reverseIP printSUMMARY
CohenCoon_PID reverse5T printDEBUG
Mixed_PID
ZN_PI
DampedOsc_PI
NoOvershoot_PI
CohenCoon_PI
Mixed_PI
*/
PID myPID(&input, &output, &setpoint, 0, 0, 0, P_ON_M, DIRECT);

//test
float outputStartTest = 20;
float tempPrev = 0;
unsigned long tPrev = 0;
unsigned long tStart = 0;
bool done = false;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
pinMode(SSR_PIN, OUTPUT);
digitalWrite(SSR_PIN, LOW);

Serial.begin(115200);
while (!Serial) delay(10);
delay(3000);

Wire.begin(21, 22);

tuner.Configure(inputSpan, outputSpan, outputStart, outputStep, testTimeSec, settleTimeSec, samples);
tuner.SetEmergencyStop(tempLimit);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {
//软件 PWM 控制
tuner.softPwm(SSR_PIN, // SSR 固态继电器 控制引脚
Input, // 当前温度
Output, // PID 输出
Setpoint, // 目标温度
outputSpan, // 窗口周期(毫秒),默认为1000毫秒(1秒)。如果是PWM输出,可设置为255.
debounce); // 去抖动设置(毫秒),使用固态继电器 (SSR) 时=0

switch (tuner.Run()) {
case tuner.sample:
Input = aht20.getTemperature();
Serial.print("1:");
tuner.plotter(Input, Output, Setpoint, 0.1f, 3); // output scale 0.1, plot every 3rd sample
break;

case tuner.tunings: 
  tuner.GetAutoTunings(&Kp, &Ki, &Kd); // sketch variables updated by sTune
  myPID.SetOutputLimits(0, outputSpan);
  myPID.SetSampleTime(outputSpan - 1);
  output = outputStep, kp = Kp, ki = Ki, kd = Kd;
  myPID.SetMode(AUTOMATIC); // the PID is turned on
  myPID.SetTunings(kp, ki, kd); // update PID with the new tunings
  Serial.println("PID 校准完成:");
  Serial.print("Kp: "); Serial.println(kp);
  Serial.print("Ki: "); Serial.println(ki);
  Serial.print("Kd: "); Serial.println(kd);
  break;

case tuner.runPid: 
  input = aht20.getTemperature();    
  myPID.Compute();
  Input = input, Output = output;
  Serial.print("2:");
  tuner.plotter(Input, Output, Setpoint, 0.1f, 3);
  break;

}

///////////////////////////////////////////////////////////////////// test settleTimeSec /////////////////////////////////////////////
static unsigned long autotuneStartTime = millis();
static unsigned long lastPrint = 0;
if (millis() - lastPrint > 10 * 1000)
{
lastPrint = millis();

if (done)
  return;

static float slopePrev = 0;

float tempNow = aht20.getTemperature();
unsigned long tNow = millis();

float dt = (tNow - tPrev) / 1000.0; 
float dT = tempNow - tempPrev;
float slope = ((dT / dt) + slopePrev) / 2;
slopePrev = slope; 

Serial.print("Run time: ");
Serial.print((tNow - tStart) / 1000);
Serial.print("s, Current Temperature: ");
Serial.print(tempNow);
Serial.print("°C, 升Heating rate: ");
Serial.print(slope, 4);
Serial.println(" °C/s");

}


Information printed by the serial port:

1:1:1:Setpoint:50.00, Input:29.53, Output:15.00,
1:1:Run time: 10s, Current Temperature: 29.53°C, Heating rate: 1.4643 °C/s

.....中间省略.....

1:Run time: 600s, Current Temperature: 39.19°C, Heating rate:0.0132 °C/s
1:1:Setpoint:50.00, Input:39.21, Output:15.00,
1:1:1:Setpoint:50.00, Input:39.25, Output:25.00,
1:1:1:Setpoint:50.00, Input:39.27, Output:25.00,

.....中间省略.....

1:Setpoint:50.00, Input:52.60, Output:25.00,
1:1:1:Setpoint:50.00, Input:52.64, Output:25.00,
1:1:1:Setpoint:50.00, Input:52.74, Output:25.00,
1:1:1:Setpoint:50.00, Input:52.82, Output:25.00,
Run time: 1040s, Current Temperature: 52.86°C, Heating rate:0.0326 °C/s
1:1:1:Setpoint:50.00, Input:52.95, Output:25.00,
1:1:PID 校准完成:
Kp: 24.60
Ki: 0.08
Kd: 0.33

The above is the information printed by the serial port after the code is run. From the information, we can see that "settleTimeSec = 600", "outputStart = 150", 600 seconds, the output is 25% for preheating, which seems to be normal, but afterwards, PID self-tuning is performed, the value of "Output" has always been "25.00" and has not changed. Even if the "Input" has exceeded the "Setpoint", the value of "Output" is still "25.00". I think this is wrong. In fact, the PID value obtained cannot keep the temperature at the Setpoint.
*****************************************************************************************************************************************``

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions