Merge pull request #3565 from thinkyhead/rc_look_at_3563
Output error message for M303 if PIDTEMP is disabled
This commit is contained in:
commit
dd94ce5bd5
4 changed files with 172 additions and 160 deletions
|
@ -5559,20 +5559,25 @@ inline void gcode_M226() {
|
||||||
* U<bool> with a non-zero value will apply the result to current settings
|
* U<bool> with a non-zero value will apply the result to current settings
|
||||||
*/
|
*/
|
||||||
inline void gcode_M303() {
|
inline void gcode_M303() {
|
||||||
int e = code_seen('E') ? code_value_short() : 0;
|
#if ENABLED(PIDTEMP)
|
||||||
int c = code_seen('C') ? code_value_short() : 5;
|
int e = code_seen('E') ? code_value_short() : 0;
|
||||||
bool u = code_seen('U') && code_value_short() != 0;
|
int c = code_seen('C') ? code_value_short() : 5;
|
||||||
|
bool u = code_seen('U') && code_value_short() != 0;
|
||||||
|
|
||||||
float temp = code_seen('S') ? code_value() : (e < 0 ? 70.0 : 150.0);
|
float temp = code_seen('S') ? code_value() : (e < 0 ? 70.0 : 150.0);
|
||||||
|
|
||||||
if (e >= 0 && e < EXTRUDERS)
|
if (e >= 0 && e < EXTRUDERS)
|
||||||
target_extruder = e;
|
target_extruder = e;
|
||||||
|
|
||||||
KEEPALIVE_STATE(NOT_BUSY); // don't send "busy: processing" messages during autotune output
|
KEEPALIVE_STATE(NOT_BUSY); // don't send "busy: processing" messages during autotune output
|
||||||
|
|
||||||
PID_autotune(temp, e, c, u);
|
PID_autotune(temp, e, c, u);
|
||||||
|
|
||||||
KEEPALIVE_STATE(IN_HANDLER);
|
KEEPALIVE_STATE(IN_HANDLER);
|
||||||
|
#else
|
||||||
|
SERIAL_ERROR_START;
|
||||||
|
SERIAL_ERRORLNPGM(MSG_ERR_M303_DISABLED);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED(SCARA)
|
#if ENABLED(SCARA)
|
||||||
|
|
|
@ -159,6 +159,7 @@
|
||||||
#define MSG_ERR_M421_REQUIRES_XYZ "M421 requires XYZ parameters"
|
#define MSG_ERR_M421_REQUIRES_XYZ "M421 requires XYZ parameters"
|
||||||
#define MSG_ERR_MESH_INDEX_OOB "Mesh XY index is out of bounds"
|
#define MSG_ERR_MESH_INDEX_OOB "Mesh XY index is out of bounds"
|
||||||
#define MSG_ERR_M428_TOO_FAR "Too far from reference point"
|
#define MSG_ERR_M428_TOO_FAR "Too far from reference point"
|
||||||
|
#define MSG_ERR_M303_DISABLED "PIDTEMP disabled"
|
||||||
#define MSG_M119_REPORT "Reporting endstop status"
|
#define MSG_M119_REPORT "Reporting endstop status"
|
||||||
#define MSG_ENDSTOP_HIT "TRIGGERED"
|
#define MSG_ENDSTOP_HIT "TRIGGERED"
|
||||||
#define MSG_ENDSTOP_OPEN "open"
|
#define MSG_ENDSTOP_OPEN "open"
|
||||||
|
|
|
@ -221,176 +221,180 @@ static void updateTemperaturesFromRawValues();
|
||||||
//================================ Functions ================================
|
//================================ Functions ================================
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void PID_autotune(float temp, int extruder, int ncycles, bool set_result/*=false*/) {
|
#if ENABLED(PIDTEMP)
|
||||||
float input = 0.0;
|
|
||||||
int cycles = 0;
|
|
||||||
bool heating = true;
|
|
||||||
|
|
||||||
millis_t temp_ms = millis(), t1 = temp_ms, t2 = temp_ms;
|
void PID_autotune(float temp, int extruder, int ncycles, bool set_result/*=false*/) {
|
||||||
long t_high = 0, t_low = 0;
|
float input = 0.0;
|
||||||
|
int cycles = 0;
|
||||||
|
bool heating = true;
|
||||||
|
|
||||||
long bias, d;
|
millis_t temp_ms = millis(), t1 = temp_ms, t2 = temp_ms;
|
||||||
float Ku, Tu;
|
long t_high = 0, t_low = 0;
|
||||||
float workKp = 0, workKi = 0, workKd = 0;
|
|
||||||
float max = 0, min = 10000;
|
|
||||||
|
|
||||||
#if HAS_AUTO_FAN
|
long bias, d;
|
||||||
millis_t next_auto_fan_check_ms = temp_ms + 2500UL;
|
float Ku, Tu;
|
||||||
#endif
|
float workKp = 0, workKi = 0, workKd = 0;
|
||||||
|
float max = 0, min = 10000;
|
||||||
|
|
||||||
if (extruder >= EXTRUDERS
|
#if HAS_AUTO_FAN
|
||||||
#if !HAS_TEMP_BED
|
millis_t next_auto_fan_check_ms = temp_ms + 2500UL;
|
||||||
|| extruder < 0
|
|
||||||
#endif
|
#endif
|
||||||
) {
|
|
||||||
SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START);
|
if (extruder >= EXTRUDERS
|
||||||
|
#if !HAS_TEMP_BED
|
||||||
disable_all_heaters(); // switch off all heaters.
|
|| extruder < 0
|
||||||
|
|
||||||
if (extruder < 0)
|
|
||||||
soft_pwm_bed = bias = d = (MAX_BED_POWER) / 2;
|
|
||||||
else
|
|
||||||
soft_pwm[extruder] = bias = d = (PID_MAX) / 2;
|
|
||||||
|
|
||||||
// PID Tuning loop
|
|
||||||
for (;;) {
|
|
||||||
|
|
||||||
millis_t ms = millis();
|
|
||||||
|
|
||||||
if (temp_meas_ready) { // temp sample ready
|
|
||||||
updateTemperaturesFromRawValues();
|
|
||||||
|
|
||||||
input = (extruder < 0) ? current_temperature_bed : current_temperature[extruder];
|
|
||||||
|
|
||||||
max = max(max, input);
|
|
||||||
min = min(min, input);
|
|
||||||
|
|
||||||
#if HAS_AUTO_FAN
|
|
||||||
if (ELAPSED(ms, next_auto_fan_check_ms)) {
|
|
||||||
checkExtruderAutoFans();
|
|
||||||
next_auto_fan_check_ms = ms + 2500UL;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
) {
|
||||||
|
SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (heating && input > temp) {
|
SERIAL_ECHOLN(MSG_PID_AUTOTUNE_START);
|
||||||
if (ELAPSED(ms, t2 + 5000UL)) {
|
|
||||||
heating = false;
|
|
||||||
if (extruder < 0)
|
|
||||||
soft_pwm_bed = (bias - d) >> 1;
|
|
||||||
else
|
|
||||||
soft_pwm[extruder] = (bias - d) >> 1;
|
|
||||||
t1 = ms;
|
|
||||||
t_high = t1 - t2;
|
|
||||||
max = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!heating && input < temp) {
|
disable_all_heaters(); // switch off all heaters.
|
||||||
if (ELAPSED(ms, t1 + 5000UL)) {
|
|
||||||
heating = true;
|
|
||||||
t2 = ms;
|
|
||||||
t_low = t2 - t1;
|
|
||||||
if (cycles > 0) {
|
|
||||||
long max_pow = extruder < 0 ? MAX_BED_POWER : PID_MAX;
|
|
||||||
bias += (d * (t_high - t_low)) / (t_low + t_high);
|
|
||||||
bias = constrain(bias, 20, max_pow - 20);
|
|
||||||
d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias;
|
|
||||||
|
|
||||||
SERIAL_PROTOCOLPGM(MSG_BIAS); SERIAL_PROTOCOL(bias);
|
if (extruder < 0)
|
||||||
SERIAL_PROTOCOLPGM(MSG_D); SERIAL_PROTOCOL(d);
|
soft_pwm_bed = bias = d = (MAX_BED_POWER) / 2;
|
||||||
SERIAL_PROTOCOLPGM(MSG_T_MIN); SERIAL_PROTOCOL(min);
|
else
|
||||||
SERIAL_PROTOCOLPGM(MSG_T_MAX); SERIAL_PROTOCOLLN(max);
|
soft_pwm[extruder] = bias = d = (PID_MAX) / 2;
|
||||||
if (cycles > 2) {
|
|
||||||
Ku = (4.0 * d) / (3.14159265 * (max - min) / 2.0);
|
// PID Tuning loop
|
||||||
Tu = ((float)(t_low + t_high) / 1000.0);
|
for (;;) {
|
||||||
SERIAL_PROTOCOLPGM(MSG_KU); SERIAL_PROTOCOL(Ku);
|
|
||||||
SERIAL_PROTOCOLPGM(MSG_TU); SERIAL_PROTOCOLLN(Tu);
|
millis_t ms = millis();
|
||||||
workKp = 0.6 * Ku;
|
|
||||||
workKi = 2 * workKp / Tu;
|
if (temp_meas_ready) { // temp sample ready
|
||||||
workKd = workKp * Tu / 8;
|
updateTemperaturesFromRawValues();
|
||||||
SERIAL_PROTOCOLLNPGM(MSG_CLASSIC_PID);
|
|
||||||
SERIAL_PROTOCOLPGM(MSG_KP); SERIAL_PROTOCOLLN(workKp);
|
input = (extruder < 0) ? current_temperature_bed : current_temperature[extruder];
|
||||||
SERIAL_PROTOCOLPGM(MSG_KI); SERIAL_PROTOCOLLN(workKi);
|
|
||||||
SERIAL_PROTOCOLPGM(MSG_KD); SERIAL_PROTOCOLLN(workKd);
|
max = max(max, input);
|
||||||
/**
|
min = min(min, input);
|
||||||
workKp = 0.33*Ku;
|
|
||||||
workKi = workKp/Tu;
|
#if HAS_AUTO_FAN
|
||||||
workKd = workKp*Tu/3;
|
if (ELAPSED(ms, next_auto_fan_check_ms)) {
|
||||||
SERIAL_PROTOCOLLNPGM(" Some overshoot ");
|
checkExtruderAutoFans();
|
||||||
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(workKp);
|
next_auto_fan_check_ms = ms + 2500UL;
|
||||||
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(workKi);
|
}
|
||||||
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(workKd);
|
#endif
|
||||||
workKp = 0.2*Ku;
|
|
||||||
workKi = 2*workKp/Tu;
|
if (heating && input > temp) {
|
||||||
workKd = workKp*Tu/3;
|
if (ELAPSED(ms, t2 + 5000UL)) {
|
||||||
SERIAL_PROTOCOLLNPGM(" No overshoot ");
|
heating = false;
|
||||||
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(workKp);
|
if (extruder < 0)
|
||||||
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(workKi);
|
soft_pwm_bed = (bias - d) >> 1;
|
||||||
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(workKd);
|
else
|
||||||
*/
|
soft_pwm[extruder] = (bias - d) >> 1;
|
||||||
}
|
t1 = ms;
|
||||||
|
t_high = t1 - t2;
|
||||||
|
max = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!heating && input < temp) {
|
||||||
|
if (ELAPSED(ms, t1 + 5000UL)) {
|
||||||
|
heating = true;
|
||||||
|
t2 = ms;
|
||||||
|
t_low = t2 - t1;
|
||||||
|
if (cycles > 0) {
|
||||||
|
long max_pow = extruder < 0 ? MAX_BED_POWER : PID_MAX;
|
||||||
|
bias += (d * (t_high - t_low)) / (t_low + t_high);
|
||||||
|
bias = constrain(bias, 20, max_pow - 20);
|
||||||
|
d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias;
|
||||||
|
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_BIAS); SERIAL_PROTOCOL(bias);
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_D); SERIAL_PROTOCOL(d);
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_T_MIN); SERIAL_PROTOCOL(min);
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_T_MAX); SERIAL_PROTOCOLLN(max);
|
||||||
|
if (cycles > 2) {
|
||||||
|
Ku = (4.0 * d) / (3.14159265 * (max - min) / 2.0);
|
||||||
|
Tu = ((float)(t_low + t_high) / 1000.0);
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_KU); SERIAL_PROTOCOL(Ku);
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_TU); SERIAL_PROTOCOLLN(Tu);
|
||||||
|
workKp = 0.6 * Ku;
|
||||||
|
workKi = 2 * workKp / Tu;
|
||||||
|
workKd = workKp * Tu / 8;
|
||||||
|
SERIAL_PROTOCOLLNPGM(MSG_CLASSIC_PID);
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_KP); SERIAL_PROTOCOLLN(workKp);
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_KI); SERIAL_PROTOCOLLN(workKi);
|
||||||
|
SERIAL_PROTOCOLPGM(MSG_KD); SERIAL_PROTOCOLLN(workKd);
|
||||||
|
/**
|
||||||
|
workKp = 0.33*Ku;
|
||||||
|
workKi = workKp/Tu;
|
||||||
|
workKd = workKp*Tu/3;
|
||||||
|
SERIAL_PROTOCOLLNPGM(" Some overshoot ");
|
||||||
|
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(workKp);
|
||||||
|
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(workKi);
|
||||||
|
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(workKd);
|
||||||
|
workKp = 0.2*Ku;
|
||||||
|
workKi = 2*workKp/Tu;
|
||||||
|
workKd = workKp*Tu/3;
|
||||||
|
SERIAL_PROTOCOLLNPGM(" No overshoot ");
|
||||||
|
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(workKp);
|
||||||
|
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(workKi);
|
||||||
|
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(workKd);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (extruder < 0)
|
||||||
|
soft_pwm_bed = (bias + d) >> 1;
|
||||||
|
else
|
||||||
|
soft_pwm[extruder] = (bias + d) >> 1;
|
||||||
|
cycles++;
|
||||||
|
min = temp;
|
||||||
}
|
}
|
||||||
if (extruder < 0)
|
|
||||||
soft_pwm_bed = (bias + d) >> 1;
|
|
||||||
else
|
|
||||||
soft_pwm[extruder] = (bias + d) >> 1;
|
|
||||||
cycles++;
|
|
||||||
min = temp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#define MAX_OVERSHOOT_PID_AUTOTUNE 20
|
||||||
#define MAX_OVERSHOOT_PID_AUTOTUNE 20
|
if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE) {
|
||||||
if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE) {
|
SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH);
|
||||||
SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
// Every 2 seconds...
|
||||||
// Every 2 seconds...
|
if (ELAPSED(ms, temp_ms + 2000UL)) {
|
||||||
if (ELAPSED(ms, temp_ms + 2000UL)) {
|
#if HAS_TEMP_HOTEND || HAS_TEMP_BED
|
||||||
#if HAS_TEMP_HOTEND || HAS_TEMP_BED
|
print_heaterstates();
|
||||||
print_heaterstates();
|
SERIAL_EOL;
|
||||||
SERIAL_EOL;
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
temp_ms = ms;
|
temp_ms = ms;
|
||||||
} // every 2 seconds
|
} // every 2 seconds
|
||||||
// Over 2 minutes?
|
// Over 2 minutes?
|
||||||
if (((ms - t1) + (ms - t2)) > (10L * 60L * 1000L * 2L)) {
|
if (((ms - t1) + (ms - t2)) > (10L * 60L * 1000L * 2L)) {
|
||||||
SERIAL_PROTOCOLLNPGM(MSG_PID_TIMEOUT);
|
SERIAL_PROTOCOLLNPGM(MSG_PID_TIMEOUT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cycles > ncycles) {
|
if (cycles > ncycles) {
|
||||||
SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED);
|
SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED);
|
||||||
const char* estring = extruder < 0 ? "bed" : "";
|
const char* estring = extruder < 0 ? "bed" : "";
|
||||||
SERIAL_PROTOCOLPGM("#define DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kp "); SERIAL_PROTOCOLLN(workKp);
|
SERIAL_PROTOCOLPGM("#define DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kp "); SERIAL_PROTOCOLLN(workKp);
|
||||||
SERIAL_PROTOCOLPGM("#define DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Ki "); SERIAL_PROTOCOLLN(workKi);
|
SERIAL_PROTOCOLPGM("#define DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Ki "); SERIAL_PROTOCOLLN(workKi);
|
||||||
SERIAL_PROTOCOLPGM("#define DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kd "); SERIAL_PROTOCOLLN(workKd);
|
SERIAL_PROTOCOLPGM("#define DEFAULT_"); SERIAL_PROTOCOL(estring); SERIAL_PROTOCOLPGM("Kd "); SERIAL_PROTOCOLLN(workKd);
|
||||||
|
|
||||||
// Use the result? (As with "M303 U1")
|
// Use the result? (As with "M303 U1")
|
||||||
if (set_result) {
|
if (set_result) {
|
||||||
if (extruder < 0) {
|
if (extruder < 0) {
|
||||||
#if ENABLED(PIDTEMPBED)
|
#if ENABLED(PIDTEMPBED)
|
||||||
bedKp = workKp;
|
bedKp = workKp;
|
||||||
bedKi = scalePID_i(workKi);
|
bedKi = scalePID_i(workKi);
|
||||||
bedKd = scalePID_d(workKd);
|
bedKd = scalePID_d(workKd);
|
||||||
|
updatePID();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PID_PARAM(Kp, extruder) = workKp;
|
||||||
|
PID_PARAM(Ki, extruder) = scalePID_i(workKi);
|
||||||
|
PID_PARAM(Kd, extruder) = scalePID_d(workKd);
|
||||||
updatePID();
|
updatePID();
|
||||||
#endif
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
PID_PARAM(Kp, extruder) = workKp;
|
|
||||||
PID_PARAM(Ki, extruder) = scalePID_i(workKi);
|
|
||||||
PID_PARAM(Kd, extruder) = scalePID_d(workKd);
|
|
||||||
updatePID();
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
lcd_update();
|
||||||
}
|
}
|
||||||
lcd_update();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#endif // PIDTEMP
|
||||||
|
|
||||||
void updatePID() {
|
void updatePID() {
|
||||||
#if ENABLED(PIDTEMP)
|
#if ENABLED(PIDTEMP)
|
||||||
|
|
|
@ -169,7 +169,9 @@ int getHeaterPower(int heater);
|
||||||
void disable_all_heaters();
|
void disable_all_heaters();
|
||||||
void updatePID();
|
void updatePID();
|
||||||
|
|
||||||
void PID_autotune(float temp, int extruder, int ncycles, bool set_result=false);
|
#if ENABLED(PIDTEMP)
|
||||||
|
void PID_autotune(float temp, int extruder, int ncycles, bool set_result=false);
|
||||||
|
#endif
|
||||||
|
|
||||||
void setExtruderAutoFanState(int pin, bool state);
|
void setExtruderAutoFanState(int pin, bool state);
|
||||||
void checkExtruderAutoFans();
|
void checkExtruderAutoFans();
|
||||||
|
|
Reference in a new issue