Browse Source

Implemented a calibration flow supporting the new & pre-built machines.
Fixed a thermal runaway on heat up.
Increased timeout of live adjust to 90 seconds.

bubnikv 8 years ago
parent
commit
854b79de46

+ 22 - 1
Firmware/Configuration.h

@@ -18,7 +18,7 @@
 #define EEPROM_BABYSTEP_X 4092
 #define EEPROM_BABYSTEP_Y 4090
 #define EEPROM_BABYSTEP_Z 4088
-#define EEPROM_BABYSTEP_Z_SET 4087
+#define EEPROM_CALIBRATION_STATUS 4087
 #define EEPROM_BABYSTEP_Z0 4085
 #define EEPROM_FILAMENTUSED 4081
 // uint32_t
@@ -692,9 +692,30 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 //#define FILAMENT_LCD_DISPLAY
 
 
+// Calibration status of the machine, to be stored into the EEPROM,
+// (unsigned char*)EEPROM_CALIBRATION_STATUS
+enum CalibrationStatus
+{
+    // Freshly assembled, needs to peform a self-test and the XYZ calibration.
+    CALIBRATION_STATUS_ASSEMBLED = 255,
 
+    // For the wizard: self test has been performed, now the XYZ calibration is needed.
+    // CALIBRATION_STATUS_XYZ_CALIBRATION = 250,
 
+    // For the wizard: factory assembled, needs to run Z calibration.
+    CALIBRATION_STATUS_Z_CALIBRATION = 240,
 
+    // The XYZ calibration has been performed, now it remains to run the V2Calibration.gcode.
+    CALIBRATION_STATUS_LIVE_ADJUST = 230,
+
+    // Calibrated, ready to print.
+    CALIBRATION_STATUS_CALIBRATED = 1,
+
+    // Legacy: resetted by issuing a G86 G-code.
+    // This value can only be expected after an upgrade from the initial MK2 firmware releases.
+    // Currently the G86 sets the calibration status to 
+    CALIBRATION_STATUS_UNKNOWN = 0,
+};
 
 #include "Configuration_adv.h"
 #include "thermistortables.h"

+ 3 - 0
Firmware/ConfigurationStore.h

@@ -19,4 +19,7 @@ FORCE_INLINE void Config_StoreSettings() {}
 FORCE_INLINE void Config_RetrieveSettings() { Config_ResetDefault(); Config_PrintSettings(); }
 #endif
 
+inline uint8_t calibration_status() { return eeprom_read_byte((uint8_t*)EEPROM_CALIBRATION_STATUS); }
+inline uint8_t calibration_status_store(uint8_t status) { eeprom_update_byte((uint8_t*)EEPROM_CALIBRATION_STATUS, status); }
+
 #endif//CONFIG_STORE_H

+ 25 - 6
Firmware/Marlin_main.cpp

@@ -947,7 +947,10 @@ void setup()
 		  SET_OUTPUT(BEEPER);
 		  WRITE(BEEPER, HIGH);
 
+      // Force language selection at the next boot up.
 		  lcd_force_language_selection();
+      // Force the "Follow calibration flow" message at the next boot up.
+      calibration_status_store(CALIBRATION_STATUS_Z_CALIBRATION);
 		  farm_no = 0;
 		  EEPROM_save_B(EEPROM_FARM_MODE, &farm_no);
 		  farm_mode = false;
@@ -970,7 +973,7 @@ void setup()
 			  WRITE(BEEPER, LOW);
 
 			  int _z = 0;
-			  eeprom_write_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET, 0x01);
+			  calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
 			  EEPROM_save_B(EEPROM_BABYSTEP_X, &_z);
 			  EEPROM_save_B(EEPROM_BABYSTEP_Y, &_z);
 			  EEPROM_save_B(EEPROM_BABYSTEP_Z, &_z);
@@ -1044,9 +1047,15 @@ void setup()
       lcd_mylang();
     }
     
