|  |  | @@ -284,32 +284,51 @@ bool volumetric_enabled = false; | 
			
		
	
		
		
			
				
					
					|  |  |  | float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(DEFAULT_NOMINAL_FILAMENT_DIA); |  |  |  | float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(DEFAULT_NOMINAL_FILAMENT_DIA); | 
			
		
	
		
		
			
				
					
					|  |  |  | float volumetric_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0); |  |  |  | float volumetric_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // The distance that XYZ has been offset by G92. Reset by G28. | 
			
		
	
		
		
			
				
					
					|  |  |  | float position_shift[3] = { 0 }; |  |  |  | float position_shift[3] = { 0 }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // This offset is added to the configured home position. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Set by M206, M428, or menu item. Saved to EEPROM. | 
			
		
	
		
		
			
				
					
					|  |  |  | float home_offset[3] = { 0 }; |  |  |  | float home_offset[3] = { 0 }; | 
			
		
	
		
		
			
				
					
					|  |  |  | float min_pos[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }; |  |  |  |  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | float max_pos[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS }; |  |  |  | // Software Endstops. Default to configured limits. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | float sw_endstop_min[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | float sw_endstop_max[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS }; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #if FAN_COUNT > 0 |  |  |  | #if FAN_COUNT > 0 | 
			
		
	
		
		
			
				
					
					|  |  |  |   int fanSpeeds[FAN_COUNT] = { 0 }; |  |  |  |   int fanSpeeds[FAN_COUNT] = { 0 }; | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // The active extruder (tool). Set with T<extruder> command. | 
			
		
	
		
		
			
				
					
					|  |  |  | uint8_t active_extruder = 0; |  |  |  | uint8_t active_extruder = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Relative Mode. Enable with G91, disable with G90. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static bool relative_mode = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | bool cancel_heatup = false; |  |  |  | bool cancel_heatup = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | const char errormagic[] PROGMEM = "Error:"; |  |  |  | const char errormagic[] PROGMEM = "Error:"; | 
			
		
	
		
		
			
				
					
					|  |  |  | const char echomagic[] PROGMEM = "echo:"; |  |  |  | const char echomagic[] PROGMEM = "echo:"; | 
			
		
	
		
		
			
				
					
					|  |  |  | const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'}; |  |  |  | const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'}; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static bool relative_mode = false;  //Determines Absolute or Relative Coordinates |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static int serial_count = 0; |  |  |  | static int serial_count = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | static char* seen_pointer; ///< A pointer to find chars in the command string (X, Y, Z, E, etc.) |  |  |  |  | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | const char* queued_commands_P = NULL; /* pointer to the current line in the active sequence of commands, or NULL when none */ |  |  |  | // GCode parameter pointer used by code_seen(), code_value(), etc. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static char* seen_pointer; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Next Immediate GCode Command pointer. NULL if none. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | const char* queued_commands_P = NULL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42 |  |  |  | const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // Inactivity shutdown |  |  |  | // Inactivity shutdown | 
			
		
	
		
		
			
				
					
					|  |  |  | millis_t previous_cmd_ms = 0; |  |  |  | millis_t previous_cmd_ms = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | static millis_t max_inactive_time = 0; |  |  |  | static millis_t max_inactive_time = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  | static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL; |  |  |  | static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // Print Job Timer | 
			
		
	
		
		
			
				
					
					|  |  |  | Stopwatch print_job_timer = Stopwatch(); |  |  |  | Stopwatch print_job_timer = Stopwatch(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static uint8_t target_extruder; |  |  |  | static uint8_t target_extruder; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #if ENABLED(AUTO_BED_LEVELING_FEATURE) |  |  |  | #if ENABLED(AUTO_BED_LEVELING_FEATURE) | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -344,8 +363,8 @@ static uint8_t target_extruder; | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #if ENABLED(BARICUDA) |  |  |  | #if ENABLED(BARICUDA) | 
			
		
	
		
		
			
				
					
					|  |  |  |   int ValvePressure = 0; |  |  |  |   int baricuda_valve_pressure = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   int EtoPPressure = 0; |  |  |  |   int baricuda_e_to_p_pressure = 0; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #if ENABLED(FWRETRACT) |  |  |  | #if ENABLED(FWRETRACT) | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -427,7 +446,7 @@ static uint8_t target_extruder; | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #if ENABLED(FILAMENT_RUNOUT_SENSOR) |  |  |  | #if ENABLED(FILAMENT_RUNOUT_SENSOR) | 
			
		
	
		
		
			
				
					
					|  |  |  |   static bool filrunoutEnqueued = false; |  |  |  |   static bool filament_ran_out = false; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | #endif |  |  |  | #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | static bool send_ok[BUFSIZE]; |  |  |  | static bool send_ok[BUFSIZE]; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -472,13 +491,13 @@ static bool send_ok[BUFSIZE]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  * *************************************************************************** |  |  |  |  * *************************************************************************** | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | void stop(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void get_available_commands(); |  |  |  | void get_available_commands(); | 
			
		
	
		
		
			
				
					
					|  |  |  | void process_next_command(); |  |  |  | void process_next_command(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void plan_arc(float target[NUM_AXIS], float* offset, uint8_t clockwise); |  |  |  | void plan_arc(float target[NUM_AXIS], float* offset, uint8_t clockwise); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | bool setTargetedHotend(int code); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void serial_echopair_P(const char* s_P, int v)           { serialprintPGM(s_P); SERIAL_ECHO(v); } |  |  |  | void serial_echopair_P(const char* s_P, int v)           { serialprintPGM(s_P); SERIAL_ECHO(v); } | 
			
		
	
		
		
			
				
					
					|  |  |  | void serial_echopair_P(const char* s_P, long v)          { serialprintPGM(s_P); SERIAL_ECHO(v); } |  |  |  | void serial_echopair_P(const char* s_P, long v)          { serialprintPGM(s_P); SERIAL_ECHO(v); } | 
			
		
	
		
		
			
				
					
					|  |  |  | void serial_echopair_P(const char* s_P, float v)         { serialprintPGM(s_P); SERIAL_ECHO(v); } |  |  |  | void serial_echopair_P(const char* s_P, float v)         { serialprintPGM(s_P); SERIAL_ECHO(v); } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1142,6 +1161,30 @@ bool code_seen(char code) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   return (seen_pointer != NULL); // Return TRUE if the code-letter was found |  |  |  |   return (seen_pointer != NULL); // Return TRUE if the code-letter was found | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * Set target_extruder from the T parameter or the active_extruder | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * Returns TRUE if the target is invalid | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | bool get_target_extruder_from_command(int code) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if (code_seen('T')) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     short t = code_value_short(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if (t >= EXTRUDERS) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       SERIAL_ECHO_START; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       SERIAL_CHAR('M'); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       SERIAL_ECHO(code); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       SERIAL_ECHOPAIR(" " MSG_INVALID_EXTRUDER " ", t); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       SERIAL_EOL; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       return true; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     target_extruder = t; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   else | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     target_extruder = active_extruder; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return false; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #define DEFINE_PGM_READ_ANY(type, reader)       \ |  |  |  | #define DEFINE_PGM_READ_ANY(type, reader)       \ | 
			
		
	
		
		
			
				
					
					|  |  |  |   static inline type pgm_read_any(const type *p)  \ |  |  |  |   static inline type pgm_read_any(const type *p)  \ | 
			
		
	
		
		
			
				
					
					|  |  |  |   { return pgm_read_##reader##_near(p); } |  |  |  |   { return pgm_read_##reader##_near(p); } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1212,24 +1255,32 @@ static void update_software_endstops(AxisEnum axis) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (axis == X_AXIS) { |  |  |  |     if (axis == X_AXIS) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       float dual_max_x = max(extruder_offset[X_AXIS][1], X2_MAX_POS); |  |  |  |       float dual_max_x = max(extruder_offset[X_AXIS][1], X2_MAX_POS); | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (active_extruder != 0) { |  |  |  |       if (active_extruder != 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         min_pos[X_AXIS] = X2_MIN_POS + offs; |  |  |  |         sw_endstop_min[X_AXIS] = X2_MIN_POS + offs; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         max_pos[X_AXIS] = dual_max_x + offs; |  |  |  |         sw_endstop_max[X_AXIS] = dual_max_x + offs; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |         return; | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |       else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { |  |  |  |       else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         min_pos[X_AXIS] = base_min_pos(X_AXIS) + offs; |  |  |  |         sw_endstop_min[X_AXIS] = base_min_pos(X_AXIS) + offs; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         max_pos[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs; |  |  |  |         sw_endstop_max[X_AXIS] = min(base_max_pos(X_AXIS), dual_max_x - duplicate_extruder_x_offset) + offs; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         return; |  |  |  |         return; | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |     else | 
			
		
	
		
		
			
				
					
					|  |  |  |   #endif |  |  |  |   #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |   { |  |  |  |   { | 
			
		
	
		
		
			
				
					
					|  |  |  |     min_pos[axis] = base_min_pos(axis) + offs; |  |  |  |     sw_endstop_min[axis] = base_min_pos(axis) + offs; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     max_pos[axis] = base_max_pos(axis) + offs; |  |  |  |     sw_endstop_max[axis] = base_max_pos(axis) + offs; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * Change the home offset for an axis, update the current | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * position and the software endstops to retain the same | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * relative distance to the new home. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * Since this changes the current_position, code should | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * call sync_plan_position soon after this. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | static void set_home_offset(AxisEnum axis, float v) { |  |  |  | static void set_home_offset(AxisEnum axis, float v) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   current_position[axis] += v - home_offset[axis]; |  |  |  |   current_position[axis] += v - home_offset[axis]; | 
			
		
	
		
		
			
				
					
					|  |  |  |   home_offset[axis] = v; |  |  |  |   home_offset[axis] = v; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1294,8 +1345,8 @@ static void set_axis_is_at_home(AxisEnum axis) { | 
			
		
	
		
		
			
				
					
					|  |  |  |        * SCARA home positions are based on configuration since the actual |  |  |  |        * SCARA home positions are based on configuration since the actual | 
			
		
	
		
		
			
				
					
					|  |  |  |        * limits are determined by the inverse kinematic transform. |  |  |  |        * limits are determined by the inverse kinematic transform. | 
			
		
	
		
		
			
				
					
					|  |  |  |        */ |  |  |  |        */ | 
			
		
	
		
		
			
				
					
					|  |  |  |       min_pos[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis)); |  |  |  |       sw_endstop_min[axis] = base_min_pos(axis); // + (delta[axis] - base_home_pos(axis)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       max_pos[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis)); |  |  |  |       sw_endstop_max[axis] = base_max_pos(axis); // + (delta[axis] - base_home_pos(axis)); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |     else | 
			
		
	
		
		
			
				
					
					|  |  |  |   #endif |  |  |  |   #endif | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1712,7 +1763,7 @@ static void setup_for_endstop_move() { | 
			
		
	
		
		
			
				
					
					|  |  |  |             SERIAL_ERRORLNPGM("Z-Probe failed to engage!"); |  |  |  |             SERIAL_ERRORLNPGM("Z-Probe failed to engage!"); | 
			
		
	
		
		
			
				
					
					|  |  |  |             LCD_ALERTMESSAGEPGM("Err: ZPROBE"); |  |  |  |             LCD_ALERTMESSAGEPGM("Err: ZPROBE"); | 
			
		
	
		
		
			
				
					
					|  |  |  |           } |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |           Stop(); |  |  |  |           stop(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     #endif // Z_PROBE_ALLEN_KEY |  |  |  |     #endif // Z_PROBE_ALLEN_KEY | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -1816,7 +1867,7 @@ static void setup_for_endstop_move() { | 
			
		
	
		
		
			
				
					
					|  |  |  |             SERIAL_ERRORLNPGM("Z-Probe failed to retract!"); |  |  |  |             SERIAL_ERRORLNPGM("Z-Probe failed to retract!"); | 
			
		
	
		
		
			
				
					
					|  |  |  |             LCD_ALERTMESSAGEPGM("Err: ZPROBE"); |  |  |  |             LCD_ALERTMESSAGEPGM("Err: ZPROBE"); | 
			
		
	
		
		
			
				
					
					|  |  |  |           } |  |  |  |           } | 
			
		
	
		
		
			
				
					
					|  |  |  |           Stop(); |  |  |  |           stop(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     #endif // Z_PROBE_ALLEN_KEY |  |  |  |     #endif // Z_PROBE_ALLEN_KEY | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -4206,7 +4257,7 @@ inline void gcode_M77() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  * M104: Set hot end temperature |  |  |  |  * M104: Set hot end temperature | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | inline void gcode_M104() { |  |  |  | inline void gcode_M104() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (setTargetedHotend(104)) return; |  |  |  |   if (get_target_extruder_from_command(104)) return; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   if (DEBUGGING(DRYRUN)) return; |  |  |  |   if (DEBUGGING(DRYRUN)) return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (code_seen('S')) { |  |  |  |   if (code_seen('S')) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -4314,7 +4365,7 @@ inline void gcode_M104() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  * M105: Read hot end and bed temperature |  |  |  |  * M105: Read hot end and bed temperature | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | inline void gcode_M105() { |  |  |  | inline void gcode_M105() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (setTargetedHotend(105)) return; |  |  |  |   if (get_target_extruder_from_command(105)) return; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   #if HAS_TEMP_HOTEND || HAS_TEMP_BED |  |  |  |   #if HAS_TEMP_HOTEND || HAS_TEMP_BED | 
			
		
	
		
		
			
				
					
					|  |  |  |     SERIAL_PROTOCOLPGM(MSG_OK); |  |  |  |     SERIAL_PROTOCOLPGM(MSG_OK); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -4358,7 +4409,7 @@ inline void gcode_M105() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | inline void gcode_M109() { |  |  |  | inline void gcode_M109() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (setTargetedHotend(109)) return; |  |  |  |   if (get_target_extruder_from_command(109)) return; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   if (DEBUGGING(DRYRUN)) return; |  |  |  |   if (DEBUGGING(DRYRUN)) return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool no_wait_for_cooling = code_seen('S'); |  |  |  |   bool no_wait_for_cooling = code_seen('S'); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -4612,22 +4663,22 @@ inline void gcode_M112() { kill(PSTR(MSG_KILLED)); } | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * M126: Heater 1 valve open |  |  |  |      * M126: Heater 1 valve open | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     inline void gcode_M126() { ValvePressure = code_seen('S') ? constrain(code_value(), 0, 255) : 255; } |  |  |  |     inline void gcode_M126() { baricuda_valve_pressure = code_seen('S') ? constrain(code_value(), 0, 255) : 255; } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * M127: Heater 1 valve close |  |  |  |      * M127: Heater 1 valve close | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     inline void gcode_M127() { ValvePressure = 0; } |  |  |  |     inline void gcode_M127() { baricuda_valve_pressure = 0; } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   #endif |  |  |  |   #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   #if HAS_HEATER_2 |  |  |  |   #if HAS_HEATER_2 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * M128: Heater 2 valve open |  |  |  |      * M128: Heater 2 valve open | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     inline void gcode_M128() { EtoPPressure = code_seen('S') ? constrain(code_value(), 0, 255) : 255; } |  |  |  |     inline void gcode_M128() { baricuda_e_to_p_pressure = code_seen('S') ? constrain(code_value(), 0, 255) : 255; } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * M129: Heater 2 valve close |  |  |  |      * M129: Heater 2 valve close | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     inline void gcode_M129() { EtoPPressure = 0; } |  |  |  |     inline void gcode_M129() { baricuda_e_to_p_pressure = 0; } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   #endif |  |  |  |   #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif //BARICUDA |  |  |  | #endif //BARICUDA | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -5025,7 +5076,7 @@ inline void gcode_M121() { enable_endstops_globally(false); } | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  */ | 
			
		
	
		
		
			
				
					
					|  |  |  | inline void gcode_M200() { |  |  |  | inline void gcode_M200() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (setTargetedHotend(200)) return; |  |  |  |   if (get_target_extruder_from_command(200)) return; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (code_seen('D')) { |  |  |  |   if (code_seen('D')) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     float diameter = code_value(); |  |  |  |     float diameter = code_value(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -5277,7 +5328,7 @@ inline void gcode_M206() { | 
			
		
	
		
		
			
				
					
					|  |  |  |    *   Z<zoffset> - Available with DUAL_X_CARRIAGE |  |  |  |    *   Z<zoffset> - Available with DUAL_X_CARRIAGE | 
			
		
	
		
		
			
				
					
					|  |  |  |    */ |  |  |  |    */ | 
			
		
	
		
		
			
				
					
					|  |  |  |   inline void gcode_M218() { |  |  |  |   inline void gcode_M218() { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (setTargetedHotend(218)) return; |  |  |  |     if (get_target_extruder_from_command(218)) return; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('X')) extruder_offset[X_AXIS][target_extruder] = code_value(); |  |  |  |     if (code_seen('X')) extruder_offset[X_AXIS][target_extruder] = code_value(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (code_seen('Y')) extruder_offset[Y_AXIS][target_extruder] = code_value(); |  |  |  |     if (code_seen('Y')) extruder_offset[Y_AXIS][target_extruder] = code_value(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -5316,7 +5367,7 @@ inline void gcode_M220() { | 
			
		
	
		
		
			
				
					
					|  |  |  | inline void gcode_M221() { |  |  |  | inline void gcode_M221() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (code_seen('S')) { |  |  |  |   if (code_seen('S')) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     int sval = code_value(); |  |  |  |     int sval = code_value(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (setTargetedHotend(221)) return; |  |  |  |     if (get_target_extruder_from_command(221)) return; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     extruder_multiplier[target_extruder] = sval; |  |  |  |     extruder_multiplier[target_extruder] = sval; | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -5842,7 +5893,7 @@ inline void gcode_M428() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool err = false; |  |  |  |   bool err = false; | 
			
		
	
		
		
			
				
					
					|  |  |  |   for (int8_t i = X_AXIS; i <= Z_AXIS; i++) { |  |  |  |   for (int8_t i = X_AXIS; i <= Z_AXIS; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (axis_homed[i]) { |  |  |  |     if (axis_homed[i]) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       float base = (current_position[i] > (min_pos[i] + max_pos[i]) / 2) ? base_home_pos(i) : 0, |  |  |  |       float base = (current_position[i] > (sw_endstop_min[i] + sw_endstop_max[i]) / 2) ? base_home_pos(i) : 0, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             diff = current_position[i] - base; |  |  |  |             diff = current_position[i] - base; | 
			
		
	
		
		
			
				
					
					|  |  |  |       if (diff > -20 && diff < 20) { |  |  |  |       if (diff > -20 && diff < 20) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         set_home_offset((AxisEnum)i, home_offset[i] - diff); |  |  |  |         set_home_offset((AxisEnum)i, home_offset[i] - diff); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -6078,7 +6129,7 @@ inline void gcode_M503() { | 
			
		
	
		
		
			
				
					
					|  |  |  |     #endif |  |  |  |     #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     #if ENABLED(FILAMENT_RUNOUT_SENSOR) |  |  |  |     #if ENABLED(FILAMENT_RUNOUT_SENSOR) | 
			
		
	
		
		
			
				
					
					|  |  |  |       filrunoutEnqueued = false; |  |  |  |       filament_ran_out = false; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     #endif |  |  |  |     #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -7032,8 +7083,8 @@ void ok_to_send() { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void clamp_to_software_endstops(float target[3]) { |  |  |  | void clamp_to_software_endstops(float target[3]) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (min_software_endstops) { |  |  |  |   if (min_software_endstops) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     NOLESS(target[X_AXIS], min_pos[X_AXIS]); |  |  |  |     NOLESS(target[X_AXIS], sw_endstop_min[X_AXIS]); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     NOLESS(target[Y_AXIS], min_pos[Y_AXIS]); |  |  |  |     NOLESS(target[Y_AXIS], sw_endstop_min[Y_AXIS]); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     float negative_z_offset = 0; |  |  |  |     float negative_z_offset = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |     #if ENABLED(AUTO_BED_LEVELING_FEATURE) |  |  |  |     #if ENABLED(AUTO_BED_LEVELING_FEATURE) | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -7048,13 +7099,13 @@ void clamp_to_software_endstops(float target[3]) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         negative_z_offset += home_offset[Z_AXIS]; |  |  |  |         negative_z_offset += home_offset[Z_AXIS]; | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |     #endif |  |  |  |     #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |     NOLESS(target[Z_AXIS], min_pos[Z_AXIS] + negative_z_offset); |  |  |  |     NOLESS(target[Z_AXIS], sw_endstop_min[Z_AXIS] + negative_z_offset); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (max_software_endstops) { |  |  |  |   if (max_software_endstops) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     NOMORE(target[X_AXIS], max_pos[X_AXIS]); |  |  |  |     NOMORE(target[X_AXIS], sw_endstop_max[X_AXIS]); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     NOMORE(target[Y_AXIS], max_pos[Y_AXIS]); |  |  |  |     NOMORE(target[Y_AXIS], sw_endstop_max[Y_AXIS]); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     NOMORE(target[Z_AXIS], max_pos[Z_AXIS]); |  |  |  |     NOMORE(target[Z_AXIS], sw_endstop_max[Z_AXIS]); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -7714,7 +7765,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   #if HAS_FILRUNOUT |  |  |  |   #if HAS_FILRUNOUT | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (IS_SD_PRINTING && !(READ(FILRUNOUT_PIN) ^ FIL_RUNOUT_INVERTING)) |  |  |  |     if (IS_SD_PRINTING && !(READ(FILRUNOUT_PIN) ^ FIL_RUNOUT_INVERTING)) | 
			
		
	
		
		
			
				
					
					|  |  |  |       filrunout(); |  |  |  |       handle_filament_runout(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   #endif |  |  |  |   #endif | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (commands_in_queue < BUFSIZE) get_available_commands(); |  |  |  |   if (commands_in_queue < BUFSIZE) get_available_commands(); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -7897,9 +7948,9 @@ void kill(const char* lcd_msg) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #if ENABLED(FILAMENT_RUNOUT_SENSOR) |  |  |  | #if ENABLED(FILAMENT_RUNOUT_SENSOR) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   void filrunout() { |  |  |  |   void handle_filament_runout() { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     if (!filrunoutEnqueued) { |  |  |  |     if (!filament_ran_out) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       filrunoutEnqueued = true; |  |  |  |       filament_ran_out = true; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT)); |  |  |  |       enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT)); | 
			
		
	
		
		
			
				
					
					|  |  |  |       st_synchronize(); |  |  |  |       st_synchronize(); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -7968,7 +8019,7 @@ void kill(const char* lcd_msg) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | #endif // FAST_PWM_FAN |  |  |  | #endif // FAST_PWM_FAN | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | void Stop() { |  |  |  | void stop() { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   disable_all_heaters(); |  |  |  |   disable_all_heaters(); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (IsRunning()) { |  |  |  |   if (IsRunning()) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     Running = false; |  |  |  |     Running = false; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -7979,27 +8030,6 @@ void Stop() { | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | /** |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  * Set target_extruder from the T parameter or the active_extruder |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  * Returns TRUE if the target is invalid |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  */ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | bool setTargetedHotend(int code) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   target_extruder = active_extruder; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (code_seen('T')) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     target_extruder = code_value_short(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (target_extruder >= EXTRUDERS) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_ECHO_START; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_CHAR('M'); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_ECHO(code); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_ECHOPGM(" " MSG_INVALID_EXTRUDER " "); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       SERIAL_ECHOLN((int)target_extruder); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       return true; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   return false; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | float calculate_volumetric_multiplier(float diameter) { |  |  |  | float calculate_volumetric_multiplier(float diameter) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!volumetric_enabled || diameter == 0) return 1.0; |  |  |  |   if (!volumetric_enabled || diameter == 0) return 1.0; | 
			
		
	
		
		
			
				
					
					|  |  |  |   float d2 = diameter * 0.5; |  |  |  |   float d2 = diameter * 0.5; | 
			
		
	
	
		
		
			
				
					
					|  |  |   |