Browse Source

Merge remote-tracking branch 'upstream/MK3' into MK3

DRracer 5 years ago
parent
commit
789ced48fc

+ 46 - 21
Firmware/Marlin_main.cpp

@@ -3001,6 +3001,32 @@ void gcode_M114()
 	SERIAL_PROTOCOLLN("");
 }
 
+//! extracted code to compute z_shift for M600 in case of filament change operation 
+//! requested from fsensors.
+//! The function ensures, that the printhead lifts to at least 25mm above the heat bed
+//! unlike the previous implementation, which was adding 25mm even when the head was
+//! printing at e.g. 24mm height.
+//! A safety margin of FILAMENTCHANGE_ZADD is added in all cases to avoid touching
+//! the printout.
+//! This function is templated to enable fast change of computation data type.
+//! @return new z_shift value
+template<typename T>
+static T gcode_M600_filament_change_z_shift()
+{
+#ifdef FILAMENTCHANGE_ZADD
+	static_assert(Z_MAX_POS < (255 - FILAMENTCHANGE_ZADD), "Z-range too high, change the T type from uint8_t to uint16_t");
+	// avoid floating point arithmetics when not necessary - results in shorter code
+	T ztmp = T( current_position[Z_AXIS] );
+	T z_shift = 0;
+	if(ztmp < T(25)){
+		z_shift = T(25) - ztmp; // make sure to be at least 25mm above the heat bed
+	} 
+	return z_shift + T(FILAMENTCHANGE_ZADD); // always move above printout
+#else
+	return T(0);
+#endif
+}	
+
 static void gcode_M600(bool automatic, float x_position, float y_position, float z_shift, float e_shift, float /*e_shift_late*/)
 {
     st_synchronize();
@@ -3390,8 +3416,10 @@ void process_commands()
 {
   #ifdef FANCHECK
   if (fan_check_error){
-    fan_check_error = false;
-    lcd_pause_print();
+	if( fan_check_error == EFCE_DETECTED ){
+		fan_check_error = EFCE_REPORTED;
+		lcd_pause_print();
+	} // otherwise it has already been reported, so just ignore further processing
     return;
   }
   #endif
@@ -3552,10 +3580,6 @@ void process_commands()
                enquecommand_P(PSTR("M24")); 
 		}	
 #ifdef FILAMENT_SENSOR
-		else if (code_seen("fsensor_recover_IR")) //! PRUSA fsensor_recover_IR
-		{
-			fsensor_restore_print_and_continue_IR();
-		}
 		else if (code_seen("fsensor_recover")) //! PRUSA fsensor_recover
 		{
                fsensor_restore_print_and_continue();
@@ -6590,7 +6614,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
 
 		float x_position = current_position[X_AXIS];
 		float y_position = current_position[Y_AXIS];
-		float z_shift = 0;
+		float z_shift = 0; // is it necessary to be a float?
 		float e_shift_init = 0;
 		float e_shift_late = 0;
 		bool automatic = false;
@@ -6626,10 +6650,7 @@ if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE))
         }
         else
         {
-          #ifdef FILAMENTCHANGE_ZADD
-            z_shift= FILAMENTCHANGE_ZADD ;
-            if(current_position[Z_AXIS] < 25) z_shift+= 25 ;
-          #endif
+			z_shift = gcode_M600_filament_change_z_shift<uint8_t>();
         }
 		//Move XY to side
         if(code_seen('X'))
@@ -9307,22 +9328,20 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
 
 	// First unretract (relative extrusion)
 	if(!saved_extruder_relative_mode){
-	  strcpy_P(buf, PSTR("M83"));
-	  enquecommand(buf, false);
+		enquecommand(PSTR("M83"), true);
 	}
 	
 	//retract 45mm/s
-	strcpy_P(buf, PSTR("G1 E"));
-	dtostrf(e_move, 6, 3, buf + strlen(buf));
-	strcat_P(buf, PSTR(" F"));
-	dtostrf(2700, 8, 3, buf + strlen(buf));
+	// A single sprintf may not be faster, but is definitely 20B shorter
+	// than a sequence of commands building the string piece by piece
+	// A snprintf would have been a safer call, but since it is not used
+	// in the whole program, its implementation would bring more bytes to the total size
+	// The behavior of dtostrf 8,3 should be roughly the same as %-0.3
+	sprintf_P(buf, PSTR("G1 E%-0.3f F2700"), e_move);
 	enquecommand(buf, false);
 
 	// Then lift Z axis