-  if (eeprom_read_byte((uint8_t*)EEPROM_BABYSTEP_Z_SET) == 0x0ff) {
+  if (calibration_status() == CALIBRATION_STATUS_ASSEMBLED ||
+      calibration_status() == CALIBRATION_STATUS_Z_CALIBRATION ||
+      calibration_status() == CALIBRATION_STATUS_UNKNOWN) {
       // Reset the babystepping values, so the printer will not move the Z axis up when the babystepping is enabled.
       eeprom_update_word((uint16_t*)EEPROM_BABYSTEP_Z, 0);
+      // Show the message.
+      lcd_show_fullscreen_message_and_wait_P(MSG_FOLLOW_CALIBRATION_FLOW);
+      lcd_update_enable(true);
+  } else if (calibration_status() == CALIBRATION_STATUS_LIVE_ADJUST) {
       // Show the message.
       lcd_show_fullscreen_message_and_wait_P(MSG_BABYSTEP_Z_NOT_SET);
       lcd_update_enable(true);
@@ -2617,14 +2626,14 @@ void process_commands()
              * This G-code will be performed at the start of a calibration script.
              */
         case 86:
-            eeprom_write_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET, 0xFF);
+            calibration_status_store(CALIBRATION_STATUS_LIVE_ADJUST);
             break;
             /**
              * G87: Prusa3D specific: Enable babystep correction after home
              * This G-code will be performed at the end of a calibration script.
              */
         case 87:
-            eeprom_write_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET, 0x01);
+            calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
             break;
 
             /**
@@ -2955,10 +2964,15 @@ void process_commands()
                 world2machine_update_current();
                 //FIXME
                 bool result = sample_mesh_and_store_reference();
-                // if (result) babystep_apply();
+                if (result) {
+                    if (calibration_status() == CALIBRATION_STATUS_Z_CALIBRATION)
+                        // Shipped, the nozzle height has been set already. The user can start printing now.
+                        calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
+                    // babystep_apply();
+                }
             } else {
                 // Reset the baby step value and the baby step applied flag.
-                eeprom_write_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET, 0xFF);
+                calibration_status_store(CALIBRATION_STATUS_ASSEMBLED);
                 eeprom_update_word((uint16_t*)EEPROM_BABYSTEP_Z, 0);
                 // Complete XYZ calibration.
                 BedSkewOffsetDetectionResultType result = find_bed_offset_and_skew(verbosity_level);
@@ -2985,6 +2999,11 @@ void process_commands()
                     // if (result >= 0) babystep_apply();
                 }
                 lcd_bed_calibration_show_result(result, point_too_far_mask);
+                if (result >= 0) {
+                    // Calibration valid, the machine should be able to print. Advise the user to run the V2Calibration.gcode.
+                    calibration_status_store(CALIBRATION_STATUS_LIVE_ADJUST);
+                    lcd_show_fullscreen_message_and_wait_P(MSG_BABYSTEP_Z_NOT_SET);
+                }
             }
         } else {
             // Timeouted.

+ 18 - 6
Firmware/language_all.cpp

@@ -87,17 +87,16 @@ const char * const MSG_BABYSTEP_Z_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_BABYSTEP_Z_PL
 };
 
-const char MSG_BABYSTEP_Z_NOT_SET_EN[] PROGMEM = "Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow.";
-const char MSG_BABYSTEP_Z_NOT_SET_CZ[] PROGMEM = "Tiskarna nebyla jeste zkalibrovana. Postupujte prosim podle manualu, kapitola Zaciname, odstavec Postup kalibrace.";
-const char MSG_BABYSTEP_Z_NOT_SET_IT[] PROGMEM = "Stampante ancora non calibrata. Si prega di seguire il manuale, capitolo PRIMI PASSI, sezione della calibrazione.";
-const char MSG_BABYSTEP_Z_NOT_SET_ES[] PROGMEM = "Impresora no esta calibrada todavia. Por favor usar el manual, el capitulo First steps, seleccion Calibration flow.";
-const char MSG_BABYSTEP_Z_NOT_SET_PL[] PROGMEM = "Drukarka nie zostala jeszcze skalibrowana. Prosze kierowac sie instrukcja, rozdzial Zaczynamy, podrozdzial Selftest.";
+const char MSG_BABYSTEP_Z_NOT_SET_EN[] PROGMEM = "Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration.";
+const char MSG_BABYSTEP_Z_NOT_SET_CZ[] PROGMEM = "Neni zkalibrovana vzdalenost trysky od tiskove podlozky. Postupujte prosim podle manualu, kapitola Zaciname, odstavec Nastaveni prvni vrstvy.";
+const char MSG_BABYSTEP_Z_NOT_SET_IT[] PROGMEM = "Distanza tra la punta dell'ugello e la superficie del letto non ancora imposta. Si prega di seguire il manuale, capitolo First steps, sezione First layer calibration.";
+const char MSG_BABYSTEP_Z_NOT_SET_ES[] PROGMEM = "Distancia entre la punta de la boquilla y la superficie de la cama no fijada aun. Por favor siga el manual, capitulo First steps, seccion First layer calibration.";
 const char * const MSG_BABYSTEP_Z_NOT_SET_LANG_TABLE[LANG_NUM] PROGMEM = {
 	MSG_BABYSTEP_Z_NOT_SET_EN,
 	MSG_BABYSTEP_Z_NOT_SET_CZ,
 	MSG_BABYSTEP_Z_NOT_SET_IT,
 	MSG_BABYSTEP_Z_NOT_SET_ES,
-	MSG_BABYSTEP_Z_NOT_SET_PL
+	MSG_BABYSTEP_Z_NOT_SET_EN
 };
 
 const char MSG_BED_EN[] PROGMEM = "Bed";
@@ -740,6 +739,19 @@ const char * const MSG_FLOW2_LANG_TABLE[1] PROGMEM = {
 	MSG_FLOW2_EN
 };
 
+const char MSG_FOLLOW_CALIBRATION_FLOW_EN[] PROGMEM = "Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow.";
+const char MSG_FOLLOW_CALIBRATION_FLOW_CZ[] PROGMEM = "Tiskarna nebyla jeste zkalibrovana. Postupujte prosim podle manualu, kapitola Zaciname, odstavec Postup kalibrace.";
+const char MSG_FOLLOW_CALIBRATION_FLOW_IT[] PROGMEM = "Stampante ancora non calibrata. Si prega di seguire il manuale, capitolo PRIMI PASSI, sezione della calibrazione.";
+const char MSG_FOLLOW_CALIBRATION_FLOW_ES[] PROGMEM = "Impresora no esta calibrada todavia. Por favor usar el manual, el capitulo First steps, seleccion Calibration flow.";
+const char MSG_FOLLOW_CALIBRATION_FLOW_PL[] PROGMEM = "Drukarka nie zostala jeszcze skalibrowana. Prosze kierowac sie instrukcja, rozdzial Zaczynamy, podrozdzial Selftest.";
+const char * const MSG_FOLLOW_CALIBRATION_FLOW_LANG_TABLE[LANG_NUM] PROGMEM = {
+	MSG_FOLLOW_CALIBRATION_FLOW_EN,
+	MSG_FOLLOW_CALIBRATION_FLOW_CZ,
+	MSG_FOLLOW_CALIBRATION_FLOW_IT,
+	MSG_FOLLOW_CALIBRATION_FLOW_ES,
+	MSG_FOLLOW_CALIBRATION_FLOW_PL
+};
+
 const char MSG_FREE_MEMORY_EN[] PROGMEM = " Free Memory: ";
 const char * const MSG_FREE_MEMORY_LANG_TABLE[1] PROGMEM = {
 	MSG_FREE_MEMORY_EN

+ 2 - 0
Firmware/language_all.h

@@ -184,6 +184,8 @@ extern const char* const MSG_FLOW1_LANG_TABLE[1];
 #define MSG_FLOW1 LANG_TABLE_SELECT_EXPLICIT(MSG_FLOW1_LANG_TABLE, 0)
 extern const char* const MSG_FLOW2_LANG_TABLE[1];
 #define MSG_FLOW2 LANG_TABLE_SELECT_EXPLICIT(MSG_FLOW2_LANG_TABLE, 0)
+extern const char* const MSG_FOLLOW_CALIBRATION_FLOW_LANG_TABLE[LANG_NUM];
+#define MSG_FOLLOW_CALIBRATION_FLOW LANG_TABLE_SELECT(MSG_FOLLOW_CALIBRATION_FLOW_LANG_TABLE)
 extern const char* const MSG_FREE_MEMORY_LANG_TABLE[1];
 #define MSG_FREE_MEMORY LANG_TABLE_SELECT_EXPLICIT(MSG_FREE_MEMORY_LANG_TABLE, 0)
 extern const char* const MSG_HEATING_LANG_TABLE[LANG_NUM];

+ 2 - 1
Firmware/language_cz.h

@@ -225,7 +225,8 @@
 
 #define MSG_NEW_FIRMWARE_AVAILABLE								"Vysla nova verze firmware:"
 #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE							"Prosim aktualizujte."
-#define MSG_BABYSTEP_Z_NOT_SET                          		"Tiskarna nebyla jeste zkalibrovana. Postupujte prosim podle manualu, kapitola Zaciname, odstavec Postup kalibrace."
+#define MSG_FOLLOW_CALIBRATION_FLOW                        		"Tiskarna nebyla jeste zkalibrovana. Postupujte prosim podle manualu, kapitola Zaciname, odstavec Postup kalibrace."
+#define MSG_BABYSTEP_Z_NOT_SET                          		"Neni zkalibrovana vzdalenost trysky od tiskove podlozky. Postupujte prosim podle manualu, kapitola Zaciname, odstavec Nastaveni prvni vrstvy."
 
 #define MSG_BED_CORRECTION_MENU									"Korekce podlozky"
 #define MSG_BED_CORRECTION_LEFT									"Vlevo  [um]"

+ 2 - 1
Firmware/language_en.h

@@ -220,7 +220,8 @@
 #define(length=20,lines=2) MSG_NEW_FIRMWARE_AVAILABLE								"New firmware version available:"
 #define(length=20) MSG_NEW_FIRMWARE_PLEASE_UPGRADE									"Please upgrade."
 
-#define(length=20,lines=8) MSG_BABYSTEP_Z_NOT_SET									"Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow."
+#define(length=20,lines=8) MSG_FOLLOW_CALIBRATION_FLOW								"Printer has not been calibrated yet. Please follow the manual, chapter First steps, section Calibration flow."
+#define(length=20,lines=12) MSG_BABYSTEP_Z_NOT_SET									"Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."
 
 #define MSG_BED_CORRECTION_MENU									"Bed level correct"
 #define MSG_BED_CORRECTION_LEFT									"Left side  um"

+ 2 - 1
Firmware/language_es.h

@@ -216,7 +216,8 @@
 #define MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED      			"Nivelacion fallada. Sensor desconectado o cables danados. Esperando reset."
 #define MSG_NEW_FIRMWARE_AVAILABLE                  				"Nuevo firmware disponible:"
 #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE                 			"Actualizar por favor"
-#define MSG_BABYSTEP_Z_NOT_SET                      			"Impresora no esta calibrada todavia. Por favor usar el manual, el capitulo First steps, seleccion Calibration flow."
+#define MSG_FOLLOW_CALIBRATION_FLOW                    			"Impresora no esta calibrada todavia. Por favor usar el manual, el capitulo First steps, seleccion Calibration flow."
+#define MSG_BABYSTEP_Z_NOT_SET                      			"Distancia entre la punta de la boquilla y la superficie de la cama no fijada aun. Por favor siga el manual, capitulo First steps, seccion First layer calibration."
 #define MSG_BED_CORRECTION_MENU                                 "Corr. de la cama"
 #define MSG_BED_CORRECTION_LEFT                                 "Izquierda [um]"
 #define MSG_BED_CORRECTION_RIGHT                                "Derecha   [um]"

+ 2 - 1
Firmware/language_it.h

@@ -209,7 +209,8 @@
 #define MSG_NEW_FIRMWARE_AVAILABLE						"Nuova versione del firmware disponibile"
 #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE					"Prega aggiorna."
 
-#define MSG_BABYSTEP_Z_NOT_SET							"Stampante ancora non calibrata. Si prega di seguire il manuale, capitolo PRIMI PASSI, sezione della calibrazione."
+#define MSG_FOLLOW_CALIBRATION_FLOW						"Stampante ancora non calibrata. Si prega di seguire il manuale, capitolo PRIMI PASSI, sezione della calibrazione."
+#define MSG_BABYSTEP_Z_NOT_SET							"Distanza tra la punta dell'ugello e la superficie del letto non ancora imposta. Si prega di seguire il manuale, capitolo First steps, sezione First layer calibration."
 
 #define MSG_BED_CORRECTION_MENU							"Correz. liv.letto"
 #define MSG_BED_CORRECTION_LEFT							"Lato sinistro um"

+ 2 - 1
Firmware/language_pl.h

@@ -222,7 +222,8 @@
 #define MSG_BED_LEVELING_FAILED_PROBE_DISCONNECTED              "Kalibracja nieudana. Sensor odlaczony lub uszkodz. kabel. Czekam na reset."
 #define MSG_NEW_FIRMWARE_AVAILABLE                              "Wyszla nowa wersja firmware:"
 #define MSG_NEW_FIRMWARE_PLEASE_UPGRADE                         "Prosze zaktualizowac"
-#define MSG_BABYSTEP_Z_NOT_SET                                  "Drukarka nie zostala jeszcze skalibrowana. Prosze kierowac sie instrukcja, rozdzial Zaczynamy, podrozdzial Selftest."
+#define MSG_FOLLOW_CALIBRATION_FLOW                             "Drukarka nie zostala jeszcze skalibrowana. Prosze kierowac sie instrukcja, rozdzial Zaczynamy, podrozdzial Selftest."
+#define MSG_BABYSTEP_Z_NOT_SET                                  "Distance between tip of the nozzle and the bed surface has not been set yet. Please follow the manual, chapter First steps, section First layer calibration."
 #define MSG_BED_CORRECTION_MENU                                 "Korekta podkladki"
 #define MSG_BED_CORRECTION_LEFT                                 "W lewo  [um]"
 #define MSG_BED_CORRECTION_RIGHT                                "W prawo [um]"

+ 2 - 1
Firmware/mesh_bed_calibration.cpp

@@ -1,5 +1,6 @@
 #include "Marlin.h"
 #include "Configuration.h"
+#include "ConfigurationStore.h"
 #include "language_all.h"
 #include "mesh_bed_calibration.h"
 #include "mesh_bed_leveling.h"
@@ -2152,7 +2153,7 @@ static int babystepLoadZ = 0;
 void babystep_apply()
 {
     // Apply Z height correction aka baby stepping before mesh bed leveing gets activated.
-    if(eeprom_read_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET) == 0x01)
+    if(calibration_status() == CALIBRATION_STATUS_CALIBRATED)
     {
         // End of G80: Apply the baby stepping value.
         EEPROM_read_B(EEPROM_BABYSTEP_Z,&babystepLoadZ);

+ 60 - 10
Firmware/temperature.cpp

@@ -158,6 +158,13 @@ static float analog2temp(int raw, uint8_t e);
 static float analog2tempBed(int raw);
 static void updateTemperaturesFromRawValues();
 
+enum TempRunawayStates
+{
+	TempRunaway_INACTIVE = 0,
+	TempRunaway_PREHEAT = 1,
+	TempRunaway_ACTIVE = 2,
+};
+
 #ifdef WATCH_TEMP_PERIOD
 int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
 unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
@@ -1049,6 +1056,9 @@ void temp_runaway_check(int _heater_id, float _target_temperature, float _curren
 	float __hysteresis = 0;
 	int __timeout = 0;
 	bool temp_runaway_check_active = false;
+	static float __preheat_start = 0;
+	static int __preheat_counter = 0;
+	static int __preheat_errors = 0;
 
 	_heater_id = (_isbed) ? _heater_id++ : _heater_id;
 
@@ -1069,8 +1079,8 @@ void temp_runaway_check(int _heater_id, float _target_temperature, float _curren
 
 	if (millis() - temp_runaway_timer[_heater_id] > 2000)
 	{
-		temp_runaway_timer[_heater_id] = millis();
 
+		temp_runaway_timer[_heater_id] = millis();
 		if (_output == 0)
 		{
 			temp_runaway_check_active = false;
@@ -1081,19 +1091,42 @@ void temp_runaway_check(int _heater_id, float _target_temperature, float _curren
 		{
 			if (_target_temperature > 0)
 			{
-				temp_runaway_status[_heater_id] = 1;
+				temp_runaway_status[_heater_id] = TempRunaway_PREHEAT;
 				temp_runaway_target[_heater_id] = _target_temperature;
+				__preheat_start = _current_temperature;
+				__preheat_counter = 0;
 			}
 			else
 			{
-				temp_runaway_status[_heater_id] = 0;
+				temp_runaway_status[_heater_id] = TempRunaway_INACTIVE;
 				temp_runaway_target[_heater_id] = _target_temperature;
 			}
 		}
 
-		if (_current_temperature >= _target_temperature  && temp_runaway_status[_heater_id] == 1)
+		if (temp_runaway_status[_heater_id] == TempRunaway_PREHEAT)
 		{
-			temp_runaway_status[_heater_id] = 2;
+			__preheat_counter++;
+			if (__preheat_counter > 4)
+			{
+
+				if (_current_temperature - __preheat_start < 2){
+					__preheat_errors++;}
+				else{
+					__preheat_errors = 0;}
+
+				if (__preheat_errors > 5)
+				{
+					temp_runaway_stop(true);
+				}
+				__preheat_start = _current_temperature;
+				__preheat_counter = 0;
+			}
+
+		}
+
+		if (_current_temperature >= _target_temperature  && temp_runaway_status[_heater_id] == TempRunaway_PREHEAT)
+		{
+			temp_runaway_status[_heater_id] = TempRunaway_ACTIVE;
 			temp_runaway_check_active = false;
 		}
 
@@ -1109,16 +1142,16 @@ void temp_runaway_check(int _heater_id, float _target_temperature, float _curren
 			if (_target_temperature - __hysteresis < _current_temperature && _current_temperature < _target_temperature + __hysteresis)
 			{
 				temp_runaway_check_active = false;
+				temp_runaway_error_counter[_heater_id] = 0;
 			}
 			else
 			{
-				if (temp_runaway_status[_heater_id] > 1)
+				if (temp_runaway_status[_heater_id] > TempRunaway_PREHEAT)
 				{
 					temp_runaway_error_counter[_heater_id]++;
-
 					if (temp_runaway_error_counter[_heater_id] * 2 > __timeout)
 					{
-						temp_runaway_stop();
+						temp_runaway_stop(false);
 					}
 				}
 			}
@@ -1127,7 +1160,7 @@ void temp_runaway_check(int _heater_id, float _target_temperature, float _curren
 	}
 }
 
-void temp_runaway_stop()
+void temp_runaway_stop(bool isPreheat)
 {
 	cancel_heatup = true;
 	quickStop();
@@ -1136,7 +1169,7 @@ void temp_runaway_stop()
 		card.sdprinting = false;
 		card.closefile();
 	}
-	LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY");
+	
 	disable_heater();
 	disable_x();
 	disable_y();
@@ -1149,6 +1182,23 @@ void temp_runaway_stop()
 	delayMicroseconds(500);
 	WRITE(BEEPER, LOW);
 	delayMicroseconds(100);
+
+	if (isPreheat)
+	{
+		Stop();
+		LCD_ALERTMESSAGEPGM("   PREHEAT ERROR");
+
+		SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
+		SET_OUTPUT(FAN_PIN);
+		WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1);
+		analogWrite(FAN_PIN, 255);
+		fanSpeed = 255;
+		delayMicroseconds(2000);
+	}
+	else
+	{
+		LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY");
+	}
 }
 #endif
 

+ 1 - 1
Firmware/temperature.h

@@ -180,7 +180,7 @@ static float temp_runaway_timer[4];
 static int temp_runaway_error_counter[4];
 
 void temp_runaway_check(int _heater_id, float _target_temperature, float _current_temperature, float _output, bool _isbed);
-void temp_runaway_stop();
+void temp_runaway_stop(bool isPreheat);
 #endif
 
 int getHeaterPower(int heater);

+ 4 - 7
Firmware/ultralcd.cpp

@@ -1244,6 +1244,8 @@ static void _lcd_babystep(int axis, const char *msg)
         menuData.babyStep.babystepMemMM[1] = menuData.babyStep.babystepMem[1]/axis_steps_per_unit[Y_AXIS];
         menuData.babyStep.babystepMemMM[2] = menuData.babyStep.babystepMem[2]/axis_steps_per_unit[Z_AXIS];
         lcdDrawUpdate = 1;
+        // Wait 90 seconds before closing the live adjust dialog.
+        lcd_timeoutToStatus = millis() + 90000;
     }
 
   if (encoderPosition != 0) 
@@ -1984,22 +1986,17 @@ void lcd_pick_babystep(){
             
         }
         
-        
         if (lcd_clicked()) {
             fsm = cursor_pos;
             int babyStepZ;
             EEPROM_read_B(EEPROM_BABYSTEP_Z0+((fsm-1)*2),&babyStepZ);
             EEPROM_save_B(EEPROM_BABYSTEP_Z,&babyStepZ);
-            eeprom_write_byte((unsigned char*)EEPROM_BABYSTEP_Z_SET, 0x01);
+            calibration_status_store(CALIBRATION_STATUS_CALIBRATED);
             delay(500);
             
         }
-        
-        
-        
     };
     
-    
     lcd_implementation_clear();
     lcd_return_to_status();
 }
@@ -3313,7 +3310,7 @@ void lcd_init()
 //#include <avr/pgmspace.h>
 
 static volatile bool lcd_update_enabled = true;
-static unsigned long lcd_timeoutToStatus = 0;
+unsigned long lcd_timeoutToStatus = 0;
 
 void lcd_update_enable(bool enabled)
 {

+ 1 - 0
Firmware/ultralcd.h

@@ -89,6 +89,7 @@ void lcd_mylang();
   #define LCD_COMMAND_STOP_PRINT 2
   #define LCD_COMMAND_FARM_MODE_CONFIRM 4
 
+  extern unsigned long lcd_timeoutToStatus;
   extern int lcd_commands_type;
   
   extern bool farm_mode;