Invariant get_pid_output with HOTENDS < 2

2.0.x
Scott Lahteine 9 years ago
parent 77283f5bf0
commit b72238f406

@ -514,88 +514,86 @@ void Temperature::min_temp_error(uint8_t e) {
} }
float Temperature::get_pid_output(int e) { float Temperature::get_pid_output(int e) {
#if HOTENDS == 1
UNUSED(e);
#define _HOTEND_TEST true
#define _HOTEND_EXTRUDER active_extruder
#else
#define _HOTEND_TEST e == active_extruder
#define _HOTEND_EXTRUDER e
#endif
float pid_output; float pid_output;
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
#if DISABLED(PID_OPENLOOP) #if DISABLED(PID_OPENLOOP)
pid_error[e] = target_temperature[e] - current_temperature[e]; pid_error[HOTEND_INDEX] = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX];
dTerm[e] = K2 * PID_PARAM(Kd, e) * (current_temperature[e] - temp_dState[e]) + K1 * dTerm[e]; dTerm[HOTEND_INDEX] = K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + K1 * dTerm[HOTEND_INDEX];
temp_dState[e] = current_temperature[e]; temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX];
if (pid_error[e] > PID_FUNCTIONAL_RANGE) { if (pid_error[HOTEND_INDEX] > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX; pid_output = BANG_MAX;
pid_reset[e] = true; pid_reset[HOTEND_INDEX] = true;
} }
else if (pid_error[e] < -(PID_FUNCTIONAL_RANGE) || target_temperature[e] == 0) { else if (pid_error[HOTEND_INDEX] < -(PID_FUNCTIONAL_RANGE) || target_temperature[HOTEND_INDEX] == 0) {
pid_output = 0; pid_output = 0;
pid_reset[e] = true; pid_reset[HOTEND_INDEX] = true;
} }
else { else {
if (pid_reset[e]) { if (pid_reset[HOTEND_INDEX]) {
temp_iState[e] = 0.0; temp_iState[HOTEND_INDEX] = 0.0;
pid_reset[e] = false; pid_reset[HOTEND_INDEX] = false;
} }
pTerm[e] = PID_PARAM(Kp, e) * pid_error[e]; pTerm[HOTEND_INDEX] = PID_PARAM(Kp, HOTEND_INDEX) * pid_error[HOTEND_INDEX];
temp_iState[e] += pid_error[e]; temp_iState[HOTEND_INDEX] += pid_error[HOTEND_INDEX];
temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); temp_iState[HOTEND_INDEX] = constrain(temp_iState[HOTEND_INDEX], temp_iState_min[HOTEND_INDEX], temp_iState_max[HOTEND_INDEX]);
iTerm[e] = PID_PARAM(Ki, e) * temp_iState[e]; iTerm[HOTEND_INDEX] = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX];
pid_output = pTerm[e] + iTerm[e] - dTerm[e]; pid_output = pTerm[HOTEND_INDEX] + iTerm[HOTEND_INDEX] - dTerm[HOTEND_INDEX];
#if ENABLED(SINGLENOZZLE)
#define _NOZZLE_TEST true
#define _NOZZLE_EXTRUDER active_extruder
#define _CTERM_INDEX 0
#else
#define _NOZZLE_TEST e == active_extruder
#define _NOZZLE_EXTRUDER e
#define _CTERM_INDEX e
#endif
#if ENABLED(PID_ADD_EXTRUSION_RATE) #if ENABLED(PID_ADD_EXTRUSION_RATE)
cTerm[_CTERM_INDEX] = 0; cTerm[HOTEND_INDEX] = 0;
if (_NOZZLE_TEST) { if (_HOTEND_TEST) {
long e_position = stepper.position(E_AXIS); long e_position = stepper.position(E_AXIS);
if (e_position > last_position[_NOZZLE_EXTRUDER]) { if (e_position > last_position[_HOTEND_EXTRUDER]) {
lpq[lpq_ptr++] = e_position - last_position[_NOZZLE_EXTRUDER]; lpq[lpq_ptr++] = e_position - last_position[_HOTEND_EXTRUDER];
last_position[_NOZZLE_EXTRUDER] = e_position; last_position[_HOTEND_EXTRUDER] = e_position;
} }
else { else {
lpq[lpq_ptr++] = 0; lpq[lpq_ptr++] = 0;
} }
if (lpq_ptr >= lpq_len) lpq_ptr = 0; if (lpq_ptr >= lpq_len) lpq_ptr = 0;
cTerm[_CTERM_INDEX] = (lpq[lpq_ptr] / planner.axis_steps_per_mm[E_AXIS]) * PID_PARAM(Kc, e); cTerm[HOTEND_INDEX] = (lpq[lpq_ptr] / planner.axis_steps_per_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX);
pid_output += cTerm[e]; pid_output += cTerm[HOTEND_INDEX];
} }
#endif //PID_ADD_EXTRUSION_RATE #endif //PID_ADD_EXTRUSION_RATE
if (pid_output > PID_MAX) { if (pid_output > PID_MAX) {
if (pid_error[e] > 0) temp_iState[e] -= pid_error[e]; // conditional un-integration if (pid_error[HOTEND_INDEX] > 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration
pid_output = PID_MAX; pid_output = PID_MAX;
} }
else if (pid_output < 0) { else if (pid_output < 0) {
if (pid_error[e] < 0) temp_iState[e] -= pid_error[e]; // conditional un-integration if (pid_error[HOTEND_INDEX] < 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration
pid_output = 0; pid_output = 0;
} }
} }
#else #else
pid_output = constrain(target_temperature[e], 0, PID_MAX); pid_output = constrain(target_temperature[HOTEND_INDEX], 0, PID_MAX);
#endif //PID_OPENLOOP #endif //PID_OPENLOOP
#if ENABLED(PID_DEBUG) #if ENABLED(PID_DEBUG)
SERIAL_ECHO_START; SERIAL_ECHO_START;
SERIAL_ECHOPAIR(MSG_PID_DEBUG, e); SERIAL_ECHOPAIR(MSG_PID_DEBUG, HOTEND_INDEX);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[e]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[HOTEND_INDEX]);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output); SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[e]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[HOTEND_INDEX]);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[e]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[HOTEND_INDEX]);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[e]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[HOTEND_INDEX]);
#if ENABLED(PID_ADD_EXTRUSION_RATE) #if ENABLED(PID_ADD_EXTRUSION_RATE)
SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[e]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[HOTEND_INDEX]);
#endif #endif
SERIAL_EOL; SERIAL_EOL;
#endif //PID_DEBUG #endif //PID_DEBUG
#else /* PID off */ #else /* PID off */
pid_output = (current_temperature[e] < target_temperature[e]) ? PID_MAX : 0; pid_output = (current_temperature[HOTEND_INDEX] < target_temperature[HOTEND_INDEX]) ? PID_MAX : 0;
#endif #endif
return pid_output; return pid_output;
@ -672,7 +670,7 @@ void Temperature::manage_heater() {
#endif #endif
// Loop through all hotends // Loop through all hotends
for (int e = 0; e < HOTENDS; e++) { for (uint8_t e = 0; e < HOTENDS; e++) {
#if ENABLED(THERMAL_PROTECTION_HOTENDS) #if ENABLED(THERMAL_PROTECTION_HOTENDS)
thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS); thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_PROTECTION_PERIOD, THERMAL_PROTECTION_HYSTERESIS);

@ -38,6 +38,16 @@
#define SOFT_PWM_SCALE 0 #define SOFT_PWM_SCALE 0
#endif #endif
#if HOTENDS == 1
#define HOTEND_ARG 0
#define HOTEND_INDEX 0
#define EXTRUDER_ARG 0
#else
#define HOTEND_ARG hotend
#define HOTEND_INDEX e
#define EXTRUDER_ARG active_extruder
#endif
class Temperature { class Temperature {
public: public:
@ -112,7 +122,12 @@ class Temperature {
#if ENABLED(PREVENT_DANGEROUS_EXTRUDE) #if ENABLED(PREVENT_DANGEROUS_EXTRUDE)
static float extrude_min_temp; static float extrude_min_temp;
static bool tooColdToExtrude(uint8_t e) { return degHotend(e) < extrude_min_temp; } static bool tooColdToExtrude(uint8_t e) {
#if HOTENDS == 1
UNUSED(e);
#endif
return degHotend(HOTEND_INDEX) < extrude_min_temp;
}
#else #else
static bool tooColdToExtrude(uint8_t e) { UNUSED(e); return false; } static bool tooColdToExtrude(uint8_t e) { UNUSED(e); return false; }
#endif #endif
@ -230,12 +245,6 @@ class Temperature {
//inline so that there is no performance decrease. //inline so that there is no performance decrease.
//deg=degreeCelsius //deg=degreeCelsius
#if HOTENDS == 1
#define HOTEND_ARG 0
#else
#define HOTEND_ARG hotend
#endif
static float degHotend(uint8_t hotend) { static float degHotend(uint8_t hotend) {
#if HOTENDS == 1 #if HOTENDS == 1
UNUSED(hotend); UNUSED(hotend);
@ -329,8 +338,8 @@ class Temperature {
#if ENABLED(AUTOTEMP) #if ENABLED(AUTOTEMP)
if (planner.autotemp_enabled) { if (planner.autotemp_enabled) {
planner.autotemp_enabled = false; planner.autotemp_enabled = false;
if (degTargetHotend(active_extruder) > planner.autotemp_min) if (degTargetHotend(EXTRUDER_ARG) > planner.autotemp_min)
setTargetHotend(0, active_extruder); setTargetHotend(0, EXTRUDER_ARG);
} }
#endif #endif
} }

Loading…
Cancel
Save