-    strcpy_P(buf, PSTR("G1 Z"));
-    dtostrf(saved_pos[Z_AXIS] + z_move, 8, 3, buf + strlen(buf));
-    strcat_P(buf, PSTR(" F"));
-    dtostrf(homing_feedrate[Z_AXIS], 8, 3, buf + strlen(buf));
+	sprintf_P(buf, PSTR("G1 Z%-0.3f F%-0.3f"), saved_pos[Z_AXIS] + z_move, homing_feedrate[Z_AXIS]); 
     // At this point the command queue is empty.
     enquecommand(buf, false);
     // If this call is invoked from the main Arduino loop() function, let the caller know that the command
@@ -9348,6 +9367,12 @@ void stop_and_save_print_to_ram(float z_move, float e_move)
 void restore_print_from_ram_and_continue(float e_move)
 {
 	if (!saved_printing) return;
+	
+#ifdef FANCHECK
+	// Do not allow resume printing if fans are still not ok
+	if( fan_check_error != EFCE_OK )return;
+#endif
+	
 //	for (int axis = X_AXIS; axis <= E_AXIS; axis++)
 //	    current_position[axis] = st_get_position_mm(axis);
 	active_extruder = saved_active_extruder; //restore active_extruder

+ 48 - 21
Firmware/fsensor.cpp

@@ -123,17 +123,12 @@ void fsensor_stop_and_save_print(void)
     stop_and_save_print_to_ram(0, 0); //XYZE - no change
 }
 
-void fsensor_restore_print_and_continue_IR(void)
+void fsensor_restore_print_and_continue(void)
 {
+    printf_P(PSTR("fsensor_restore_print_and_continue\n"));
 	fsensor_watch_runout = true;
 	fsensor_err_cnt = 0;
 	fsensor_m600_enqueued = false;
-}
-
-void fsensor_restore_print_and_continue(void)
-{
-    printf_P(PSTR("fsensor_restore_print_and_continue\n"));
-    fsensor_restore_print_and_continue_IR();
     restore_print_from_ram_and_continue(0); //XYZ = orig, E - no change
 }
 
@@ -527,6 +522,47 @@ void fsensor_st_block_chunk(block_t* bl, int cnt)
 	}
 }
 
+//! This ensures generating z-position at least 25mm above the heat bed.
+//! Making this a template enables changing the computation data type easily at all spots where necessary.
+//! @param current_z current z-position
+//! @return z-position at least 25mm above the heat bed plus FILAMENTCHANGE_ZADD 
+template <typename T>
+inline T fsensor_clamp_z(float current_z){
+	T z( current_z );
+	if(z < T(25)){ // make sure the compiler understands, that the constant 25 is of correct type
+		// - necessary for uint8_t -> results in shorter code
+		z = T(25); // move to at least 25mm above heat bed
+	}
+	return z + T(FILAMENTCHANGE_ZADD); // always move above the printout by FILAMENTCHANGE_ZADD (default 2mm)	
+}
+
+//! Common code for enqueing M600 and supplemental codes into the command queue.
+//! Used both for the IR sensor and the PAT9125
+void fsensor_enque_M600(){
+	printf_P(PSTR("fsensor_update - M600\n"));
+	eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
+	eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
+	enquecommand_front_P(PSTR("PRUSA fsensor_recover"));
+	fsensor_m600_enqueued = true;
+	enquecommand_front_P((PSTR("M600")));
+#define xstr(a) str(a)
+#define str(a) #a
+	static const char gcodeMove[] PROGMEM = 
+			"G1 X" xstr(FILAMENTCHANGE_XPOS) 
+			" Y" xstr(FILAMENTCHANGE_YPOS) 
+			" Z%u";
+#undef str
+#undef xstr
+	char buf[32];
+	// integer arithmetics is far shorter, I don't need a precise float position here, just move a bit above
+	// 8bit arithmetics in fsensor_clamp_z is 10B shorter than 16bit (not talking about float ;) ) 
+	// The compile-time static_assert here ensures, that the computation gets enough bits in case of Z-range too high,
+	// i.e. makes the user change the data type, which also results in larger code
+	static_assert(Z_MAX_POS < (255 - FILAMENTCHANGE_ZADD), "Z-range too high, change fsensor_clamp_z<uint8_t> to <uint16_t>");
+	sprintf_P(buf, gcodeMove, fsensor_clamp_z<uint8_t>(current_position[Z_AXIS]) );
+	enquecommand_front(buf, false);
+}
+
 //! @brief filament sensor update (perform M600 on filament runout)
 //!
 //! Works only if filament sensor is enabled.
