Procházet zdrojové kódy

Merge pull request #3818 from wavexx/tm_default_state

TM: Provide full defaults for model data and enable it by default
3d-gussner před 1 rokem
rodič
revize
65f5b9e53d

+ 0 - 10
Firmware/Marlin_main.cpp

@@ -8665,16 +8665,6 @@ Sigma_Exit:
     }
     break;
 
-    /*!
-    ### M999 - Restart after being stopped <a href="https://reprap.org/wiki/G-code#M999:_Restart_after_being_stopped_by_error">M999: Restart after being stopped by error</a>
-    @todo Usually doesn't work. Should be fixed or removed. Most of the time, if `Stopped` it set, the print fails and is unrecoverable.
-    */
-    case 999:
-      Stopped = false;
-      lcd_reset_alert_level();
-//@@TODO      gcode_LastN = Stopped_gcode_LastN;
-      FlushSerialRequestResend();
-    break;
 	/*!
 	#### End of M-Commands
     */

+ 0 - 1
Firmware/cardreader.cpp

@@ -273,7 +273,6 @@ void CardReader::startFileprint()
   if(cardOK)
   {
     sdprinting = true;
-    Stopped = false;
 	#ifdef SDCARD_SORT_ALPHA
 		//flush_presort();
 	#endif

+ 1 - 0
Firmware/eeprom.h

@@ -92,6 +92,7 @@ static_assert(sizeof(Sheets) == EEPROM_SHEETS_SIZEOF, "Sizeof(Sheets) is not EEP
 | 0x0FF7 4087 | uint8   | EEPROM_CALIBRATION_STATUS             | ffh 255      | ffh 255               | Assembled _default_                               | ???          | D3 Ax0ff7 C1
 | ^           | ^       | ^                                     | 01h 1        | ^                     | Calibrated                                        | ^            | ^
 | ^           | ^       | ^                                     | e6h 230      | ^                     | needs Live Z adjustment                           | ^            | ^
+| ^           | ^       | ^                                     | ebh 235      | ^                     | needs Temp Model calibration                      | ^            | ^
 | ^           | ^       | ^                                     | f0h 240      | ^               __P__ | needs Z calibration                               | ^            | ^
 | ^           | ^       | ^                                     | fah 250      | ^                     | needs XYZ calibration                             | ^            | ^
 | ^           | ^       | ^                                     | 00h 0        | ^                     | Unknown                                           | ^            | ^

+ 1 - 1
Firmware/temp_model.h

@@ -15,6 +15,7 @@ constexpr uint8_t TEMP_MODEL_LAG_SIZE = (TEMP_MODEL_LAG / TEMP_MGR_INTV + 0.5);
 
 // resistance values for all fan levels
 constexpr uint8_t TEMP_MODEL_R_SIZE = (1 << FAN_SOFT_PWM_BITS);
+static const float TEMP_MODEL_R_DEFAULT[TEMP_MODEL_R_SIZE] PROGMEM = TEMP_MODEL_Rv;
 
 namespace temp_model {
 
@@ -59,7 +60,6 @@ struct model_data
 };
 
 static bool enabled;          // model check enabled
-static bool valid = false;    // model is valid
 static bool warn_beep = true; // beep on warning threshold
 static model_data data;       // default heater data
 

+ 51 - 36
Firmware/temperature.cpp

@@ -2504,10 +2504,14 @@ static void temp_model_reset_enabled(bool enabled)
 {
     TempMgrGuard temp_mgr_guard;
     temp_model::enabled = enabled;
-    temp_model::valid = enabled;
     temp_model::data.flag_bits.uninitialized = true;
 }
 
+bool temp_model_enabled()
+{
+    return temp_model::enabled;
+}
+
 void temp_model_set_enabled(bool enabled)
 {
     // set the enabled flag
@@ -2515,19 +2519,11 @@ void temp_model_set_enabled(bool enabled)
         TempMgrGuard temp_mgr_guard;
         temp_model::enabled = enabled;
         temp_model::setup();
-        temp_model::valid = true;
     }
 
     // verify that the model has been enabled
-    if(enabled && !temp_model::enabled) {
+    if(enabled && !temp_model::enabled)
         SERIAL_ECHOLNPGM("TM: invalid parameters, cannot enable");
-        temp_model::valid = false;
-    }
-}
-
-bool temp_model_valid()
-{
-  return temp_model::valid;
 }
 
 void temp_model_set_warn_beep(bool enabled)
@@ -2581,15 +2577,14 @@ void temp_model_reset_settings()
 
     temp_model::data.P = TEMP_MODEL_P;
     temp_model::data.C = TEMP_MODEL_C;
-    temp_model::data.R[0] = TEMP_MODEL_R;
-    for(uint8_t i = 1; i != TEMP_MODEL_R_SIZE; ++i)
-        temp_model::data.R[i] = NAN;
+    for(uint8_t i = 0; i != TEMP_MODEL_R_SIZE; ++i)
+        temp_model::data.R[i] = pgm_read_float(TEMP_MODEL_R_DEFAULT + i);
     temp_model::data.Ta_corr = TEMP_MODEL_Ta_corr;
     temp_model::data.warn = TEMP_MODEL_W;
     temp_model::data.err = TEMP_MODEL_E;
     temp_model::warn_beep = true;
-    temp_model::enabled = false;
-    temp_model::valid = false;
+    temp_model::enabled = true;
+    temp_model::data.flag_bits.uninitialized = true;
 }
 
 void temp_model_load_settings()
