diff --git a/Firmware/Configuration.h b/Firmware/Configuration.h
index b363912ae..cdd0f8c2e 100644
--- a/Firmware/Configuration.h
+++ b/Firmware/Configuration.h
@@ -141,13 +141,11 @@
// Comment the following line to disable PID and enable bang-bang.
#define PIDTEMP
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
-#define PID_MAX BANG_MAX // limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
+#define PID_MAX BANG_MAX // limits current to nozzle while PID is active; 255=full current
#ifdef PIDTEMP
//#define PID_DEBUG // Sends debug data to the serial port.
//#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
- #define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
- // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
#define PID_INTEGRAL_DRIVE_MAX PID_MAX //limit for the integral term
#define K1 0.95 //smoothing factor within the PID
#define PID_dT ((OVERSAMPLENR * 10.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine
diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp
index 9dc0f3c18..81ba55103 100644
--- a/Firmware/Marlin_main.cpp
+++ b/Firmware/Marlin_main.cpp
@@ -1,21 +1,6 @@
/* -*- c++ -*- */
-
-/*
- Reprap firmware based on Sprinter and grbl.
- Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
+/**
+ * @file
*/
/*
@@ -6385,6 +6370,7 @@ void Stop()
disable_heater();
if(Stopped == false) {
Stopped = true;
+ lcd_print_stop();
Stopped_gcode_LastN = gcode_LastN; // Save last g_code for restart
SERIAL_ERROR_START;
SERIAL_ERRORLNRPGM(MSG_ERR_STOPPED);
diff --git a/Firmware/temperature.cpp b/Firmware/temperature.cpp
index 9e8fdd36d..7e509b64e 100644
--- a/Firmware/temperature.cpp
+++ b/Firmware/temperature.cpp
@@ -91,15 +91,15 @@ static volatile bool temp_meas_ready = false;
#ifdef PIDTEMP
//static cannot be external:
- static float temp_iState[EXTRUDERS] = { 0 };
- static float temp_dState[EXTRUDERS] = { 0 };
+ static float iState_sum[EXTRUDERS] = { 0 };
+ static float dState_last[EXTRUDERS] = { 0 };
static float pTerm[EXTRUDERS];
static float iTerm[EXTRUDERS];
static float dTerm[EXTRUDERS];
//int output;
static float pid_error[EXTRUDERS];
- static float temp_iState_min[EXTRUDERS];
- static float temp_iState_max[EXTRUDERS];
+ static float iState_sum_min[EXTRUDERS];
+ static float iState_sum_max[EXTRUDERS];
// static float pid_input[EXTRUDERS];
// static float pid_output[EXTRUDERS];
static bool pid_reset[EXTRUDERS];
@@ -396,7 +396,7 @@ void updatePID()
{
#ifdef PIDTEMP
for(int e = 0; e < EXTRUDERS; e++) {
- temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
+ iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
}
#endif
#ifdef PIDTEMPBED
@@ -482,6 +482,12 @@ void checkExtruderAutoFans()
#endif // any extruder auto fan pins set
+// ready for eventually parameters adjusting
+void resetPID(uint8_t) // only for compiler-warning elimination (if function do nothing)
+//void resetPID(uint8_t extruder)
+{
+}
+
void manage_heater()
{
float pid_input;
@@ -489,6 +495,7 @@ void manage_heater()
if(temp_meas_ready != true) //better readability
return;
+// more precisely - this condition partially stabilizes time interval for regulation values evaluation (@ ~ 230ms)
updateTemperaturesFromRawValues();
@@ -507,38 +514,42 @@ void manage_heater()
pid_input = current_temperature[e];
#ifndef PID_OPENLOOP
- pid_error[e] = target_temperature[e] - pid_input;
- if(pid_error[e] > PID_FUNCTIONAL_RANGE) {
- pid_output = BANG_MAX;
- pid_reset[e] = true;
- }
- else if(pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
+ if(target_temperature[e] == 0) {
pid_output = 0;
pid_reset[e] = true;
- }
- else {
- if(pid_reset[e] == true) {
- temp_iState[e] = 0.0;
+ } else {
+ pid_error[e] = target_temperature[e] - pid_input;
+ if(pid_reset[e]) {
+ iState_sum[e] = 0.0;
+ dTerm[e] = 0.0; // 'dState_last[e]' initial setting is not necessary (see end of if-statement)
pid_reset[e] = false;
}
+#ifndef PonM
pTerm[e] = Kp * pid_error[e];
- temp_iState[e] += pid_error[e];
- temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
- iTerm[e] = Ki * temp_iState[e];
-
- //K1 defined in Configuration.h in the PID settings
+ iState_sum[e] += pid_error[e];
+ iState_sum[e] = constrain(iState_sum[e], iState_sum_min[e], iState_sum_max[e]);
+ iTerm[e] = Ki * iState_sum[e];
+ // K1 defined in Configuration.h in the PID settings
#define K2 (1.0-K1)
- dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
- pid_output = pTerm[e] + iTerm[e] - dTerm[e];
+ dTerm[e] = (Kd * (pid_input - dState_last[e]))*K2 + (K1 * dTerm[e]); // e.g. digital filtration of derivative term changes
+ pid_output = pTerm[e] + iTerm[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
if (pid_output > PID_MAX) {
- if (pid_error[e] > 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
+ if (pid_error[e] > 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
pid_output=PID_MAX;
- } else if (pid_output < 0){
- if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
+ } else if (pid_output < 0) {
+ if (pid_error[e] < 0 ) iState_sum[e] -= pid_error[e]; // conditional un-integration
pid_output=0;
}
+#else // PonM ("Proportional on Measurement" method)
+ iState_sum[e] += Ki * pid_error[e];
+ iState_sum[e] -= Kp * (pid_input - dState_last[e]);
+ iState_sum[e] = constrain(iState_sum[e], 0, PID_INTEGRAL_DRIVE_MAX);
+ dTerm[e] = Kd * (pid_input - dState_last[e]);
+ pid_output = iState_sum[e] - dTerm[e]; // subtraction due to "Derivative on Measurement" method (i.e. derivative of input instead derivative of error is used)
+ pid_output = constrain(pid_output, 0, PID_MAX);
+#endif // PonM
}
- temp_dState[e] = pid_input;
+ dState_last[e] = pid_input;
#else
pid_output = constrain(target_temperature[e], 0, PID_MAX);
#endif //PID_OPENLOOP
@@ -555,7 +566,7 @@ void manage_heater()
SERIAL_ECHO(" iTerm ");
SERIAL_ECHO(iTerm[e]);
SERIAL_ECHO(" dTerm ");
- SERIAL_ECHOLN(dTerm[e]);
+ SERIAL_ECHOLN(-dTerm[e]);
#endif //PID_DEBUG
#else /* PID off */
pid_output = 0;
@@ -565,11 +576,12 @@ void manage_heater()
#endif
// Check if temperature is within the correct range
- if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e]))
+ if((current_temperature[e] < maxttemp[e]) && (target_temperature[e] != 0))
{
soft_pwm[e] = (int)pid_output >> 1;
}
- else {
+ else
+ {
soft_pwm[e] = 0;
}
@@ -693,6 +705,8 @@ void manage_heater()
WRITE(HEATER_BED_PIN,LOW);
}
#endif
+ if(target_temperature_bed==0)
+ soft_pwm_bed = 0;
#endif
//code for controlling the extruder rate based on the width sensor
@@ -891,8 +905,8 @@ void tp_init()
// populate with the first value
maxttemp[e] = maxttemp[0];
#ifdef PIDTEMP
- temp_iState_min[e] = 0.0;
- temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
+ iState_sum_min[e] = 0.0;
+ iState_sum_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
#endif //PIDTEMP
#ifdef PIDTEMPBED
temp_iState_min_bed = 0.0;
diff --git a/Firmware/temperature.h b/Firmware/temperature.h
index 5e80a0b39..d22269f35 100644
--- a/Firmware/temperature.h
+++ b/Firmware/temperature.h
@@ -76,6 +76,8 @@ extern float current_temperature_bed;
extern volatile int babystepsTodo[3];
#endif
+void resetPID(uint8_t extruder);
+
inline void babystepsTodoZadd(int n)
{
if (n != 0) {
@@ -126,8 +128,22 @@ FORCE_INLINE float degTargetBed() {
FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {
target_temperature[extruder] = celsius;
+ resetPID(extruder);
};
+static inline void setTargetHotendSafe(const float &celsius, uint8_t extruder)
+{
+ if (extruder