@@ -535,7 +571,7 @@ void fsensor_st_block_chunk(block_t* bl, int cnt)
 void fsensor_update(void)
 {
 #ifdef PAT9125
-		if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX))
+		if (fsensor_enabled && fsensor_watch_runout && (fsensor_err_cnt > FSENSOR_ERR_MAX) && ( ! fsensor_m600_enqueued) )
 		{
 			bool autoload_enabled_tmp = fsensor_autoload_enabled;
 			fsensor_autoload_enabled = false;
@@ -575,11 +611,7 @@ void fsensor_update(void)
 			}
 			else
 			{
-				printf_P(PSTR("fsensor_update - M600\n"));
-				eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
-				eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
-				enquecommand_front_P(PSTR("PRUSA fsensor_recover"));
-				enquecommand_front_P((PSTR("M600")));
+				fsensor_enque_M600();
 				fsensor_watch_runout = false;
 			}
 			fsensor_autoload_enabled = autoload_enabled_tmp;
@@ -587,14 +619,9 @@ void fsensor_update(void)
 		}
 #else //PAT9125
 		if ((digitalRead(IR_SENSOR_PIN) == 1) && CHECK_FSENSOR && fsensor_enabled && ir_sensor_detected && ( ! fsensor_m600_enqueued) )
-		{	// just plan a simple M600 without any additional position save/restore,
-			// which caused weird heating issues standing directly over the print
-			printf_P(PSTR("fsensor_update - M600\n"));
-			eeprom_update_byte((uint8_t*)EEPROM_FERROR_COUNT, eeprom_read_byte((uint8_t*)EEPROM_FERROR_COUNT) + 1);
-			eeprom_update_word((uint16_t*)EEPROM_FERROR_COUNT_TOT, eeprom_read_word((uint16_t*)EEPROM_FERROR_COUNT_TOT) + 1);
-			enquecommand_front_P(PSTR("PRUSA fsensor_recover_IR"));
-			fsensor_m600_enqueued = true;
-			enquecommand_front_P((PSTR("M600")));
+		{
+			fsensor_stop_and_save_print();
+			fsensor_enque_M600();
 		}
 #endif //PAT9125
 }

+ 1 - 3
Firmware/fsensor.h

@@ -18,9 +18,7 @@ extern bool fsensor_oq_meassure_enabled;
 //! @name save restore printing
 //! @{
 extern void fsensor_stop_and_save_print(void);
-//! special handling for the IR sensor (no restore position and heating, since this is already correctly handled in the M600 itself)
-extern void fsensor_restore_print_and_continue_IR(void);
-//! legacy restore print - restore position and heatup to original temperature - for the MMU and the optical fsensor
+//! restore print - restore position and heatup to original temperature
 extern void fsensor_restore_print_and_continue(void);
 //! @}
 

+ 1 - 2
Firmware/pins_Einsy_1_0.h

@@ -99,8 +99,7 @@
 
 //#define KILL_PIN            32
 
-// LCD backlight pin may interfere with something, this is yet to be found out correctly
-#define LCD_BL_PIN          5   //backlight control pin
+//#define LCD_BL_PIN          5   //backlight control pin
 #define BEEPER              84  // Beeper on AUX-4
 #define LCD_PINS_RS         82
 #define LCD_PINS_ENABLE     61 // !!! changed from 18 (EINY03)

+ 29 - 21
Firmware/temperature.cpp

@@ -95,7 +95,7 @@ float current_temperature_bed = 0.0;
 #endif
 
 #ifdef FANCHECK
-  volatile bool fan_check_error = false;
+  volatile uint8_t fan_check_error = EFCE_OK;
 #endif
 
 unsigned char soft_pwm_bed;
@@ -512,6 +512,12 @@ void checkFanSpeed()
 	else fan_speed_errors[1] = 0;
 #endif
 