@@ -2792,7 +2787,8 @@ static bool autotune(int16_t cal_temp)
 {
     uint16_t samples;
     float e;
-    char tm_message[20];
+    char tm_message[LCD_WIDTH+1];
+
     // bootstrap C/R values without fan
     set_fan_speed(0);
 
@@ -2800,16 +2796,12 @@ static bool autotune(int16_t cal_temp)
         const char* PROGMEM verb = (i == 0? PSTR("initial"): PSTR("refine"));
         target_temperature[0] = 0;
         if(current_temperature[0] >= TEMP_MODEL_CAL_Tl) {
-//!01234567890123456789|
-//!TM: cool down <50C  |
             sprintf_P(tm_message, PSTR("TM: cool down <%dC"), TEMP_MODEL_CAL_Tl);
             lcd_setstatus_serial(tm_message);
             cooldown(TEMP_MODEL_CAL_Tl);
             wait(10000);
         }
-//!01234567890123456789|
-//!TM: initial R est.  |
-//!TM: refine R est.   |
+
         sprintf_P(tm_message, PSTR("TM: %S C est."), verb);
         lcd_setstatus_serial(tm_message);
         target_temperature[0] = cal_temp;
@@ -2830,9 +2822,7 @@ static bool autotune(int16_t cal_temp)
         wait_temp();
         if(i) break; // we don't need to refine R
         wait(30000); // settle PID regulation
-//!01234567890123456789|
-//!TM: initial R 230C  |
-//!TM: refine R 230C   |
+
         sprintf_P(tm_message, PSTR("TM: %S R %dC"), verb, cal_temp);
         lcd_setstatus_serial(tm_message);
         samples = record();
@@ -2854,11 +2844,14 @@ static bool autotune(int16_t cal_temp)
     wait(30000);
 
     for(int8_t i = TEMP_MODEL_R_SIZE - 1; i > 0; i -= TEMP_MODEL_CAL_R_STEP) {
+        // always disable the checker while estimating fan resistance as the difference
+        // (esp with 3rd-party blowers) can be massive
+        temp_model::data.R[i] = NAN;
+
         uint8_t speed = 256 / TEMP_MODEL_R_SIZE * (i + 1) - 1;
         set_fan_speed(speed);
         wait(10000);
-//!01234567890123456789|
-//!TM: R[15] estimat.  |
+
         sprintf_P(tm_message, PSTR("TM: R[%u] estimat."), (unsigned)i);
         lcd_setstatus_serial(tm_message);
         samples = record();
@@ -2894,12 +2887,19 @@ static bool autotune(int16_t cal_temp)
 
 } // namespace temp_model_cal
 
+static bool temp_model_autotune_err = true;
+
 void temp_model_autotune(int16_t temp, bool selftest)
 {
-    char tm_message[20];
+    float orig_C, orig_R[TEMP_MODEL_R_SIZE];
+    bool orig_enabled;
+    static_assert(sizeof(orig_R) == sizeof(temp_model::data.R));
+
+    // fail-safe error state
+    temp_model_autotune_err = true;
+
+    char tm_message[LCD_WIDTH+1];
     if(moves_planned() || printer_active()) {
-//!01234567890123456789|
-//!TM: Cal. NOT ILDE   |
         sprintf_P(tm_message, PSTR("TM: Cal. NOT IDLE"));
         lcd_setstatus_serial(tm_message);
         return;
@@ -2910,26 +2910,36 @@ void temp_model_autotune(int16_t temp, bool selftest)
     menu_set_block(MENU_BLOCK_TEMP_MODEL_AUTOTUNE);
     lcd_return_to_status();
 
-    // set the model checking state during self-calibration
-    bool was_enabled = temp_model::enabled;
+    // save the original model data and set the model checking state during self-calibration
+    orig_C = temp_model::data.C;
+    memcpy(orig_R, temp_model::data.R, sizeof(temp_model::data.R));
+    orig_enabled = temp_model::enabled;
     temp_model_reset_enabled(selftest);
+
+    // autotune
     SERIAL_ECHOLNPGM("TM: calibration start");
-    bool err = temp_model_cal::autotune(temp > 0 ? temp : TEMP_MODEL_CAL_Th);
+    temp_model_autotune_err = temp_model_cal::autotune(temp > 0 ? temp : TEMP_MODEL_CAL_Th);
 
     // always reset temperature
     disable_heater();
 
-    if(err) {
-//!01234567890123456789|
-//!TM: calibr. failed! |
+    if(temp_model_autotune_err) {
         sprintf_P(tm_message, PSTR("TM: calibr. failed!"));
         lcd_setstatus_serial(tm_message);
         if(temp_error_state.v)
             temp_model_cal::set_fan_speed(255);
+
+        // show calibrated values before overwriting them
+        temp_model_report_settings();
+
+        // restore original state
+        temp_model::data.C = orig_C;
+        memcpy(temp_model::data.R, orig_R, sizeof(temp_model::data.R));
+        temp_model_set_enabled(orig_enabled);
     } else {
         lcd_setstatuspgm(MSG_WELCOME);
         temp_model_cal::set_fan_speed(0);
-        temp_model_set_enabled(was_enabled);
+        temp_model_set_enabled(orig_enabled);
         temp_model_report_settings();
     }
 
@@ -2937,6 +2947,11 @@ void temp_model_autotune(int16_t temp, bool selftest)
     menu_unset_block(MENU_BLOCK_TEMP_MODEL_AUTOTUNE);
 }
 
+bool temp_model_autotune_result()
+{
+    return !temp_model_autotune_err;
+}
+
 #ifdef TEMP_MODEL_DEBUG
 void temp_model_log_enable(bool enable)
 {

+ 2 - 1
Firmware/temperature.h

@@ -217,8 +217,8 @@ FORCE_INLINE void autotempShutdown(){
 void PID_autotune(float temp, int extruder, int ncycles);
 
 #ifdef TEMP_MODEL
+bool temp_model_enabled(); // return temperature model state
 void temp_model_set_enabled(bool enabled);
-bool temp_model_valid();
 void temp_model_set_warn_beep(bool enabled);
 void temp_model_set_params(float C = NAN, float P = NAN, float Ta_corr = NAN, float warn = NAN, float err = NAN);
 void temp_model_set_resistance(uint8_t index, float R);
@@ -229,6 +229,7 @@ void temp_model_load_settings();
 void temp_model_save_settings();
 
 void temp_model_autotune(int16_t temp = 0, bool selftest = false);
+bool temp_model_autotune_result(); // return true if the last autotune was complete and successful
 
 #ifdef TEMP_MODEL_DEBUG
 void temp_model_log_enable(bool enable);

+ 65 - 50
Firmware/ultralcd.cpp

@@ -985,27 +985,42 @@ void lcd_commands()
 			lcd_commands_type = LcdCommands::Idle;
 		}
 	}
+
 #ifdef TEMP_MODEL
-    if (lcd_commands_type == LcdCommands::TempModel) {
-        if (lcd_commands_step == 0) {
+    if (lcd_commands_type == LcdCommands::TempModel && cmd_buffer_empty())
+    {
+        switch (lcd_commands_step)
+        {
+        case 0:
             lcd_commands_step = 3;
-        }
-        if (lcd_commands_step == 3) {
-            enquecommand_P(PSTR("M310 A F0"));
+            [[fallthrough]];
+
+        case 3:
+            enquecommand_P(PSTR("M310 A F1"));
             lcd_commands_step = 2;
-        }
-        if (lcd_commands_step ==2 && temp_model_valid()) {
-            enquecommand_P(PSTR("M310 S1"));
+            break;
+
+        case 2:
+            if (temp_model_autotune_result())
+                enquecommand_P(PSTR("M500"));
             lcd_commands_step = 1;
-        }
-        //if (lcd_commands_step == 1 && calibrated()) {
-        if (lcd_commands_step == 1 && temp_model_valid()) {
+            break;
+
+        case 1:
             lcd_commands_step = 0;
             lcd_commands_type = LcdCommands::Idle;
-            enquecommand_P(PSTR("M500"));
-            if (eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) == 1) {
-                lcd_wizard(WizState::IsFil);
+
+            if (temp_model_autotune_result()) {
+                if (calibration_status() == CALIBRATION_STATUS_TEMP_MODEL_CALIBRATION) {
+                    // move to the next calibration step if not fully calibrated
+                    calibration_status_store(CALIBRATION_STATUS_LIVE_ADJUST);
+                }
+                if ((eeprom_read_byte((uint8_t*)EEPROM_WIZARD_ACTIVE) == 1)) {
+                    // successful: resume the wizard
+                    lcd_wizard(WizState::IsFil);
+                }
             }
+            break;
         }
     }
 #endif //TEMP_MODEL
@@ -1014,6 +1029,9 @@ void lcd_commands()
 	{
         if (!blocks_queued() && cmd_buffer_empty() && !saved_printing)
         {
+#ifdef TEMP_MODEL
+            static bool was_enabled;
+#endif //TEMP_MODEL
             switch(lcd_commands_step)
             {
             case 0:
@@ -1028,7 +1046,7 @@ void lcd_commands()
                 enquecommand_P(PSTR("G1 X125 Y10 Z150 F1000"));
                 enquecommand_P(PSTR("M109 S280"));
 #ifdef TEMP_MODEL
-                //enquecommand_P(PSTR("M310 S0"));
+                was_enabled = temp_model_enabled();
                 temp_model_set_enabled(false);
 #endif //TEMP_MODEL
                 lcd_commands_step = 2;
@@ -1042,13 +1060,11 @@ void lcd_commands()
                 enquecommand_P(PSTR("M84 XY"));
                 lcd_update_enabled = false; //hack to avoid lcd_update recursion.
                 if (lcd_show_fullscreen_message_yes_no_and_wait_P(_T(MSG_NOZZLE_CNG_CHANGED), false) == LCD_LEFT_BUTTON_CHOICE) {
+                    setAllTargetHotends(0);
 #ifdef TEMP_MODEL
-                //enquecommand_P(PSTR("M310 S1"));
-                temp_model_set_enabled(true);
+                    temp_model_set_enabled(was_enabled);
 #endif //TEMP_MODEL
-                //enquecommand_P(PSTR("M104 S0"));
-                setTargetHotendSafe(0,0);
-                lcd_commands_step = 1;
+                    lcd_commands_step = 1;
                 }
                 lcd_update_enabled = true;
                 break;
@@ -4123,10 +4139,6 @@ void lcd_wizard(WizState state)
 	case S::Z: //z cal.
 		msg = _T(MSG_WIZARD_CALIBRATION_FAILED);
 		break;
-#ifdef TEMP_MODEL
-	case S::TempModel: //Temp model calibration
-		break;
-#endif //TEMP_MODEL
 	case S::Finish: //we are finished
 		msg = _T(MSG_WIZARD_DONE);
 		lcd_reset_alert_level();
@@ -4136,6 +4148,9 @@ void lcd_wizard(WizState state)
     case S::Preheat:
     case S::Lay1CalCold:
     case S::Lay1CalHot:
+#ifdef TEMP_MODEL
+	case S::TempModel: // exiting for calibration
+#endif //TEMP_MODEL
         break;
 	default:
 		msg = _T(MSG_WIZARD_QUIT);
@@ -6799,11 +6814,7 @@ static bool lcd_selfcheck_endstops()
 
 static bool lcd_selfcheck_check_heater(bool _isbed)
 {
-	uint8_t _counter = 0;
 	uint8_t _progress = 0;
-	bool _stepresult = false;
-	bool _docycle = true;
-
 	int _checked_snapshot = (_isbed) ? degBed() : degHotend(0);
 	int _opposite_snapshot = (_isbed) ? degHotend(0) : degBed();
 	uint8_t _cycles = (_isbed) ? 180 : 60; //~ 90s / 30s
@@ -6813,13 +6824,13 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
 	manage_heater();
 	manage_inactivity(true);
 
-	do {
-		_counter++;
-		_docycle = (_counter < _cycles) ? true : false;
-
+    for(uint8_t _counter = 0; _counter < _cycles && !Stopped; ++_counter)
+    {
 		manage_heater();
 		manage_inactivity(true);
-		_progress = (_isbed) ? lcd_selftest_screen(TestScreen::Bed, _progress, 2, false, 400) : lcd_selftest_screen(TestScreen::Hotend, _progress, 2, false, 400);
+		_progress = (_isbed?
+			lcd_selftest_screen(TestScreen::Bed, _progress, 2, false, 400) :
+			lcd_selftest_screen(TestScreen::Hotend, _progress, 2, false, 400));
 		/*if (_isbed) {
 			MYSERIAL.print("Bed temp:");
 			MYSERIAL.println(degBed());
@@ -6829,8 +6840,7 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
 			MYSERIAL.println(degHotend(0));
 		}*/
 		if(_counter%5 == 0) serialecho_temperatures(); //show temperatures once in two seconds
-
-	} while (_docycle); 
+	}
 
 	target_temperature[0] = 0;
 	target_temperature_bed = 0;
@@ -6846,21 +6856,26 @@ static bool lcd_selfcheck_check_heater(bool _isbed)
 	MYSERIAL.println(_opposite_result);
 	*/
 
-	if (_opposite_result < ((_isbed) ? 30 : 9))
-	{
-		if (_checked_result >= ((_isbed) ? 9 : 30))
-		{
-			_stepresult = true;
-		}
-		else
-		{
-			lcd_selftest_error(TestError::Heater, "", "");
-		}
-	}
-	else
-	{
-		lcd_selftest_error(TestError::Bed, "", "");
-	}
+    bool _stepresult = false;
+    if (Stopped)
+    {
+        // thermal error occurred while heating the nozzle
+        lcd_selftest_error(TestError::Heater, "", "");
+    }
+    else
+    {
+        if (_opposite_result < ((_isbed) ? 30 : 9))
+        {
+            if (_checked_result >= ((_isbed) ? 9 : 30))
+                _stepresult = true;
+            else
+                lcd_selftest_error(TestError::Heater, "", "");
+        }
+        else
+        {
+            lcd_selftest_error(TestError::Bed, "", "");
+        }
+    }
 
 	manage_heater();
 	manage_inactivity(true);

+ 3 - 0
Firmware/variants/1_75mm_MK3-EINSy10a-E3Dv6full.h

@@ -437,6 +437,9 @@
 #define TEMP_MODEL_CAL_Th 230 // Default calibration working temperature (C)
 #define TEMP_MODEL_CAL_Tl 50  // Default calibration cooling temperature (C)
 
+// fall-back resistance vector (R0-15)
+#define TEMP_MODEL_Rv {TEMP_MODEL_R, 18.4, 16.7, 15.2, 14.1, 13.3, 12.7, 12.1, 11.7, 11.3, 11., 10.8, 10.6, 10.4, 10.2, 10.1}
+
 
 /*------------------------------------
  MOTOR CURRENT SETTINGS

+ 3 - 0
Firmware/variants/1_75mm_MK3S-EINSy10a-E3Dv6full.h

@@ -441,6 +441,9 @@
 #define TEMP_MODEL_CAL_Th 230 // Default calibration working temperature (C)
 #define TEMP_MODEL_CAL_Tl 50  // Default calibration cooling temperature (C)
 
+// fall-back resistance vector (R0-15)
+#define TEMP_MODEL_Rv {TEMP_MODEL_R, 18.4, 16.7, 15.2, 14.1, 13.3, 12.7, 12.1, 11.7, 11.3, 11., 10.8, 10.6, 10.4, 10.2, 10.1}
+
 
 /*------------------------------------
  MOTOR CURRENT SETTINGS