From 4714fb8fcba53761e06aaf1e7be43def133e91c4 Mon Sep 17 00:00:00 2001 From: Thomas Moore Date: Thu, 9 Nov 2017 23:10:41 -0600 Subject: [PATCH 1/4] Normalize load/unload length in M600 --- Marlin/Marlin_main.cpp | 4 ++-- Marlin/planner.cpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index ae15b60641..f9ad8a916d 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -6553,7 +6553,7 @@ inline void gcode_M17() { #endif void do_pause_e_move(const float &length, const float fr) { - current_position[E_AXIS] += length; + current_position[E_AXIS] += length * 100.0 / flow_percentage[active_extruder] / volumetric_multiplier[active_extruder]; set_destination_from_current(); RUNPLAN(fr); stepper.synchronize(); @@ -12962,7 +12962,7 @@ void prepare_move_to_destination() { SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); } #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - if (destination[E_AXIS] - current_position[E_AXIS] > EXTRUDE_MAXLENGTH) { + if (fabs(destination[E_AXIS] - current_position[E_AXIS]) > EXTRUDE_MAXLENGTH / volumetric_multiplier[active_extruder]) { current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index ddf47d0063..443cb41139 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -736,7 +736,8 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); } #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - if (labs(de) > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int + int32_t de_mm = labs(de * volumetric_multiplier[active_extruder]); + if (de_mm > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part de = 0; // no difference #if ENABLED(LIN_ADVANCE) From 24b302c001d4f4dcf6e60a5023800ef561d8dded Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 10 Nov 2017 01:32:48 -0600 Subject: [PATCH 2/4] Fix cold/lengthy extrusion handling --- Marlin/Marlin_main.cpp | 21 +++++++++++++-------- Marlin/planner.cpp | 34 +++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index f9ad8a916d..1640bd4be8 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -12947,27 +12947,32 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { * * This may result in several calls to planner.buffer_line to * do smaller moves for DELTA, SCARA, mesh moves, etc. + * + * Make sure current_position[E] and destination[E] are good + * before calling or cold/lengthy extrusion may get missed. */ void prepare_move_to_destination() { clamp_to_software_endstops(destination); refresh_cmd_timeout(); - #if ENABLED(PREVENT_COLD_EXTRUSION) + #if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE) if (!DEBUGGING(DRYRUN)) { if (destination[E_AXIS] != current_position[E_AXIS]) { - if (thermalManager.tooColdToExtrude(active_extruder)) { - current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part - SERIAL_ECHO_START(); - SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); - } + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (thermalManager.tooColdToExtrude(active_extruder)) { + current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #endif // PREVENT_COLD_EXTRUSION #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - if (fabs(destination[E_AXIS] - current_position[E_AXIS]) > EXTRUDE_MAXLENGTH / volumetric_multiplier[active_extruder]) { + if (FABS(destination[E_AXIS] - current_position[E_AXIS]) > (EXTRUDE_MAXLENGTH) / volumetric_multiplier[active_extruder]) { current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); } - #endif + #endif // PREVENT_LENGTHY_EXTRUDE } } diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 443cb41139..016bb49372 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -719,24 +719,28 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const long de = target[E_AXIS] - position[E_AXIS]; + const float e_factor = volumetric_multiplier[extruder] * flow_percentage[extruder] * 0.01; + #if ENABLED(LIN_ADVANCE) float de_float = e - position_float[E_AXIS]; #endif - #if ENABLED(PREVENT_COLD_EXTRUSION) + #if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE) if (de) { - if (thermalManager.tooColdToExtrude(extruder)) { - position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part - de = 0; // no difference - #if ENABLED(LIN_ADVANCE) - position_float[E_AXIS] = e; - de_float = 0; - #endif - SERIAL_ECHO_START(); - SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); - } + #if ENABLED(PREVENT_COLD_EXTRUSION) + if (thermalManager.tooColdToExtrude(extruder)) { + position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part + de = 0; // no difference + #if ENABLED(LIN_ADVANCE) + position_float[E_AXIS] = e; + de_float = 0; + #endif + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM(MSG_ERR_COLD_EXTRUDE_STOP); + } + #endif // PREVENT_COLD_EXTRUSION #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - int32_t de_mm = labs(de * volumetric_multiplier[active_extruder]); + const int32_t de_mm = labs(de * e_factor); if (de_mm > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part de = 0; // no difference @@ -747,9 +751,9 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); } - #endif + #endif // PREVENT_LENGTHY_EXTRUDE } - #endif + #endif // PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE // Compute direction bit-mask for this block uint8_t dm = 0; @@ -778,7 +782,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const #endif if (de < 0) SBI(dm, E_AXIS); - const float esteps_float = de * volumetric_multiplier[extruder] * flow_percentage[extruder] * 0.01; + const float esteps_float = de * e_factor; const int32_t esteps = abs(esteps_float) + 0.5; // Calculate the buffer head after we push this byte From 32938236424ddde78e3c136feb031f50292f3660 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 10 Nov 2017 02:38:53 -0600 Subject: [PATCH 3/4] Add pre-calculated planner.e_factor --- Marlin/Marlin.h | 6 ----- Marlin/Marlin_main.cpp | 44 ++++++++++++------------------- Marlin/configuration_store.cpp | 41 ++++++++++++++--------------- Marlin/gcode.cpp | 2 ++ Marlin/gcode.h | 6 ++--- Marlin/planner.cpp | 27 ++++++++++++++----- Marlin/planner.h | 13 ++++++++++ Marlin/temperature.cpp | 3 ++- Marlin/ultralcd.cpp | 47 +++++++++++++++++++++++----------- Marlin/ultralcd_impl_DOGM.h | 4 +-- Marlin/ultralcd_impl_HD44780.h | 2 +- 11 files changed, 110 insertions(+), 85 deletions(-) diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h index 96cb26065e..bcbf3181bd 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -215,10 +215,6 @@ extern int16_t feedrate_percentage; #define MMS_SCALED(MM_S) ((MM_S)*feedrate_percentage*0.01) extern bool axis_relative_modes[]; -extern bool volumetric_enabled; -extern int16_t flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder -extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder. -extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner extern bool axis_known_position[XYZ]; extern bool axis_homed[XYZ]; extern volatile bool wait_for_heatup; @@ -427,8 +423,6 @@ extern uint8_t active_extruder; extern float mixing_factor[MIXING_STEPPERS]; #endif -void calculate_volumetric_multipliers(); - /** * Blocking movement and shorthand functions */ diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 1640bd4be8..7fba19dedc 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -452,13 +452,10 @@ FORCE_INLINE float homing_feedrate(const AxisEnum a) { return pgm_read_float(&ho float feedrate_mm_s = MMM_TO_MMS(1500.0); static float saved_feedrate_mm_s; -int16_t feedrate_percentage = 100, saved_feedrate_percentage, - flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); +int16_t feedrate_percentage = 100, saved_feedrate_percentage; // Initialized by settings.load() -bool axis_relative_modes[] = AXIS_RELATIVE_MODES, - volumetric_enabled; -float filament_size[EXTRUDERS], volumetric_multiplier[EXTRUDERS]; +bool axis_relative_modes[] = AXIS_RELATIVE_MODES; #if HAS_WORKSPACE_OFFSET #if HAS_POSITION_SHIFT @@ -3226,7 +3223,7 @@ static void homeaxis(const AxisEnum axis) { set_destination_from_current(); stepper.synchronize(); // Wait for buffered moves to complete - const float renormalize = 100.0 / flow_percentage[active_extruder] / volumetric_multiplier[active_extruder]; + const float renormalize = 1.0 / planner.e_factor[active_extruder]; if (retracting) { // Retract by moving from a faux E position back to the current E position @@ -6553,7 +6550,7 @@ inline void gcode_M17() { #endif void do_pause_e_move(const float &length, const float fr) { - current_position[E_AXIS] += length * 100.0 / flow_percentage[active_extruder] / volumetric_multiplier[active_extruder]; + current_position[E_AXIS] += length / planner.e_factor[active_extruder]; set_destination_from_current(); RUNPLAN(fr); stepper.synchronize(); @@ -8832,15 +8829,14 @@ inline void gcode_M200() { // setting any extruder filament size disables volumetric on the assumption that // slicers either generate in extruder values as cubic mm or as as filament feeds // for all extruders - volumetric_enabled = (parser.value_linear_units() != 0.0); - if (volumetric_enabled) { - filament_size[target_extruder] = parser.value_linear_units(); + if ( (parser.volumetric_enabled = (parser.value_linear_units() != 0.0)) ) { + planner.filament_size[target_extruder] = parser.value_linear_units(); // make sure all extruders have some sane value for the filament size - for (uint8_t i = 0; i < COUNT(filament_size); i++) - if (! filament_size[i]) filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA; + for (uint8_t i = 0; i < COUNT(planner.filament_size); i++) + if (!planner.filament_size[i]) planner.filament_size[i] = DEFAULT_NOMINAL_FILAMENT_DIA; } } - calculate_volumetric_multipliers(); + planner.calculate_volumetric_multipliers(); } /** @@ -9201,8 +9197,10 @@ inline void gcode_M220() { */ inline void gcode_M221() { if (get_target_extruder_from_command(221)) return; - if (parser.seenval('S')) - flow_percentage[target_extruder] = parser.value_int(); + if (parser.seenval('S')) { + planner.flow_percentage[target_extruder] = parser.value_int(); + planner.refresh_e_factor(target_extruder); + } } /** @@ -9735,7 +9733,7 @@ inline void gcode_M400() { stepper.synchronize(); } //SERIAL_PROTOCOLPGM("Filament dia (measured mm):"); //SERIAL_PROTOCOL(filament_width_meas); //SERIAL_PROTOCOLPGM("Extrusion ratio(%):"); - //SERIAL_PROTOCOL(flow_percentage[active_extruder]); + //SERIAL_PROTOCOL(planner.flow_percentage[active_extruder]); } /** @@ -9743,7 +9741,7 @@ inline void gcode_M400() { stepper.synchronize(); } */ inline void gcode_M406() { filament_sensor = false; - calculate_volumetric_multipliers(); // Restore correct 'volumetric_multiplier' value + planner.calculate_volumetric_multipliers(); // Restore correct 'volumetric_multiplier' value } /** @@ -12967,7 +12965,7 @@ void prepare_move_to_destination() { } #endif // PREVENT_COLD_EXTRUSION #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - if (FABS(destination[E_AXIS] - current_position[E_AXIS]) > (EXTRUDE_MAXLENGTH) / volumetric_multiplier[active_extruder]) { + if (FABS(destination[E_AXIS] - current_position[E_AXIS]) * planner.e_factor[active_extruder] > (EXTRUDE_MAXLENGTH)) { current_position[E_AXIS] = destination[E_AXIS]; // Behave as if the move really took place, but ignore E part SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(MSG_ERR_LONG_EXTRUDE_STOP); @@ -13387,16 +13385,6 @@ void prepare_move_to_destination() { #endif // FAST_PWM_FAN -float calculate_volumetric_multiplier(const float diameter) { - if (!volumetric_enabled || diameter == 0) return 1.0; - return 1.0 / (M_PI * sq(diameter * 0.5)); -} - -void calculate_volumetric_multipliers() { - for (uint8_t i = 0; i < COUNT(filament_size); i++) - volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]); -} - void enable_all_steppers() { enable_X(); enable_Y(); diff --git a/Marlin/configuration_store.cpp b/Marlin/configuration_store.cpp index 088adc2fa4..9d15c31c3a 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/configuration_store.cpp @@ -138,8 +138,8 @@ * 533 M208 R swap_retract_recover_feedrate_mm_s (float) * * Volumetric Extrusion: 21 bytes - * 537 M200 D volumetric_enabled (bool) - * 538 M200 T D filament_size (float x5) (T0..3) + * 537 M200 D parser.volumetric_enabled (bool) + * 538 M200 T D planner.filament_size (float x5) (T0..3) * * HAVE_TMC2130: 22 bytes * 558 M906 X Stepper X current (uint16_t) @@ -188,10 +188,7 @@ MarlinSettings settings; #include "temperature.h" #include "ultralcd.h" #include "stepper.h" - -#if ENABLED(INCH_MODE_SUPPORT) || (ENABLED(ULTIPANEL) && ENABLED(TEMPERATURE_UNITS_SUPPORT)) - #include "gcode.h" -#endif +#include "gcode.h" #if ENABLED(MESH_BED_LEVELING) #include "mesh_bed_leveling.h" @@ -238,7 +235,7 @@ void MarlinSettings::postprocess() { thermalManager.updatePID(); #endif - calculate_volumetric_multipliers(); + planner.calculate_volumetric_multipliers(); #if HAS_HOME_OFFSET || ENABLED(DUAL_X_CARRIAGE) // Software endstops depend on home_offset @@ -569,11 +566,11 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(swap_retract_recover_length); EEPROM_WRITE(swap_retract_recover_feedrate_mm_s); - EEPROM_WRITE(volumetric_enabled); + EEPROM_WRITE(parser.volumetric_enabled); // Save filament sizes for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { - if (q < COUNT(filament_size)) dummy = filament_size[q]; + if (q < COUNT(planner.filament_size)) dummy = planner.filament_size[q]; EEPROM_WRITE(dummy); } @@ -1018,10 +1015,10 @@ void MarlinSettings::postprocess() { // Volumetric & Filament Size // - EEPROM_READ(volumetric_enabled); + EEPROM_READ(parser.volumetric_enabled); for (uint8_t q = 0; q < MAX_EXTRUDERS; q++) { EEPROM_READ(dummy); - if (q < COUNT(filament_size)) filament_size[q] = dummy; + if (q < COUNT(planner.filament_size)) planner.filament_size[q] = dummy; } // @@ -1424,15 +1421,15 @@ void MarlinSettings::reset() { swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP; #endif // FWRETRACT - volumetric_enabled = + parser.volumetric_enabled = #if ENABLED(VOLUMETRIC_DEFAULT_ON) true #else false #endif ; - for (uint8_t q = 0; q < COUNT(filament_size); q++) - filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA; + for (uint8_t q = 0; q < COUNT(planner.filament_size); q++) + planner.filament_size[q] = DEFAULT_NOMINAL_FILAMENT_DIA; endstops.enable_globally( #if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT) @@ -1515,7 +1512,7 @@ void MarlinSettings::reset() { CONFIG_ECHO_START; #if ENABLED(INCH_MODE_SUPPORT) #define LINEAR_UNIT(N) ((N) / parser.linear_unit_factor) - #define VOLUMETRIC_UNIT(N) ((N) / (volumetric_enabled ? parser.volumetric_unit_factor : parser.linear_unit_factor)) + #define VOLUMETRIC_UNIT(N) ((N) / (parser.volumetric_enabled ? parser.volumetric_unit_factor : parser.linear_unit_factor)) SERIAL_ECHOPGM(" G2"); SERIAL_CHAR(parser.linear_unit_factor == 1.0 ? '1' : '0'); SERIAL_ECHOPGM(" ; Units in "); @@ -1552,37 +1549,37 @@ void MarlinSettings::reset() { if (!forReplay) { CONFIG_ECHO_START; SERIAL_ECHOPGM("Filament settings:"); - if (volumetric_enabled) + if (parser.volumetric_enabled) SERIAL_EOL(); else SERIAL_ECHOLNPGM(" Disabled"); } CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 D", filament_size[0]); + SERIAL_ECHOPAIR(" M200 D", planner.filament_size[0]); SERIAL_EOL(); #if EXTRUDERS > 1 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T1 D", filament_size[1]); + SERIAL_ECHOPAIR(" M200 T1 D", planner.filament_size[1]); SERIAL_EOL(); #if EXTRUDERS > 2 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T2 D", filament_size[2]); + SERIAL_ECHOPAIR(" M200 T2 D", planner.filament_size[2]); SERIAL_EOL(); #if EXTRUDERS > 3 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T3 D", filament_size[3]); + SERIAL_ECHOPAIR(" M200 T3 D", planner.filament_size[3]); SERIAL_EOL(); #if EXTRUDERS > 4 CONFIG_ECHO_START; - SERIAL_ECHOPAIR(" M200 T4 D", filament_size[4]); + SERIAL_ECHOPAIR(" M200 T4 D", planner.filament_size[4]); SERIAL_EOL(); #endif // EXTRUDERS > 4 #endif // EXTRUDERS > 3 #endif // EXTRUDERS > 2 #endif // EXTRUDERS > 1 - if (!volumetric_enabled) { + if (!parser.volumetric_enabled) { CONFIG_ECHO_START; SERIAL_ECHOLNPGM(" M200 D0"); } diff --git a/Marlin/gcode.cpp b/Marlin/gcode.cpp index 34ff60f633..6596024d5f 100644 --- a/Marlin/gcode.cpp +++ b/Marlin/gcode.cpp @@ -32,6 +32,8 @@ // Must be declared for allocation and to satisfy the linker // Zero values need no initialization. +bool GCodeParser::volumetric_enabled; + #if ENABLED(INCH_MODE_SUPPORT) float GCodeParser::linear_unit_factor, GCodeParser::volumetric_unit_factor; #endif diff --git a/Marlin/gcode.h b/Marlin/gcode.h index b415dcb114..3ad2113908 100644 --- a/Marlin/gcode.h +++ b/Marlin/gcode.h @@ -44,10 +44,6 @@ #include "serial.h" #endif -#if ENABLED(INCH_MODE_SUPPORT) - extern bool volumetric_enabled; -#endif - /** * GCode parser * @@ -76,6 +72,8 @@ public: // Global states for GCode-level units features + static bool volumetric_enabled; + #if ENABLED(INCH_MODE_SUPPORT) static float linear_unit_factor, volumetric_unit_factor; #endif diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 016bb49372..a08b3b9e87 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -91,6 +91,12 @@ float Planner::max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second uint8_t Planner::last_extruder = 0; // Respond to extruder change #endif +int16_t Planner::flow_percentage[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(100); // Extrusion factor for each extruder + +float Planner::e_factor[EXTRUDERS], // The flow percentage and volumetric multiplier combine to scale E movement + Planner::filament_size[EXTRUDERS], // diameter of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder + Planner::volumetric_multiplier[EXTRUDERS]; // Reciprocal of cross-sectional area of filament (in mm^2). Pre-calculated to reduce computation in the planner + uint32_t Planner::max_acceleration_steps_per_s2[XYZE_N], Planner::max_acceleration_mm_per_s2[XYZE_N]; // Use M201 to override by software @@ -521,6 +527,18 @@ void Planner::check_axes_activity() { #endif } +inline float calculate_volumetric_multiplier(const float &diameter) { + if (!parser.volumetric_enabled || diameter == 0) return 1.0; + return 1.0 / CIRCLE_AREA(diameter * 0.5); +} + +void Planner::calculate_volumetric_multipliers() { + for (uint8_t i = 0; i < COUNT(filament_size); i++) { + volumetric_multiplier[i] = calculate_volumetric_multiplier(filament_size[i]); + refresh_e_factor(i); + } +} + #if PLANNER_LEVELING /** * rx, ry, rz - cartesian position in mm @@ -719,10 +737,8 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const long de = target[E_AXIS] - position[E_AXIS]; - const float e_factor = volumetric_multiplier[extruder] * flow_percentage[extruder] * 0.01; - #if ENABLED(LIN_ADVANCE) - float de_float = e - position_float[E_AXIS]; + float de_float = e - position_float[E_AXIS]; // Should this include e_factor? #endif #if ENABLED(PREVENT_COLD_EXTRUSION) || ENABLED(PREVENT_LENGTHY_EXTRUDE) @@ -740,8 +756,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const } #endif // PREVENT_COLD_EXTRUSION #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - const int32_t de_mm = labs(de * e_factor); - if (de_mm > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int + if (labs(de * e_factor[extruder]) > (int32_t)axis_steps_per_mm[E_AXIS_N] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part de = 0; // no difference #if ENABLED(LIN_ADVANCE) @@ -782,7 +797,7 @@ void Planner::_buffer_line(const float &a, const float &b, const float &c, const #endif if (de < 0) SBI(dm, E_AXIS); - const float esteps_float = de * e_factor; + const float esteps_float = de * e_factor[extruder]; const int32_t esteps = abs(esteps_float) + 0.5; // Calculate the buffer head after we push this byte diff --git a/Marlin/planner.h b/Marlin/planner.h index d387ba4052..f3fd5ea11d 100644 --- a/Marlin/planner.h +++ b/Marlin/planner.h @@ -140,6 +140,13 @@ class Planner { static uint8_t last_extruder; // Respond to extruder change #endif + static int16_t flow_percentage[EXTRUDERS]; // Extrusion factor for each extruder + + static float e_factor[EXTRUDERS], // The flow percentage and volumetric multiplier combine to scale E movement + filament_size[EXTRUDERS], // diameter of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder + volumetric_multiplier[EXTRUDERS]; // Reciprocal of cross-sectional area of filament (in mm^2). Pre-calculated to reduce computation in the planner + // May be auto-adjusted by a filament width sensor + static float max_feedrate_mm_s[XYZE_N], // Max speeds in mm per second axis_steps_per_mm[XYZE_N], steps_to_mm[XYZE_N]; @@ -236,9 +243,15 @@ class Planner { static void reset_acceleration_rates(); static void refresh_positioning(); + FORCE_INLINE static void refresh_e_factor(const uint8_t e) { + e_factor[e] = volumetric_multiplier[e] * flow_percentage[e] * 0.01; + } + // Manage fans, paste pressure, etc. static void check_axes_activity(); + static void calculate_volumetric_multipliers(); + /** * Number of moves currently in the planner */ diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp index bded5c5400..ae31fe8655 100644 --- a/Marlin/temperature.cpp +++ b/Marlin/temperature.cpp @@ -815,7 +815,8 @@ void Temperature::manage_heater() { // Get the delayed info and add 100 to reconstitute to a percent of // the nominal filament diameter then square it to get an area const float vmroot = measurement_delay[meas_shift_index] * 0.01 + 1.0; - volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vmroot <= 0.1 ? 0.01 : sq(vmroot); + planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = vmroot <= 0.1 ? 0.01 : sq(vmroot); + planner.refresh_e_factor(FILAMENT_SENSOR_EXTRUDER_NUM); } #endif // FILAMENT_WIDTH_SENSOR diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp index 298c606886..9533916de9 100644 --- a/Marlin/ultralcd.cpp +++ b/Marlin/ultralcd.cpp @@ -33,6 +33,7 @@ #include "stepper.h" #include "configuration_store.h" #include "utility.h" +#include "gcode.h" #if HAS_BUZZER && DISABLED(LCD_USE_I2C_BUZZER) #include "buzzer.h" @@ -1248,6 +1249,22 @@ void kill_screen(const char* lcd_msg) { #endif #endif + // Refresh the E factor after changing flow + inline void _lcd_refresh_e_factor_0() { planner.refresh_e_factor(0); } + #if EXTRUDERS > 1 + inline void _lcd_refresh_e_factor() { planner.refresh_e_factor(active_extruder); } + inline void _lcd_refresh_e_factor_1() { planner.refresh_e_factor(1); } + #if EXTRUDERS > 2 + inline void _lcd_refresh_e_factor_2() { planner.refresh_e_factor(2); } + #if EXTRUDERS > 3 + inline void _lcd_refresh_e_factor_3() { planner.refresh_e_factor(3); } + #if EXTRUDERS > 4 + inline void _lcd_refresh_e_factor_4() { planner.refresh_e_factor(4); } + #endif // EXTRUDERS > 4 + #endif // EXTRUDERS > 3 + #endif // EXTRUDERS > 2 + #endif // EXTRUDERS > 1 + /** * * "Tune" submenu @@ -1327,17 +1344,17 @@ void kill_screen(const char* lcd_msg) { // Flow [1-5]: // #if EXTRUDERS == 1 - MENU_ITEM_EDIT(int3, MSG_FLOW, &flow_percentage[0], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW, &planner.flow_percentage[0], 10, 999, _lcd_refresh_e_factor_0); #else // EXTRUDERS > 1 - MENU_ITEM_EDIT(int3, MSG_FLOW, &flow_percentage[active_extruder], 10, 999); - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N1, &flow_percentage[0], 10, 999); - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N2, &flow_percentage[1], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW, &planner.flow_percentage[active_extruder], 10, 999, _lcd_refresh_e_factor); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N1, &planner.flow_percentage[0], 10, 999, _lcd_refresh_e_factor_0); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N2, &planner.flow_percentage[1], 10, 999, _lcd_refresh_e_factor_1); #if EXTRUDERS > 2 - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N3, &flow_percentage[2], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N3, &planner.flow_percentage[2], 10, 999, _lcd_refresh_e_factor_2); #if EXTRUDERS > 3 - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N4, &flow_percentage[3], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N4, &planner.flow_percentage[3], 10, 999, _lcd_refresh_e_factor_3); #if EXTRUDERS > 4 - MENU_ITEM_EDIT(int3, MSG_FLOW MSG_N5, &flow_percentage[4], 10, 999); + MENU_ITEM_EDIT_CALLBACK(int3, MSG_FLOW MSG_N5, &planner.flow_percentage[4], 10, 999, _lcd_refresh_e_factor_4); #endif // EXTRUDERS > 4 #endif // EXTRUDERS > 3 #endif // EXTRUDERS > 2 @@ -3678,20 +3695,20 @@ void kill_screen(const char* lcd_msg) { MENU_ITEM_EDIT(float3, MSG_ADVANCE_K, &planner.extruder_advance_k, 0, 999); #endif - MENU_ITEM_EDIT_CALLBACK(bool, MSG_VOLUMETRIC_ENABLED, &volumetric_enabled, calculate_volumetric_multipliers); + MENU_ITEM_EDIT_CALLBACK(bool, MSG_VOLUMETRIC_ENABLED, &parser.volumetric_enabled, planner.calculate_volumetric_multipliers); - if (volumetric_enabled) { + if (parser.volumetric_enabled) { #if EXTRUDERS == 1 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &filament_size[0], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM, &planner.filament_size[0], 1.5, 3.25, planner.calculate_volumetric_multipliers); #else // EXTRUDERS > 1 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E1, &filament_size[0], 1.5, 3.25, calculate_volumetric_multipliers); - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E2, &filament_size[1], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E1, &planner.filament_size[0], 1.5, 3.25, planner.calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E2, &planner.filament_size[1], 1.5, 3.25, planner.calculate_volumetric_multipliers); #if EXTRUDERS > 2 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E3, &filament_size[2], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E3, &planner.filament_size[2], 1.5, 3.25, planner.calculate_volumetric_multipliers); #if EXTRUDERS > 3 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E4, &filament_size[3], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E4, &planner.filament_size[3], 1.5, 3.25, planner.calculate_volumetric_multipliers); #if EXTRUDERS > 4 - MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E5, &filament_size[4], 1.5, 3.25, calculate_volumetric_multipliers); + MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float43, MSG_FILAMENT_DIAM MSG_DIAM_E5, &planner.filament_size[4], 1.5, 3.25, planner.calculate_volumetric_multipliers); #endif // EXTRUDERS > 4 #endif // EXTRUDERS > 3 #endif // EXTRUDERS > 2 diff --git a/Marlin/ultralcd_impl_DOGM.h b/Marlin/ultralcd_impl_DOGM.h index 1f09054d51..b742268aa2 100644 --- a/Marlin/ultralcd_impl_DOGM.h +++ b/Marlin/ultralcd_impl_DOGM.h @@ -650,7 +650,7 @@ static void lcd_implementation_status_screen() { strcpy(zstring, ftostr52sp(FIXFLOAT(LOGICAL_Z_POSITION(current_position[Z_AXIS])))); #if ENABLED(FILAMENT_LCD_DISPLAY) && DISABLED(SDSUPPORT) strcpy(wstring, ftostr12ns(filament_width_meas)); - strcpy(mstring, itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + strcpy(mstring, itostr3(100.0 * planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); #endif } @@ -739,7 +739,7 @@ static void lcd_implementation_status_screen() { lcd_print(ftostr12ns(filament_width_meas)); lcd_printPGM(PSTR(" " LCD_STR_FILAM_MUL)); u8g.print(':'); - lcd_print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + lcd_print(itostr3(100.0 * planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); u8g.print('%'); } #else diff --git a/Marlin/ultralcd_impl_HD44780.h b/Marlin/ultralcd_impl_HD44780.h index 749c7e43a5..327d599763 100644 --- a/Marlin/ultralcd_impl_HD44780.h +++ b/Marlin/ultralcd_impl_HD44780.h @@ -857,7 +857,7 @@ static void lcd_implementation_status_screen() { lcd_printPGM(PSTR("Dia ")); lcd.print(ftostr12ns(filament_width_meas)); lcd_printPGM(PSTR(" V")); - lcd.print(itostr3(100.0 * volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); + lcd.print(itostr3(100.0 * planner.volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM])); lcd.write('%'); return; } From df44bcc5ae93cfa7aa808b533689bf066ed94ed3 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 10 Nov 2017 20:37:41 -0600 Subject: [PATCH 4/4] Use do_blocking_move_to where possible --- Marlin/Marlin_main.cpp | 13 +------------ Marlin/ubl_G29.cpp | 23 ++++++++--------------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 7fba19dedc..813c5e14b7 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -2414,17 +2414,8 @@ static void clean_up_after_endstop_or_probe_move() { : !position_is_reachable_by_probe(rx, ry) ) return NAN; - const float old_feedrate_mm_s = feedrate_mm_s; - - #if ENABLED(DELTA) - if (current_position[Z_AXIS] > delta_clip_start_height) - do_blocking_move_to_z(delta_clip_start_height); - #endif - - feedrate_mm_s = XY_PROBE_FEEDRATE_MM_S; - // Move the probe to the given XY - do_blocking_move_to_xy(nx, ny); + do_blocking_move_to_xy(nx, ny, XY_PROBE_FEEDRATE_MM_S); float measured_z = NAN; if (!DEPLOY_PROBE()) { @@ -2450,8 +2441,6 @@ static void clean_up_after_endstop_or_probe_move() { if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("<<< probe_pt"); #endif - feedrate_mm_s = old_feedrate_mm_s; - if (isnan(measured_z)) { LCD_MESSAGEPGM(MSG_ERR_PROBING_FAILED); SERIAL_ERROR_START(); diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp index c667f70df8..9fd2e534d6 100644 --- a/Marlin/ubl_G29.cpp +++ b/Marlin/ubl_G29.cpp @@ -466,6 +466,7 @@ // SERIAL_PROTOCOLLNPGM("Manually probing unreachable mesh locations."); do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); + if (!g29_x_flag && !g29_y_flag) { /** * Use a good default location for the path. @@ -911,8 +912,7 @@ has_control_of_lcd_panel = true; save_ubl_active_state_and_disable(); // Disable bed level correction for probing - do_blocking_move_to_z(in_height); - do_blocking_move_to_xy(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y))); + do_blocking_move_to(0.5 * (MESH_MAX_X - (MESH_MIN_X)), 0.5 * (MESH_MAX_Y - (MESH_MIN_Y)), in_height); //, min(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS]) / 2.0); stepper.synchronize(); @@ -955,8 +955,7 @@ has_control_of_lcd_panel = true; save_ubl_active_state_and_disable(); // we don't do bed level correction because we want the raw data when we probe - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - do_blocking_move_to_xy(rx, ry); + do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES); lcd_return_to_status(); @@ -971,11 +970,9 @@ if (!position_is_reachable(xProbe, yProbe)) break; // SHOULD NOT OCCUR (find_closest_mesh_point only returns reachable points) - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - LCD_MESSAGEPGM(MSG_UBL_MOVING_TO_NEXT); - do_blocking_move_to_xy(xProbe, yProbe); + do_blocking_move_to(xProbe, yProbe, Z_CLEARANCE_BETWEEN_PROBES); do_blocking_move_to_z(z_clearance); KEEPALIVE_STATE(PAUSED_FOR_USER); @@ -1032,8 +1029,7 @@ restore_ubl_active_state_and_leave(); KEEPALIVE_STATE(IN_HANDLER); - do_blocking_move_to_z(Z_CLEARANCE_DEPLOY_PROBE); - do_blocking_move_to_xy(rx, ry); + do_blocking_move_to(rx, ry, Z_CLEARANCE_DEPLOY_PROBE); } #endif // NEWPANEL @@ -1486,8 +1482,7 @@ LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH); - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - do_blocking_move_to_xy(rx, ry); + do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES); uint16_t not_done[16]; memset(not_done, 0xFF, sizeof(not_done)); @@ -1510,8 +1505,7 @@ if (isnan(new_z)) // if the mesh point is invalid, set it to 0.0 so it can be edited new_z = 0.0; - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); // Move the nozzle to where we are going to edit - do_blocking_move_to_xy(rawx, rawy); + do_blocking_move_to(rawx, rawy, Z_CLEARANCE_BETWEEN_PROBES); // Move the nozzle to the edit point new_z = FLOOR(new_z * 1000.0) * 0.001; // Chop off digits after the 1000ths place @@ -1571,9 +1565,8 @@ if (do_ubl_mesh_map) display_map(g29_map_type); restore_ubl_active_state_and_leave(); - do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES); - do_blocking_move_to_xy(rx, ry); + do_blocking_move_to(rx, ry, Z_CLEARANCE_BETWEEN_PROBES); LCD_MESSAGEPGM(MSG_UBL_DONE_EDITING_MESH); SERIAL_ECHOLNPGM("Done Editing Mesh");