+	// drop the fan_check_error flag when both fans are ok
+	if( fan_speed_errors[0] == 0 && fan_speed_errors[1] == 0 && fan_check_error == EFCE_REPORTED){
+		// we may even send some info to the LCD from here
+		fan_check_error = EFCE_OK;
+	}
+
 	if ((fan_speed_errors[0] > max_extruder_fan_errors) && fans_check_enabled) {
 		fan_speed_errors[0] = 0;
 		fanSpeedError(0); //extruder fan
@@ -522,6 +528,23 @@ void checkFanSpeed()
 	}
 }
 
+//! Prints serialMsg to serial port, displays lcdMsg onto the LCD and beeps.
+//! Extracted from fanSpeedError to save some space.
+//! @param serialMsg pointer into PROGMEM, this text will be printed to the serial port
+//! @param lcdMsg pointer into PROGMEM, this text will be printed onto the LCD
+static void fanSpeedErrorBeep(const char *serialMsg, const char *lcdMsg){
+	SERIAL_ECHOLNRPGM(serialMsg);
+	if (get_message_level() == 0) {
+		if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)||(eSoundMode==e_SOUND_MODE_SILENT)){
+			WRITE(BEEPER, HIGH);
+			delayMicroseconds(200);
+			WRITE(BEEPER, LOW);
+			delayMicroseconds(100); // what is this wait for?
+		}
+		LCD_ALERTMESSAGERPGM(lcdMsg);
+	}
+}
+
 void fanSpeedError(unsigned char _fan) {
 	if (get_message_level() != 0 && isPrintPaused) return; 
 	//to ensure that target temp. is not set to zero in case taht we are resuming print 
@@ -530,7 +553,8 @@ void fanSpeedError(unsigned char _fan) {
 			lcd_print_stop();
 		}
 		else {
-			fan_check_error = true;
+			fan_check_error = EFCE_DETECTED;
+
 		}
 	}
 	else {
@@ -538,27 +562,11 @@ void fanSpeedError(unsigned char _fan) {
 			SERIAL_ECHOLNPGM("// action:pause"); //for octoprint
 	}
 	switch (_fan) {
-	case 0:
-			SERIAL_ECHOLNPGM("Extruder fan speed is lower then expected");
-			if (get_message_level() == 0) {
-if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)||(eSoundMode==e_SOUND_MODE_SILENT))
-				WRITE(BEEPER, HIGH);
-				delayMicroseconds(200);
-				WRITE(BEEPER, LOW);
-				delayMicroseconds(100);
-				LCD_ALERTMESSAGEPGM("Err: EXTR. FAN ERROR");
-			}
+	case 0:	// extracting the same code from case 0 and case 1 into a function saves 72B
+		fanSpeedErrorBeep(PSTR("Extruder fan speed is lower than expected"), PSTR("Err: EXTR. FAN ERROR") );
 		break;
 	case 1:
-			SERIAL_ECHOLNPGM("Print fan speed is lower then expected");
-			if (get_message_level() == 0) {
-if((eSoundMode==e_SOUND_MODE_LOUD)||(eSoundMode==e_SOUND_MODE_ONCE)||(eSoundMode==e_SOUND_MODE_SILENT))
-				WRITE(BEEPER, HIGH);
-				delayMicroseconds(200);
-				WRITE(BEEPER, LOW);
-				delayMicroseconds(100);
-				LCD_ALERTMESSAGEPGM("Err: PRINT FAN ERROR");
-			}
+		fanSpeedErrorBeep(PSTR("Print fan speed is lower than expected"), PSTR("Err: PRINT FAN ERROR") );
 		break;
 	}
 }

+ 6 - 1
Firmware/temperature.h

@@ -238,7 +238,12 @@ void checkExtruderAutoFans();
 
 #if (defined(FANCHECK) && defined(TACH_0) && (TACH_0 > -1))
 
-extern volatile bool fan_check_error;
+enum { 
+	EFCE_OK = 0,   //!< normal operation, both fans are ok
+	EFCE_DETECTED, //!< fan error detected, but not reported yet
+	EFCE_REPORTED  //!< fan error detected and reported to LCD and serial
+};
+extern volatile uint8_t fan_check_error;
 
 void countFanSpeed();
 void checkFanSpeed();

+ 1 - 1
Firmware/ultralcd.cpp

@@ -5972,7 +5972,7 @@ static void fil_load_menu()
 
     if (mmu_enabled)
     {
-        MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), '5', extr_adj, 3);
+        MENU_ITEM_FUNCTION_NR_P(_T(MSG_LOAD_FILAMENT), '5', extr_adj, 4);
     }
     MENU_END();
 }