diff options
author | David Crocker <dcrocker@eschertech.com> | 2016-08-25 22:53:45 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2016-08-25 22:54:30 +0300 |
commit | a79a91721b25bed15760e2af1a28f2bae787ec74 (patch) | |
tree | 25b672b1ed62f014588f7b7e523e85a0bf20f818 /src | |
parent | 5b1cd82404cc4c69661ed92381dd43c9ac2fff8e (diff) |
Version 1.15b
Fixed problem that sometimes caused temperatures to creep up when using
legacy PID parameters
Diffstat (limited to 'src')
-rw-r--r-- | src/Configuration.h | 6 | ||||
-rw-r--r-- | src/Heating/Pid.cpp | 28 |
2 files changed, 21 insertions, 13 deletions
diff --git a/src/Configuration.h b/src/Configuration.h index c42aab13..dc96e120 100644 --- a/src/Configuration.h +++ b/src/Configuration.h @@ -26,11 +26,11 @@ Licence: GPL // Firmware name is now defined in the Pins file #ifndef VERSION -# define VERSION "1.15" +# define VERSION "1.15b" #endif #ifndef DATE -# define DATE "2016-08-23" +# define DATE "2016-08-25" #endif #define AUTHORS "reprappro, dc42, zpl, t3p3, dnewman" @@ -76,7 +76,7 @@ const float HEAT_SAMPLE_TIME = 0.5; // Seconds const float HEAT_PWM_AVERAGE_TIME = 5.0; // Seconds const float TEMPERATURE_CLOSE_ENOUGH = 2.5; // Celsius -const float MaxStableTemperatureError = 8.0; // How much error we tolerate when maintaining temperature before deciding that a heater fault has occurred +const float MaxStableTemperatureError = 10.0; // How much error we tolerate when maintaining temperature before deciding that a heater fault has occurred static_assert(MaxStableTemperatureError > TEMPERATURE_CLOSE_ENOUGH, "MaxStableTemperatureError is too low"); const float TEMPERATURE_LOW_SO_DONT_CARE = 40.0; // Celsius const float HOT_ENOUGH_TO_EXTRUDE = 160.0; // Celsius diff --git a/src/Heating/Pid.cpp b/src/Heating/Pid.cpp index 04296697..356a581f 100644 --- a/src/Heating/Pid.cpp +++ b/src/Heating/Pid.cpp @@ -176,15 +176,20 @@ void PID::Spin() } else { - // We have a good temperature reading. Calculate the derivative, if possible. + // We have an apparently-good temperature reading. Calculate the derivative, if possible. float derivative = 0.0; bool gotDerivative = false; badTemperatureCount = 0; if ((previousTemperaturesGood & (1 << (NumPreviousTemperatures - 1))) != 0) { - derivative = SecondsToMillis * (temperature - previousTemperatures[previousTemperatureIndex]) + const float tentativeDerivative = SecondsToMillis * (temperature - previousTemperatures[previousTemperatureIndex]) / (float)(platform->HeatSampleInterval() * NumPreviousTemperatures); - gotDerivative = true; + // Some sensors give occasional temperature spikes. We don't expect the temperature to increase by more than 10C/second. + if (fabs(tentativeDerivative) <= 10.0) + { + derivative = tentativeDerivative; + gotDerivative = true; + } } previousTemperatures[previousTemperatureIndex] = temperature; previousTemperaturesGood = (previousTemperaturesGood << 1) | 1; @@ -259,6 +264,7 @@ void PID::Spin() else { // We could check for temperature excessive or not falling here, but without an alarm or a power-off mechanism, there is not much we can do + // TODO emergency stop? } break; @@ -278,7 +284,7 @@ void PID::Spin() float maxPwm = (useModel) ? model.GetMaxPwm() : pp.kS; if (usingPid) { - // Using PID mode + // Using PID mode. Determine the PID parameters to use. float kP, recipTi, tD, gain; bool inSetPointMode; if (useModel) @@ -295,24 +301,26 @@ void PID::Spin() inSetPointMode = false; // use standard PID always kP = (pp.kP * pp.kS) * (1.0/255.0); recipTi = pp.kI/pp.kP; - tD = pp.kD/kP; + tD = pp.kD/pp.kP; gain = 255.0/pp.kT; } - // If the P term still has full authority, preset the I term to the expected PWM for this temperature - // and turn the heater full on or full off + // If the P and D terms together demand that the heater is full on or full off, disregard the I term const float errorMinusDterm = error - (tD * derivative); const float pPlusD = kP * errorMinusDterm; const float expectedPwm = constrain<float>((temperature - NormalAmbientTemperature)/gain, 0.0, maxPwm); if (pPlusD + expectedPwm > maxPwm) { lastPwm = maxPwm; - iAccumulator = expectedPwm; + // If we are heating up, preset the I term to the expected PWM at this temperature, ready for the switch over to PID + if (error > 0.0 && derivative > 0.0) + { + iAccumulator = expectedPwm; + } } else if (pPlusD + expectedPwm < 0.0) { lastPwm = 0.0; - // Don't set iAccumulator to expectedPwm here, it may slow down cooling or cause unexpected heating } else { @@ -592,7 +600,7 @@ void PID::DoTuningStep() break; case HeaterMode::tuning1: - if (millis() - tuningPhaseStartTime > (uint32_t)(model.GetDeadTime() * SecondsToMillis) + 20000 && (temperature - tuningStartTemp) < 4.0) + if (millis() - tuningPhaseStartTime > (uint32_t)(model.GetDeadTime() * SecondsToMillis) + 30000 && (temperature - tuningStartTemp) < 3.0) { platform->Message(GENERIC_MESSAGE, "Auto tune cancelled because temperature is not increasing\n"); break; |