Fix and improve EEPROM storage (#12054)

* Clean up Temperature PID
* Improve EEPROM read/write/validate
* Group `SINGLENOZZLE` saved settings
* Group planner saved settings
* Group filament change saved settings
* Group skew saved settings
* Group `FWRETRACT` saved settings
This commit is contained in:
Scott Lahteine 2018-10-10 09:45:20 -05:00 committed by GitHub
parent 9b5c1a5e77
commit d556dc1865
Signed by: GitHub
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 1151 additions and 1246 deletions

View file

@ -25,3 +25,22 @@
#include <string.h> #include <string.h>
typedef uint32_t millis_t; typedef uint32_t millis_t;
#pragma pack(push, 1) // No padding between fields
typedef struct {
float unload_length, load_length;
} fil_change_settings_t;
typedef struct {
float retract_length, // M207 S - G10 Retract length
retract_feedrate_mm_s, // M207 F - G10 Retract feedrate
retract_zlift, // M207 Z - G10 Retract hop size
retract_recover_length, // M208 S - G11 Recover length
retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate
swap_retract_length, // M207 W - G10 Swap Retract length
swap_retract_recover_length, // M208 W - G11 Swap Recover length
swap_retract_recover_feedrate_mm_s; // M208 R - G11 Swap Recover feedrate
} fwretract_settings_t;
#pragma pack(pop)

View file

@ -163,7 +163,7 @@ void I2CPositionEncoder::update() {
//SERIAL_ECHOLN(error); //SERIAL_ECHOLN(error);
#ifdef I2CPE_ERR_THRESH_ABORT #ifdef I2CPE_ERR_THRESH_ABORT
if (ABS(error) > I2CPE_ERR_THRESH_ABORT * planner.axis_steps_per_mm[encoderAxis]) { if (ABS(error) > I2CPE_ERR_THRESH_ABORT * planner.settings.axis_steps_per_mm[encoderAxis]) {
//kill("Significant Error"); //kill("Significant Error");
SERIAL_ECHOPGM("Axis error greater than set threshold, aborting!"); SERIAL_ECHOPGM("Axis error greater than set threshold, aborting!");
SERIAL_ECHOLN(error); SERIAL_ECHOLN(error);
@ -175,7 +175,7 @@ void I2CPositionEncoder::update() {
if (errIdx == 0) { if (errIdx == 0) {
// In order to correct for "error" but avoid correcting for noise and non-skips // In order to correct for "error" but avoid correcting for noise and non-skips
// it must be > threshold and have a difference average of < 10 and be < 2000 steps // it must be > threshold and have a difference average of < 10 and be < 2000 steps
if (ABS(error) > threshold * planner.axis_steps_per_mm[encoderAxis] && if (ABS(error) > threshold * planner.settings.axis_steps_per_mm[encoderAxis] &&
diffSum < 10 * (I2CPE_ERR_ARRAY_SIZE - 1) && ABS(error) < 2000) { // Check for persistent error (skip) diffSum < 10 * (I2CPE_ERR_ARRAY_SIZE - 1) && ABS(error) < 2000) { // Check for persistent error (skip)
errPrst[errPrstIdx++] = error; // Error must persist for I2CPE_ERR_PRST_ARRAY_SIZE error cycles. This also serves to improve the average accuracy errPrst[errPrstIdx++] = error; // Error must persist for I2CPE_ERR_PRST_ARRAY_SIZE error cycles. This also serves to improve the average accuracy
if (errPrstIdx >= I2CPE_ERR_PRST_ARRAY_SIZE) { if (errPrstIdx >= I2CPE_ERR_PRST_ARRAY_SIZE) {
@ -193,14 +193,14 @@ void I2CPositionEncoder::update() {
errPrstIdx = 0; errPrstIdx = 0;
} }
#else #else
if (ABS(error) > threshold * planner.axis_steps_per_mm[encoderAxis]) { if (ABS(error) > threshold * planner.settings.axis_steps_per_mm[encoderAxis]) {
//SERIAL_ECHOLN(error); //SERIAL_ECHOLN(error);
//SERIAL_ECHOLN(position); //SERIAL_ECHOLN(position);
thermalManager.babystepsTodo[encoderAxis] = -LROUND(error / 2); thermalManager.babystepsTodo[encoderAxis] = -LROUND(error / 2);
} }
#endif #endif
if (ABS(error) > I2CPE_ERR_CNT_THRESH * planner.axis_steps_per_mm[encoderAxis]) { if (ABS(error) > I2CPE_ERR_CNT_THRESH * planner.settings.axis_steps_per_mm[encoderAxis]) {
const millis_t ms = millis(); const millis_t ms = millis();
if (ELAPSED(ms, nextErrorCountTime)) { if (ELAPSED(ms, nextErrorCountTime)) {
SERIAL_ECHOPAIR("Large error on ", axis_codes[encoderAxis]); SERIAL_ECHOPAIR("Large error on ", axis_codes[encoderAxis]);
@ -284,7 +284,7 @@ int32_t I2CPositionEncoder::get_axis_error_steps(const bool report) {
//int32_t stepperTicks = stepper.position(encoderAxis); //int32_t stepperTicks = stepper.position(encoderAxis);
// With a rotary encoder we're concerned with ticks/rev; whereas with a linear we're concerned with ticks/mm // With a rotary encoder we're concerned with ticks/rev; whereas with a linear we're concerned with ticks/mm
stepperTicksPerUnit = (type == I2CPE_ENC_TYPE_ROTARY) ? stepperTicks : planner.axis_steps_per_mm[encoderAxis]; stepperTicksPerUnit = (type == I2CPE_ENC_TYPE_ROTARY) ? stepperTicks : planner.settings.axis_steps_per_mm[encoderAxis];
//convert both 'ticks' into same units / base //convert both 'ticks' into same units / base
encoderCountInStepperTicksScaled = LROUND((stepperTicksPerUnit * encoderTicks) / encoderTicksPerUnit); encoderCountInStepperTicksScaled = LROUND((stepperTicksPerUnit * encoderTicks) / encoderTicksPerUnit);
@ -444,14 +444,14 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
SERIAL_ECHOLNPGM("mm."); SERIAL_ECHOLNPGM("mm.");
//Calculate new axis steps per unit //Calculate new axis steps per unit
old_steps_mm = planner.axis_steps_per_mm[encoderAxis]; old_steps_mm = planner.settings.axis_steps_per_mm[encoderAxis];
new_steps_mm = (old_steps_mm * travelDistance) / travelledDistance; new_steps_mm = (old_steps_mm * travelDistance) / travelledDistance;
SERIAL_ECHOLNPAIR("Old steps per mm: ", old_steps_mm); SERIAL_ECHOLNPAIR("Old steps per mm: ", old_steps_mm);
SERIAL_ECHOLNPAIR("New steps per mm: ", new_steps_mm); SERIAL_ECHOLNPAIR("New steps per mm: ", new_steps_mm);
//Save new value //Save new value
planner.axis_steps_per_mm[encoderAxis] = new_steps_mm; planner.settings.axis_steps_per_mm[encoderAxis] = new_steps_mm;
if (iter > 1) { if (iter > 1) {
total += new_steps_mm; total += new_steps_mm;

View file

@ -155,7 +155,7 @@ class I2CPositionEncoder {
case I2CPE_ENC_TYPE_LINEAR: case I2CPE_ENC_TYPE_LINEAR:
return count / encoderTicksPerUnit; return count / encoderTicksPerUnit;
case I2CPE_ENC_TYPE_ROTARY: case I2CPE_ENC_TYPE_ROTARY:
return (count * stepperTicks) / (encoderTicksPerUnit * planner.axis_steps_per_mm[encoderAxis]); return (count * stepperTicks) / (encoderTicksPerUnit * planner.settings.axis_steps_per_mm[encoderAxis]);
} }
} }
@ -199,7 +199,7 @@ class I2CPositionEncoder {
case I2CPE_ENC_TYPE_LINEAR: case I2CPE_ENC_TYPE_LINEAR:
return encoderTicksPerUnit; return encoderTicksPerUnit;
case I2CPE_ENC_TYPE_ROTARY: case I2CPE_ENC_TYPE_ROTARY:
return (int)((encoderTicksPerUnit / stepperTicks) * planner.axis_steps_per_mm[encoderAxis]); return (int)((encoderTicksPerUnit / stepperTicks) * planner.settings.axis_steps_per_mm[encoderAxis]);
} }
} }

View file

@ -803,7 +803,7 @@
save_ubl_active_state_and_disable(); // Disable bed level correction for probing save_ubl_active_state_and_disable(); // Disable bed level correction for probing
do_blocking_move_to(0.5f * (MESH_MAX_X - (MESH_MIN_X)), 0.5f * (MESH_MAX_Y - (MESH_MIN_Y)), in_height); do_blocking_move_to(0.5f * (MESH_MAX_X - (MESH_MIN_X)), 0.5f * (MESH_MAX_Y - (MESH_MIN_Y)), in_height);
//, MIN(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS]) * 0.5f); //, MIN(planner.settings.max_feedrate_mm_s[X_AXIS], planner.settings.max_feedrate_mm_s[Y_AXIS]) * 0.5f);
planner.synchronize(); planner.synchronize();
SERIAL_PROTOCOLPGM("Place shim under nozzle"); SERIAL_PROTOCOLPGM("Place shim under nozzle");

View file

@ -43,34 +43,32 @@ FWRetract fwretract; // Single instance - this calls the constructor
// private: // private:
#if EXTRUDERS > 1 #if EXTRUDERS > 1
bool FWRetract::retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted bool FWRetract::retracted_swap[EXTRUDERS]; // Which extruders are swap-retracted
#endif #endif
// public: // public:
bool FWRetract::autoretract_enabled, // M209 S - Autoretract switch fwretract_settings_t FWRetract::settings; // M207 S F Z W, M208 S F W R
FWRetract::retracted[EXTRUDERS]; // Which extruders are currently retracted
float FWRetract::retract_length, // M207 S - G10 Retract length #if ENABLED(FWRETRACT_AUTORETRACT)
FWRetract::retract_feedrate_mm_s, // M207 F - G10 Retract feedrate bool FWRetract::autoretract_enabled; // M209 S - Autoretract switch
FWRetract::retract_zlift, // M207 Z - G10 Retract hop size #endif
FWRetract::retract_recover_length, // M208 S - G11 Recover length
FWRetract::retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate bool FWRetract::retracted[EXTRUDERS]; // Which extruders are currently retracted
FWRetract::swap_retract_length, // M207 W - G10 Swap Retract length
FWRetract::swap_retract_recover_length, // M208 W - G11 Swap Recover length float FWRetract::current_retract[EXTRUDERS], // Retract value used by planner
FWRetract::swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
FWRetract::current_retract[EXTRUDERS], // Retract value used by planner
FWRetract::current_hop; FWRetract::current_hop;
void FWRetract::reset() { void FWRetract::reset() {
autoretract_enabled = false; autoretract_enabled = false;
retract_length = RETRACT_LENGTH; settings.retract_length = RETRACT_LENGTH;
retract_feedrate_mm_s = RETRACT_FEEDRATE; settings.retract_feedrate_mm_s = RETRACT_FEEDRATE;
retract_zlift = RETRACT_ZLIFT; settings.retract_zlift = RETRACT_ZLIFT;
retract_recover_length = RETRACT_RECOVER_LENGTH; settings.retract_recover_length = RETRACT_RECOVER_LENGTH;
retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE; settings.retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE;
swap_retract_length = RETRACT_LENGTH_SWAP; settings.swap_retract_length = RETRACT_LENGTH_SWAP;
swap_retract_recover_length = RETRACT_RECOVER_LENGTH_SWAP; settings.swap_retract_recover_length = RETRACT_RECOVER_LENGTH_SWAP;
swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP; settings.swap_retract_recover_feedrate_mm_s = RETRACT_RECOVER_FEEDRATE_SWAP;
current_hop = 0.0; current_hop = 0.0;
for (uint8_t i = 0; i < EXTRUDERS; ++i) { for (uint8_t i = 0; i < EXTRUDERS; ++i) {
@ -132,7 +130,7 @@ void FWRetract::retract(const bool retracting
unscale_e = RECIPROCAL(planner.e_factor[active_extruder]), unscale_e = RECIPROCAL(planner.e_factor[active_extruder]),
unscale_fr = 100.0 / feedrate_percentage, // Disable feedrate scaling for retract moves unscale_fr = 100.0 / feedrate_percentage, // Disable feedrate scaling for retract moves
base_retract = ( base_retract = (
(swapping ? swap_retract_length : retract_length) (swapping ? settings.swap_retract_length : settings.retract_length)
#if ENABLED(RETRACT_SYNC_MIXING) #if ENABLED(RETRACT_SYNC_MIXING)
* (MIXING_STEPPERS) * (MIXING_STEPPERS)
#endif #endif
@ -152,7 +150,7 @@ void FWRetract::retract(const bool retracting
if (retracting) { if (retracting) {
// Retract by moving from a faux E position back to the current E position // Retract by moving from a faux E position back to the current E position
feedrate_mm_s = ( feedrate_mm_s = (
retract_feedrate_mm_s * unscale_fr settings.retract_feedrate_mm_s * unscale_fr
#if ENABLED(RETRACT_SYNC_MIXING) #if ENABLED(RETRACT_SYNC_MIXING)
* (MIXING_STEPPERS) * (MIXING_STEPPERS)
#endif #endif
@ -162,9 +160,9 @@ void FWRetract::retract(const bool retracting
planner.synchronize(); // Wait for move to complete planner.synchronize(); // Wait for move to complete
// Is a Z hop set, and has the hop not yet been done? // Is a Z hop set, and has the hop not yet been done?
if (retract_zlift > 0.01 && !current_hop) { // Apply hop only once if (settings.retract_zlift > 0.01 && !current_hop) { // Apply hop only once
current_hop += retract_zlift; // Add to the hop total (again, only once) current_hop += settings.retract_zlift; // Add to the hop total (again, only once)
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS] * unscale_fr; // Maximum Z feedrate feedrate_mm_s = planner.settings.max_feedrate_mm_s[Z_AXIS] * unscale_fr; // Maximum Z feedrate
prepare_move_to_destination(); // Raise up, set_current_to_destination prepare_move_to_destination(); // Raise up, set_current_to_destination
planner.synchronize(); // Wait for move to complete planner.synchronize(); // Wait for move to complete
} }
@ -173,12 +171,12 @@ void FWRetract::retract(const bool retracting
// If a hop was done and Z hasn't changed, undo the Z hop // If a hop was done and Z hasn't changed, undo the Z hop
if (current_hop) { if (current_hop) {
current_hop = 0.0; current_hop = 0.0;
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS] * unscale_fr; // Z feedrate to max feedrate_mm_s = planner.settings.max_feedrate_mm_s[Z_AXIS] * unscale_fr; // Z feedrate to max
prepare_move_to_destination(); // Lower Z, set_current_to_destination prepare_move_to_destination(); // Lower Z, set_current_to_destination
planner.synchronize(); // Wait for move to complete planner.synchronize(); // Wait for move to complete
} }
const float extra_recover = swapping ? swap_retract_recover_length : retract_recover_length; const float extra_recover = swapping ? settings.swap_retract_recover_length : settings.retract_recover_length;
if (extra_recover != 0.0) { if (extra_recover != 0.0) {
current_position[E_AXIS] -= extra_recover; // Adjust the current E position by the extra amount to recover current_position[E_AXIS] -= extra_recover; // Adjust the current E position by the extra amount to recover
sync_plan_position_e(); // Sync the planner position so the extra amount is recovered sync_plan_position_e(); // Sync the planner position so the extra amount is recovered
@ -186,7 +184,7 @@ void FWRetract::retract(const bool retracting
current_retract[active_extruder] = 0.0; current_retract[active_extruder] = 0.0;
feedrate_mm_s = ( feedrate_mm_s = (
(swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s) * unscale_fr (swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s) * unscale_fr
#if ENABLED(RETRACT_SYNC_MIXING) #if ENABLED(RETRACT_SYNC_MIXING)
* (MIXING_STEPPERS) * (MIXING_STEPPERS)
#endif #endif

View file

@ -19,15 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#pragma once
/** /**
* fwretract.h - Define firmware-based retraction interface * fwretract.h - Define firmware-based retraction interface
*/ */
#ifndef FWRETRACT_H #include "../inc/MarlinConfigPre.h"
#define FWRETRACT_H
#include "../inc/MarlinConfig.h"
class FWRetract { class FWRetract {
private: private:
@ -36,17 +34,16 @@ private:
#endif #endif
public: public:
static bool autoretract_enabled, // M209 S - Autoretract switch static fwretract_settings_t settings;
retracted[EXTRUDERS]; // Which extruders are currently retracted
static float retract_length, // M207 S - G10 Retract length #if ENABLED(FWRETRACT_AUTORETRACT)
retract_feedrate_mm_s, // M207 F - G10 Retract feedrate static bool autoretract_enabled; // M209 S - Autoretract switch
retract_zlift, // M207 Z - G10 Retract hop size #else
retract_recover_length, // M208 S - G11 Recover length constexpr static bool autoretract_enabled = false;
retract_recover_feedrate_mm_s, // M208 F - G11 Recover feedrate #endif
swap_retract_length, // M207 W - G10 Swap Retract length
swap_retract_recover_length, // M208 W - G11 Swap Recover length static bool retracted[EXTRUDERS]; // Which extruders are currently retracted
swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate static float current_retract[EXTRUDERS], // Retract value used by planner
current_retract[EXTRUDERS], // Retract value used by planner
current_hop; // Hop value used by planner current_hop; // Hop value used by planner
FWRetract() { reset(); } FWRetract() { reset(); }
@ -54,7 +51,7 @@ public:
static void reset(); static void reset();
static void refresh_autoretract() { static void refresh_autoretract() {
for (uint8_t i = 0; i < EXTRUDERS; i++) retracted[i] = false; LOOP_L_N(i, EXTRUDERS) retracted[i] = false;
} }
static void enable_autoretract(const bool enable) { static void enable_autoretract(const bool enable) {
@ -72,5 +69,3 @@ public:
}; };
extern FWRetract fwretract; extern FWRetract fwretract;
#endif // FWRETRACT_H

View file

@ -25,7 +25,7 @@
* This may be combined with related G-codes if features are consolidated. * This may be combined with related G-codes if features are consolidated.
*/ */
#include "../inc/MarlinConfig.h" #include "../inc/MarlinConfigPre.h"
#if ENABLED(ADVANCED_PAUSE_FEATURE) #if ENABLED(ADVANCED_PAUSE_FEATURE)
@ -59,8 +59,7 @@ static float resume_position[XYZE];
AdvancedPauseMenuResponse advanced_pause_menu_response; AdvancedPauseMenuResponse advanced_pause_menu_response;
float filament_change_unload_length[EXTRUDERS], fil_change_settings_t fc_settings[EXTRUDERS];
filament_change_load_length[EXTRUDERS];
#if ENABLED(SDSUPPORT) #if ENABLED(SDSUPPORT)
#include "../sd/cardreader.h" #include "../sd/cardreader.h"
@ -191,14 +190,14 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
// Fast Load Filament // Fast Load Filament
if (fast_load_length) { if (fast_load_length) {
#if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0
const float saved_acceleration = planner.retract_acceleration; const float saved_acceleration = planner.settings.retract_acceleration;
planner.retract_acceleration = FILAMENT_CHANGE_FAST_LOAD_ACCEL; planner.settings.retract_acceleration = FILAMENT_CHANGE_FAST_LOAD_ACCEL;
#endif #endif
do_pause_e_move(fast_load_length, FILAMENT_CHANGE_FAST_LOAD_FEEDRATE); do_pause_e_move(fast_load_length, FILAMENT_CHANGE_FAST_LOAD_FEEDRATE);
#if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0
planner.retract_acceleration = saved_acceleration; planner.settings.retract_acceleration = saved_acceleration;
#endif #endif
} }
@ -295,18 +294,18 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
safe_delay(FILAMENT_UNLOAD_DELAY); safe_delay(FILAMENT_UNLOAD_DELAY);
// Quickly purge // Quickly purge
do_pause_e_move(FILAMENT_UNLOAD_RETRACT_LENGTH + FILAMENT_UNLOAD_PURGE_LENGTH, planner.max_feedrate_mm_s[E_AXIS]); do_pause_e_move(FILAMENT_UNLOAD_RETRACT_LENGTH + FILAMENT_UNLOAD_PURGE_LENGTH, planner.settings.max_feedrate_mm_s[E_AXIS]);
// Unload filament // Unload filament
#if FILAMENT_CHANGE_UNLOAD_ACCEL > 0 #if FILAMENT_CHANGE_UNLOAD_ACCEL > 0
const float saved_acceleration = planner.retract_acceleration; const float saved_acceleration = planner.settings.retract_acceleration;
planner.retract_acceleration = FILAMENT_CHANGE_UNLOAD_ACCEL; planner.settings.retract_acceleration = FILAMENT_CHANGE_UNLOAD_ACCEL;
#endif #endif
do_pause_e_move(unload_length, FILAMENT_CHANGE_UNLOAD_FEEDRATE); do_pause_e_move(unload_length, FILAMENT_CHANGE_UNLOAD_FEEDRATE);
#if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0 #if FILAMENT_CHANGE_FAST_LOAD_ACCEL > 0
planner.retract_acceleration = saved_acceleration; planner.settings.retract_acceleration = saved_acceleration;
#endif #endif
// Disable extruders steppers for manual filament changing (only on boards that have separate ENABLE_PINS) // Disable extruders steppers for manual filament changing (only on boards that have separate ENABLE_PINS)
@ -559,7 +558,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
#if ENABLED(FWRETRACT) #if ENABLED(FWRETRACT)
// If retracted before goto pause // If retracted before goto pause
if (fwretract.retracted[active_extruder]) if (fwretract.retracted[active_extruder])
do_pause_e_move(-fwretract.retract_length, fwretract.retract_feedrate_mm_s); do_pause_e_move(-fwretract.settings.retract_length, fwretract.settings.retract_feedrate_mm_s);
#endif #endif
// If resume_position is negative // If resume_position is negative

View file

@ -19,15 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#pragma once
/** /**
* feature/pause.h - Pause feature support functions * feature/pause.h - Pause feature support functions
* This may be combined with related G-codes if features are consolidated. * This may be combined with related G-codes if features are consolidated.
*/ */
#ifndef _PAUSE_H_
#define _PAUSE_H_
#include "../libs/nozzle.h" #include "../libs/nozzle.h"
#include "../inc/MarlinConfigPre.h" #include "../inc/MarlinConfigPre.h"
@ -62,8 +60,7 @@ enum AdvancedPauseMenuResponse : char {
extern AdvancedPauseMenuResponse advanced_pause_menu_response; extern AdvancedPauseMenuResponse advanced_pause_menu_response;
extern float filament_change_unload_length[EXTRUDERS], extern fil_change_settings_t fc_settings[EXTRUDERS];
filament_change_load_length[EXTRUDERS];
extern uint8_t did_pause_print; extern uint8_t did_pause_print;
@ -89,5 +86,3 @@ bool load_filament(const float &slow_load_length=0, const float &fast_load_lengt
const bool pause_for_user=false, const AdvancedPauseMode mode=ADVANCED_PAUSE_MODE_PAUSE_PRINT DXC_PARAMS); const bool pause_for_user=false, const AdvancedPauseMode mode=ADVANCED_PAUSE_MODE_PAUSE_PRINT DXC_PARAMS);
bool unload_filament(const float &unload_length, const bool show_lcd=false, const AdvancedPauseMode mode=ADVANCED_PAUSE_MODE_PAUSE_PRINT); bool unload_filament(const float &unload_length, const bool show_lcd=false, const AdvancedPauseMode mode=ADVANCED_PAUSE_MODE_PAUSE_PRINT);
#endif // _PAUSE_H_

View file

@ -456,62 +456,62 @@
static void tmc_debug_loop(const TMC_debug_enum i) { static void tmc_debug_loop(const TMC_debug_enum i) {
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
tmc_status(stepperX, i, planner.axis_steps_per_mm[X_AXIS]); tmc_status(stepperX, i, planner.settings.axis_steps_per_mm[X_AXIS]);
#endif #endif
#if AXIS_IS_TMC(X2) #if AXIS_IS_TMC(X2)
tmc_status(stepperX2, i, planner.axis_steps_per_mm[X_AXIS]); tmc_status(stepperX2, i, planner.settings.axis_steps_per_mm[X_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Y) #if AXIS_IS_TMC(Y)
tmc_status(stepperY, i, planner.axis_steps_per_mm[Y_AXIS]); tmc_status(stepperY, i, planner.settings.axis_steps_per_mm[Y_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Y2) #if AXIS_IS_TMC(Y2)
tmc_status(stepperY2, i, planner.axis_steps_per_mm[Y_AXIS]); tmc_status(stepperY2, i, planner.settings.axis_steps_per_mm[Y_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Z) #if AXIS_IS_TMC(Z)
tmc_status(stepperZ, i, planner.axis_steps_per_mm[Z_AXIS]); tmc_status(stepperZ, i, planner.settings.axis_steps_per_mm[Z_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Z2) #if AXIS_IS_TMC(Z2)
tmc_status(stepperZ2, i, planner.axis_steps_per_mm[Z_AXIS]); tmc_status(stepperZ2, i, planner.settings.axis_steps_per_mm[Z_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Z3) #if AXIS_IS_TMC(Z3)
tmc_status(stepperZ3, i, planner.axis_steps_per_mm[Z_AXIS]); tmc_status(stepperZ3, i, planner.settings.axis_steps_per_mm[Z_AXIS]);
#endif #endif
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
tmc_status(stepperE0, i, planner.axis_steps_per_mm[E_AXIS]); tmc_status(stepperE0, i, planner.settings.axis_steps_per_mm[E_AXIS]);
#endif #endif
#if AXIS_IS_TMC(E1) #if AXIS_IS_TMC(E1)
tmc_status(stepperE1, i, planner.axis_steps_per_mm[E_AXIS tmc_status(stepperE1, i, planner.settings.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
+ 1 + 1
#endif #endif
]); ]);
#endif #endif
#if AXIS_IS_TMC(E2) #if AXIS_IS_TMC(E2)
tmc_status(stepperE2, i, planner.axis_steps_per_mm[E_AXIS tmc_status(stepperE2, i, planner.settings.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
+ 2 + 2
#endif #endif
]); ]);
#endif #endif
#if AXIS_IS_TMC(E3) #if AXIS_IS_TMC(E3)
tmc_status(stepperE3, i, planner.axis_steps_per_mm[E_AXIS tmc_status(stepperE3, i, planner.settings.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
+ 3 + 3
#endif #endif
]); ]);
#endif #endif
#if AXIS_IS_TMC(E4) #if AXIS_IS_TMC(E4)
tmc_status(stepperE4, i, planner.axis_steps_per_mm[E_AXIS tmc_status(stepperE4, i, planner.settings.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
+ 4 + 4
#endif #endif
]); ]);
#endif #endif
#if AXIS_IS_TMC(E5) #if AXIS_IS_TMC(E5)
tmc_status(stepperE5, i, planner.axis_steps_per_mm[E_AXIS tmc_status(stepperE5, i, planner.settings.axis_steps_per_mm[E_AXIS
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
+ 5 + 5
#endif #endif

View file

@ -232,7 +232,7 @@ void move_to(const float &rx, const float &ry, const float &z, const float &e_de
if (z != last_z) { if (z != last_z) {
last_z = z; last_z = z;
feed_value = planner.max_feedrate_mm_s[Z_AXIS]/(3.0); // Base the feed rate off of the configured Z_AXIS feed rate feed_value = planner.settings.max_feedrate_mm_s[Z_AXIS]/(3.0); // Base the feed rate off of the configured Z_AXIS feed rate
destination[X_AXIS] = current_position[X_AXIS]; destination[X_AXIS] = current_position[X_AXIS];
destination[Y_AXIS] = current_position[Y_AXIS]; destination[Y_AXIS] = current_position[Y_AXIS];
@ -245,7 +245,7 @@ void move_to(const float &rx, const float &ry, const float &z, const float &e_de
// Check if X or Y is involved in the movement. // Check if X or Y is involved in the movement.
// Yes: a 'normal' movement. No: a retract() or recover() // Yes: a 'normal' movement. No: a retract() or recover()
feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5; feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.settings.max_feedrate_mm_s[E_AXIS] / 1.5;
if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value); if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
@ -496,7 +496,7 @@ inline bool prime_nozzle() {
Total_Prime += 0.25; Total_Prime += 0.25;
if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERR; if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERR;
#endif #endif
G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); G26_line_to_destination(planner.settings.max_feedrate_mm_s[E_AXIS] / 15.0);
set_destination_from_current(); set_destination_from_current();
planner.synchronize(); // Without this synchronize, the purge is more consistent, planner.synchronize(); // Without this synchronize, the purge is more consistent,
// but because the planner has a buffer, we won't be able // but because the planner has a buffer, we won't be able
@ -519,7 +519,7 @@ inline bool prime_nozzle() {
#endif #endif
set_destination_from_current(); set_destination_from_current();
destination[E_AXIS] += g26_prime_length; destination[E_AXIS] += g26_prime_length;
G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0); G26_line_to_destination(planner.settings.max_feedrate_mm_s[E_AXIS] / 15.0);
set_destination_from_current(); set_destination_from_current();
retract_filament(destination); retract_filament(destination);
} }

View file

@ -42,8 +42,8 @@ void GcodeSuite::M852() {
++ijk; ++ijk;
const float value = parser.value_linear_units(); const float value = parser.value_linear_units();
if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
if (planner.xy_skew_factor != value) { if (planner.skew_factor.xy != value) {
planner.xy_skew_factor = value; planner.skew_factor.xy = value;
++setval; ++setval;
} }
} }
@ -57,8 +57,8 @@ void GcodeSuite::M852() {
++ijk; ++ijk;
const float value = parser.value_linear_units(); const float value = parser.value_linear_units();
if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
if (planner.xz_skew_factor != value) { if (planner.skew_factor.xz != value) {
planner.xz_skew_factor = value; planner.skew_factor.xz = value;
++setval; ++setval;
} }
} }
@ -70,8 +70,8 @@ void GcodeSuite::M852() {
++ijk; ++ijk;
const float value = parser.value_linear_units(); const float value = parser.value_linear_units();
if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) { if (WITHIN(value, SKEW_FACTOR_MIN, SKEW_FACTOR_MAX)) {
if (planner.yz_skew_factor != value) { if (planner.skew_factor.yz != value) {
planner.yz_skew_factor = value; planner.skew_factor.yz = value;
++setval; ++setval;
} }
} }
@ -94,11 +94,11 @@ void GcodeSuite::M852() {
if (!ijk) { if (!ijk) {
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPGM(MSG_SKEW_FACTOR " XY: "); SERIAL_ECHOPGM(MSG_SKEW_FACTOR " XY: ");
SERIAL_ECHO_F(planner.xy_skew_factor, 6); SERIAL_ECHO_F(planner.skew_factor.xy, 6);
SERIAL_EOL(); SERIAL_EOL();
#if ENABLED(SKEW_CORRECTION_FOR_Z) #if ENABLED(SKEW_CORRECTION_FOR_Z)
SERIAL_ECHOPAIR(" XZ: ", planner.xz_skew_factor); SERIAL_ECHOPAIR(" XZ: ", planner.skew_factor.xz);
SERIAL_ECHOLNPAIR(" YZ: ", planner.yz_skew_factor); SERIAL_ECHOLNPAIR(" YZ: ", planner.skew_factor.yz);
#else #else
SERIAL_EOL(); SERIAL_EOL();
#endif #endif

View file

@ -60,7 +60,7 @@ void GcodeSuite::M201() {
LOOP_XYZE(i) { LOOP_XYZE(i) {
if (parser.seen(axis_codes[i])) { if (parser.seen(axis_codes[i])) {
const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0); const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0);
planner.max_acceleration_mm_per_s2[a] = parser.value_axis_units((AxisEnum)a); planner.settings.max_acceleration_mm_per_s2[a] = parser.value_axis_units((AxisEnum)a);
} }
} }
// steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner) // steps per sq second need to be updated to agree with the units per sq second (as they are what is used in the planner)
@ -79,7 +79,7 @@ void GcodeSuite::M203() {
LOOP_XYZE(i) LOOP_XYZE(i)
if (parser.seen(axis_codes[i])) { if (parser.seen(axis_codes[i])) {
const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0); const uint8_t a = i + (i == E_AXIS ? TARGET_EXTRUDER : 0);
planner.max_feedrate_mm_s[a] = parser.value_axis_units((AxisEnum)a); planner.settings.max_feedrate_mm_s[a] = parser.value_axis_units((AxisEnum)a);
} }
} }
@ -93,25 +93,25 @@ void GcodeSuite::M203() {
void GcodeSuite::M204() { void GcodeSuite::M204() {
bool report = true; bool report = true;
if (parser.seenval('S')) { // Kept for legacy compatibility. Should NOT BE USED for new developments. if (parser.seenval('S')) { // Kept for legacy compatibility. Should NOT BE USED for new developments.
planner.travel_acceleration = planner.acceleration = parser.value_linear_units(); planner.settings.travel_acceleration = planner.settings.acceleration = parser.value_linear_units();
report = false; report = false;
} }
if (parser.seenval('P')) { if (parser.seenval('P')) {
planner.acceleration = parser.value_linear_units(); planner.settings.acceleration = parser.value_linear_units();
report = false; report = false;
} }
if (parser.seenval('R')) { if (parser.seenval('R')) {
planner.retract_acceleration = parser.value_linear_units(); planner.settings.retract_acceleration = parser.value_linear_units();
report = false; report = false;
} }
if (parser.seenval('T')) { if (parser.seenval('T')) {
planner.travel_acceleration = parser.value_linear_units(); planner.settings.travel_acceleration = parser.value_linear_units();
report = false; report = false;
} }
if (report) { if (report) {
SERIAL_ECHOPAIR("Acceleration: P", planner.acceleration); SERIAL_ECHOPAIR("Acceleration: P", planner.settings.acceleration);
SERIAL_ECHOPAIR(" R", planner.retract_acceleration); SERIAL_ECHOPAIR(" R", planner.settings.retract_acceleration);
SERIAL_ECHOLNPAIR(" T", planner.travel_acceleration); SERIAL_ECHOLNPAIR(" T", planner.settings.travel_acceleration);
} }
} }
@ -128,9 +128,9 @@ void GcodeSuite::M204() {
* J = Junction Deviation (mm) (Requires JUNCTION_DEVIATION) * J = Junction Deviation (mm) (Requires JUNCTION_DEVIATION)
*/ */
void GcodeSuite::M205() { void GcodeSuite::M205() {
if (parser.seen('B')) planner.min_segment_time_us = parser.value_ulong(); if (parser.seen('B')) planner.settings.min_segment_time_us = parser.value_ulong();
if (parser.seen('S')) planner.min_feedrate_mm_s = parser.value_linear_units(); if (parser.seen('S')) planner.settings.min_feedrate_mm_s = parser.value_linear_units();
if (parser.seen('T')) planner.min_travel_feedrate_mm_s = parser.value_linear_units(); if (parser.seen('T')) planner.settings.min_travel_feedrate_mm_s = parser.value_linear_units();
#if ENABLED(JUNCTION_DEVIATION) #if ENABLED(JUNCTION_DEVIATION)
if (parser.seen('J')) { if (parser.seen('J')) {
const float junc_dev = parser.value_linear_units(); const float junc_dev = parser.value_linear_units();

View file

@ -36,9 +36,9 @@ void M217_report(const bool eeprom=false) {
const int16_t port = command_queue_port[cmd_queue_index_r]; const int16_t port = command_queue_port[cmd_queue_index_r];
#endif #endif
serialprintPGM_P(port, eeprom ? PSTR(" M217") : PSTR("Singlenozzle:")); serialprintPGM_P(port, eeprom ? PSTR(" M217") : PSTR("Singlenozzle:"));
SERIAL_ECHOPAIR_P(port, " S", singlenozzle_swap_length); SERIAL_ECHOPAIR_P(port, " S", sn_settings.swap_length);
SERIAL_ECHOPAIR_P(port, " P", singlenozzle_prime_speed); SERIAL_ECHOPAIR_P(port, " P", sn_settings.prime_speed);
SERIAL_ECHOLNPAIR_P(port, " R", singlenozzle_retract_speed); SERIAL_ECHOLNPAIR_P(port, " R", sn_settings.retract_speed);
} }
/** /**
@ -52,9 +52,9 @@ void GcodeSuite::M217() {
bool report = true; bool report = true;
if (parser.seenval('S')) { report = false; const float v = parser.value_float(); singlenozzle_swap_length = constrain(v, 0, 500); } if (parser.seenval('S')) { report = false; const float v = parser.value_float(); sn_settings.swap_length = constrain(v, 0, 500); }
if (parser.seenval('P')) { report = false; const int16_t v = parser.value_int(); singlenozzle_prime_speed = constrain(v, 10, 5400); } if (parser.seenval('P')) { report = false; const int16_t v = parser.value_int(); sn_settings.prime_speed = constrain(v, 10, 5400); }
if (parser.seenval('R')) { report = false; const int16_t v = parser.value_int(); singlenozzle_retract_speed = constrain(v, 10, 5400); } if (parser.seenval('R')) { report = false; const int16_t v = parser.value_int(); sn_settings.retract_speed = constrain(v, 10, 5400); }
if (report) M217_report(); if (report) M217_report();

View file

@ -72,7 +72,7 @@ void GcodeSuite::M218() {
#if ENABLED(DELTA) #if ENABLED(DELTA)
if (target_extruder == active_extruder) if (target_extruder == active_extruder)
do_blocking_move_to_xy(current_position[X_AXIS], current_position[Y_AXIS], planner.max_feedrate_mm_s[X_AXIS]); do_blocking_move_to_xy(current_position[X_AXIS], current_position[Y_AXIS], planner.settings.max_feedrate_mm_s[X_AXIS]);
#endif #endif
} }

View file

@ -28,14 +28,14 @@
#include "../../module/temperature.h" #include "../../module/temperature.h"
void GcodeSuite::M304() { void GcodeSuite::M304() {
if (parser.seen('P')) thermalManager.bedKp = parser.value_float(); if (parser.seen('P')) thermalManager.bed_pid.Kp = parser.value_float();
if (parser.seen('I')) thermalManager.bedKi = scalePID_i(parser.value_float()); if (parser.seen('I')) thermalManager.bed_pid.Ki = scalePID_i(parser.value_float());
if (parser.seen('D')) thermalManager.bedKd = scalePID_d(parser.value_float()); if (parser.seen('D')) thermalManager.bed_pid.Kd = scalePID_d(parser.value_float());
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPAIR(" p:", thermalManager.bedKp); SERIAL_ECHOPAIR(" p:", thermalManager.bed_pid.Kp);
SERIAL_ECHOPAIR(" i:", unscalePID_i(thermalManager.bedKi)); SERIAL_ECHOPAIR(" i:", unscalePID_i(thermalManager.bed_pid.Ki));
SERIAL_ECHOLNPAIR(" d:", unscalePID_d(thermalManager.bedKd)); SERIAL_ECHOLNPAIR(" d:", unscalePID_d(thermalManager.bed_pid.Kd));
} }
#endif // PIDTEMPBED #endif // PIDTEMPBED

View file

@ -38,17 +38,17 @@ void GcodeSuite::M92() {
if (i == E_AXIS) { if (i == E_AXIS) {
const float value = parser.value_per_axis_unit((AxisEnum)(E_AXIS + TARGET_EXTRUDER)); const float value = parser.value_per_axis_unit((AxisEnum)(E_AXIS + TARGET_EXTRUDER));
if (value < 20) { if (value < 20) {
float factor = planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] / value; // increase e constants if M92 E14 is given for netfab. float factor = planner.settings.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] / value; // increase e constants if M92 E14 is given for netfab.
#if HAS_CLASSIC_JERK && (DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)) #if HAS_CLASSIC_JERK && (DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE))
planner.max_jerk[E_AXIS] *= factor; planner.max_jerk[E_AXIS] *= factor;
#endif #endif
planner.max_feedrate_mm_s[E_AXIS + TARGET_EXTRUDER] *= factor; planner.settings.max_feedrate_mm_s[E_AXIS + TARGET_EXTRUDER] *= factor;
planner.max_acceleration_steps_per_s2[E_AXIS + TARGET_EXTRUDER] *= factor; planner.max_acceleration_steps_per_s2[E_AXIS + TARGET_EXTRUDER] *= factor;
} }
planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] = value; planner.settings.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] = value;
} }
else { else {
planner.axis_steps_per_mm[i] = parser.value_per_axis_unit((AxisEnum)i); planner.settings.axis_steps_per_mm[i] = parser.value_per_axis_unit((AxisEnum)i);
} }
} }
} }

View file

@ -36,10 +36,10 @@
* Z[units] retract_zlift * Z[units] retract_zlift
*/ */
void GcodeSuite::M207() { void GcodeSuite::M207() {
if (parser.seen('S')) fwretract.retract_length = parser.value_axis_units(E_AXIS); if (parser.seen('S')) fwretract.settings.retract_length = parser.value_axis_units(E_AXIS);
if (parser.seen('F')) fwretract.retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); if (parser.seen('F')) fwretract.settings.retract_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('Z')) fwretract.retract_zlift = parser.value_linear_units(); if (parser.seen('Z')) fwretract.settings.retract_zlift = parser.value_linear_units();
if (parser.seen('W')) fwretract.swap_retract_length = parser.value_axis_units(E_AXIS); if (parser.seen('W')) fwretract.settings.swap_retract_length = parser.value_axis_units(E_AXIS);
} }
/** /**
@ -51,10 +51,10 @@ void GcodeSuite::M207() {
* R[units/min] swap_retract_recover_feedrate_mm_s * R[units/min] swap_retract_recover_feedrate_mm_s
*/ */
void GcodeSuite::M208() { void GcodeSuite::M208() {
if (parser.seen('S')) fwretract.retract_recover_length = parser.value_axis_units(E_AXIS); if (parser.seen('S')) fwretract.settings.retract_recover_length = parser.value_axis_units(E_AXIS);
if (parser.seen('F')) fwretract.retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); if (parser.seen('F')) fwretract.settings.retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('R')) fwretract.swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS)); if (parser.seen('R')) fwretract.settings.swap_retract_recover_feedrate_mm_s = MMM_TO_MMS(parser.value_axis_units(E_AXIS));
if (parser.seen('W')) fwretract.swap_retract_recover_length = parser.value_axis_units(E_AXIS); if (parser.seen('W')) fwretract.settings.swap_retract_recover_length = parser.value_axis_units(E_AXIS);
} }
#if ENABLED(FWRETRACT_AUTORETRACT) #if ENABLED(FWRETRACT_AUTORETRACT)

View file

@ -111,14 +111,14 @@ void GcodeSuite::M600() {
// Unload filament // Unload filament
const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS) const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS)
: filament_change_unload_length[active_extruder]); : fc_settings[active_extruder].unload_length);
// Slow load filament // Slow load filament
constexpr float slow_load_length = FILAMENT_CHANGE_SLOW_LOAD_LENGTH; constexpr float slow_load_length = FILAMENT_CHANGE_SLOW_LOAD_LENGTH;
// Fast load filament // Fast load filament
const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS)
: filament_change_load_length[active_extruder]); : fc_settings[active_extruder].load_length);
const int beep_count = parser.intval('B', const int beep_count = parser.intval('B',
#ifdef FILAMENT_CHANGE_ALERT_BEEPS #ifdef FILAMENT_CHANGE_ALERT_BEEPS

View file

@ -47,17 +47,17 @@ void GcodeSuite::M603() {
// Unload length // Unload length
if (parser.seen('U')) { if (parser.seen('U')) {
filament_change_unload_length[target_extruder] = ABS(parser.value_axis_units(E_AXIS)); fc_settings[target_extruder].unload_length = ABS(parser.value_axis_units(E_AXIS));
#if ENABLED(PREVENT_LENGTHY_EXTRUDE) #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
NOMORE(filament_change_unload_length[target_extruder], EXTRUDE_MAXLENGTH); NOMORE(fc_settings[target_extruder].unload_length, EXTRUDE_MAXLENGTH);
#endif #endif
} }
// Load length // Load length
if (parser.seen('L')) { if (parser.seen('L')) {
filament_change_load_length[target_extruder] = ABS(parser.value_axis_units(E_AXIS)); fc_settings[target_extruder].load_length = ABS(parser.value_axis_units(E_AXIS));
#if ENABLED(PREVENT_LENGTHY_EXTRUDE) #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
NOMORE(filament_change_load_length[target_extruder], EXTRUDE_MAXLENGTH); NOMORE(fc_settings[target_extruder].load_length, EXTRUDE_MAXLENGTH);
#endif #endif
} }
} }

View file

@ -79,7 +79,7 @@ void GcodeSuite::M701() {
// Load filament // Load filament
constexpr float slow_load_length = FILAMENT_CHANGE_SLOW_LOAD_LENGTH; constexpr float slow_load_length = FILAMENT_CHANGE_SLOW_LOAD_LENGTH;
const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS) const float fast_load_length = ABS(parser.seen('L') ? parser.value_axis_units(E_AXIS)
: filament_change_load_length[active_extruder]); : fc_settings[active_extruder].load_length);
load_filament(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, FILAMENT_CHANGE_ALERT_BEEPS, load_filament(slow_load_length, fast_load_length, ADVANCED_PAUSE_PURGE_LENGTH, FILAMENT_CHANGE_ALERT_BEEPS,
true, thermalManager.still_heating(target_extruder), ADVANCED_PAUSE_MODE_LOAD_FILAMENT true, thermalManager.still_heating(target_extruder), ADVANCED_PAUSE_MODE_LOAD_FILAMENT
#if ENABLED(DUAL_X_CARRIAGE) #if ENABLED(DUAL_X_CARRIAGE)
@ -147,7 +147,7 @@ void GcodeSuite::M702() {
if (!parser.seenval('T')) { if (!parser.seenval('T')) {
HOTEND_LOOP() { HOTEND_LOOP() {
if (e != active_extruder) tool_change(e, 0, true); if (e != active_extruder) tool_change(e, 0, true);
unload_filament(-filament_change_unload_length[e], true, ADVANCED_PAUSE_MODE_UNLOAD_FILAMENT); unload_filament(-fc_settings[e].unload_length, true, ADVANCED_PAUSE_MODE_UNLOAD_FILAMENT);
} }
} }
else else
@ -155,7 +155,7 @@ void GcodeSuite::M702() {
{ {
// Unload length // Unload length
const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS) : const float unload_length = -ABS(parser.seen('U') ? parser.value_axis_units(E_AXIS) :
filament_change_unload_length[target_extruder]); fc_settings[target_extruder].unload_length);
unload_filament(unload_length, true, ADVANCED_PAUSE_MODE_UNLOAD_FILAMENT); unload_filament(unload_length, true, ADVANCED_PAUSE_MODE_UNLOAD_FILAMENT);
} }

View file

@ -161,10 +161,10 @@
*/ */
#if ENABLED(HYBRID_THRESHOLD) #if ENABLED(HYBRID_THRESHOLD)
void GcodeSuite::M913() { void GcodeSuite::M913() {
#define TMC_SAY_PWMTHRS(A,Q) tmc_get_pwmthrs(stepper##Q, planner.axis_steps_per_mm[_AXIS(A)]) #define TMC_SAY_PWMTHRS(A,Q) tmc_get_pwmthrs(stepper##Q, planner.settings.axis_steps_per_mm[_AXIS(A)])
#define TMC_SET_PWMTHRS(A,Q) tmc_set_pwmthrs(stepper##Q, value, planner.axis_steps_per_mm[_AXIS(A)]) #define TMC_SET_PWMTHRS(A,Q) tmc_set_pwmthrs(stepper##Q, value, planner.settings.axis_steps_per_mm[_AXIS(A)])
#define TMC_SAY_PWMTHRS_E(E) tmc_get_pwmthrs(stepperE##E, planner.axis_steps_per_mm[E_AXIS_N(E)]) #define TMC_SAY_PWMTHRS_E(E) tmc_get_pwmthrs(stepperE##E, planner.settings.axis_steps_per_mm[E_AXIS_N(E)])
#define TMC_SET_PWMTHRS_E(E) tmc_set_pwmthrs(stepperE##E, value, planner.axis_steps_per_mm[E_AXIS_N(E)]) #define TMC_SET_PWMTHRS_E(E) tmc_set_pwmthrs(stepperE##E, value, planner.settings.axis_steps_per_mm[E_AXIS_N(E)])
bool report = true; bool report = true;
const uint8_t index = parser.byteval('I'); const uint8_t index = parser.byteval('I');

View file

@ -113,7 +113,7 @@
* M84 - Disable steppers until next move, or use S<seconds> to specify an idle * M84 - Disable steppers until next move, or use S<seconds> to specify an idle
* duration after which steppers should turn off. S0 disables the timeout. * duration after which steppers should turn off. S0 disables the timeout.
* M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default) * M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
* M92 - Set planner.axis_steps_per_mm for one or more axes. * M92 - Set planner.settings.axis_steps_per_mm for one or more axes.
* M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER) * M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER)
* M104 - Set extruder target temp. * M104 - Set extruder target temp.
* M105 - Report current temperatures. * M105 - Report current temperatures.

View file

@ -64,7 +64,7 @@ void GcodeSuite::M290() {
for (uint8_t a = X_AXIS; a <= Z_AXIS; a++) for (uint8_t a = X_AXIS; a <= Z_AXIS; a++)
if (parser.seenval(axis_codes[a]) || (a == Z_AXIS && parser.seenval('S'))) { if (parser.seenval(axis_codes[a]) || (a == Z_AXIS && parser.seenval('S'))) {
const float offs = constrain(parser.value_axis_units((AxisEnum)a), -2, 2); const float offs = constrain(parser.value_axis_units((AxisEnum)a), -2, 2);
thermalManager.babystep_axis((AxisEnum)a, offs * planner.axis_steps_per_mm[a]); thermalManager.babystep_axis((AxisEnum)a, offs * planner.settings.axis_steps_per_mm[a]);
#if ENABLED(BABYSTEP_ZPROBE_OFFSET) #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
if (a == Z_AXIS && (!parser.seen('P') || parser.value_bool())) mod_zprobe_zoffset(offs); if (a == Z_AXIS && (!parser.seen('P') || parser.value_bool())) mod_zprobe_zoffset(offs);
#endif #endif
@ -72,7 +72,7 @@ void GcodeSuite::M290() {
#else #else
if (parser.seenval('Z') || parser.seenval('S')) { if (parser.seenval('Z') || parser.seenval('S')) {
const float offs = constrain(parser.value_axis_units(Z_AXIS), -2, 2); const float offs = constrain(parser.value_axis_units(Z_AXIS), -2, 2);
thermalManager.babystep_axis(Z_AXIS, offs * planner.axis_steps_per_mm[Z_AXIS]); thermalManager.babystep_axis(Z_AXIS, offs * planner.settings.axis_steps_per_mm[Z_AXIS]);
#if ENABLED(BABYSTEP_ZPROBE_OFFSET) #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
if (!parser.seen('P') || parser.value_bool()) mod_zprobe_zoffset(offs); if (!parser.seen('P') || parser.value_bool()) mod_zprobe_zoffset(offs);
#endif #endif

View file

@ -147,9 +147,9 @@ namespace UI {
float getAxisSteps_per_mm(const axis_t axis) { float getAxisSteps_per_mm(const axis_t axis) {
switch (axis) { switch (axis) {
case X: case Y: case Z: case X: case Y: case Z:
return planner.axis_steps_per_mm[axis]; return planner.settings.axis_steps_per_mm[axis];
case E0: case E1: case E2: case E3: case E4: case E5: case E0: case E1: case E2: case E3: case E4: case E5:
return planner.axis_steps_per_mm[E_AXIS_N(axis - E0)]; return planner.settings.axis_steps_per_mm[E_AXIS_N(axis - E0)];
default: return 0; default: return 0;
} }
} }
@ -157,10 +157,10 @@ namespace UI {
void setAxisSteps_per_mm(const axis_t axis, const float steps_per_mm) { void setAxisSteps_per_mm(const axis_t axis, const float steps_per_mm) {
switch (axis) { switch (axis) {
case X: case Y: case Z: case X: case Y: case Z:
planner.axis_steps_per_mm[axis] = steps_per_mm; planner.settings.axis_steps_per_mm[axis] = steps_per_mm;
break; break;
case E0: case E1: case E2: case E3: case E4: case E5: case E0: case E1: case E2: case E3: case E4: case E5:
planner.axis_steps_per_mm[E_AXIS_N(axis - E0)] = steps_per_mm; planner.settings.axis_steps_per_mm[E_AXIS_N(axis - E0)] = steps_per_mm;
break; break;
} }
} }
@ -168,9 +168,9 @@ namespace UI {
float getAxisMaxFeedrate_mm_s(const axis_t axis) { float getAxisMaxFeedrate_mm_s(const axis_t axis) {
switch (axis) { switch (axis) {
case X: case Y: case Z: case X: case Y: case Z:
return planner.max_feedrate_mm_s[axis]; return planner.settings.max_feedrate_mm_s[axis];
case E0: case E1: case E2: case E3: case E4: case E5: case E0: case E1: case E2: case E3: case E4: case E5:
return planner.max_feedrate_mm_s[E_AXIS_N(axis - E0)]; return planner.settings.max_feedrate_mm_s[E_AXIS_N(axis - E0)];
default: return 0; default: return 0;
} }
} }
@ -178,10 +178,10 @@ namespace UI {
void setAxisMaxFeedrate_mm_s(const axis_t axis, const float max_feedrate_mm_s) { void setAxisMaxFeedrate_mm_s(const axis_t axis, const float max_feedrate_mm_s) {
switch (axis) { switch (axis) {
case X: case Y: case Z: case X: case Y: case Z:
planner.max_feedrate_mm_s[axis] = max_feedrate_mm_s; planner.settings.max_feedrate_mm_s[axis] = max_feedrate_mm_s;
break; break;
case E0: case E1: case E2: case E3: case E4: case E5: case E0: case E1: case E2: case E3: case E4: case E5:
planner.max_feedrate_mm_s[E_AXIS_N(axis - E0)] = max_feedrate_mm_s; planner.settings.max_feedrate_mm_s[E_AXIS_N(axis - E0)] = max_feedrate_mm_s;
break; break;
default: return; default: return;
} }
@ -190,9 +190,9 @@ namespace UI {
float getAxisMaxAcceleration_mm_s2(const axis_t axis) { float getAxisMaxAcceleration_mm_s2(const axis_t axis) {
switch (axis) { switch (axis) {
case X: case Y: case Z: case X: case Y: case Z:
return planner.max_acceleration_mm_per_s2[axis]; return planner.settings.max_acceleration_mm_per_s2[axis];
case E0: case E1: case E2: case E3: case E4: case E5: case E0: case E1: case E2: case E3: case E4: case E5:
return planner.max_acceleration_mm_per_s2[E_AXIS_N(axis - E0)]; return planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(axis - E0)];
default: return 0; default: return 0;
} }
} }
@ -200,10 +200,10 @@ namespace UI {
void setAxisMaxAcceleration_mm_s2(const axis_t axis, const float max_acceleration_mm_per_s2) { void setAxisMaxAcceleration_mm_s2(const axis_t axis, const float max_acceleration_mm_per_s2) {
switch (axis) { switch (axis) {
case X: case Y: case Z: case X: case Y: case Z:
planner.max_acceleration_mm_per_s2[axis] = max_acceleration_mm_per_s2; planner.settings.max_acceleration_mm_per_s2[axis] = max_acceleration_mm_per_s2;
break; break;
case E0: case E1: case E2: case E3: case E4: case E5: case E0: case E1: case E2: case E3: case E4: case E5:
planner.max_acceleration_mm_per_s2[E_AXIS_N(axis - E0)] = max_acceleration_mm_per_s2; planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(axis - E0)] = max_acceleration_mm_per_s2;
break; break;
default: return; default: return;
} }
@ -253,16 +253,16 @@ namespace UI {
} }
#endif #endif
float getMinFeedrate_mm_s() { return planner.min_feedrate_mm_s; } float getMinFeedrate_mm_s() { return planner.settings.min_feedrate_mm_s; }
float getMinTravelFeedrate_mm_s() { return planner.min_travel_feedrate_mm_s; } float getMinTravelFeedrate_mm_s() { return planner.settings.min_travel_feedrate_mm_s; }
float getPrintingAcceleration_mm_s2() { return planner.acceleration; } float getPrintingAcceleration_mm_s2() { return planner.settings.acceleration; }
float getRetractAcceleration_mm_s2() { return planner.retract_acceleration; } float getRetractAcceleration_mm_s2() { return planner.settings.retract_acceleration; }
float getTravelAcceleration_mm_s2() { return planner.travel_acceleration; } float getTravelAcceleration_mm_s2() { return planner.settings.travel_acceleration; }
void setMinFeedrate_mm_s(const float fr) { planner.min_feedrate_mm_s = fr; } void setMinFeedrate_mm_s(const float fr) { planner.settings.min_feedrate_mm_s = fr; }
void setMinTravelFeedrate_mm_s(const float fr) { planner.min_travel_feedrate_mm_s = fr; } void setMinTravelFeedrate_mm_s(const float fr) { planner.settings.min_travel_feedrate_mm_s = fr; }
void setPrintingAcceleration_mm_per_s2(const float acc) { planner.acceleration = acc; } void setPrintingAcceleration_mm_per_s2(const float acc) { planner.settings.acceleration = acc; }
void setRetractAcceleration_mm_s2(const float acc) { planner.retract_acceleration = acc; } void setRetractAcceleration_mm_s2(const float acc) { planner.settings.retract_acceleration = acc; }
void setTravelAcceleration_mm_s2(const float acc) { planner.travel_acceleration = acc; } void setTravelAcceleration_mm_s2(const float acc) { planner.settings.travel_acceleration = acc; }
#if ENABLED(BABYSTEP_ZPROBE_OFFSET) #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
float getZOffset_mm() { float getZOffset_mm() {

View file

@ -980,9 +980,9 @@ void lcd_quick_feedback(const bool clear_buttons) {
void singlenozzle_swap_menu() { void singlenozzle_swap_menu() {
START_MENU(); START_MENU();
MENU_BACK(MSG_MAIN); MENU_BACK(MSG_MAIN);
MENU_ITEM_EDIT(float3, MSG_FILAMENT_SWAP_LENGTH, &singlenozzle_swap_length, 0, 200); MENU_ITEM_EDIT(float3, MSG_FILAMENT_SWAP_LENGTH, &sn_settings.swap_length, 0, 200);
MENU_MULTIPLIER_ITEM_EDIT(int4, MSG_SINGLENOZZLE_RETRACT_SPD, &singlenozzle_retract_speed, 10, 5400); MENU_MULTIPLIER_ITEM_EDIT(int4, MSG_SINGLENOZZLE_RETRACT_SPD, &sn_settings.retract_speed, 10, 5400);
MENU_MULTIPLIER_ITEM_EDIT(int4, MSG_SINGLENOZZLE_PRIME_SPD, &singlenozzle_prime_speed, 10, 5400); MENU_MULTIPLIER_ITEM_EDIT(int4, MSG_SINGLENOZZLE_PRIME_SPD, &sn_settings.prime_speed, 10, 5400);
END_MENU(); END_MENU();
} }
#endif #endif
@ -3818,7 +3818,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
if (e == active_extruder) if (e == active_extruder)
_planner_refresh_positioning(); _planner_refresh_positioning();
else else
planner.steps_to_mm[E_AXIS + e] = 1.0f / planner.axis_steps_per_mm[E_AXIS + e]; planner.steps_to_mm[E_AXIS + e] = 1.0f / planner.settings.axis_steps_per_mm[E_AXIS + e];
} }
void _planner_refresh_e0_positioning() { _planner_refresh_e_positioning(0); } void _planner_refresh_e0_positioning() { _planner_refresh_e_positioning(0); }
void _planner_refresh_e1_positioning() { _planner_refresh_e_positioning(1); } void _planner_refresh_e1_positioning() { _planner_refresh_e_positioning(1); }
@ -3842,35 +3842,35 @@ void lcd_quick_feedback(const bool clear_buttons) {
MENU_BACK(MSG_ADVANCED_SETTINGS); MENU_BACK(MSG_ADVANCED_SETTINGS);
// M203 Max Feedrate // M203 Max Feedrate
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_A, &planner.max_feedrate_mm_s[A_AXIS], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_A, &planner.settings.max_feedrate_mm_s[A_AXIS], 1, 999);
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_B, &planner.max_feedrate_mm_s[B_AXIS], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_B, &planner.settings.max_feedrate_mm_s[B_AXIS], 1, 999);
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_C, &planner.max_feedrate_mm_s[C_AXIS], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_C, &planner.settings.max_feedrate_mm_s[C_AXIS], 1, 999);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.max_feedrate_mm_s[E_AXIS + active_extruder], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.settings.max_feedrate_mm_s[E_AXIS + active_extruder], 1, 999);
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E1, &planner.max_feedrate_mm_s[E_AXIS], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E1, &planner.settings.max_feedrate_mm_s[E_AXIS], 1, 999);
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E2, &planner.max_feedrate_mm_s[E_AXIS + 1], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E2, &planner.settings.max_feedrate_mm_s[E_AXIS + 1], 1, 999);
#if E_STEPPERS > 2 #if E_STEPPERS > 2
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E3, &planner.max_feedrate_mm_s[E_AXIS + 2], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E3, &planner.settings.max_feedrate_mm_s[E_AXIS + 2], 1, 999);
#if E_STEPPERS > 3 #if E_STEPPERS > 3
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E4, &planner.max_feedrate_mm_s[E_AXIS + 3], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E4, &planner.settings.max_feedrate_mm_s[E_AXIS + 3], 1, 999);
#if E_STEPPERS > 4 #if E_STEPPERS > 4
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E5, &planner.max_feedrate_mm_s[E_AXIS + 4], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E5, &planner.settings.max_feedrate_mm_s[E_AXIS + 4], 1, 999);
#if E_STEPPERS > 5 #if E_STEPPERS > 5
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E6, &planner.max_feedrate_mm_s[E_AXIS + 5], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E6, &planner.settings.max_feedrate_mm_s[E_AXIS + 5], 1, 999);
#endif // E_STEPPERS > 5 #endif // E_STEPPERS > 5
#endif // E_STEPPERS > 4 #endif // E_STEPPERS > 4
#endif // E_STEPPERS > 3 #endif // E_STEPPERS > 3
#endif // E_STEPPERS > 2 #endif // E_STEPPERS > 2
#else #else
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.max_feedrate_mm_s[E_AXIS], 1, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMAX MSG_E, &planner.settings.max_feedrate_mm_s[E_AXIS], 1, 999);
#endif #endif
// M205 S Min Feedrate // M205 S Min Feedrate
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMIN, &planner.min_feedrate_mm_s, 0, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VMIN, &planner.settings.min_feedrate_mm_s, 0, 999);
// M205 T Min Travel Feedrate // M205 T Min Travel Feedrate
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VTRAV_MIN, &planner.min_travel_feedrate_mm_s, 0, 999); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VTRAV_MIN, &planner.settings.min_travel_feedrate_mm_s, 0, 999);
END_MENU(); END_MENU();
} }
@ -3881,37 +3881,37 @@ void lcd_quick_feedback(const bool clear_buttons) {
MENU_BACK(MSG_ADVANCED_SETTINGS); MENU_BACK(MSG_ADVANCED_SETTINGS);
// M204 P Acceleration // M204 P Acceleration
MENU_MULTIPLIER_ITEM_EDIT(float5, MSG_ACC, &planner.acceleration, 10, 99000); MENU_MULTIPLIER_ITEM_EDIT(float5, MSG_ACC, &planner.settings.acceleration, 10, 99000);
// M204 R Retract Acceleration // M204 R Retract Acceleration
MENU_MULTIPLIER_ITEM_EDIT(float5, MSG_A_RETRACT, &planner.retract_acceleration, 100, 99000); MENU_MULTIPLIER_ITEM_EDIT(float5, MSG_A_RETRACT, &planner.settings.retract_acceleration, 100, 99000);
// M204 T Travel Acceleration // M204 T Travel Acceleration
MENU_MULTIPLIER_ITEM_EDIT(float5, MSG_A_TRAVEL, &planner.travel_acceleration, 100, 99000); MENU_MULTIPLIER_ITEM_EDIT(float5, MSG_A_TRAVEL, &planner.settings.travel_acceleration, 100, 99000);
// M201 settings // M201 settings
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_A, &planner.max_acceleration_mm_per_s2[A_AXIS], 100, 99000, _reset_acceleration_rates); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_A, &planner.settings.max_acceleration_mm_per_s2[A_AXIS], 100, 99000, _reset_acceleration_rates);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_B, &planner.max_acceleration_mm_per_s2[B_AXIS], 100, 99000, _reset_acceleration_rates); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_B, &planner.settings.max_acceleration_mm_per_s2[B_AXIS], 100, 99000, _reset_acceleration_rates);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_C, &planner.max_acceleration_mm_per_s2[C_AXIS], 10, 99000, _reset_acceleration_rates); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_C, &planner.settings.max_acceleration_mm_per_s2[C_AXIS], 10, 99000, _reset_acceleration_rates);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &planner.max_acceleration_mm_per_s2[E_AXIS + active_extruder], 100, 99000, _reset_acceleration_rates); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS + active_extruder], 100, 99000, _reset_acceleration_rates);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E1, &planner.max_acceleration_mm_per_s2[E_AXIS], 100, 99000, _reset_e0_acceleration_rate); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E1, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, 99000, _reset_e0_acceleration_rate);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E2, &planner.max_acceleration_mm_per_s2[E_AXIS + 1], 100, 99000, _reset_e1_acceleration_rate); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E2, &planner.settings.max_acceleration_mm_per_s2[E_AXIS + 1], 100, 99000, _reset_e1_acceleration_rate);
#if E_STEPPERS > 2 #if E_STEPPERS > 2
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E3, &planner.max_acceleration_mm_per_s2[E_AXIS + 2], 100, 99000, _reset_e2_acceleration_rate); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E3, &planner.settings.max_acceleration_mm_per_s2[E_AXIS + 2], 100, 99000, _reset_e2_acceleration_rate);
#if E_STEPPERS > 3 #if E_STEPPERS > 3
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E4, &planner.max_acceleration_mm_per_s2[E_AXIS + 3], 100, 99000, _reset_e3_acceleration_rate); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E4, &planner.settings.max_acceleration_mm_per_s2[E_AXIS + 3], 100, 99000, _reset_e3_acceleration_rate);
#if E_STEPPERS > 4 #if E_STEPPERS > 4
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E5, &planner.max_acceleration_mm_per_s2[E_AXIS + 4], 100, 99000, _reset_e4_acceleration_rate); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E5, &planner.settings.max_acceleration_mm_per_s2[E_AXIS + 4], 100, 99000, _reset_e4_acceleration_rate);
#if E_STEPPERS > 5 #if E_STEPPERS > 5
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E6, &planner.max_acceleration_mm_per_s2[E_AXIS + 5], 100, 99000, _reset_e5_acceleration_rate); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E6, &planner.settings.max_acceleration_mm_per_s2[E_AXIS + 5], 100, 99000, _reset_e5_acceleration_rate);
#endif // E_STEPPERS > 5 #endif // E_STEPPERS > 5
#endif // E_STEPPERS > 4 #endif // E_STEPPERS > 4
#endif // E_STEPPERS > 3 #endif // E_STEPPERS > 3
#endif // E_STEPPERS > 2 #endif // E_STEPPERS > 2
#else #else
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &planner.max_acceleration_mm_per_s2[E_AXIS], 100, 99000, _reset_acceleration_rates); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(long5, MSG_AMAX MSG_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, 99000, _reset_acceleration_rates);
#endif #endif
END_MENU(); END_MENU();
@ -3950,28 +3950,28 @@ void lcd_quick_feedback(const bool clear_buttons) {
START_MENU(); START_MENU();
MENU_BACK(MSG_ADVANCED_SETTINGS); MENU_BACK(MSG_ADVANCED_SETTINGS);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ASTEPS, &planner.axis_steps_per_mm[A_AXIS], 5, 9999, _planner_refresh_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ASTEPS, &planner.settings.axis_steps_per_mm[A_AXIS], 5, 9999, _planner_refresh_positioning);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_BSTEPS, &planner.axis_steps_per_mm[B_AXIS], 5, 9999, _planner_refresh_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_BSTEPS, &planner.settings.axis_steps_per_mm[B_AXIS], 5, 9999, _planner_refresh_positioning);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_CSTEPS, &planner.axis_steps_per_mm[C_AXIS], 5, 9999, _planner_refresh_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_CSTEPS, &planner.settings.axis_steps_per_mm[C_AXIS], 5, 9999, _planner_refresh_positioning);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ESTEPS, &planner.axis_steps_per_mm[E_AXIS + active_extruder], 5, 9999, _planner_refresh_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ESTEPS, &planner.settings.axis_steps_per_mm[E_AXIS + active_extruder], 5, 9999, _planner_refresh_positioning);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E1STEPS, &planner.axis_steps_per_mm[E_AXIS], 5, 9999, _planner_refresh_e0_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E1STEPS, &planner.settings.axis_steps_per_mm[E_AXIS], 5, 9999, _planner_refresh_e0_positioning);
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E2STEPS, &planner.axis_steps_per_mm[E_AXIS + 1], 5, 9999, _planner_refresh_e1_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E2STEPS, &planner.settings.axis_steps_per_mm[E_AXIS + 1], 5, 9999, _planner_refresh_e1_positioning);
#if E_STEPPERS > 2 #if E_STEPPERS > 2
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E3STEPS, &planner.axis_steps_per_mm[E_AXIS + 2], 5, 9999, _planner_refresh_e2_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E3STEPS, &planner.settings.axis_steps_per_mm[E_AXIS + 2], 5, 9999, _planner_refresh_e2_positioning);
#if E_STEPPERS > 3 #if E_STEPPERS > 3
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E4STEPS, &planner.axis_steps_per_mm[E_AXIS + 3], 5, 9999, _planner_refresh_e3_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E4STEPS, &planner.settings.axis_steps_per_mm[E_AXIS + 3], 5, 9999, _planner_refresh_e3_positioning);
#if E_STEPPERS > 4 #if E_STEPPERS > 4
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E5STEPS, &planner.axis_steps_per_mm[E_AXIS + 4], 5, 9999, _planner_refresh_e4_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E5STEPS, &planner.settings.axis_steps_per_mm[E_AXIS + 4], 5, 9999, _planner_refresh_e4_positioning);
#if E_STEPPERS > 5 #if E_STEPPERS > 5
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E6STEPS, &planner.axis_steps_per_mm[E_AXIS + 5], 5, 9999, _planner_refresh_e5_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_E6STEPS, &planner.settings.axis_steps_per_mm[E_AXIS + 5], 5, 9999, _planner_refresh_e5_positioning);
#endif // E_STEPPERS > 5 #endif // E_STEPPERS > 5
#endif // E_STEPPERS > 4 #endif // E_STEPPERS > 4
#endif // E_STEPPERS > 3 #endif // E_STEPPERS > 3
#endif // E_STEPPERS > 2 #endif // E_STEPPERS > 2
#else #else
MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ESTEPS, &planner.axis_steps_per_mm[E_AXIS], 5, 9999, _planner_refresh_positioning); MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(float62, MSG_ESTEPS, &planner.settings.axis_steps_per_mm[E_AXIS], 5, 9999, _planner_refresh_positioning);
#endif #endif
END_MENU(); END_MENU();
@ -4159,19 +4159,19 @@ void lcd_quick_feedback(const bool clear_buttons) {
; ;
#if EXTRUDERS == 1 #if EXTRUDERS == 1
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD, &filament_change_unload_length[0], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD, &fc_settings[0].unload_length, 0, extrude_maxlength);
#else // EXTRUDERS > 1 #else // EXTRUDERS > 1
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD, &filament_change_unload_length[active_extruder], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD, &fc_settings[active_extruder].unload_length, 0, extrude_maxlength);
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E1, &filament_change_unload_length[0], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E1, &fc_settings[0].unload_length, 0, extrude_maxlength);
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E2, &filament_change_unload_length[1], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E2, &fc_settings[1].unload_length, 0, extrude_maxlength);
#if EXTRUDERS > 2 #if EXTRUDERS > 2
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E3, &filament_change_unload_length[2], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E3, &fc_settings[2].unload_length, 0, extrude_maxlength);
#if EXTRUDERS > 3 #if EXTRUDERS > 3
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E4, &filament_change_unload_length[3], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E4, &fc_settings[3].unload_length, 0, extrude_maxlength);
#if EXTRUDERS > 4 #if EXTRUDERS > 4
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E5, &filament_change_unload_length[4], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E5, &fc_settings[4].unload_length, 0, extrude_maxlength);
#if EXTRUDERS > 5 #if EXTRUDERS > 5
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E6, &filament_change_unload_length[5], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_UNLOAD MSG_DIAM_E6, &fc_settings[5].unload_length, 0, extrude_maxlength);
#endif // EXTRUDERS > 5 #endif // EXTRUDERS > 5
#endif // EXTRUDERS > 4 #endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3 #endif // EXTRUDERS > 3
@ -4179,19 +4179,19 @@ void lcd_quick_feedback(const bool clear_buttons) {
#endif // EXTRUDERS > 1 #endif // EXTRUDERS > 1
#if EXTRUDERS == 1 #if EXTRUDERS == 1
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD, &filament_change_load_length[0], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD, &fc_settings[0].load_length, 0, extrude_maxlength);
#else // EXTRUDERS > 1 #else // EXTRUDERS > 1
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD, &filament_change_load_length[active_extruder], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD, &fc_settings[active_extruder].load_length, 0, extrude_maxlength);
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E1, &filament_change_load_length[0], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E1, &fc_settings[0].load_length, 0, extrude_maxlength);
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E2, &filament_change_load_length[1], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E2, &fc_settings[1].load_length, 0, extrude_maxlength);
#if EXTRUDERS > 2 #if EXTRUDERS > 2
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E3, &filament_change_load_length[2], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E3, &fc_settings[2].load_length, 0, extrude_maxlength);
#if EXTRUDERS > 3 #if EXTRUDERS > 3
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E4, &filament_change_load_length[3], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E4, &fc_settings[3].load_length, 0, extrude_maxlength);
#if EXTRUDERS > 4 #if EXTRUDERS > 4
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E5, &filament_change_load_length[4], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E5, &fc_settings[4].load_length, 0, extrude_maxlength);
#if EXTRUDERS > 5 #if EXTRUDERS > 5
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E6, &filament_change_load_length[5], 0, extrude_maxlength); MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_FILAMENT_LOAD MSG_DIAM_E6, &fc_settings[5].load_length, 0, extrude_maxlength);
#endif // EXTRUDERS > 5 #endif // EXTRUDERS > 5
#endif // EXTRUDERS > 4 #endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3 #endif // EXTRUDERS > 3
@ -4216,19 +4216,19 @@ void lcd_quick_feedback(const bool clear_buttons) {
#if ENABLED(FWRETRACT_AUTORETRACT) #if ENABLED(FWRETRACT_AUTORETRACT)
MENU_ITEM_EDIT_CALLBACK(bool, MSG_AUTORETRACT, &fwretract.autoretract_enabled, fwretract.refresh_autoretract); MENU_ITEM_EDIT_CALLBACK(bool, MSG_AUTORETRACT, &fwretract.autoretract_enabled, fwretract.refresh_autoretract);
#endif #endif
MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT, &fwretract.retract_length, 0, 100); MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT, &fwretract.settings.retract_length, 0, 100);
#if EXTRUDERS > 1 #if EXTRUDERS > 1
MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_SWAP, &fwretract.swap_retract_length, 0, 100); MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_SWAP, &fwretract.settings.swap_retract_length, 0, 100);
#endif #endif
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &fwretract.retract_feedrate_mm_s, 1, 999); MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACTF, &fwretract.settings.retract_feedrate_mm_s, 1, 999);
MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_ZLIFT, &fwretract.retract_zlift, 0, 999); MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_ZLIFT, &fwretract.settings.retract_zlift, 0, 999);
MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_RECOVER, &fwretract.retract_recover_length, -100, 100); MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_RECOVER, &fwretract.settings.retract_recover_length, -100, 100);
#if EXTRUDERS > 1 #if EXTRUDERS > 1
MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_RECOVER_SWAP, &fwretract.swap_retract_recover_length, -100, 100); MENU_ITEM_EDIT(float52sign, MSG_CONTROL_RETRACT_RECOVER_SWAP, &fwretract.settings.swap_retract_recover_length, -100, 100);
#endif #endif
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &fwretract.retract_recover_feedrate_mm_s, 1, 999); MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &fwretract.settings.retract_recover_feedrate_mm_s, 1, 999);
#if EXTRUDERS > 1 #if EXTRUDERS > 1
MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &fwretract.swap_retract_recover_feedrate_mm_s, 1, 999); MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &fwretract.settings.swap_retract_recover_feedrate_mm_s, 1, 999);
#endif #endif
END_MENU(); END_MENU();
} }

View file

@ -81,15 +81,6 @@
#include "../module/probe.h" #include "../module/probe.h"
#endif #endif
#if HAS_TRINAMIC
#include "stepper_indirection.h"
#include "../feature/tmc_util.h"
#define TMC_GET_PWMTHRS(A,Q) _tmc_thrs(stepper##Q.microsteps(), stepper##Q.TPWMTHRS(), planner.axis_steps_per_mm[_AXIS(A)])
#endif
typedef struct { uint16_t X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5; } tmc_stepper_current_t;
typedef struct { uint32_t X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5; } tmc_hybrid_threshold_t;
typedef struct { int16_t X, Y, Z; } tmc_sgt_t;
#if ENABLED(FWRETRACT) #if ENABLED(FWRETRACT)
#include "../feature/fwretract.h" #include "../feature/fwretract.h"
#endif #endif
@ -103,14 +94,20 @@ typedef struct { int16_t X, Y, Z; } tmc
void M217_report(const bool eeprom); void M217_report(const bool eeprom);
#endif #endif
#if ENABLED(PID_EXTRUSION_SCALING) #if HAS_TRINAMIC
#define LPQ_LEN thermalManager.lpq_len #include "stepper_indirection.h"
#include "../feature/tmc_util.h"
#define TMC_GET_PWMTHRS(A,Q) _tmc_thrs(stepper##Q.microsteps(), stepper##Q.TPWMTHRS(), planner.settings.axis_steps_per_mm[_AXIS(A)])
#endif #endif
#pragma pack(push, 1) // No padding between variables #pragma pack(push, 1) // No padding between variables
typedef struct PID { float Kp, Ki, Kd; } PID; typedef struct { uint16_t X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5; } tmc_stepper_current_t;
typedef struct PIDC { float Kp, Ki, Kd, Kc; } PIDC; typedef struct { uint32_t X, Y, Z, X2, Y2, Z2, Z3, E0, E1, E2, E3, E4, E5; } tmc_hybrid_threshold_t;
typedef struct { int16_t X, Y, Z; } tmc_sgt_t;
// Limit an index to an array size
#define ALIM(I,ARR) MIN(I, COUNT(ARR) - 1)
/** /**
* Current EEPROM Layout * Current EEPROM Layout
@ -127,17 +124,10 @@ typedef struct SettingsDataStruct {
// //
uint8_t esteppers; // XYZE_N - XYZ uint8_t esteppers; // XYZE_N - XYZ
uint32_t planner_max_acceleration_mm_per_s2[XYZE_N], // M201 XYZE planner.max_acceleration_mm_per_s2[XYZE_N] planner_settings_t planner_settings;
planner_min_segment_time_us; // M205 B planner.min_segment_time_us
float planner_axis_steps_per_mm[XYZE_N], // M92 XYZE planner.axis_steps_per_mm[XYZE_N] float planner_max_jerk[XYZE], // M205 XYZE planner.max_jerk[XYZE]
planner_max_feedrate_mm_s[XYZE_N], // M203 XYZE planner.max_feedrate_mm_s[XYZE_N] planner_junction_deviation_mm; // M205 J planner.junction_deviation_mm
planner_acceleration, // M204 P planner.acceleration
planner_retract_acceleration, // M204 R planner.retract_acceleration
planner_travel_acceleration, // M204 T planner.travel_acceleration
planner_min_feedrate_mm_s, // M205 S planner.min_feedrate_mm_s
planner_min_travel_feedrate_mm_s, // M205 T planner.min_travel_feedrate_mm_s
planner_max_jerk[XYZE], // M205 XYZE planner.max_jerk[XYZE]
planner_junction_deviation_mm; // M205 J planner.junction_deviation_mm
float home_offset[XYZ]; // M206 XYZ float home_offset[XYZ]; // M206 XYZ
@ -225,32 +215,24 @@ typedef struct SettingsDataStruct {
// //
// PIDTEMP // PIDTEMP
// //
PIDC hotendPID[HOTENDS]; // M301 En PIDC / M303 En U PIDC_t hotendPID[HOTENDS]; // M301 En PIDC / M303 En U
int16_t lpq_len; // M301 L int16_t lpq_len; // M301 L
// //
// PIDTEMPBED // PIDTEMPBED
// //
PID bedPID; // M304 PID / M303 E-1 U PID_t bedPID; // M304 PID / M303 E-1 U
// //
// HAS_LCD_CONTRAST // HAS_LCD_CONTRAST
// //
int16_t lcd_contrast; // M250 C int16_t lcd_contrast; // M250 C
// //
// FWRETRACT // FWRETRACT
// //
fwretract_settings_t fwretract_settings; // M207 S F Z W, M208 S F W R
bool autoretract_enabled; // M209 S bool autoretract_enabled; // M209 S
float retract_length, // M207 S
retract_feedrate_mm_s, // M207 F
retract_zlift, // M207 Z
retract_recover_length, // M208 S
retract_recover_feedrate_mm_s, // M208 F
swap_retract_length, // M207 W
swap_retract_recover_length, // M208 W
swap_retract_recover_feedrate_mm_s; // M208 R
// //
// !NO_VOLUMETRIC // !NO_VOLUMETRIC
@ -274,7 +256,7 @@ typedef struct SettingsDataStruct {
// //
// HAS_MOTOR_CURRENT_PWM // HAS_MOTOR_CURRENT_PWM
// //
uint32_t motor_current_setting[XYZ]; // M907 X Z E uint32_t motor_current_setting[3]; // M907 X Z E
// //
// CNC_COORDINATE_SYSTEMS // CNC_COORDINATE_SYSTEMS
@ -284,29 +266,22 @@ typedef struct SettingsDataStruct {
// //
// SKEW_CORRECTION // SKEW_CORRECTION
// //
float planner_xy_skew_factor, // M852 I planner.xy_skew_factor skew_factor_t planner_skew_factor; // M852 I J K planner.skew_factor
planner_xz_skew_factor, // M852 J planner.xz_skew_factor
planner_yz_skew_factor; // M852 K planner.yz_skew_factor
// //
// ADVANCED_PAUSE_FEATURE // ADVANCED_PAUSE_FEATURE
// //
float filament_change_unload_length[EXTRUDERS], // M603 T U fil_change_settings_t fc_settings[EXTRUDERS]; // M603 T U L
filament_change_load_length[EXTRUDERS]; // M603 T L
// //
// SINGLENOZZLE toolchange values // SINGLENOZZLE toolchange values
// //
#if ENABLED(SINGLENOZZLE) #if ENABLED(SINGLENOZZLE)
float singlenozzle_swap_length; // M217 S singlenozzle_settings_t sn_settings; // M217 S P R
int16_t singlenozzle_prime_speed, // M217 P
singlenozzle_retract_speed; // M217 R
#endif #endif
} SettingsData; } SettingsData;
#pragma pack(pop)
MarlinSettings settings; MarlinSettings settings;
uint16_t MarlinSettings::datasize() { return sizeof(SettingsData); } uint16_t MarlinSettings::datasize() { return sizeof(SettingsData); }
@ -405,14 +380,13 @@ void MarlinSettings::postprocess() {
#if ENABLED(EEPROM_SETTINGS) #if ENABLED(EEPROM_SETTINGS)
#include "../HAL/shared/persistent_store_api.h" #include "../HAL/shared/persistent_store_api.h"
#define DUMMY_PID_VALUE 3000.0f
#define EEPROM_START() int eeprom_index = EEPROM_OFFSET; persistentStore.access_start() #define EEPROM_START() int eeprom_index = EEPROM_OFFSET; persistentStore.access_start()
#define EEPROM_FINISH() persistentStore.access_finish() #define EEPROM_FINISH() persistentStore.access_finish()
#define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR) #define EEPROM_SKIP(VAR) eeprom_index += sizeof(VAR)
#define EEPROM_WRITE(VAR) persistentStore.write_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc) #define EEPROM_WRITE(VAR) persistentStore.write_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc)
#define EEPROM_READ(VAR) persistentStore.read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc, !validating) #define EEPROM_READ(VAR) persistentStore.read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc, !validating)
#define EEPROM_READ_ALWAYS(VAR) persistentStore.read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc) #define EEPROM_READ_ALWAYS(VAR) persistentStore.read_data(eeprom_index, (uint8_t*)&VAR, sizeof(VAR), &working_crc)
#define EEPROM_ASSERT(TST,ERR) if (!(TST)) do{ SERIAL_ERROR_START_P(port); SERIAL_ERRORLNPGM_P(port, ERR); eeprom_error = true; }while(0) #define EEPROM_ASSERT(TST,ERR) do{ if (!(TST)) { SERIAL_ERROR_START_P(port); SERIAL_ERRORLNPGM_P(port, ERR); eeprom_error = true; } }while(0)
#if ENABLED(DEBUG_EEPROM_READWRITE) #if ENABLED(DEBUG_EEPROM_READWRITE)
#define _FIELD_TEST(FIELD) \ #define _FIELD_TEST(FIELD) \
@ -462,18 +436,10 @@ void MarlinSettings::postprocess() {
_FIELD_TEST(esteppers); _FIELD_TEST(esteppers);
const uint8_t esteppers = COUNT(planner.axis_steps_per_mm) - XYZ; const uint8_t esteppers = COUNT(planner.settings.axis_steps_per_mm) - XYZ;
EEPROM_WRITE(esteppers); EEPROM_WRITE(esteppers);
EEPROM_WRITE(planner.max_acceleration_mm_per_s2); EEPROM_WRITE(planner.settings);
EEPROM_WRITE(planner.min_segment_time_us);
EEPROM_WRITE(planner.axis_steps_per_mm);
EEPROM_WRITE(planner.max_feedrate_mm_s);
EEPROM_WRITE(planner.acceleration);
EEPROM_WRITE(planner.retract_acceleration);
EEPROM_WRITE(planner.travel_acceleration);
EEPROM_WRITE(planner.min_feedrate_mm_s);
EEPROM_WRITE(planner.min_travel_feedrate_mm_s);
#if HAS_CLASSIC_JERK #if HAS_CLASSIC_JERK
EEPROM_WRITE(planner.max_jerk); EEPROM_WRITE(planner.max_jerk);
@ -678,40 +644,43 @@ void MarlinSettings::postprocess() {
EEPROM_WRITE(lcd_preheat_bed_temp); EEPROM_WRITE(lcd_preheat_bed_temp);
EEPROM_WRITE(lcd_preheat_fan_speed); EEPROM_WRITE(lcd_preheat_fan_speed);
for (uint8_t e = 0; e < HOTENDS; e++) { //
#if ENABLED(PIDTEMP) // PIDTEMP
EEPROM_WRITE(PID_PARAM(Kp, e)); //
EEPROM_WRITE(PID_PARAM(Ki, e)); {
EEPROM_WRITE(PID_PARAM(Kd, e)); _FIELD_TEST(hotendPID);
#if ENABLED(PID_EXTRUSION_SCALING) HOTEND_LOOP() {
EEPROM_WRITE(PID_PARAM(Kc, e)); PIDC_t pidc = {
#else PID_PARAM(Kp, e), PID_PARAM(Ki, e), PID_PARAM(Kd, e), PID_PARAM(Kc, e)
dummy = 1.0f; // 1.0 = default kc };
EEPROM_WRITE(dummy); EEPROM_WRITE(pidc);
#endif }
_FIELD_TEST(lpq_len);
#if ENABLED(PID_EXTRUSION_SCALING)
EEPROM_WRITE(thermalManager.lpq_len);
#else #else
dummy = DUMMY_PID_VALUE; // When read, will not change the existing value const int16_t lpq_len = 20;
EEPROM_WRITE(dummy); // Kp EEPROM_WRITE(lpq_len);
dummy = 0;
for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy); // Ki, Kd, Kc
#endif #endif
} // Hotends Loop }
_FIELD_TEST(lpq_len); //
// PIDTEMPBED
//
{
_FIELD_TEST(bedPID);
#if DISABLED(PIDTEMPBED)
const PID_t bed_pid = { DUMMY_PID_VALUE, DUMMY_PID_VALUE, DUMMY_PID_VALUE };
EEPROM_WRITE(bed_pid);
#else
EEPROM_WRITE(thermalManager.bed_pid);
#endif
}
#if DISABLED(PID_EXTRUSION_SCALING) //
const int16_t LPQ_LEN = 20; // LCD Contrast
#endif //
EEPROM_WRITE(LPQ_LEN);
#if DISABLED(PIDTEMPBED)
dummy = DUMMY_PID_VALUE;
for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy);
#else
EEPROM_WRITE(thermalManager.bedKp);
EEPROM_WRITE(thermalManager.bedKi);
EEPROM_WRITE(thermalManager.bedKd);
#endif
_FIELD_TEST(lcd_contrast); _FIELD_TEST(lcd_contrast);
@ -720,228 +689,224 @@ void MarlinSettings::postprocess() {
#endif #endif
EEPROM_WRITE(lcd_contrast); EEPROM_WRITE(lcd_contrast);
const bool autoretract_enabled = //
#if DISABLED(FWRETRACT_AUTORETRACT) // Firmware Retraction
false //
#else {
fwretract.autoretract_enabled _FIELD_TEST(fwretract_settings);
#endif
;
EEPROM_WRITE(autoretract_enabled);
#if DISABLED(FWRETRACT) #if ENABLED(FWRETRACT)
const float autoretract_defaults[] = { 3, 45, 0, 0, 0, 13, 0, 8 }; EEPROM_WRITE(fwretract.settings);
EEPROM_WRITE(autoretract_defaults); EEPROM_WRITE(fwretract.autoretract_enabled);
#else #else
EEPROM_WRITE(fwretract.retract_length); const fwretract_settings_t autoretract_defaults = { 3, 45, 0, 0, 0, 13, 0, 8 };
EEPROM_WRITE(fwretract.retract_feedrate_mm_s); const bool autoretract_enabled = false;
EEPROM_WRITE(fwretract.retract_zlift); EEPROM_WRITE(autoretract_defaults);
EEPROM_WRITE(fwretract.retract_recover_length); EEPROM_WRITE(autoretract_enabled);
EEPROM_WRITE(fwretract.retract_recover_feedrate_mm_s); #endif
EEPROM_WRITE(fwretract.swap_retract_length); }
EEPROM_WRITE(fwretract.swap_retract_recover_length);
EEPROM_WRITE(fwretract.swap_retract_recover_feedrate_mm_s);
#endif
// //
// Volumetric & Filament Size // Volumetric & Filament Size
// //
{
_FIELD_TEST(parser_volumetric_enabled);
_FIELD_TEST(parser_volumetric_enabled); #if DISABLED(NO_VOLUMETRICS)
#if DISABLED(NO_VOLUMETRICS) EEPROM_WRITE(parser.volumetric_enabled);
EEPROM_WRITE(planner.filament_size);
EEPROM_WRITE(parser.volumetric_enabled); #else
// Save filament sizes const bool volumetric_enabled = false;
for (uint8_t q = 0; q < COUNT(planner.filament_size); q++) dummy = DEFAULT_NOMINAL_FILAMENT_DIA;
EEPROM_WRITE(planner.filament_size[q]); EEPROM_WRITE(volumetric_enabled);
for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummy);
#else #endif
}
const bool volumetric_enabled = false;
dummy = DEFAULT_NOMINAL_FILAMENT_DIA;
EEPROM_WRITE(volumetric_enabled);
for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummy);
#endif
// //
// Save TMC Configuration, and placeholder values // TMC Configuration
// //
{
_FIELD_TEST(tmc_stepper_current);
_FIELD_TEST(tmc_stepper_current); tmc_stepper_current_t tmc_stepper_current = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
tmc_stepper_current_t tmc_stepper_current = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #if HAS_TRINAMIC
#if AXIS_IS_TMC(X)
#if HAS_TRINAMIC tmc_stepper_current.X = stepperX.getMilliamps();
#if AXIS_IS_TMC(X)
tmc_stepper_current.X = stepperX.getMilliamps();
#endif
#if AXIS_IS_TMC(Y)
tmc_stepper_current.Y = stepperY.getMilliamps();
#endif
#if AXIS_IS_TMC(Z)
tmc_stepper_current.Z = stepperZ.getMilliamps();
#endif
#if AXIS_IS_TMC(X2)
tmc_stepper_current.X2 = stepperX2.getMilliamps();
#endif
#if AXIS_IS_TMC(Y2)
tmc_stepper_current.Y2 = stepperY2.getMilliamps();
#endif
#if AXIS_IS_TMC(Z2)
tmc_stepper_current.Z2 = stepperZ2.getMilliamps();
#endif
#if AXIS_IS_TMC(Z3)
tmc_stepper_current.Z3 = stepperZ3.getMilliamps();
#endif
#if MAX_EXTRUDERS
#if AXIS_IS_TMC(E0)
tmc_stepper_current.E0 = stepperE0.getMilliamps();
#endif #endif
#if MAX_EXTRUDERS > 1 #if AXIS_IS_TMC(Y)
#if AXIS_IS_TMC(E1) tmc_stepper_current.Y = stepperY.getMilliamps();
tmc_stepper_current.E1 = stepperE1.getMilliamps();
#endif
#if MAX_EXTRUDERS > 2
#if AXIS_IS_TMC(E2)
tmc_stepper_current.E2 = stepperE2.getMilliamps();
#endif
#if MAX_EXTRUDERS > 3
#if AXIS_IS_TMC(E3)
tmc_stepper_current.E3 = stepperE3.getMilliamps();
#endif
#if MAX_EXTRUDERS > 4
#if AXIS_IS_TMC(E4)
tmc_stepper_current.E4 = stepperE4.getMilliamps();
#endif
#if MAX_EXTRUDERS > 5
#if AXIS_IS_TMC(E5)
tmc_stepper_current.E5 = stepperE5.getMilliamps();
#endif
#endif // MAX_EXTRUDERS > 5
#endif // MAX_EXTRUDERS > 4
#endif // MAX_EXTRUDERS > 3
#endif // MAX_EXTRUDERS > 2
#endif // MAX_EXTRUDERS > 1
#endif // MAX_EXTRUDERS
#endif
EEPROM_WRITE(tmc_stepper_current);
//
// Save TMC Hybrid Threshold, and placeholder values
//
_FIELD_TEST(tmc_hybrid_threshold);
#if ENABLED(HYBRID_THRESHOLD)
tmc_hybrid_threshold_t tmc_hybrid_threshold = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
#if AXIS_HAS_STEALTHCHOP(X)
tmc_hybrid_threshold.X = TMC_GET_PWMTHRS(X, X);
#endif
#if AXIS_HAS_STEALTHCHOP(Y)
tmc_hybrid_threshold.Y = TMC_GET_PWMTHRS(Y, Y);
#endif
#if AXIS_HAS_STEALTHCHOP(Z)
tmc_hybrid_threshold.Z = TMC_GET_PWMTHRS(Z, Z);
#endif
#if AXIS_HAS_STEALTHCHOP(X2)
tmc_hybrid_threshold.X2 = TMC_GET_PWMTHRS(X, X2);
#endif
#if AXIS_HAS_STEALTHCHOP(Y2)
tmc_hybrid_threshold.Y2 = TMC_GET_PWMTHRS(Y, Y2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z2)
tmc_hybrid_threshold.Z2 = TMC_GET_PWMTHRS(Z, Z2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z3)
tmc_hybrid_threshold.Z3 = TMC_GET_PWMTHRS(Z, Z3);
#endif
#if MAX_EXTRUDERS
#if AXIS_HAS_STEALTHCHOP(E0)
tmc_hybrid_threshold.E0 = TMC_GET_PWMTHRS(E, E0);
#endif #endif
#if MAX_EXTRUDERS > 1 #if AXIS_IS_TMC(Z)
#if AXIS_HAS_STEALTHCHOP(E1) tmc_stepper_current.Z = stepperZ.getMilliamps();
tmc_hybrid_threshold.E1 = TMC_GET_PWMTHRS(E, E1); #endif
#if AXIS_IS_TMC(X2)
tmc_stepper_current.X2 = stepperX2.getMilliamps();
#endif
#if AXIS_IS_TMC(Y2)
tmc_stepper_current.Y2 = stepperY2.getMilliamps();
#endif
#if AXIS_IS_TMC(Z2)
tmc_stepper_current.Z2 = stepperZ2.getMilliamps();
#endif
#if AXIS_IS_TMC(Z3)
tmc_stepper_current.Z3 = stepperZ3.getMilliamps();
#endif
#if MAX_EXTRUDERS
#if AXIS_IS_TMC(E0)
tmc_stepper_current.E0 = stepperE0.getMilliamps();
#endif #endif
#if MAX_EXTRUDERS > 2 #if MAX_EXTRUDERS > 1
#if AXIS_HAS_STEALTHCHOP(E2) #if AXIS_IS_TMC(E1)
tmc_hybrid_threshold.E2 = TMC_GET_PWMTHRS(E, E2); tmc_stepper_current.E1 = stepperE1.getMilliamps();
#endif #endif
#if MAX_EXTRUDERS > 3 #if MAX_EXTRUDERS > 2
#if AXIS_HAS_STEALTHCHOP(E3) #if AXIS_IS_TMC(E2)
tmc_hybrid_threshold.E3 = TMC_GET_PWMTHRS(E, E3); tmc_stepper_current.E2 = stepperE2.getMilliamps();
#endif #endif
#if MAX_EXTRUDERS > 4 #if MAX_EXTRUDERS > 3
#if AXIS_HAS_STEALTHCHOP(E4) #if AXIS_IS_TMC(E3)
tmc_hybrid_threshold.E4 = TMC_GET_PWMTHRS(E, E4); tmc_stepper_current.E3 = stepperE3.getMilliamps();
#endif #endif
#if MAX_EXTRUDERS > 5 #if MAX_EXTRUDERS > 4
#if AXIS_HAS_STEALTHCHOP(E5) #if AXIS_IS_TMC(E4)
tmc_hybrid_threshold.E5 = TMC_GET_PWMTHRS(E, E5); tmc_stepper_current.E4 = stepperE4.getMilliamps();
#endif #endif
#endif // MAX_EXTRUDERS > 5 #if MAX_EXTRUDERS > 5
#endif // MAX_EXTRUDERS > 4 #if AXIS_IS_TMC(E5)
#endif // MAX_EXTRUDERS > 3 tmc_stepper_current.E5 = stepperE5.getMilliamps();
#endif // MAX_EXTRUDERS > 2 #endif
#endif // MAX_EXTRUDERS > 1 #endif // MAX_EXTRUDERS > 5
#endif // MAX_EXTRUDERS #endif // MAX_EXTRUDERS > 4
#else #endif // MAX_EXTRUDERS > 3
const tmc_hybrid_threshold_t tmc_hybrid_threshold = { #endif // MAX_EXTRUDERS > 2
.X = 100, .Y = 100, .Z = 3, #endif // MAX_EXTRUDERS > 1
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3, #endif // MAX_EXTRUDERS
.E0 = 30, .E1 = 30, .E2 = 30, #endif
.E3 = 30, .E4 = 30, .E5 = 30 EEPROM_WRITE(tmc_stepper_current);
}; }
#endif
EEPROM_WRITE(tmc_hybrid_threshold); //
// TMC Hybrid Threshold, and placeholder values
//
{
_FIELD_TEST(tmc_hybrid_threshold);
#if ENABLED(HYBRID_THRESHOLD)
tmc_hybrid_threshold_t tmc_hybrid_threshold = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
#if AXIS_HAS_STEALTHCHOP(X)
tmc_hybrid_threshold.X = TMC_GET_PWMTHRS(X, X);
#endif
#if AXIS_HAS_STEALTHCHOP(Y)
tmc_hybrid_threshold.Y = TMC_GET_PWMTHRS(Y, Y);
#endif
#if AXIS_HAS_STEALTHCHOP(Z)
tmc_hybrid_threshold.Z = TMC_GET_PWMTHRS(Z, Z);
#endif
#if AXIS_HAS_STEALTHCHOP(X2)
tmc_hybrid_threshold.X2 = TMC_GET_PWMTHRS(X, X2);
#endif
#if AXIS_HAS_STEALTHCHOP(Y2)
tmc_hybrid_threshold.Y2 = TMC_GET_PWMTHRS(Y, Y2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z2)
tmc_hybrid_threshold.Z2 = TMC_GET_PWMTHRS(Z, Z2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z3)
tmc_hybrid_threshold.Z3 = TMC_GET_PWMTHRS(Z, Z3);
#endif
#if MAX_EXTRUDERS
#if AXIS_HAS_STEALTHCHOP(E0)
tmc_hybrid_threshold.E0 = TMC_GET_PWMTHRS(E, E0);
#endif
#if MAX_EXTRUDERS > 1
#if AXIS_HAS_STEALTHCHOP(E1)
tmc_hybrid_threshold.E1 = TMC_GET_PWMTHRS(E, E1);
#endif
#if MAX_EXTRUDERS > 2
#if AXIS_HAS_STEALTHCHOP(E2)
tmc_hybrid_threshold.E2 = TMC_GET_PWMTHRS(E, E2);
#endif
#if MAX_EXTRUDERS > 3
#if AXIS_HAS_STEALTHCHOP(E3)
tmc_hybrid_threshold.E3 = TMC_GET_PWMTHRS(E, E3);
#endif
#if MAX_EXTRUDERS > 4
#if AXIS_HAS_STEALTHCHOP(E4)
tmc_hybrid_threshold.E4 = TMC_GET_PWMTHRS(E, E4);
#endif
#if MAX_EXTRUDERS > 5
#if AXIS_HAS_STEALTHCHOP(E5)
tmc_hybrid_threshold.E5 = TMC_GET_PWMTHRS(E, E5);
#endif
#endif // MAX_EXTRUDERS > 5
#endif // MAX_EXTRUDERS > 4
#endif // MAX_EXTRUDERS > 3
#endif // MAX_EXTRUDERS > 2
#endif // MAX_EXTRUDERS > 1
#endif // MAX_EXTRUDERS
#else
const tmc_hybrid_threshold_t tmc_hybrid_threshold = {
.X = 100, .Y = 100, .Z = 3,
.X2 = 100, .Y2 = 100, .Z2 = 3, .Z3 = 3,
.E0 = 30, .E1 = 30, .E2 = 30,
.E3 = 30, .E4 = 30, .E5 = 30
};
#endif
EEPROM_WRITE(tmc_hybrid_threshold);
}
// //
// TMC StallGuard threshold // TMC StallGuard threshold
// //
{
tmc_sgt_t tmc_sgt = { 0, 0, 0 }; tmc_sgt_t tmc_sgt = { 0, 0, 0 };
#if USE_SENSORLESS
#if USE_SENSORLESS #if X_SENSORLESS
#if X_SENSORLESS tmc_sgt.X = stepperX.sgt();
tmc_sgt.X = stepperX.sgt(); #endif
#if Y_SENSORLESS
tmc_sgt.Y = stepperY.sgt();
#endif
#if Z_SENSORLESS
tmc_sgt.Z = stepperZ.sgt();
#endif
#endif #endif
#if Y_SENSORLESS EEPROM_WRITE(tmc_sgt);
tmc_sgt.Y = stepperY.sgt(); }
#endif
#if Z_SENSORLESS
tmc_sgt.Z = stepperZ.sgt();
#endif
#endif
EEPROM_WRITE(tmc_sgt);
// //
// Linear Advance // Linear Advance
// //
{
_FIELD_TEST(planner_extruder_advance_K);
_FIELD_TEST(planner_extruder_advance_K); #if ENABLED(LIN_ADVANCE)
EEPROM_WRITE(planner.extruder_advance_K);
#if ENABLED(LIN_ADVANCE) #else
LOOP_L_N(i, EXTRUDERS) EEPROM_WRITE(planner.extruder_advance_K[i]); dummy = 0;
#else for (uint8_t q = EXTRUDERS; q--;) EEPROM_WRITE(dummy);
dummy = 0; #endif
LOOP_L_N(i, EXTRUDERS) EEPROM_WRITE(dummy); }
#endif
_FIELD_TEST(motor_current_setting);
// //
// Motor Current PWM // Motor Current PWM
// //
{
_FIELD_TEST(motor_current_setting);
#if HAS_MOTOR_CURRENT_PWM #if HAS_MOTOR_CURRENT_PWM
for (uint8_t q = XYZ; q--;) EEPROM_WRITE(stepper.motor_current_setting[q]); EEPROM_WRITE(stepper.motor_current_setting);
#else #else
const uint32_t dummyui32[XYZ] = { 0 }; const uint32_t dummyui32[XYZ] = { 0 };
EEPROM_WRITE(dummyui32); EEPROM_WRITE(dummyui32);
#endif #endif
}
// //
// CNC Coordinate Systems // CNC Coordinate Systems
@ -950,52 +915,36 @@ void MarlinSettings::postprocess() {
_FIELD_TEST(coordinate_system); _FIELD_TEST(coordinate_system);
#if ENABLED(CNC_COORDINATE_SYSTEMS) #if ENABLED(CNC_COORDINATE_SYSTEMS)
EEPROM_WRITE(gcode.coordinate_system); // 27 floats EEPROM_WRITE(gcode.coordinate_system);
#else #else
dummy = 0; const float coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ] = { { 0 } };
for (uint8_t q = MAX_COORDINATE_SYSTEMS * XYZ; q--;) EEPROM_WRITE(dummy); EEPROM_WRITE(coordinate_system);
#endif #endif
// //
// Skew correction factors // Skew correction factors
// //
_FIELD_TEST(planner_skew_factor);
_FIELD_TEST(planner_xy_skew_factor); EEPROM_WRITE(planner.skew_factor);
#if ENABLED(SKEW_CORRECTION)
EEPROM_WRITE(planner.xy_skew_factor);
EEPROM_WRITE(planner.xz_skew_factor);
EEPROM_WRITE(planner.yz_skew_factor);
#else
dummy = 0;
for (uint8_t q = 3; q--;) EEPROM_WRITE(dummy);
#endif
// //
// Advanced Pause filament load & unload lengths // Advanced Pause filament load & unload lengths
// //
{
_FIELD_TEST(filament_change_unload_length); #if DISABLED(ADVANCED_PAUSE_FEATURE)
const fil_change_settings_t fc_settings[EXTRUDERS] = { { 0 } };
#if ENABLED(ADVANCED_PAUSE_FEATURE) #endif
for (uint8_t q = 0; q < COUNT(filament_change_unload_length); q++) { _FIELD_TEST(fc_settings);
EEPROM_WRITE(filament_change_unload_length[q]); EEPROM_WRITE(fc_settings);
EEPROM_WRITE(filament_change_load_length[q]); }
}
#else
dummy = 0;
for (uint8_t q = EXTRUDERS * 2; q--;) EEPROM_WRITE(dummy);
#endif
// //
// SINGLENOZZLE // SINGLENOZZLE
// //
#if ENABLED(SINGLENOZZLE) #if ENABLED(SINGLENOZZLE)
_FIELD_TEST(singlenozzle_swap_length); _FIELD_TEST(sn_settings);
EEPROM_WRITE(singlenozzle_swap_length); EEPROM_WRITE(sn_settings);
EEPROM_WRITE(singlenozzle_prime_speed);
EEPROM_WRITE(singlenozzle_retract_speed);
#endif #endif
// //
@ -1087,22 +1036,23 @@ void MarlinSettings::postprocess() {
uint32_t tmp1[XYZ + esteppers]; uint32_t tmp1[XYZ + esteppers];
EEPROM_READ(tmp1); // max_acceleration_mm_per_s2 EEPROM_READ(tmp1); // max_acceleration_mm_per_s2
EEPROM_READ(planner.min_segment_time_us); EEPROM_READ(planner.settings.min_segment_time_us);
float tmp2[XYZ + esteppers], tmp3[XYZ + esteppers]; float tmp2[XYZ + esteppers], tmp3[XYZ + esteppers];
EEPROM_READ(tmp2); // axis_steps_per_mm EEPROM_READ(tmp2); // axis_steps_per_mm
EEPROM_READ(tmp3); // max_feedrate_mm_s EEPROM_READ(tmp3); // max_feedrate_mm_s
if (!validating) LOOP_XYZE_N(i) { if (!validating) LOOP_XYZE_N(i) {
planner.max_acceleration_mm_per_s2[i] = i < XYZ + esteppers ? tmp1[i] : def1[i < COUNT(def1) ? i : COUNT(def1) - 1]; const bool in = (i < esteppers + XYZ);
planner.axis_steps_per_mm[i] = i < XYZ + esteppers ? tmp2[i] : def2[i < COUNT(def2) ? i : COUNT(def2) - 1]; planner.settings.max_acceleration_mm_per_s2[i] = in ? tmp1[i] : def1[ALIM(i, def1)];
planner.max_feedrate_mm_s[i] = i < XYZ + esteppers ? tmp3[i] : def3[i < COUNT(def3) ? i : COUNT(def3) - 1]; planner.settings.axis_steps_per_mm[i] = in ? tmp2[i] : def2[ALIM(i, def2)];
planner.settings.max_feedrate_mm_s[i] = in ? tmp3[i] : def3[ALIM(i, def3)];
} }
EEPROM_READ(planner.acceleration); EEPROM_READ(planner.settings.acceleration);
EEPROM_READ(planner.retract_acceleration); EEPROM_READ(planner.settings.retract_acceleration);
EEPROM_READ(planner.travel_acceleration); EEPROM_READ(planner.settings.travel_acceleration);
EEPROM_READ(planner.min_feedrate_mm_s); EEPROM_READ(planner.settings.min_feedrate_mm_s);
EEPROM_READ(planner.min_travel_feedrate_mm_s); EEPROM_READ(planner.settings.min_travel_feedrate_mm_s);
#if HAS_CLASSIC_JERK #if HAS_CLASSIC_JERK
EEPROM_READ(planner.max_jerk); EEPROM_READ(planner.max_jerk);
@ -1299,351 +1249,333 @@ void MarlinSettings::postprocess() {
// //
// Hotend PID // Hotend PID
// //
{
#if ENABLED(PIDTEMP) HOTEND_LOOP() {
for (uint8_t e = 0; e < HOTENDS; e++) { PIDC_t pidc;
EEPROM_READ(dummy); // Kp EEPROM_READ(pidc);
if (dummy != DUMMY_PID_VALUE) { #if ENABLED(PIDTEMP)
// do not need to scale PID values as the values in EEPROM are already scaled if (!validating && pidc.Kp != DUMMY_PID_VALUE) {
if (!validating) PID_PARAM(Kp, e) = dummy; // No need to scale PID values since EEPROM values are scaled
EEPROM_READ(PID_PARAM(Ki, e)); PID_PARAM(Kp, e) = pidc.Kp;
EEPROM_READ(PID_PARAM(Kd, e)); PID_PARAM(Ki, e) = pidc.Ki;
#if ENABLED(PID_EXTRUSION_SCALING) PID_PARAM(Kd, e) = pidc.Kd;
EEPROM_READ(PID_PARAM(Kc, e)); #if ENABLED(PID_EXTRUSION_SCALING)
#else PID_PARAM(Kc, e) = pidc.Kc;
EEPROM_READ(dummy); #endif
#endif }
} #endif
else
for (uint8_t q=3; q--;) EEPROM_READ(dummy); // Ki, Kd, Kc
} }
#else // !PIDTEMP }
// 4 x 4 = 16 slots for PID parameters
for (uint8_t q = HOTENDS * 4; q--;) EEPROM_READ(dummy); // Kp, Ki, Kd, Kc
#endif // !PIDTEMP
// //
// PID Extrusion Scaling // PID Extrusion Scaling
// //
{
_FIELD_TEST(lpq_len); _FIELD_TEST(lpq_len);
#if ENABLED(PID_EXTRUSION_SCALING)
#if DISABLED(PID_EXTRUSION_SCALING) EEPROM_READ(thermalManager.lpq_len);
int16_t LPQ_LEN; #else
#endif int16_t lpq_len;
EEPROM_READ(LPQ_LEN); EEPROM_READ(lpq_len);
#endif
}
// //
// Heated Bed PID // Heated Bed PID
// //
{
#if ENABLED(PIDTEMPBED) PID_t pid;
EEPROM_READ(dummy); // bedKp EEPROM_READ(pid);
if (dummy != DUMMY_PID_VALUE) { #if ENABLED(PIDTEMPBED)
if (!validating) thermalManager.bedKp = dummy; if (!validating && pid.Kp != DUMMY_PID_VALUE)
EEPROM_READ(thermalManager.bedKi); memcpy(&thermalManager.bed_pid, &pid, sizeof(pid));
EEPROM_READ(thermalManager.bedKd); #endif
} }
#else
for (uint8_t q=3; q--;) EEPROM_READ(dummy); // bedKp, bedKi, bedKd
#endif
// //
// LCD Contrast // LCD Contrast
// //
{
_FIELD_TEST(lcd_contrast); _FIELD_TEST(lcd_contrast);
#if !HAS_LCD_CONTRAST
#if !HAS_LCD_CONTRAST int16_t lcd_contrast;
int16_t lcd_contrast; #endif
#endif EEPROM_READ(lcd_contrast);
EEPROM_READ(lcd_contrast); }
// //
// Firmware Retraction // Firmware Retraction
// //
{
_FIELD_TEST(fwretract_settings);
#if ENABLED(FWRETRACT) #if ENABLED(FWRETRACT)
#if DISABLED(FWRETRACT_AUTORETRACT) EEPROM_READ(fwretract.settings);
EEPROM_READ(dummyb);
#else
EEPROM_READ(fwretract.autoretract_enabled); EEPROM_READ(fwretract.autoretract_enabled);
#else
fwretract_settings_t fwretract_settings;
bool autoretract_enabled;
EEPROM_READ(fwretract_settings);
EEPROM_READ(autoretract_enabled);
#endif #endif
EEPROM_READ(fwretract.retract_length); }
EEPROM_READ(fwretract.retract_feedrate_mm_s);
EEPROM_READ(fwretract.retract_zlift);
EEPROM_READ(fwretract.retract_recover_length);
EEPROM_READ(fwretract.retract_recover_feedrate_mm_s);
EEPROM_READ(fwretract.swap_retract_length);
EEPROM_READ(fwretract.swap_retract_recover_length);
EEPROM_READ(fwretract.swap_retract_recover_feedrate_mm_s);
#else
EEPROM_READ(dummyb);
for (uint8_t q=8; q--;) EEPROM_READ(dummy);
#endif
// //
// Volumetric & Filament Size // Volumetric & Filament Size
// //
{
struct {
bool volumetric_enabled;
float filament_size[EXTRUDERS];
} storage;
_FIELD_TEST(parser_volumetric_enabled); _FIELD_TEST(parser_volumetric_enabled);
EEPROM_READ(storage);
#if DISABLED(NO_VOLUMETRICS) #if DISABLED(NO_VOLUMETRICS)
if (!validating) {
EEPROM_READ(parser.volumetric_enabled); parser.volumetric_enabled = storage.volumetric_enabled;
COPY(planner.filament_size, storage.filament_size);
for (uint8_t q = 0; q < COUNT(planner.filament_size); q++) { }
EEPROM_READ(dummy); #endif
if (!validating) planner.filament_size[q] = dummy; }
}
#else
EEPROM_READ(dummyb);
for (uint8_t q=EXTRUDERS; q--;) EEPROM_READ(dummy);
#endif
if (!validating) reset_stepper_drivers();
// //
// TMC Stepper Settings // TMC Stepper Settings
// //
_FIELD_TEST(tmc_stepper_current); if (!validating) reset_stepper_drivers();
#if HAS_TRINAMIC // TMC Stepper Current
{
_FIELD_TEST(tmc_stepper_current);
#define SET_CURR(Q) stepper##Q.rms_current(currents.Q ? currents.Q : Q##_CURRENT) tmc_stepper_current_t tmc_stepper_current;
tmc_stepper_current_t currents;
EEPROM_READ(currents);
if (!validating) {
#if AXIS_IS_TMC(X)
SET_CURR(X);
#endif
#if AXIS_IS_TMC(Y)
SET_CURR(Y);
#endif
#if AXIS_IS_TMC(Z)
SET_CURR(Z);
#endif
#if AXIS_IS_TMC(X2)
SET_CURR(X2);
#endif
#if AXIS_IS_TMC(Y2)
SET_CURR(Y2);
#endif
#if AXIS_IS_TMC(Z2)
SET_CURR(Z2);
#endif
#if AXIS_IS_TMC(Z3)
SET_CURR(Z3);
#endif
#if AXIS_IS_TMC(E0)
SET_CURR(E0);
#endif
#if AXIS_IS_TMC(E1)
SET_CURR(E1);
#endif
#if AXIS_IS_TMC(E2)
SET_CURR(E2);
#endif
#if AXIS_IS_TMC(E3)
SET_CURR(E3);
#endif
#if AXIS_IS_TMC(E4)
SET_CURR(E4);
#endif
#if AXIS_IS_TMC(E5)
SET_CURR(E5);
#endif
}
#else
uint16_t val;
for (uint8_t q=TMC_AXES; q--;) EEPROM_READ(val);
#endif
_FIELD_TEST(tmc_hybrid_threshold); #if HAS_TRINAMIC
#if ENABLED(HYBRID_THRESHOLD) #define SET_CURR(Q) stepper##Q.rms_current(currents.Q ? currents.Q : Q##_CURRENT)
#define TMC_SET_PWMTHRS(A,Q) tmc_set_pwmthrs(stepper##Q, tmc_hybrid_threshold.Q, planner.axis_steps_per_mm[_AXIS(A)]) tmc_stepper_current_t currents;
EEPROM_READ(currents);
if (!validating) {
#if AXIS_IS_TMC(X)
SET_CURR(X);
#endif
#if AXIS_IS_TMC(Y)
SET_CURR(Y);
#endif
#if AXIS_IS_TMC(Z)
SET_CURR(Z);
#endif
#if AXIS_IS_TMC(X2)
SET_CURR(X2);
#endif
#if AXIS_IS_TMC(Y2)
SET_CURR(Y2);
#endif
#if AXIS_IS_TMC(Z2)
SET_CURR(Z2);
#endif
#if AXIS_IS_TMC(Z3)
SET_CURR(Z3);
#endif
#if AXIS_IS_TMC(E0)
SET_CURR(E0);
#endif
#if AXIS_IS_TMC(E1)
SET_CURR(E1);
#endif
#if AXIS_IS_TMC(E2)
SET_CURR(E2);
#endif
#if AXIS_IS_TMC(E3)
SET_CURR(E3);
#endif
#if AXIS_IS_TMC(E4)
SET_CURR(E4);
#endif
#if AXIS_IS_TMC(E5)
SET_CURR(E5);
#endif
}
#else
uint16_t val;
for (uint8_t q=TMC_AXES; q--;) EEPROM_READ(val);
#endif
}
// TMC Hybrid Threshold
{
tmc_hybrid_threshold_t tmc_hybrid_threshold; tmc_hybrid_threshold_t tmc_hybrid_threshold;
_FIELD_TEST(tmc_hybrid_threshold);
EEPROM_READ(tmc_hybrid_threshold); EEPROM_READ(tmc_hybrid_threshold);
if (!validating) {
#if AXIS_HAS_STEALTHCHOP(X)
TMC_SET_PWMTHRS(X, X);
#endif
#if AXIS_HAS_STEALTHCHOP(Y)
TMC_SET_PWMTHRS(Y, Y);
#endif
#if AXIS_HAS_STEALTHCHOP(Z)
TMC_SET_PWMTHRS(Z, Z);
#endif
#if AXIS_HAS_STEALTHCHOP(X2)
TMC_SET_PWMTHRS(X, X2);
#endif
#if AXIS_HAS_STEALTHCHOP(Y2)
TMC_SET_PWMTHRS(Y, Y2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z2)
TMC_SET_PWMTHRS(Z, Z2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z3)
TMC_SET_PWMTHRS(Z, Z3);
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
TMC_SET_PWMTHRS(E, E0);
#endif
#if AXIS_HAS_STEALTHCHOP(E1)
TMC_SET_PWMTHRS(E, E1);
#endif
#if AXIS_HAS_STEALTHCHOP(E2)
TMC_SET_PWMTHRS(E, E2);
#endif
#if AXIS_HAS_STEALTHCHOP(E3)
TMC_SET_PWMTHRS(E, E3);
#endif
#if AXIS_HAS_STEALTHCHOP(E4)
TMC_SET_PWMTHRS(E, E4);
#endif
#if AXIS_HAS_STEALTHCHOP(E5)
TMC_SET_PWMTHRS(E, E5);
#endif
}
#else
uint32_t thrs_val;
for (uint8_t q=TMC_AXES; q--;) EEPROM_READ(thrs_val);
#endif
/** #if ENABLED(HYBRID_THRESHOLD)
* TMC StallGuard threshold. #define TMC_SET_PWMTHRS(A,Q) tmc_set_pwmthrs(stepper##Q, tmc_hybrid_threshold.Q, planner.settings.axis_steps_per_mm[_AXIS(A)])
* X and X2 use the same value if (!validating) {
* Y and Y2 use the same value #if AXIS_HAS_STEALTHCHOP(X)
* Z, Z2 and Z3 use the same value TMC_SET_PWMTHRS(X, X);
*/ #endif
#if AXIS_HAS_STEALTHCHOP(Y)
TMC_SET_PWMTHRS(Y, Y);
#endif
#if AXIS_HAS_STEALTHCHOP(Z)
TMC_SET_PWMTHRS(Z, Z);
#endif
#if AXIS_HAS_STEALTHCHOP(X2)
TMC_SET_PWMTHRS(X, X2);
#endif
#if AXIS_HAS_STEALTHCHOP(Y2)
TMC_SET_PWMTHRS(Y, Y2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z2)
TMC_SET_PWMTHRS(Z, Z2);
#endif
#if AXIS_HAS_STEALTHCHOP(Z3)
TMC_SET_PWMTHRS(Z, Z3);
#endif
#if AXIS_HAS_STEALTHCHOP(E0)
TMC_SET_PWMTHRS(E, E0);
#endif
#if AXIS_HAS_STEALTHCHOP(E1)
TMC_SET_PWMTHRS(E, E1);
#endif
#if AXIS_HAS_STEALTHCHOP(E2)
TMC_SET_PWMTHRS(E, E2);
#endif
#if AXIS_HAS_STEALTHCHOP(E3)
TMC_SET_PWMTHRS(E, E3);
#endif
#if AXIS_HAS_STEALTHCHOP(E4)
TMC_SET_PWMTHRS(E, E4);
#endif
#if AXIS_HAS_STEALTHCHOP(E5)
TMC_SET_PWMTHRS(E, E5);
#endif
}
#endif
}
_FIELD_TEST(tmc_sgt); //
// TMC StallGuard threshold.
tmc_sgt_t tmc_sgt; // X and X2 use the same value
EEPROM_READ(tmc_sgt); // Y and Y2 use the same value
#if USE_SENSORLESS // Z, Z2 and Z3 use the same value
if (!validating) { //
#ifdef X_STALL_SENSITIVITY {
#if AXIS_HAS_STALLGUARD(X) tmc_sgt_t tmc_sgt;
stepperX.sgt(tmc_sgt.X); _FIELD_TEST(tmc_sgt);
EEPROM_READ(tmc_sgt);
#if USE_SENSORLESS
if (!validating) {
#ifdef X_STALL_SENSITIVITY
#if AXIS_HAS_STALLGUARD(X)
stepperX.sgt(tmc_sgt.X);
#endif
#if AXIS_HAS_STALLGUARD(X2)
stepperX2.sgt(tmc_sgt.X);
#endif
#endif #endif
#if AXIS_HAS_STALLGUARD(X2) #ifdef Y_STALL_SENSITIVITY
stepperX2.sgt(tmc_sgt.X); #if AXIS_HAS_STALLGUARD(Y)
stepperY.sgt(tmc_sgt.Y);
#endif
#if AXIS_HAS_STALLGUARD(Y2)
stepperY2.sgt(tmc_sgt.Y);
#endif
#endif #endif
#endif #ifdef Z_STALL_SENSITIVITY
#ifdef Y_STALL_SENSITIVITY #if AXIS_HAS_STALLGUARD(Z)
#if AXIS_HAS_STALLGUARD(Y) stepperZ.sgt(tmc_sgt.Z);
stepperY.sgt(tmc_sgt.Y); #endif
#if AXIS_HAS_STALLGUARD(Z2)
stepperZ2.sgt(tmc_sgt.Z);
#endif
#if AXIS_HAS_STALLGUARD(Z3)
stepperZ3.sgt(tmc_sgt.Z);
#endif
#endif #endif
#if AXIS_HAS_STALLGUARD(Y2) }
stepperY2.sgt(tmc_sgt.Y); #endif
#endif }
#endif
#ifdef Z_STALL_SENSITIVITY
#if AXIS_HAS_STALLGUARD(Z)
stepperZ.sgt(tmc_sgt.Z);
#endif
#if AXIS_HAS_STALLGUARD(Z2)
stepperZ2.sgt(tmc_sgt.Z);
#endif
#if AXIS_HAS_STALLGUARD(Z3)
stepperZ3.sgt(tmc_sgt.Z);
#endif
#endif
}
#endif
// //
// Linear Advance // Linear Advance
// //
_FIELD_TEST(planner_extruder_advance_K); {
float extruder_advance_K[EXTRUDERS];
LOOP_L_N(i, EXTRUDERS) { _FIELD_TEST(planner_extruder_advance_K);
EEPROM_READ(extruder_advance_K);
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
EEPROM_READ(planner.extruder_advance_K[i]); if (!validating)
#else COPY(planner.extruder_advance_K, extruder_advance_K);
EEPROM_READ(dummy);
#endif #endif
} }
// //
// Motor Current PWM // Motor Current PWM
// //
{
_FIELD_TEST(motor_current_setting); uint32_t motor_current_setting[3];
_FIELD_TEST(motor_current_setting);
#if HAS_MOTOR_CURRENT_PWM EEPROM_READ(motor_current_setting);
for (uint8_t q = XYZ; q--;) EEPROM_READ(stepper.motor_current_setting[q]); #if HAS_MOTOR_CURRENT_PWM
#else if (!validating)
uint32_t dummyui32[XYZ]; COPY(stepper.motor_current_setting, motor_current_setting);
EEPROM_READ(dummyui32); #endif
#endif }
// //
// CNC Coordinate System // CNC Coordinate System
// //
{
_FIELD_TEST(coordinate_system); _FIELD_TEST(coordinate_system);
#if ENABLED(CNC_COORDINATE_SYSTEMS)
#if ENABLED(CNC_COORDINATE_SYSTEMS) if (!validating) (void)gcode.select_coordinate_system(-1); // Go back to machine space
if (!validating) (void)gcode.select_coordinate_system(-1); // Go back to machine space EEPROM_READ(gcode.coordinate_system);
EEPROM_READ(gcode.coordinate_system); // 27 floats #else
#else float coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ];
for (uint8_t q = MAX_COORDINATE_SYSTEMS * XYZ; q--;) EEPROM_READ(dummy); EEPROM_READ(coordinate_system);
#endif #endif
}
// //
// Skew correction factors // Skew correction factors
// //
{
_FIELD_TEST(planner_xy_skew_factor); skew_factor_t skew_factor;
_FIELD_TEST(planner_skew_factor);
#if ENABLED(SKEW_CORRECTION_GCODE) EEPROM_READ(skew_factor);
EEPROM_READ(planner.xy_skew_factor); #if ENABLED(SKEW_CORRECTION_GCODE)
#if ENABLED(SKEW_CORRECTION_FOR_Z) if (!validating) {
EEPROM_READ(planner.xz_skew_factor); planner.skew_factor.xy = skew_factor.xy;
EEPROM_READ(planner.yz_skew_factor); #if ENABLED(SKEW_CORRECTION_FOR_Z)
#else planner.skew_factor.xz = skew_factor.xz;
EEPROM_READ(dummy); planner.skew_factor.yz = skew_factor.yz;
EEPROM_READ(dummy); #endif
}
#endif #endif
#else }
for (uint8_t q = 3; q--;) EEPROM_READ(dummy);
#endif
// //
// Advanced Pause filament load & unload lengths // Advanced Pause filament load & unload lengths
// //
{
_FIELD_TEST(filament_change_unload_length); #if DISABLED(ADVANCED_PAUSE_FEATURE)
fil_change_settings_t fc_settings[EXTRUDERS];
#if ENABLED(ADVANCED_PAUSE_FEATURE) #endif
for (uint8_t q = 0; q < COUNT(filament_change_unload_length); q++) { _FIELD_TEST(fc_settings);
EEPROM_READ(dummy); EEPROM_READ(fc_settings);
if (!validating && q < COUNT(filament_change_unload_length)) filament_change_unload_length[q] = dummy; }
EEPROM_READ(dummy);
if (!validating && q < COUNT(filament_change_load_length)) filament_change_load_length[q] = dummy;
}
#else
for (uint8_t q = EXTRUDERS * 2; q--;) EEPROM_READ(dummy);
#endif
// //
// SINGLENOZZLE toolchange values // SINGLENOZZLE toolchange values
// //
#if ENABLED(SINGLENOZZLE) #if ENABLED(SINGLENOZZLE)
_FIELD_TEST(singlenozzle_swap_length); _FIELD_TEST(sn_settings);
EEPROM_READ(singlenozzle_swap_length); EEPROM_READ(sn_settings);
EEPROM_READ(singlenozzle_prime_speed);
EEPROM_READ(singlenozzle_retract_speed);
#endif #endif
eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET)); eeprom_error = size_error(eeprom_index - (EEPROM_OFFSET));
if (eeprom_error) { if (eeprom_error) {
#if ENABLED(EEPROM_CHITCHAT) #if ENABLED(EEPROM_CHITCHAT)
@ -1861,21 +1793,17 @@ void MarlinSettings::reset(PORTARG_SOLO) {
static const float tmp1[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] PROGMEM = DEFAULT_MAX_FEEDRATE; static const float tmp1[] PROGMEM = DEFAULT_AXIS_STEPS_PER_UNIT, tmp2[] PROGMEM = DEFAULT_MAX_FEEDRATE;
static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION; static const uint32_t tmp3[] PROGMEM = DEFAULT_MAX_ACCELERATION;
LOOP_XYZE_N(i) { LOOP_XYZE_N(i) {
planner.axis_steps_per_mm[i] = pgm_read_float(&tmp1[i < COUNT(tmp1) ? i : COUNT(tmp1) - 1]); planner.settings.axis_steps_per_mm[i] = pgm_read_float(&tmp1[ALIM(i, tmp1)]);
planner.max_feedrate_mm_s[i] = pgm_read_float(&tmp2[i < COUNT(tmp2) ? i : COUNT(tmp2) - 1]); planner.settings.max_feedrate_mm_s[i] = pgm_read_float(&tmp2[ALIM(i, tmp2)]);
planner.max_acceleration_mm_per_s2[i] = pgm_read_dword_near(&tmp3[i < COUNT(tmp3) ? i : COUNT(tmp3) - 1]); planner.settings.max_acceleration_mm_per_s2[i] = pgm_read_dword_near(&tmp3[ALIM(i, tmp3)]);
} }
planner.min_segment_time_us = DEFAULT_MINSEGMENTTIME; planner.settings.min_segment_time_us = DEFAULT_MINSEGMENTTIME;
planner.acceleration = DEFAULT_ACCELERATION; planner.settings.acceleration = DEFAULT_ACCELERATION;
planner.retract_acceleration = DEFAULT_RETRACT_ACCELERATION; planner.settings.retract_acceleration = DEFAULT_RETRACT_ACCELERATION;
planner.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION; planner.settings.travel_acceleration = DEFAULT_TRAVEL_ACCELERATION;
planner.min_feedrate_mm_s = DEFAULT_MINIMUMFEEDRATE; planner.settings.min_feedrate_mm_s = DEFAULT_MINIMUMFEEDRATE;
planner.min_travel_feedrate_mm_s = DEFAULT_MINTRAVELFEEDRATE; planner.settings.min_travel_feedrate_mm_s = DEFAULT_MINTRAVELFEEDRATE;
#if ENABLED(JUNCTION_DEVIATION)
planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM);
#endif
#if HAS_CLASSIC_JERK #if HAS_CLASSIC_JERK
planner.max_jerk[X_AXIS] = DEFAULT_XJERK; planner.max_jerk[X_AXIS] = DEFAULT_XJERK;
@ -1886,6 +1814,10 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#endif #endif
#endif #endif
#if ENABLED(JUNCTION_DEVIATION)
planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM);
#endif
#if HAS_HOME_OFFSET #if HAS_HOME_OFFSET
ZERO(home_offset); ZERO(home_offset);
#endif #endif
@ -1903,9 +1835,9 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#endif #endif
#if ENABLED(SINGLENOZZLE) #if ENABLED(SINGLENOZZLE)
singlenozzle_swap_length = SINGLENOZZLE_SWAP_LENGTH; sn_settings.swap_length = SINGLENOZZLE_SWAP_LENGTH;
singlenozzle_prime_speed = SINGLENOZZLE_SWAP_PRIME_SPEED; sn_settings.prime_speed = SINGLENOZZLE_SWAP_PRIME_SPEED;
singlenozzle_retract_speed = SINGLENOZZLE_SWAP_RETRACT_SPEED; sn_settings.retract_speed = SINGLENOZZLE_SWAP_RETRACT_SPEED;
#endif #endif
// //
@ -2029,10 +1961,7 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#endif #endif
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
#if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 HOTEND_LOOP() {
HOTEND_LOOP()
#endif
{
PID_PARAM(Kp, e) = float(DEFAULT_Kp); PID_PARAM(Kp, e) = float(DEFAULT_Kp);
PID_PARAM(Ki, e) = scalePID_i(DEFAULT_Ki); PID_PARAM(Ki, e) = scalePID_i(DEFAULT_Ki);
PID_PARAM(Kd, e) = scalePID_d(DEFAULT_Kd); PID_PARAM(Kd, e) = scalePID_d(DEFAULT_Kd);
@ -2046,9 +1975,9 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#endif // PIDTEMP #endif // PIDTEMP
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
thermalManager.bedKp = DEFAULT_bedKp; thermalManager.bed_pid.Kp = DEFAULT_bedKp;
thermalManager.bedKi = scalePID_i(DEFAULT_bedKi); thermalManager.bed_pid.Ki = scalePID_i(DEFAULT_bedKi);
thermalManager.bedKd = scalePID_d(DEFAULT_bedKd); thermalManager.bed_pid.Kd = scalePID_d(DEFAULT_bedKd);
#endif #endif
#if HAS_LCD_CONTRAST #if HAS_LCD_CONTRAST
@ -2088,23 +2017,23 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#endif #endif
#if HAS_MOTOR_CURRENT_PWM #if HAS_MOTOR_CURRENT_PWM
uint32_t tmp_motor_current_setting[XYZ] = PWM_MOTOR_CURRENT; uint32_t tmp_motor_current_setting[3] = PWM_MOTOR_CURRENT;
for (uint8_t q = XYZ; q--;) for (uint8_t q = 3; q--;)
stepper.digipot_current(q, (stepper.motor_current_setting[q] = tmp_motor_current_setting[q])); stepper.digipot_current(q, (stepper.motor_current_setting[q] = tmp_motor_current_setting[q]));
#endif #endif
#if ENABLED(SKEW_CORRECTION_GCODE) #if ENABLED(SKEW_CORRECTION_GCODE)
planner.xy_skew_factor = XY_SKEW_FACTOR; planner.skew_factor.xy = XY_SKEW_FACTOR;
#if ENABLED(SKEW_CORRECTION_FOR_Z) #if ENABLED(SKEW_CORRECTION_FOR_Z)
planner.xz_skew_factor = XZ_SKEW_FACTOR; planner.skew_factor.xz = XZ_SKEW_FACTOR;
planner.yz_skew_factor = YZ_SKEW_FACTOR; planner.skew_factor.yz = YZ_SKEW_FACTOR;
#endif #endif
#endif #endif
#if ENABLED(ADVANCED_PAUSE_FEATURE) #if ENABLED(ADVANCED_PAUSE_FEATURE)
for (uint8_t e = 0; e < EXTRUDERS; e++) { for (uint8_t e = 0; e < EXTRUDERS; e++) {
filament_change_unload_length[e] = FILAMENT_CHANGE_UNLOAD_LENGTH; fc_settings[e].unload_length = FILAMENT_CHANGE_UNLOAD_LENGTH;
filament_change_load_length[e] = FILAMENT_CHANGE_FAST_LOAD_LENGTH; fc_settings[e].load_length = FILAMENT_CHANGE_FAST_LOAD_LENGTH;
} }
#endif #endif
@ -2258,18 +2187,18 @@ void MarlinSettings::reset(PORTARG_SOLO) {
SERIAL_ECHOLNPGM_P(port, "Steps per unit:"); SERIAL_ECHOLNPGM_P(port, "Steps per unit:");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M92 X", LINEAR_UNIT(planner.axis_steps_per_mm[X_AXIS])); SERIAL_ECHOPAIR_P(port, " M92 X", LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]));
SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.axis_steps_per_mm[Y_AXIS])); SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]));
SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.axis_steps_per_mm[Z_AXIS])); SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]));
#if DISABLED(DISTINCT_E_FACTORS) #if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS])); SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS]));
#endif #endif
SERIAL_EOL_P(port); SERIAL_EOL_P(port);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
CONFIG_ECHO_START; CONFIG_ECHO_START;
for (uint8_t i = 0; i < E_STEPPERS; i++) { for (uint8_t i = 0; i < E_STEPPERS; i++) {
SERIAL_ECHOPAIR_P(port, " M92 T", (int)i); SERIAL_ECHOPAIR_P(port, " M92 T", (int)i);
SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.axis_steps_per_mm[E_AXIS + i])); SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.settings.axis_steps_per_mm[E_AXIS + i]));
} }
#endif #endif
@ -2278,18 +2207,18 @@ void MarlinSettings::reset(PORTARG_SOLO) {
SERIAL_ECHOLNPGM_P(port, "Maximum feedrates (units/s):"); SERIAL_ECHOLNPGM_P(port, "Maximum feedrates (units/s):");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M203 X", LINEAR_UNIT(planner.max_feedrate_mm_s[X_AXIS])); SERIAL_ECHOPAIR_P(port, " M203 X", LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]));
SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_feedrate_mm_s[Y_AXIS])); SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]));
SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_feedrate_mm_s[Z_AXIS])); SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]));
#if DISABLED(DISTINCT_E_FACTORS) #if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS])); SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS]));
#endif #endif
SERIAL_EOL_P(port); SERIAL_EOL_P(port);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
CONFIG_ECHO_START; CONFIG_ECHO_START;
for (uint8_t i = 0; i < E_STEPPERS; i++) { for (uint8_t i = 0; i < E_STEPPERS; i++) {
SERIAL_ECHOPAIR_P(port, " M203 T", (int)i); SERIAL_ECHOPAIR_P(port, " M203 T", (int)i);
SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_feedrate_mm_s[E_AXIS + i])); SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS + i]));
} }
#endif #endif
@ -2298,18 +2227,18 @@ void MarlinSettings::reset(PORTARG_SOLO) {
SERIAL_ECHOLNPGM_P(port, "Maximum Acceleration (units/s2):"); SERIAL_ECHOLNPGM_P(port, "Maximum Acceleration (units/s2):");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M201 X", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[X_AXIS])); SERIAL_ECHOPAIR_P(port, " M201 X", LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]));
SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Y_AXIS])); SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]));
SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_acceleration_mm_per_s2[Z_AXIS])); SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]));
#if DISABLED(DISTINCT_E_FACTORS) #if DISABLED(DISTINCT_E_FACTORS)
SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS])); SERIAL_ECHOPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS]));
#endif #endif
SERIAL_EOL_P(port); SERIAL_EOL_P(port);
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
CONFIG_ECHO_START; CONFIG_ECHO_START;
for (uint8_t i = 0; i < E_STEPPERS; i++) { for (uint8_t i = 0; i < E_STEPPERS; i++) {
SERIAL_ECHOPAIR_P(port, " M201 T", (int)i); SERIAL_ECHOPAIR_P(port, " M201 T", (int)i);
SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.max_acceleration_mm_per_s2[E_AXIS + i])); SERIAL_ECHOLNPAIR_P(port, " E", VOLUMETRIC_UNIT(planner.settings.max_acceleration_mm_per_s2[E_AXIS + i]));
} }
#endif #endif
@ -2318,9 +2247,9 @@ void MarlinSettings::reset(PORTARG_SOLO) {
SERIAL_ECHOLNPGM_P(port, "Acceleration (units/s2): P<print_accel> R<retract_accel> T<travel_accel>"); SERIAL_ECHOLNPGM_P(port, "Acceleration (units/s2): P<print_accel> R<retract_accel> T<travel_accel>");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M204 P", LINEAR_UNIT(planner.acceleration)); SERIAL_ECHOPAIR_P(port, " M204 P", LINEAR_UNIT(planner.settings.acceleration));
SERIAL_ECHOPAIR_P(port, " R", LINEAR_UNIT(planner.retract_acceleration)); SERIAL_ECHOPAIR_P(port, " R", LINEAR_UNIT(planner.settings.retract_acceleration));
SERIAL_ECHOLNPAIR_P(port, " T", LINEAR_UNIT(planner.travel_acceleration)); SERIAL_ECHOLNPAIR_P(port, " T", LINEAR_UNIT(planner.settings.travel_acceleration));
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
@ -2337,9 +2266,9 @@ void MarlinSettings::reset(PORTARG_SOLO) {
SERIAL_EOL_P(port); SERIAL_EOL_P(port);
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M205 B", LINEAR_UNIT(planner.min_segment_time_us)); SERIAL_ECHOPAIR_P(port, " M205 B", LINEAR_UNIT(planner.settings.min_segment_time_us));
SERIAL_ECHOPAIR_P(port, " S", LINEAR_UNIT(planner.min_feedrate_mm_s)); SERIAL_ECHOPAIR_P(port, " S", LINEAR_UNIT(planner.settings.min_feedrate_mm_s));
SERIAL_ECHOPAIR_P(port, " T", LINEAR_UNIT(planner.min_travel_feedrate_mm_s)); SERIAL_ECHOPAIR_P(port, " T", LINEAR_UNIT(planner.settings.min_travel_feedrate_mm_s));
#if ENABLED(JUNCTION_DEVIATION) #if ENABLED(JUNCTION_DEVIATION)
SERIAL_ECHOPAIR_P(port, " J", LINEAR_UNIT(planner.junction_deviation_mm)); SERIAL_ECHOPAIR_P(port, " J", LINEAR_UNIT(planner.junction_deviation_mm));
@ -2597,9 +2526,9 @@ void MarlinSettings::reset(PORTARG_SOLO) {
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M304 P", thermalManager.bedKp); SERIAL_ECHOPAIR_P(port, " M304 P", thermalManager.bed_pid.Kp);
SERIAL_ECHOPAIR_P(port, " I", unscalePID_i(thermalManager.bedKi)); SERIAL_ECHOPAIR_P(port, " I", unscalePID_i(thermalManager.bed_pid.Ki));
SERIAL_ECHOPAIR_P(port, " D", unscalePID_d(thermalManager.bedKd)); SERIAL_ECHOPAIR_P(port, " D", unscalePID_d(thermalManager.bed_pid.Kd));
SERIAL_EOL_P(port); SERIAL_EOL_P(port);
#endif #endif
@ -2621,19 +2550,19 @@ void MarlinSettings::reset(PORTARG_SOLO) {
SERIAL_ECHOLNPGM_P(port, "Retract: S<length> F<units/m> Z<lift>"); SERIAL_ECHOLNPGM_P(port, "Retract: S<length> F<units/m> Z<lift>");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M207 S", LINEAR_UNIT(fwretract.retract_length)); SERIAL_ECHOPAIR_P(port, " M207 S", LINEAR_UNIT(fwretract.settings.retract_length));
SERIAL_ECHOPAIR_P(port, " W", LINEAR_UNIT(fwretract.swap_retract_length)); SERIAL_ECHOPAIR_P(port, " W", LINEAR_UNIT(fwretract.settings.swap_retract_length));
SERIAL_ECHOPAIR_P(port, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_feedrate_mm_s))); SERIAL_ECHOPAIR_P(port, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.settings.retract_feedrate_mm_s)));
SERIAL_ECHOLNPAIR_P(port, " Z", LINEAR_UNIT(fwretract.retract_zlift)); SERIAL_ECHOLNPAIR_P(port, " Z", LINEAR_UNIT(fwretract.settings.retract_zlift));
if (!forReplay) { if (!forReplay) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOLNPGM_P(port, "Recover: S<length> F<units/m>"); SERIAL_ECHOLNPGM_P(port, "Recover: S<length> F<units/m>");
} }
CONFIG_ECHO_START; CONFIG_ECHO_START;
SERIAL_ECHOPAIR_P(port, " M208 S", LINEAR_UNIT(fwretract.retract_recover_length)); SERIAL_ECHOPAIR_P(port, " M208 S", LINEAR_UNIT(fwretract.settings.retract_recover_length));
SERIAL_ECHOPAIR_P(port, " W", LINEAR_UNIT(fwretract.swap_retract_recover_length)); SERIAL_ECHOPAIR_P(port, " W", LINEAR_UNIT(fwretract.settings.swap_retract_recover_length));
SERIAL_ECHOLNPAIR_P(port, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.retract_recover_feedrate_mm_s))); SERIAL_ECHOLNPAIR_P(port, " F", MMS_TO_MMM(LINEAR_UNIT(fwretract.settings.retract_recover_feedrate_mm_s)));
#if ENABLED(FWRETRACT_AUTORETRACT) #if ENABLED(FWRETRACT_AUTORETRACT)
@ -2672,15 +2601,15 @@ void MarlinSettings::reset(PORTARG_SOLO) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
#if ENABLED(SKEW_CORRECTION_FOR_Z) #if ENABLED(SKEW_CORRECTION_FOR_Z)
SERIAL_ECHOPGM_P(port, " M852 I"); SERIAL_ECHOPGM_P(port, " M852 I");
SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.xy_skew_factor), 6); SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.skew_factor.xy), 6);
SERIAL_ECHOPGM_P(port, " J"); SERIAL_ECHOPGM_P(port, " J");
SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.xz_skew_factor), 6); SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.skew_factor.xz), 6);
SERIAL_ECHOPGM_P(port, " K"); SERIAL_ECHOPGM_P(port, " K");
SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.yz_skew_factor), 6); SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.skew_factor.yz), 6);
SERIAL_EOL_P(port); SERIAL_EOL_P(port);
#else #else
SERIAL_ECHOPGM_P(port, " M852 S"); SERIAL_ECHOPGM_P(port, " M852 S");
SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.xy_skew_factor), 6); SERIAL_ECHO_F_P(port, LINEAR_UNIT(planner.skew_factor.xy), 6);
SERIAL_EOL_P(port); SERIAL_EOL_P(port);
#endif #endif
#endif #endif
@ -2929,36 +2858,36 @@ void MarlinSettings::reset(PORTARG_SOLO) {
CONFIG_ECHO_START; CONFIG_ECHO_START;
#if EXTRUDERS == 1 #if EXTRUDERS == 1
say_M603(PORTVAR_SOLO); say_M603(PORTVAR_SOLO);
SERIAL_ECHOPAIR_P(port, "L", LINEAR_UNIT(filament_change_load_length[0])); SERIAL_ECHOPAIR_P(port, "L", LINEAR_UNIT(fc_settings[0].load_length));
SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[0])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(fc_settings[0].unload_length));
#else #else
say_M603(PORTVAR_SOLO); say_M603(PORTVAR_SOLO);
SERIAL_ECHOPAIR_P(port, "T0 L", LINEAR_UNIT(filament_change_load_length[0])); SERIAL_ECHOPAIR_P(port, "T0 L", LINEAR_UNIT(fc_settings[0].load_length));
SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[0])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(fc_settings[0].unload_length));
CONFIG_ECHO_START; CONFIG_ECHO_START;
say_M603(PORTVAR_SOLO); say_M603(PORTVAR_SOLO);
SERIAL_ECHOPAIR_P(port, "T1 L", LINEAR_UNIT(filament_change_load_length[1])); SERIAL_ECHOPAIR_P(port, "T1 L", LINEAR_UNIT(fc_settings[1].load_length));
SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[1])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(fc_settings[1].unload_length));
#if EXTRUDERS > 2 #if EXTRUDERS > 2
CONFIG_ECHO_START; CONFIG_ECHO_START;
say_M603(PORTVAR_SOLO); say_M603(PORTVAR_SOLO);
SERIAL_ECHOPAIR_P(port, "T2 L", LINEAR_UNIT(filament_change_load_length[2])); SERIAL_ECHOPAIR_P(port, "T2 L", LINEAR_UNIT(fc_settings[2].load_length));
SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[2])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(fc_settings[2].unload_length));
#if EXTRUDERS > 3 #if EXTRUDERS > 3
CONFIG_ECHO_START; CONFIG_ECHO_START;
say_M603(PORTVAR_SOLO); say_M603(PORTVAR_SOLO);
SERIAL_ECHOPAIR_P(port, "T3 L", LINEAR_UNIT(filament_change_load_length[3])); SERIAL_ECHOPAIR_P(port, "T3 L", LINEAR_UNIT(fc_settings[3].load_length));
SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[3])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(fc_settings[3].unload_length));
#if EXTRUDERS > 4 #if EXTRUDERS > 4
CONFIG_ECHO_START; CONFIG_ECHO_START;
say_M603(PORTVAR_SOLO); say_M603(PORTVAR_SOLO);
SERIAL_ECHOPAIR_P(port, "T4 L", LINEAR_UNIT(filament_change_load_length[4])); SERIAL_ECHOPAIR_P(port, "T4 L", LINEAR_UNIT(fc_settings[4].load_length));
SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[4])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(fc_settings[4].unload_length));
#if EXTRUDERS > 5 #if EXTRUDERS > 5
CONFIG_ECHO_START; CONFIG_ECHO_START;
say_M603(PORTVAR_SOLO); say_M603(PORTVAR_SOLO);
SERIAL_ECHOPAIR_P(port, "T5 L", LINEAR_UNIT(filament_change_load_length[5])); SERIAL_ECHOPAIR_P(port, "T5 L", LINEAR_UNIT(fc_settings[5].load_length));
SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(filament_change_unload_length[5])); SERIAL_ECHOLNPAIR_P(port, " U", LINEAR_UNIT(fc_settings[5].unload_length));
#endif // EXTRUDERS > 5 #endif // EXTRUDERS > 5
#endif // EXTRUDERS > 4 #endif // EXTRUDERS > 4
#endif // EXTRUDERS > 3 #endif // EXTRUDERS > 3
@ -2977,3 +2906,5 @@ void MarlinSettings::reset(PORTARG_SOLO) {
} }
#endif // !DISABLE_M503 #endif // !DISABLE_M503
#pragma pack(pop)

View file

@ -817,9 +817,9 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
#define RAISED_Y raised_parked_position[Y_AXIS] #define RAISED_Y raised_parked_position[Y_AXIS]
#define RAISED_Z raised_parked_position[Z_AXIS] #define RAISED_Z raised_parked_position[Z_AXIS]
if ( planner.buffer_line(RAISED_X, RAISED_Y, RAISED_Z, CUR_E, planner.max_feedrate_mm_s[Z_AXIS], active_extruder)) if ( planner.buffer_line(RAISED_X, RAISED_Y, RAISED_Z, CUR_E, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder))
if (planner.buffer_line( CUR_X, CUR_Y, RAISED_Z, CUR_E, PLANNER_XY_FEEDRATE(), active_extruder)) if (planner.buffer_line( CUR_X, CUR_Y, RAISED_Z, CUR_E, PLANNER_XY_FEEDRATE(), active_extruder))
planner.buffer_line( CUR_X, CUR_Y, CUR_Z, CUR_E, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); planner.buffer_line( CUR_X, CUR_Y, CUR_Z, CUR_E, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder);
delayed_move_time = 0; delayed_move_time = 0;
active_extruder_parked = false; active_extruder_parked = false;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
@ -841,7 +841,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
if (!planner.buffer_line( if (!planner.buffer_line(
dual_x_carriage_mode == DXC_DUPLICATION_MODE ? duplicate_extruder_x_offset + current_position[X_AXIS] : inactive_extruder_x_pos, dual_x_carriage_mode == DXC_DUPLICATION_MODE ? duplicate_extruder_x_offset + current_position[X_AXIS] : inactive_extruder_x_pos,
current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS],
planner.max_feedrate_mm_s[X_AXIS], 1 planner.settings.max_feedrate_mm_s[X_AXIS], 1
) )
) break; ) break;
planner.synchronize(); planner.synchronize();

View file

@ -111,18 +111,11 @@ volatile uint8_t Planner::block_buffer_head, // Index of the next block to be
uint16_t Planner::cleaning_buffer_counter; // A counter to disable queuing of blocks uint16_t Planner::cleaning_buffer_counter; // A counter to disable queuing of blocks
uint8_t Planner::delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks uint8_t Planner::delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks
uint32_t Planner::max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE planner_settings_t Planner::settings; // Initialized by settings.load()
Planner::max_acceleration_steps_per_s2[XYZE_N], // (steps/s^2) Derived from mm_per_s2
Planner::min_segment_time_us; // (µs) M205 B
float Planner::max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds uint32_t Planner::max_acceleration_steps_per_s2[XYZE_N]; // (steps/s^2) Derived from mm_per_s2
Planner::axis_steps_per_mm[XYZE_N], // (steps) M92 XYZE - Steps per millimeter
Planner::steps_to_mm[XYZE_N], // (mm) Millimeters per step float Planner::steps_to_mm[XYZE_N]; // (mm) Millimeters per step
Planner::min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
Planner::acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
Planner::retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
Planner::travel_acceleration, // (mm/s^2) M204 T - Travel acceleration. DEFAULT ACCELERATION for all NON printing moves.
Planner::min_travel_feedrate_mm_s; // (mm/s) M205 T - Minimum travel feedrate
#if ENABLED(JUNCTION_DEVIATION) #if ENABLED(JUNCTION_DEVIATION)
float Planner::junction_deviation_mm; // (mm) M205 J float Planner::junction_deviation_mm; // (mm) M205 J
@ -177,18 +170,7 @@ float Planner::e_factor[EXTRUDERS] = ARRAY_BY_EXTRUDERS1(1.0f); // The flow perc
constexpr bool Planner::leveling_active; constexpr bool Planner::leveling_active;
#endif #endif
#if ENABLED(SKEW_CORRECTION) skew_factor_t Planner::skew_factor; // Initialized by settings.load()
#if ENABLED(SKEW_CORRECTION_GCODE)
float Planner::xy_skew_factor;
#else
constexpr float Planner::xy_skew_factor;
#endif
#if ENABLED(SKEW_CORRECTION_FOR_Z) && ENABLED(SKEW_CORRECTION_GCODE)
float Planner::xz_skew_factor, Planner::yz_skew_factor;
#else
constexpr float Planner::xz_skew_factor, Planner::yz_skew_factor;
#endif
#endif
#if ENABLED(AUTOTEMP) #if ENABLED(AUTOTEMP)
float Planner::autotemp_max = 250, float Planner::autotemp_max = 250,
@ -1094,7 +1076,7 @@ void Planner::recalculate_trapezoids() {
calculate_trapezoid_for_block(current, current_entry_speed * nomr, next_entry_speed * nomr); calculate_trapezoid_for_block(current, current_entry_speed * nomr, next_entry_speed * nomr);
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
if (current->use_advance_lead) { if (current->use_advance_lead) {
const float comp = current->e_D_ratio * extruder_advance_K[active_extruder] * axis_steps_per_mm[E_AXIS]; const float comp = current->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
current->max_adv_steps = current_nominal_speed * comp; current->max_adv_steps = current_nominal_speed * comp;
current->final_adv_steps = next_entry_speed * comp; current->final_adv_steps = next_entry_speed * comp;
} }
@ -1133,7 +1115,7 @@ void Planner::recalculate_trapezoids() {
calculate_trapezoid_for_block(next, next_entry_speed * nomr, float(MINIMUM_PLANNER_SPEED) * nomr); calculate_trapezoid_for_block(next, next_entry_speed * nomr, float(MINIMUM_PLANNER_SPEED) * nomr);
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
if (next->use_advance_lead) { if (next->use_advance_lead) {
const float comp = next->e_D_ratio * extruder_advance_K[active_extruder] * axis_steps_per_mm[E_AXIS]; const float comp = next->e_D_ratio * extruder_advance_K[active_extruder] * settings.axis_steps_per_mm[E_AXIS];
next->max_adv_steps = next_nominal_speed * comp; next->max_adv_steps = next_nominal_speed * comp;
next->final_adv_steps = (MINIMUM_PLANNER_SPEED) * comp; next->final_adv_steps = (MINIMUM_PLANNER_SPEED) * comp;
} }
@ -1687,7 +1669,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
} }
#endif // PREVENT_COLD_EXTRUSION #endif // PREVENT_COLD_EXTRUSION
#if ENABLED(PREVENT_LENGTHY_EXTRUDE) #if ENABLED(PREVENT_LENGTHY_EXTRUDE)
if (ABS(de * e_factor[extruder]) > (int32_t)axis_steps_per_mm[E_AXIS_N(extruder)] * (EXTRUDE_MAXLENGTH)) { // It's not important to get max. extrusion length in a precision < 1mm, so save some cycles and cast to int if (ABS(de * e_factor[extruder]) > (int32_t)settings.axis_steps_per_mm[E_AXIS_N(extruder)] * (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 position[E_AXIS] = target[E_AXIS]; // Behave as if the move really took place, but ignore E part
#if HAS_POSITION_FLOAT #if HAS_POSITION_FLOAT
position_float[E_AXIS] = target_float[E_AXIS]; position_float[E_AXIS] = target_float[E_AXIS];
@ -1946,9 +1928,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
} }
if (esteps) if (esteps)
NOLESS(fr_mm_s, min_feedrate_mm_s); NOLESS(fr_mm_s, settings.min_feedrate_mm_s);
else else
NOLESS(fr_mm_s, min_travel_feedrate_mm_s); NOLESS(fr_mm_s, settings.min_travel_feedrate_mm_s);
/** /**
* This part of the code calculates the total length of the movement. * This part of the code calculates the total length of the movement.
@ -2023,9 +2005,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#if ENABLED(SLOWDOWN) #if ENABLED(SLOWDOWN)
if (WITHIN(moves_queued, 2, (BLOCK_BUFFER_SIZE) / 2 - 1)) { if (WITHIN(moves_queued, 2, (BLOCK_BUFFER_SIZE) / 2 - 1)) {
if (segment_time_us < min_segment_time_us) { if (segment_time_us < settings.min_segment_time_us) {
// buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more. // buffer is draining, add extra time. The amount of time added increases if the buffer is still emptied more.
const uint32_t nst = segment_time_us + LROUND(2 * (min_segment_time_us - segment_time_us) / moves_queued); const uint32_t nst = segment_time_us + LROUND(2 * (settings.min_segment_time_us - segment_time_us) / moves_queued);
inverse_secs = 1000000.0f / nst; inverse_secs = 1000000.0f / nst;
#if defined(XY_FREQUENCY_LIMIT) || ENABLED(ULTRA_LCD) #if defined(XY_FREQUENCY_LIMIT) || ENABLED(ULTRA_LCD)
segment_time_us = nst; segment_time_us = nst;
@ -2100,7 +2082,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
if (i == E_AXIS) i += extruder; if (i == E_AXIS) i += extruder;
#endif #endif
if (cs > max_feedrate_mm_s[i]) NOMORE(speed_factor, max_feedrate_mm_s[i] / cs); if (cs > settings.max_feedrate_mm_s[i]) NOMORE(speed_factor, settings.max_feedrate_mm_s[i] / cs);
} }
// Max segment time in µs. // Max segment time in µs.
@ -2153,7 +2135,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
uint32_t accel; uint32_t accel;
if (!block->steps[A_AXIS] && !block->steps[B_AXIS] && !block->steps[C_AXIS]) { if (!block->steps[A_AXIS] && !block->steps[B_AXIS] && !block->steps[C_AXIS]) {
// convert to: acceleration steps/sec^2 // convert to: acceleration steps/sec^2
accel = CEIL(retract_acceleration * steps_per_mm); accel = CEIL(settings.retract_acceleration * steps_per_mm);
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
block->use_advance_lead = false; block->use_advance_lead = false;
#endif #endif
@ -2174,7 +2156,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
}while(0) }while(0)
// Start with print or travel acceleration // Start with print or travel acceleration
accel = CEIL((esteps ? acceleration : travel_acceleration) * steps_per_mm); accel = CEIL((esteps ? settings.acceleration : settings.travel_acceleration) * steps_per_mm);
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
@ -2254,7 +2236,7 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
#endif #endif
#if ENABLED(LIN_ADVANCE) #if ENABLED(LIN_ADVANCE)
if (block->use_advance_lead) { if (block->use_advance_lead) {
block->advance_speed = (STEPPER_TIMER_RATE) / (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * axis_steps_per_mm[E_AXIS_N(extruder)]); block->advance_speed = (STEPPER_TIMER_RATE) / (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * settings.axis_steps_per_mm[E_AXIS_N(extruder)]);
#if ENABLED(LA_DEBUG) #if ENABLED(LA_DEBUG)
if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < SQRT(block->nominal_speed_sqr) * block->e_D_ratio) if (extruder_advance_K[active_extruder] * block->e_D_ratio * block->acceleration * 2 < SQRT(block->nominal_speed_sqr) * block->e_D_ratio)
SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed."); SERIAL_ECHOLNPGM("More than 2 steps per eISR loop executed.");
@ -2566,8 +2548,8 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
// When changing extruders recalculate steps corresponding to the E position // When changing extruders recalculate steps corresponding to the E position
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
if (last_extruder != extruder && axis_steps_per_mm[E_AXIS_N(extruder)] != axis_steps_per_mm[E_AXIS + last_extruder]) { if (last_extruder != extruder && settings.axis_steps_per_mm[E_AXIS_N(extruder)] != settings.axis_steps_per_mm[E_AXIS + last_extruder]) {
position[E_AXIS] = LROUND(position[E_AXIS] * axis_steps_per_mm[E_AXIS_N(extruder)] * steps_to_mm[E_AXIS + last_extruder]); position[E_AXIS] = LROUND(position[E_AXIS] * settings.axis_steps_per_mm[E_AXIS_N(extruder)] * steps_to_mm[E_AXIS + last_extruder]);
last_extruder = extruder; last_extruder = extruder;
} }
#endif #endif
@ -2575,10 +2557,10 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
// The target position of the tool in absolute steps // The target position of the tool in absolute steps
// Calculate target position in absolute steps // Calculate target position in absolute steps
const int32_t target[ABCE] = { const int32_t target[ABCE] = {
LROUND(a * axis_steps_per_mm[A_AXIS]), LROUND(a * settings.axis_steps_per_mm[A_AXIS]),
LROUND(b * axis_steps_per_mm[B_AXIS]), LROUND(b * settings.axis_steps_per_mm[B_AXIS]),
LROUND(c * axis_steps_per_mm[C_AXIS]), LROUND(c * settings.axis_steps_per_mm[C_AXIS]),
LROUND(e * axis_steps_per_mm[E_AXIS_N(extruder)]) LROUND(e * settings.axis_steps_per_mm[E_AXIS_N(extruder)])
}; };
#if HAS_POSITION_FLOAT #if HAS_POSITION_FLOAT
@ -2714,10 +2696,10 @@ void Planner::set_machine_position_mm(const float &a, const float &b, const floa
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
last_extruder = active_extruder; last_extruder = active_extruder;
#endif #endif
position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]); position[A_AXIS] = LROUND(a * settings.axis_steps_per_mm[A_AXIS]);
position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]); position[B_AXIS] = LROUND(b * settings.axis_steps_per_mm[B_AXIS]);
position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]); position[C_AXIS] = LROUND(c * settings.axis_steps_per_mm[C_AXIS]);
position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]); position[E_AXIS] = LROUND(e * settings.axis_steps_per_mm[_EINDEX]);
#if HAS_POSITION_FLOAT #if HAS_POSITION_FLOAT
position_float[A_AXIS] = a; position_float[A_AXIS] = a;
position_float[B_AXIS] = b; position_float[B_AXIS] = b;
@ -2770,7 +2752,7 @@ void Planner::set_e_position_mm(const float &e) {
#else #else
const float e_new = e; const float e_new = e;
#endif #endif
position[E_AXIS] = LROUND(axis_steps_per_mm[axis_index] * e_new); position[E_AXIS] = LROUND(settings.axis_steps_per_mm[axis_index] * e_new);
#if HAS_POSITION_FLOAT #if HAS_POSITION_FLOAT
position_float[E_AXIS] = e_new; position_float[E_AXIS] = e_new;
#endif #endif
@ -2792,7 +2774,7 @@ void Planner::reset_acceleration_rates() {
#endif #endif
uint32_t highest_rate = 1; uint32_t highest_rate = 1;
LOOP_XYZE_N(i) { LOOP_XYZE_N(i) {
max_acceleration_steps_per_s2[i] = max_acceleration_mm_per_s2[i] * axis_steps_per_mm[i]; max_acceleration_steps_per_s2[i] = settings.max_acceleration_mm_per_s2[i] * settings.axis_steps_per_mm[i];
if (AXIS_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]); if (AXIS_CONDITION) NOLESS(highest_rate, max_acceleration_steps_per_s2[i]);
} }
cutoff_long = 4294967295UL / highest_rate; // 0xFFFFFFFFUL cutoff_long = 4294967295UL / highest_rate; // 0xFFFFFFFFUL
@ -2801,9 +2783,9 @@ void Planner::reset_acceleration_rates() {
#endif #endif
} }
// Recalculate position, steps_to_mm if axis_steps_per_mm changes! // Recalculate position, steps_to_mm if settings.axis_steps_per_mm changes!
void Planner::refresh_positioning() { void Planner::refresh_positioning() {
LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / axis_steps_per_mm[i]; LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / settings.axis_steps_per_mm[i];
set_position_mm(current_position); set_position_mm(current_position);
reset_acceleration_rates(); reset_acceleration_rates();
} }

View file

@ -19,6 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#pragma once
/** /**
* planner.h * planner.h
@ -29,9 +30,6 @@
* Copyright (c) 2009-2011 Simen Svale Skogsrud * Copyright (c) 2009-2011 Simen Svale Skogsrud
*/ */
#ifndef PLANNER_H
#define PLANNER_H
#include "../Marlin.h" #include "../Marlin.h"
#include "motion.h" #include "motion.h"
@ -159,6 +157,42 @@ typedef struct {
#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1)) #define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
typedef struct {
uint32_t max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE
min_segment_time_us; // (µs) M205 B
float axis_steps_per_mm[XYZE_N], // (steps) M92 XYZE - Steps per millimeter
max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
travel_acceleration, // (mm/s^2) M204 T - Travel acceleration. DEFAULT ACCELERATION for all NON printing moves.
min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
min_travel_feedrate_mm_s; // (mm/s) M205 T - Minimum travel feedrate
} planner_settings_t;
#ifndef XY_SKEW_FACTOR
#define XY_SKEW_FACTOR 0
#endif
#ifndef XZ_SKEW_FACTOR
#define XZ_SKEW_FACTOR 0
#endif
#ifndef YZ_SKEW_FACTOR
#define YZ_SKEW_FACTOR 0
#endif
typedef struct {
#if ENABLED(SKEW_CORRECTION_GCODE)
float xy;
#if ENABLED(SKEW_CORRECTION_FOR_Z)
float xz, yz;
#else
const float xz = XZ_SKEW_FACTOR, yz = YZ_SKEW_FACTOR;
#endif
#else
const float xy = XY_SKEW_FACTOR,
xz = XZ_SKEW_FACTOR, yz = YZ_SKEW_FACTOR;
#endif
} skew_factor_t;
class Planner { class Planner {
public: public:
@ -199,17 +233,10 @@ class Planner {
// May be auto-adjusted by a filament width sensor // May be auto-adjusted by a filament width sensor
#endif #endif
static uint32_t max_acceleration_mm_per_s2[XYZE_N], // (mm/s^2) M201 XYZE static planner_settings_t settings;
max_acceleration_steps_per_s2[XYZE_N], // (steps/s^2) Derived from mm_per_s2
min_segment_time_us; // (µs) M205 B static uint32_t max_acceleration_steps_per_s2[XYZE_N]; // (steps/s^2) Derived from mm_per_s2
static float max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds static float steps_to_mm[XYZE_N]; // Millimeters per step
axis_steps_per_mm[XYZE_N], // (steps) M92 XYZE - Steps per millimeter
steps_to_mm[XYZE_N], // (mm) Millimeters per step
min_feedrate_mm_s, // (mm/s) M205 S - Minimum linear feedrate
acceleration, // (mm/s^2) M204 S - Normal acceleration. DEFAULT ACCELERATION for all printing moves.
retract_acceleration, // (mm/s^2) M204 R - Retract acceleration. Filament pull-back and push-forward while standing still in the other axes
travel_acceleration, // (mm/s^2) M204 T - Travel acceleration. DEFAULT ACCELERATION for all NON printing moves.
min_travel_feedrate_mm_s; // (mm/s) M205 T - Minimum travel feedrate
#if ENABLED(JUNCTION_DEVIATION) #if ENABLED(JUNCTION_DEVIATION)
static float junction_deviation_mm; // (mm) M205 J static float junction_deviation_mm; // (mm) M205 J
@ -256,22 +283,7 @@ class Planner {
static float position_cart[XYZE]; static float position_cart[XYZE];
#endif #endif
#if ENABLED(SKEW_CORRECTION) static skew_factor_t skew_factor;
#if ENABLED(SKEW_CORRECTION_GCODE)
static float xy_skew_factor;
#else
static constexpr float xy_skew_factor = XY_SKEW_FACTOR;
#endif
#if ENABLED(SKEW_CORRECTION_FOR_Z)
#if ENABLED(SKEW_CORRECTION_GCODE)
static float xz_skew_factor, yz_skew_factor;
#else
static constexpr float xz_skew_factor = XZ_SKEW_FACTOR, yz_skew_factor = YZ_SKEW_FACTOR;
#endif
#else
static constexpr float xz_skew_factor = 0, yz_skew_factor = 0;
#endif
#endif
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) #if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
static bool abort_on_endstop_hit; static bool abort_on_endstop_hit;
@ -419,8 +431,8 @@ class Planner {
FORCE_INLINE static void skew(float &cx, float &cy, const float &cz) { FORCE_INLINE static void skew(float &cx, float &cy, const float &cz) {
if (WITHIN(cx, X_MIN_POS + 1, X_MAX_POS) && WITHIN(cy, Y_MIN_POS + 1, Y_MAX_POS)) { if (WITHIN(cx, X_MIN_POS + 1, X_MAX_POS) && WITHIN(cy, Y_MIN_POS + 1, Y_MAX_POS)) {
const float sx = cx - cy * xy_skew_factor - cz * (xz_skew_factor - (xy_skew_factor * yz_skew_factor)), const float sx = cx - cy * skew_factor.xy - cz * (skew_factor.xz - (skew_factor.xy * skew_factor.yz)),
sy = cy - cz * yz_skew_factor; sy = cy - cz * skew_factor.yz;
if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) { if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) {
cx = sx; cy = sy; cx = sx; cy = sy;
} }
@ -431,8 +443,8 @@ class Planner {
FORCE_INLINE static void unskew(float &cx, float &cy, const float &cz) { FORCE_INLINE static void unskew(float &cx, float &cy, const float &cz) {
if (WITHIN(cx, X_MIN_POS, X_MAX_POS) && WITHIN(cy, Y_MIN_POS, Y_MAX_POS)) { if (WITHIN(cx, X_MIN_POS, X_MAX_POS) && WITHIN(cy, Y_MIN_POS, Y_MAX_POS)) {
const float sx = cx + cy * xy_skew_factor + cz * xz_skew_factor, const float sx = cx + cy * skew_factor.xy + cz * skew_factor.xz,
sy = cy + cz * yz_skew_factor; sy = cy + cz * skew_factor.yz;
if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) { if (WITHIN(sx, X_MIN_POS, X_MAX_POS) && WITHIN(sy, Y_MIN_POS, Y_MAX_POS)) {
cx = sx; cy = sy; cx = sx; cy = sy;
} }
@ -848,9 +860,9 @@ class Planner {
#define GET_MAX_E_JERK(N) SQRT(SQRT(0.5) * junction_deviation_mm * (N) * RECIPROCAL(1.0 - SQRT(0.5))) #define GET_MAX_E_JERK(N) SQRT(SQRT(0.5) * junction_deviation_mm * (N) * RECIPROCAL(1.0 - SQRT(0.5)))
#if ENABLED(DISTINCT_E_FACTORS) #if ENABLED(DISTINCT_E_FACTORS)
for (uint8_t i = 0; i < EXTRUDERS; i++) for (uint8_t i = 0; i < EXTRUDERS; i++)
max_e_jerk[i] = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS + i]); max_e_jerk[i] = GET_MAX_E_JERK(settings.max_acceleration_mm_per_s2[E_AXIS + i]);
#else #else
max_e_jerk = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS]); max_e_jerk = GET_MAX_E_JERK(settings.max_acceleration_mm_per_s2[E_AXIS]);
#endif #endif
} }
#endif #endif
@ -927,15 +939,13 @@ class Planner {
FORCE_INLINE static float limit_value_by_axis_maximum(const float &max_value, float (&unit_vec)[XYZE]) { FORCE_INLINE static float limit_value_by_axis_maximum(const float &max_value, float (&unit_vec)[XYZE]) {
float limit_value = max_value; float limit_value = max_value;
LOOP_XYZE(idx) if (unit_vec[idx]) // Avoid divide by zero LOOP_XYZE(idx) if (unit_vec[idx]) // Avoid divide by zero
NOMORE(limit_value, ABS(max_acceleration_mm_per_s2[idx] / unit_vec[idx])); NOMORE(limit_value, ABS(settings.max_acceleration_mm_per_s2[idx] / unit_vec[idx]));
return limit_value; return limit_value;
} }
#endif // JUNCTION_DEVIATION #endif // JUNCTION_DEVIATION
}; };
#define PLANNER_XY_FEEDRATE() (MIN(planner.max_feedrate_mm_s[X_AXIS], planner.max_feedrate_mm_s[Y_AXIS])) #define PLANNER_XY_FEEDRATE() (MIN(planner.settings.max_feedrate_mm_s[X_AXIS], planner.settings.max_feedrate_mm_s[Y_AXIS]))
extern Planner planner; extern Planner planner;
#endif // PLANNER_H

View file

@ -2413,7 +2413,7 @@ void Stepper::report_positions() {
#if HAS_MOTOR_CURRENT_PWM #if HAS_MOTOR_CURRENT_PWM
void Stepper::refresh_motor_power() { void Stepper::refresh_motor_power() {
for (uint8_t i = 0; i < COUNT(motor_current_setting); ++i) { LOOP_L_N(i, COUNT(motor_current_setting)) {
switch (i) { switch (i) {
#if PIN_EXISTS(MOTOR_CURRENT_PWM_XY) #if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
case 0: case 0:
@ -2443,7 +2443,7 @@ void Stepper::report_positions() {
#elif HAS_MOTOR_CURRENT_PWM #elif HAS_MOTOR_CURRENT_PWM
if (WITHIN(driver, 0, 2)) if (WITHIN(driver, 0, COUNT(motor_current_setting) - 1))
motor_current_setting[driver] = current; // update motor_current_setting motor_current_setting[driver] = current; // update motor_current_setting
#define _WRITE_CURRENT_PWM(P) analogWrite(MOTOR_CURRENT_PWM_## P ##_PIN, 255L * current / (MOTOR_CURRENT_PWM_RANGE)) #define _WRITE_CURRENT_PWM(P) analogWrite(MOTOR_CURRENT_PWM_## P ##_PIN, 255L * current / (MOTOR_CURRENT_PWM_RANGE))

View file

@ -606,43 +606,43 @@ void reset_stepper_drivers() {
#endif #endif
#if AXIS_IS_TMC(X) #if AXIS_IS_TMC(X)
_TMC_INIT(X, planner.axis_steps_per_mm[X_AXIS]); _TMC_INIT(X, planner.settings.axis_steps_per_mm[X_AXIS]);
#endif #endif
#if AXIS_IS_TMC(X2) #if AXIS_IS_TMC(X2)
_TMC_INIT(X2, planner.axis_steps_per_mm[X_AXIS]); _TMC_INIT(X2, planner.settings.axis_steps_per_mm[X_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Y) #if AXIS_IS_TMC(Y)
_TMC_INIT(Y, planner.axis_steps_per_mm[Y_AXIS]); _TMC_INIT(Y, planner.settings.axis_steps_per_mm[Y_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Y2) #if AXIS_IS_TMC(Y2)
_TMC_INIT(Y2, planner.axis_steps_per_mm[Y_AXIS]); _TMC_INIT(Y2, planner.settings.axis_steps_per_mm[Y_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Z) #if AXIS_IS_TMC(Z)
_TMC_INIT(Z, planner.axis_steps_per_mm[Z_AXIS]); _TMC_INIT(Z, planner.settings.axis_steps_per_mm[Z_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Z2) #if AXIS_IS_TMC(Z2)
_TMC_INIT(Z2, planner.axis_steps_per_mm[Z_AXIS]); _TMC_INIT(Z2, planner.settings.axis_steps_per_mm[Z_AXIS]);
#endif #endif
#if AXIS_IS_TMC(Z3) #if AXIS_IS_TMC(Z3)
_TMC_INIT(Z3, planner.axis_steps_per_mm[Z_AXIS]); _TMC_INIT(Z3, planner.settings.axis_steps_per_mm[Z_AXIS]);
#endif #endif
#if AXIS_IS_TMC(E0) #if AXIS_IS_TMC(E0)
_TMC_INIT(E0, planner.axis_steps_per_mm[E_AXIS_N(0)]); _TMC_INIT(E0, planner.settings.axis_steps_per_mm[E_AXIS_N(0)]);
#endif #endif
#if AXIS_IS_TMC(E1) #if AXIS_IS_TMC(E1)
_TMC_INIT(E1, planner.axis_steps_per_mm[E_AXIS_N(1)]); _TMC_INIT(E1, planner.settings.axis_steps_per_mm[E_AXIS_N(1)]);
#endif #endif
#if AXIS_IS_TMC(E2) #if AXIS_IS_TMC(E2)
_TMC_INIT(E2, planner.axis_steps_per_mm[E_AXIS_N(2)]); _TMC_INIT(E2, planner.settings.axis_steps_per_mm[E_AXIS_N(2)]);
#endif #endif
#if AXIS_IS_TMC(E3) #if AXIS_IS_TMC(E3)
_TMC_INIT(E3, planner.axis_steps_per_mm[E_AXIS_N(3)]); _TMC_INIT(E3, planner.settings.axis_steps_per_mm[E_AXIS_N(3)]);
#endif #endif
#if AXIS_IS_TMC(E4) #if AXIS_IS_TMC(E4)
_TMC_INIT(E4, planner.axis_steps_per_mm[E_AXIS_N(4)]); _TMC_INIT(E4, planner.settings.axis_steps_per_mm[E_AXIS_N(4)]);
#endif #endif
#if AXIS_IS_TMC(E5) #if AXIS_IS_TMC(E5)
_TMC_INIT(E5, planner.axis_steps_per_mm[E_AXIS_N(5)]); _TMC_INIT(E5, planner.settings.axis_steps_per_mm[E_AXIS_N(5)]);
#endif #endif
#if USE_SENSORLESS #if USE_SENSORLESS

View file

@ -116,13 +116,7 @@ int16_t Temperature::current_temperature_raw[HOTENDS] = { 0 },
millis_t Temperature::watch_bed_next_ms = 0; millis_t Temperature::watch_bed_next_ms = 0;
#endif #endif
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
float Temperature::bedKp, Temperature::bedKi, Temperature::bedKd, // Initialized by settings.load() PID_t Temperature::bed_pid; // Initialized by settings.load()
Temperature::temp_iState_bed = { 0 },
Temperature::temp_dState_bed = { 0 },
Temperature::pTerm_bed,
Temperature::iTerm_bed,
Temperature::dTerm_bed,
Temperature::pid_error_bed;
#else #else
millis_t Temperature::next_bed_check_ms; millis_t Temperature::next_bed_check_ms;
#endif #endif
@ -141,17 +135,7 @@ int16_t Temperature::current_temperature_raw[HOTENDS] = { 0 },
// Initialized by settings.load() // Initialized by settings.load()
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
#if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1 hotend_pid_t Temperature::pid[HOTENDS];
float Temperature::Kp[HOTENDS], Temperature::Ki[HOTENDS], Temperature::Kd[HOTENDS];
#if ENABLED(PID_EXTRUSION_SCALING)
float Temperature::Kc[HOTENDS];
#endif
#else
float Temperature::Kp, Temperature::Ki, Temperature::Kd;
#if ENABLED(PID_EXTRUSION_SCALING)
float Temperature::Kc;
#endif
#endif
#endif #endif
#if ENABLED(BABYSTEPPING) #if ENABLED(BABYSTEPPING)
@ -182,21 +166,11 @@ int16_t Temperature::current_temperature_raw[HOTENDS] = { 0 },
volatile bool Temperature::temp_meas_ready = false; volatile bool Temperature::temp_meas_ready = false;
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
float Temperature::temp_iState[HOTENDS] = { 0 },
Temperature::temp_dState[HOTENDS] = { 0 },
Temperature::pTerm[HOTENDS],
Temperature::iTerm[HOTENDS],
Temperature::dTerm[HOTENDS];
#if ENABLED(PID_EXTRUSION_SCALING) #if ENABLED(PID_EXTRUSION_SCALING)
float Temperature::cTerm[HOTENDS];
long Temperature::last_e_position; long Temperature::last_e_position;
long Temperature::lpq[LPQ_MAX_LEN]; long Temperature::lpq[LPQ_MAX_LEN];
int Temperature::lpq_ptr = 0; int Temperature::lpq_ptr = 0;
#endif #endif
float Temperature::pid_error[HOTENDS];
bool Temperature::pid_reset[HOTENDS];
#endif #endif
uint16_t Temperature::raw_temp_value[MAX_EXTRUDERS] = { 0 }; uint16_t Temperature::raw_temp_value[MAX_EXTRUDERS] = { 0 };
@ -254,6 +228,8 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
#if HAS_PID_HEATING #if HAS_PID_HEATING
inline void say_default_() { SERIAL_PROTOCOLPGM("#define DEFAULT_"); }
/** /**
* PID Autotuning (M303) * PID Autotuning (M303)
* *
@ -269,9 +245,8 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
long t_high = 0, t_low = 0; long t_high = 0, t_low = 0;
long bias, d; long bias, d;
float Ku, Tu, PID_t tune_pid = { 0, 0, 0 };
workKp = 0, workKi = 0, workKd = 0, float max = 0, min = 10000;
max = 0, min = 10000;
#if HAS_PID_FOR_BOTH #if HAS_PID_FOR_BOTH
#define GHV(B,H) (hotend < 0 ? (B) : (H)) #define GHV(B,H) (hotend < 0 ? (B) : (H))
@ -375,32 +350,32 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
SERIAL_PROTOCOLPAIR(MSG_T_MIN, min); SERIAL_PROTOCOLPAIR(MSG_T_MIN, min);
SERIAL_PROTOCOLPAIR(MSG_T_MAX, max); SERIAL_PROTOCOLPAIR(MSG_T_MAX, max);
if (cycles > 2) { if (cycles > 2) {
Ku = (4.0f * d) / (float(M_PI) * (max - min) * 0.5f); float Ku = (4.0f * d) / (float(M_PI) * (max - min) * 0.5f),
Tu = ((float)(t_low + t_high) * 0.001f); Tu = ((float)(t_low + t_high) * 0.001f);
SERIAL_PROTOCOLPAIR(MSG_KU, Ku); SERIAL_PROTOCOLPAIR(MSG_KU, Ku);
SERIAL_PROTOCOLPAIR(MSG_TU, Tu); SERIAL_PROTOCOLPAIR(MSG_TU, Tu);
workKp = 0.6f * Ku; tune_pid.Kp = 0.6f * Ku;
workKi = 2 * workKp / Tu; tune_pid.Ki = 2 * tune_pid.Kp / Tu;
workKd = workKp * Tu * 0.125f; tune_pid.Kd = tune_pid.Kp * Tu * 0.125f;
SERIAL_PROTOCOLLNPGM("\n" MSG_CLASSIC_PID); SERIAL_PROTOCOLLNPGM("\n" MSG_CLASSIC_PID);
SERIAL_PROTOCOLPAIR(MSG_KP, workKp); SERIAL_PROTOCOLPAIR(MSG_KP, tune_pid.Kp);
SERIAL_PROTOCOLPAIR(MSG_KI, workKi); SERIAL_PROTOCOLPAIR(MSG_KI, tune_pid.Ki);
SERIAL_PROTOCOLLNPAIR(MSG_KD, workKd); SERIAL_PROTOCOLLNPAIR(MSG_KD, tune_pid.Kd);
/** /**
workKp = 0.33*Ku; tune_pid.Kp = 0.33*Ku;
workKi = workKp/Tu; tune_pid.Ki = tune_pid.Kp/Tu;
workKd = workKp*Tu/3; tune_pid.Kd = tune_pid.Kp*Tu/3;
SERIAL_PROTOCOLLNPGM(" Some overshoot"); SERIAL_PROTOCOLLNPGM(" Some overshoot");
SERIAL_PROTOCOLPAIR(" Kp: ", workKp); SERIAL_PROTOCOLPAIR(" Kp: ", tune_pid.Kp);
SERIAL_PROTOCOLPAIR(" Ki: ", workKi); SERIAL_PROTOCOLPAIR(" Ki: ", tune_pid.Ki);
SERIAL_PROTOCOLPAIR(" Kd: ", workKd); SERIAL_PROTOCOLPAIR(" Kd: ", tune_pid.Kd);
workKp = 0.2*Ku; tune_pid.Kp = 0.2*Ku;
workKi = 2*workKp/Tu; tune_pid.Ki = 2*tune_pid.Kp/Tu;
workKd = workKp*Tu/3; tune_pid.Kd = tune_pid.Kp*Tu/3;
SERIAL_PROTOCOLLNPGM(" No overshoot"); SERIAL_PROTOCOLLNPGM(" No overshoot");
SERIAL_PROTOCOLPAIR(" Kp: ", workKp); SERIAL_PROTOCOLPAIR(" Kp: ", tune_pid.Kp);
SERIAL_PROTOCOLPAIR(" Ki: ", workKi); SERIAL_PROTOCOLPAIR(" Ki: ", tune_pid.Ki);
SERIAL_PROTOCOLPAIR(" Kd: ", workKd); SERIAL_PROTOCOLPAIR(" Kd: ", tune_pid.Kd);
*/ */
} }
} }
@ -467,39 +442,36 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS];
SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED); SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED);
#if HAS_PID_FOR_BOTH #if HAS_PID_FOR_BOTH
const char* estring = GHV("bed", ""); const char * const estring = GHV(PSTR("bed"), PSTR(""));
SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Kp ", workKp); SERIAL_EOL(); say_default_(); serialprintPGM(estring); SERIAL_PROTOCOLLNPAIR("Kp ", tune_pid.Kp);
SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Ki ", workKi); SERIAL_EOL(); say_default_(); serialprintPGM(estring); SERIAL_PROTOCOLLNPAIR("Ki ", tune_pid.Ki);
SERIAL_PROTOCOLPAIR("#define DEFAULT_", estring); SERIAL_PROTOCOLPAIR("Kd ", workKd); SERIAL_EOL(); say_default_(); serialprintPGM(estring); SERIAL_PROTOCOLLNPAIR("Kd ", tune_pid.Kd);
#elif ENABLED(PIDTEMP) #elif ENABLED(PIDTEMP)
SERIAL_PROTOCOLPAIR("#define DEFAULT_Kp ", workKp); SERIAL_EOL(); say_default_(); SERIAL_PROTOCOLLNPAIR("Kp ", tune_pid.Kp);
SERIAL_PROTOCOLPAIR("#define DEFAULT_Ki ", workKi); SERIAL_EOL(); say_default_(); SERIAL_PROTOCOLLNPAIR("Ki ", tune_pid.Ki);
SERIAL_PROTOCOLPAIR("#define DEFAULT_Kd ", workKd); SERIAL_EOL(); say_default_(); SERIAL_PROTOCOLLNPAIR("Kd ", tune_pid.Kd);
#else #else
SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKp ", workKp); SERIAL_EOL(); say_default_(); SERIAL_PROTOCOLLNPAIR("bedKp ", tune_pid.Kp);
SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKi ", workKi); SERIAL_EOL(); say_default_(); SERIAL_PROTOCOLLNPAIR("bedKi ", tune_pid.Ki);
SERIAL_PROTOCOLPAIR("#define DEFAULT_bedKd ", workKd); SERIAL_EOL(); say_default_(); SERIAL_PROTOCOLLNPAIR("bedKd ", tune_pid.Kd);
#endif #endif
#define _SET_BED_PID() do { \ #define _SET_BED_PID() do { \
bedKp = workKp; \ bed_pid.Kp = tune_pid.Kp; \
bedKi = scalePID_i(workKi); \ bed_pid.Ki = scalePID_i(tune_pid.Ki); \
bedKd = scalePID_d(workKd); \ bed_pid.Kd = scalePID_d(tune_pid.Kd); \
}while(0) }while(0)
#define _SET_EXTRUDER_PID() do { \ #define _SET_EXTRUDER_PID() do { \
PID_PARAM(Kp, hotend) = workKp; \ PID_PARAM(Kp, hotend) = tune_pid.Kp; \
PID_PARAM(Ki, hotend) = scalePID_i(workKi); \ PID_PARAM(Ki, hotend) = scalePID_i(tune_pid.Ki); \
PID_PARAM(Kd, hotend) = scalePID_d(workKd); \ PID_PARAM(Kd, hotend) = scalePID_d(tune_pid.Kd); \
updatePID(); }while(0) updatePID(); }while(0)
// Use the result? (As with "M303 U1") // Use the result? (As with "M303 U1")
if (set_result) { if (set_result) {
#if HAS_PID_FOR_BOTH #if HAS_PID_FOR_BOTH
if (hotend < 0) if (hotend < 0) _SET_BED_PID(); else _SET_EXTRUDER_PID();
_SET_BED_PID();
else
_SET_EXTRUDER_PID();
#elif ENABLED(PIDTEMP) #elif ENABLED(PIDTEMP)
_SET_EXTRUDER_PID(); _SET_EXTRUDER_PID();
#else #else
@ -612,15 +584,19 @@ void Temperature::min_temp_error(const int8_t e) {
float Temperature::get_pid_output(const int8_t e) { float Temperature::get_pid_output(const int8_t e) {
#if HOTENDS == 1 #if HOTENDS == 1
UNUSED(e); UNUSED(e);
#define _HOTEND_TEST true #define _HOTEND_TEST true
#else #else
#define _HOTEND_TEST e == active_extruder #define _HOTEND_TEST (e == active_extruder)
#endif #endif
float pid_output;
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
#if DISABLED(PID_OPENLOOP) #if DISABLED(PID_OPENLOOP)
pid_error[HOTEND_INDEX] = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX]; static hotend_pid_t work_pid[HOTENDS];
dTerm[HOTEND_INDEX] = PID_K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + float(PID_K1) * dTerm[HOTEND_INDEX]; static float temp_iState[HOTENDS] = { 0 },
temp_dState[HOTENDS] = { 0 };
static bool pid_reset[HOTENDS] = { false };
float pid_output,
pid_error = target_temperature[HOTEND_INDEX] - current_temperature[HOTEND_INDEX];
work_pid[HOTEND_INDEX].Kd = PID_K2 * PID_PARAM(Kd, HOTEND_INDEX) * (current_temperature[HOTEND_INDEX] - temp_dState[HOTEND_INDEX]) + float(PID_K1) * work_pid[HOTEND_INDEX].Kd;
temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX]; temp_dState[HOTEND_INDEX] = current_temperature[HOTEND_INDEX];
#if HEATER_IDLE_HANDLER #if HEATER_IDLE_HANDLER
if (heater_idle_timeout_exceeded[HOTEND_INDEX]) { if (heater_idle_timeout_exceeded[HOTEND_INDEX]) {
@ -629,57 +605,60 @@ float Temperature::get_pid_output(const int8_t e) {
} }
else else
#endif #endif
if (pid_error[HOTEND_INDEX] > PID_FUNCTIONAL_RANGE) { if (pid_error > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX; pid_output = BANG_MAX;
pid_reset[HOTEND_INDEX] = true; pid_reset[HOTEND_INDEX] = true;
}
else if (pid_error[HOTEND_INDEX] < -(PID_FUNCTIONAL_RANGE) || target_temperature[HOTEND_INDEX] == 0
#if HEATER_IDLE_HANDLER
|| heater_idle_timeout_exceeded[HOTEND_INDEX]
#endif
) {
pid_output = 0;
pid_reset[HOTEND_INDEX] = true;
}
else {
if (pid_reset[HOTEND_INDEX]) {
temp_iState[HOTEND_INDEX] = 0.0;
pid_reset[HOTEND_INDEX] = false;
}
pTerm[HOTEND_INDEX] = PID_PARAM(Kp, HOTEND_INDEX) * pid_error[HOTEND_INDEX];
temp_iState[HOTEND_INDEX] += pid_error[HOTEND_INDEX];
iTerm[HOTEND_INDEX] = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX];
pid_output = pTerm[HOTEND_INDEX] + iTerm[HOTEND_INDEX] - dTerm[HOTEND_INDEX];
#if ENABLED(PID_EXTRUSION_SCALING)
cTerm[HOTEND_INDEX] = 0;
if (_HOTEND_TEST) {
const long e_position = stepper.position(E_AXIS);
if (e_position > last_e_position) {
lpq[lpq_ptr] = e_position - last_e_position;
last_e_position = e_position;
}
else
lpq[lpq_ptr] = 0;
if (++lpq_ptr >= lpq_len) lpq_ptr = 0;
cTerm[HOTEND_INDEX] = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX);
pid_output += cTerm[HOTEND_INDEX];
} }
#endif // PID_EXTRUSION_SCALING else if (pid_error < -(PID_FUNCTIONAL_RANGE) || target_temperature[HOTEND_INDEX] == 0
#if HEATER_IDLE_HANDLER
|| heater_idle_timeout_exceeded[HOTEND_INDEX]
#endif
) {
pid_output = 0;
pid_reset[HOTEND_INDEX] = true;
}
else {
if (pid_reset[HOTEND_INDEX]) {
temp_iState[HOTEND_INDEX] = 0.0;
pid_reset[HOTEND_INDEX] = false;
}
temp_iState[HOTEND_INDEX] += pid_error;
work_pid[HOTEND_INDEX].Kp = PID_PARAM(Kp, HOTEND_INDEX) * pid_error;
work_pid[HOTEND_INDEX].Ki = PID_PARAM(Ki, HOTEND_INDEX) * temp_iState[HOTEND_INDEX];
pid_output = work_pid[HOTEND_INDEX].Kp + work_pid[HOTEND_INDEX].Ki - work_pid[HOTEND_INDEX].Kd;
#if ENABLED(PID_EXTRUSION_SCALING)
work_pid[HOTEND_INDEX].Kc = 0;
if (_HOTEND_TEST) {
const long e_position = stepper.position(E_AXIS);
if (e_position > last_e_position) {
lpq[lpq_ptr] = e_position - last_e_position;
last_e_position = e_position;
}
else
lpq[lpq_ptr] = 0;
if (++lpq_ptr >= lpq_len) lpq_ptr = 0;
work_pid[HOTEND_INDEX].Kc = (lpq[lpq_ptr] * planner.steps_to_mm[E_AXIS]) * PID_PARAM(Kc, HOTEND_INDEX);
pid_output += work_pid[HOTEND_INDEX].Kc;
}
#endif // PID_EXTRUSION_SCALING
if (pid_output > PID_MAX) {
if (pid_error > 0) temp_iState[HOTEND_INDEX] -= pid_error; // conditional un-integration
pid_output = PID_MAX;
}
else if (pid_output < 0) {
if (pid_error < 0) temp_iState[HOTEND_INDEX] -= pid_error; // conditional un-integration
pid_output = 0;
}
}
#else // PID_OPENLOOP
const float pid_output = constrain(target_temperature[HOTEND_INDEX], 0, PID_MAX);
if (pid_output > PID_MAX) {
if (pid_error[HOTEND_INDEX] > 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration
pid_output = PID_MAX;
}
else if (pid_output < 0) {
if (pid_error[HOTEND_INDEX] < 0) temp_iState[HOTEND_INDEX] -= pid_error[HOTEND_INDEX]; // conditional un-integration
pid_output = 0;
}
}
#else
pid_output = constrain(target_temperature[HOTEND_INDEX], 0, PID_MAX);
#endif // PID_OPENLOOP #endif // PID_OPENLOOP
#if ENABLED(PID_DEBUG) #if ENABLED(PID_DEBUG)
@ -687,11 +666,13 @@ float Temperature::get_pid_output(const int8_t e) {
SERIAL_ECHOPAIR(MSG_PID_DEBUG, HOTEND_INDEX); SERIAL_ECHOPAIR(MSG_PID_DEBUG, HOTEND_INDEX);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[HOTEND_INDEX]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_INPUT, current_temperature[HOTEND_INDEX]);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output); SERIAL_ECHOPAIR(MSG_PID_DEBUG_OUTPUT, pid_output);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, pTerm[HOTEND_INDEX]); #if DISABLED(PID_OPENLOOP)
SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, iTerm[HOTEND_INDEX]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, work_pid[HOTEND_INDEX].Kp);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, dTerm[HOTEND_INDEX]); SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, work_pid[HOTEND_INDEX].Ki);
#if ENABLED(PID_EXTRUSION_SCALING) SERIAL_ECHOPAIR(MSG_PID_DEBUG_DTERM, work_pid[HOTEND_INDEX].Kd);
SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, cTerm[HOTEND_INDEX]); #if ENABLED(PID_EXTRUSION_SCALING)
SERIAL_ECHOPAIR(MSG_PID_DEBUG_CTERM, work_pid[HOTEND_INDEX].Kc);
#endif
#endif #endif
SERIAL_EOL(); SERIAL_EOL();
#endif // PID_DEBUG #endif // PID_DEBUG
@ -709,47 +690,52 @@ float Temperature::get_pid_output(const int8_t e) {
} }
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
float Temperature::get_pid_output_bed() { float Temperature::get_pid_output_bed() {
float pid_output;
#if DISABLED(PID_OPENLOOP) #if DISABLED(PID_OPENLOOP)
pid_error_bed = target_temperature_bed - current_temperature_bed;
pTerm_bed = bedKp * pid_error_bed;
temp_iState_bed += pid_error_bed;
iTerm_bed = bedKi * temp_iState_bed;
dTerm_bed = PID_K2 * bedKd * (current_temperature_bed - temp_dState_bed) + PID_K1 * dTerm_bed; static PID_t work_pid = { 0 };
temp_dState_bed = current_temperature_bed; static float temp_iState = 0, temp_dState = 0;
pid_output = pTerm_bed + iTerm_bed - dTerm_bed; float pid_error = target_temperature_bed - current_temperature_bed;
temp_iState += pid_error;
work_pid.Kp = bed_pid.Kp * pid_error;
work_pid.Ki = bed_pid.Ki * temp_iState;
work_pid.Kd = PID_K2 * bed_pid.Kd * (current_temperature_bed - temp_dState) + PID_K1 * work_pid.Kd;
temp_dState = current_temperature_bed;
float pid_output = work_pid.Kp + work_pid.Ki - work_pid.Kd;
if (pid_output > MAX_BED_POWER) { if (pid_output > MAX_BED_POWER) {
if (pid_error_bed > 0) temp_iState_bed -= pid_error_bed; // conditional un-integration if (pid_error > 0) temp_iState -= pid_error; // conditional un-integration
pid_output = MAX_BED_POWER; pid_output = MAX_BED_POWER;
} }
else if (pid_output < 0) { else if (pid_output < 0) {
if (pid_error_bed < 0) temp_iState_bed -= pid_error_bed; // conditional un-integration if (pid_error < 0) temp_iState -= pid_error; // conditional un-integration
pid_output = 0; pid_output = 0;
} }
#else
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER); #else // PID_OPENLOOP
const float pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
#endif // PID_OPENLOOP #endif // PID_OPENLOOP
#if ENABLED(PID_BED_DEBUG) #if ENABLED(PID_BED_DEBUG)
SERIAL_ECHO_START(); SERIAL_ECHO_START();
SERIAL_ECHOPGM(" PID_BED_DEBUG "); SERIAL_ECHOPAIR(" PID_BED_DEBUG : Input ", current_temperature_bed);
SERIAL_ECHOPGM(": Input "); SERIAL_ECHOPAIR(" Output ", pid_output);
SERIAL_ECHO(current_temperature_bed); #if DISABLED(PID_OPENLOOP)
SERIAL_ECHOPGM(" Output "); SERIAL_ECHOPAIR(MSG_PID_DEBUG_PTERM, work_pid.Kp);
SERIAL_ECHO(pid_output); SERIAL_ECHOPAIR(MSG_PID_DEBUG_ITERM, work_pid.Ki);
SERIAL_ECHOPGM(" pTerm "); SERIAL_ECHOLNPAIR(MSG_PID_DEBUG_DTERM, work_pid.Kd);
SERIAL_ECHO(pTerm_bed); #endif
SERIAL_ECHOPGM(" iTerm "); #endif
SERIAL_ECHO(iTerm_bed);
SERIAL_ECHOPGM(" dTerm ");
SERIAL_ECHOLN(dTerm_bed);
#endif // PID_BED_DEBUG
return pid_output; return pid_output;
} }
#endif // PIDTEMPBED #endif // PIDTEMPBED
/** /**

View file

@ -48,6 +48,35 @@
#define HOTEND_INDEX e #define HOTEND_INDEX e
#endif #endif
// PID storage
typedef struct { float Kp, Ki, Kd; } PID_t;
typedef struct { float Kp, Ki, Kd, Kc; } PIDC_t;
#if ENABLED(PID_EXTRUSION_SCALING)
typedef PIDC_t hotend_pid_t;
#else
typedef PID_t hotend_pid_t;
#endif
#define DUMMY_PID_VALUE 3000.0f
#if ENABLED(PIDTEMP)
#define _PID_Kp(H) Temperature::pid[H].Kp
#define _PID_Ki(H) Temperature::pid[H].Ki
#define _PID_Kd(H) Temperature::pid[H].Kd
#if ENABLED(PID_EXTRUSION_SCALING)
#define _PID_Kc(H) Temperature::pid[H].Kc
#else
#define _PID_Kc(H) 1
#endif
#else
#define _PID_Kp(H) DUMMY_PID_VALUE
#define _PID_Ki(H) DUMMY_PID_VALUE
#define _PID_Kd(H) DUMMY_PID_VALUE
#define _PID_Kc(H) 1
#endif
#define PID_PARAM(F,H) _PID_##F(H)
/** /**
* States for ADC reading in the ISR * States for ADC reading in the ISR
*/ */
@ -132,25 +161,7 @@ class Temperature {
#endif #endif
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
static hotend_pid_t pid[HOTENDS];
#if ENABLED(PID_PARAMS_PER_HOTEND) && HOTENDS > 1
static float Kp[HOTENDS], Ki[HOTENDS], Kd[HOTENDS];
#if ENABLED(PID_EXTRUSION_SCALING)
static float Kc[HOTENDS];
#endif
#define PID_PARAM(param, h) Temperature::param[h]
#else
static float Kp, Ki, Kd;
#if ENABLED(PID_EXTRUSION_SCALING)
static float Kc;
#endif
#define PID_PARAM(param, h) Temperature::param
#endif // PID_PARAMS_PER_HOTEND
#endif #endif
#if HAS_HEATED_BED #if HAS_HEATED_BED
@ -158,7 +169,7 @@ class Temperature {
static int16_t current_temperature_bed_raw, target_temperature_bed; static int16_t current_temperature_bed_raw, target_temperature_bed;
static uint8_t soft_pwm_amount_bed; static uint8_t soft_pwm_amount_bed;
#if ENABLED(PIDTEMPBED) #if ENABLED(PIDTEMPBED)
static float bedKp, bedKi, bedKd; static PID_t bed_pid;
#endif #endif
#endif #endif
@ -210,21 +221,11 @@ class Temperature {
#endif #endif
#if ENABLED(PIDTEMP) #if ENABLED(PIDTEMP)
static float temp_iState[HOTENDS],
temp_dState[HOTENDS],
pTerm[HOTENDS],
iTerm[HOTENDS],
dTerm[HOTENDS];
#if ENABLED(PID_EXTRUSION_SCALING) #if ENABLED(PID_EXTRUSION_SCALING)
static float cTerm[HOTENDS];
static long last_e_position; static long last_e_position;
static long lpq[LPQ_MAX_LEN]; static long lpq[LPQ_MAX_LEN];
static int lpq_ptr; static int lpq_ptr;
#endif #endif
static float pid_error[HOTENDS];
static bool pid_reset[HOTENDS];
#endif #endif
// Init min and max temp with extreme values to prevent false errors during startup // Init min and max temp with extreme values to prevent false errors during startup
@ -239,14 +240,7 @@ class Temperature {
static uint16_t watch_target_bed_temp; static uint16_t watch_target_bed_temp;
static millis_t watch_bed_next_ms; static millis_t watch_bed_next_ms;
#endif #endif
#if ENABLED(PIDTEMPBED) #if DISABLED(PIDTEMPBED)
static float temp_iState_bed,
temp_dState_bed,
pTerm_bed,
iTerm_bed,
dTerm_bed,
pid_error_bed;
#else
static millis_t next_bed_check_ms; static millis_t next_bed_check_ms;
#endif #endif
#if HEATER_IDLE_HANDLER #if HEATER_IDLE_HANDLER

View file

@ -30,9 +30,7 @@
#include "../Marlin.h" #include "../Marlin.h"
#if ENABLED(SINGLENOZZLE) #if ENABLED(SINGLENOZZLE)
float singlenozzle_swap_length = SINGLENOZZLE_SWAP_LENGTH; singlenozzle_settings_t sn_settings; // Initialized by settings.load()
int16_t singlenozzle_prime_speed = SINGLENOZZLE_SWAP_PRIME_SPEED,
singlenozzle_retract_speed = SINGLENOZZLE_SWAP_RETRACT_SPEED;
uint16_t singlenozzle_temp[EXTRUDERS]; uint16_t singlenozzle_temp[EXTRUDERS];
#if FAN_COUNT > 0 #if FAN_COUNT > 0
uint8_t singlenozzle_fan_speed[EXTRUDERS]; uint8_t singlenozzle_fan_speed[EXTRUDERS];
@ -152,7 +150,7 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
// STEP 2 // STEP 2
@ -163,7 +161,7 @@
DEBUG_POS("Moving ParkPos", current_position); DEBUG_POS("Moving ParkPos", current_position);
} }
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[X_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
// STEP 3 // STEP 3
@ -181,7 +179,7 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move away from parked extruder", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("Move away from parked extruder", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[X_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
// STEP 5 // STEP 5
@ -196,12 +194,12 @@
// STEP 6 // STEP 6
current_position[X_AXIS] = grabpos + (tmp_extruder ? -10 : 10); current_position[X_AXIS] = grabpos + (tmp_extruder ? -10 : 10);
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[X_AXIS], active_extruder);
current_position[X_AXIS] = grabpos; current_position[X_AXIS] = grabpos;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("(6) Unpark extruder", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("(6) Unpark extruder", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS]/2, active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[X_AXIS]/2, active_extruder);
planner.synchronize(); planner.synchronize();
// Step 7 // Step 7
@ -209,7 +207,7 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("(7) Move midway between hotends", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("(7) Move midway between hotends", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[X_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
SERIAL_ECHOLNPGM("Autopark done."); SERIAL_ECHOLNPGM("Autopark done.");
@ -259,7 +257,7 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
// STEP 2 // STEP 2
@ -270,14 +268,14 @@
DEBUG_POS("Move X SwitchPos", current_position); DEBUG_POS("Move X SwitchPos", current_position);
} }
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[X_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY; current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Y_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
// STEP 3 // STEP 3
@ -291,14 +289,14 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position);
#endif #endif
planner.buffer_line(current_position,(planner.max_feedrate_mm_s[Y_AXIS] * 0.5), active_extruder); planner.buffer_line(current_position,(planner.settings.max_feedrate_mm_s[Y_AXIS] * 0.5), active_extruder);
planner.synchronize(); planner.synchronize();
safe_delay(200); safe_delay(200);
current_position[Y_AXIS] -= SWITCHING_TOOLHEAD_Y_CLEAR; current_position[Y_AXIS] -= SWITCHING_TOOLHEAD_Y_CLEAR;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
planner.synchronize(); planner.synchronize();
// STEP 4 // STEP 4
@ -309,13 +307,13 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move to new toolhead X", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("Move to new toolhead X", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[X_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY; current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY;
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Y_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
// STEP 5 // STEP 5
@ -326,7 +324,7 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS] * 0.5, active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Y_AXIS] * 0.5, active_extruder);
planner.synchronize(); planner.synchronize();
safe_delay(200); safe_delay(200);
@ -337,7 +335,7 @@
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position); if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position);
#endif #endif
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
planner.synchronize(); planner.synchronize();
// STEP 6 // STEP 6
@ -413,9 +411,9 @@ inline void invalid_extruder_error(const uint8_t e) {
#define CUR_Z current_position[Z_AXIS] #define CUR_Z current_position[Z_AXIS]
#define CUR_E current_position[E_AXIS] #define CUR_E current_position[E_AXIS]
planner.buffer_line(CUR_X, CUR_Y, raised_z, CUR_E, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); planner.buffer_line(CUR_X, CUR_Y, raised_z, CUR_E, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder);
planner.buffer_line(xhome, CUR_Y, raised_z, CUR_E, planner.max_feedrate_mm_s[X_AXIS], active_extruder); planner.buffer_line(xhome, CUR_Y, raised_z, CUR_E, planner.settings.max_feedrate_mm_s[X_AXIS], active_extruder);
planner.buffer_line(xhome, CUR_Y, CUR_Z, CUR_E, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); planner.buffer_line(xhome, CUR_Y, CUR_Z, CUR_E, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder);
planner.synchronize(); planner.synchronize();
} }
@ -556,7 +554,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
#if ENABLED(SWITCHING_NOZZLE) #if ENABLED(SWITCHING_NOZZLE)
// Always raise by at least 1 to avoid workpiece // Always raise by at least 1 to avoid workpiece
current_position[Z_AXIS] += MAX(-zdiff, 0.0) + 1; current_position[Z_AXIS] += MAX(-zdiff, 0.0) + 1;
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder);
move_nozzle_servo(tmp_extruder); move_nozzle_servo(tmp_extruder);
#endif #endif
#endif #endif
@ -595,7 +593,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
#if DISABLED(SWITCHING_NOZZLE) #if DISABLED(SWITCHING_NOZZLE)
// Do a small lift to avoid the workpiece in the move back (below) // Do a small lift to avoid the workpiece in the move back (below)
current_position[Z_AXIS] += 1.0; current_position[Z_AXIS] += 1.0;
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder);
#endif #endif
#if ENABLED(DEBUG_LEVELING_FEATURE) #if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination); if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination);
@ -616,7 +614,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
#if ENABLED(SWITCHING_NOZZLE) #if ENABLED(SWITCHING_NOZZLE)
else { else {
// Move back down. (Including when the new tool is higher.) // Move back down. (Including when the new tool is higher.)
do_blocking_move_to_z(destination[Z_AXIS], planner.max_feedrate_mm_s[Z_AXIS]); do_blocking_move_to_z(destination[Z_AXIS], planner.settings.max_feedrate_mm_s[Z_AXIS]);
} }
#endif #endif
} // (tmp_extruder != active_extruder) } // (tmp_extruder != active_extruder)
@ -663,12 +661,12 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
set_destination_from_current(); set_destination_from_current();
if (singlenozzle_swap_length) { if (sn_settings.swap_length) {
#if ENABLED(ADVANCED_PAUSE_FEATURE) #if ENABLED(ADVANCED_PAUSE_FEATURE)
do_pause_e_move(-singlenozzle_swap_length, MMM_TO_MMS(singlenozzle_retract_speed)); do_pause_e_move(-sn_settings.swap_length, MMM_TO_MMS(sn_settings.retract_speed));
#else #else
current_position[E_AXIS] -= singlenozzle_swap_length / planner.e_factor[active_extruder]; current_position[E_AXIS] -= sn_settings.swap_length / planner.e_factor[active_extruder];
planner.buffer_line(current_position, MMM_TO_MMS(singlenozzle_retract_speed), active_extruder); planner.buffer_line(current_position, MMM_TO_MMS(sn_settings.retract_speed), active_extruder);
#endif #endif
} }
@ -680,7 +678,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
#endif #endif
); );
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder); planner.buffer_line(current_position, planner.settings.max_feedrate_mm_s[Z_AXIS], active_extruder);
#if ENABLED(SINGLENOZZLE_SWAP_PARK) #if ENABLED(SINGLENOZZLE_SWAP_PARK)
current_position[X_AXIS] = singlenozzle_change_point.x; current_position[X_AXIS] = singlenozzle_change_point.x;
@ -699,12 +697,12 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
active_extruder = tmp_extruder; active_extruder = tmp_extruder;
if (singlenozzle_swap_length) { if (sn_settings.swap_length) {
#if ENABLED(ADVANCED_PAUSE_FEATURE) #if ENABLED(ADVANCED_PAUSE_FEATURE)
do_pause_e_move(singlenozzle_swap_length, singlenozzle_prime_speed); do_pause_e_move(sn_settings.swap_length, sn_settings.prime_speed);
#else #else
current_position[E_AXIS] += singlenozzle_swap_length / planner.e_factor[tmp_extruder]; current_position[E_AXIS] += sn_settings.swap_length / planner.e_factor[tmp_extruder];
planner.buffer_line(current_position, singlenozzle_prime_speed, tmp_extruder); planner.buffer_line(current_position, sn_settings.prime_speed, tmp_extruder);
#endif #endif
} }

View file

@ -19,11 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
#pragma once
#ifndef TOOL_CHANGE_H #include "../inc/MarlinConfigPre.h"
#define TOOL_CHANGE_H
#include "../inc/MarlinConfig.h"
#if DO_SWITCH_EXTRUDER #if DO_SWITCH_EXTRUDER
void move_extruder_servo(const uint8_t e); void move_extruder_servo(const uint8_t e);
@ -51,9 +49,11 @@
#endif // PARKING_EXTRUDER #endif // PARKING_EXTRUDER
#if ENABLED(SINGLENOZZLE) #if ENABLED(SINGLENOZZLE)
extern float singlenozzle_swap_length; typedef struct {
extern int16_t singlenozzle_prime_speed, float swap_length;
singlenozzle_retract_speed; int16_t prime_speed, retract_speed;
} singlenozzle_settings_t;
extern singlenozzle_settings_t sn_settings;
extern uint16_t singlenozzle_temp[EXTRUDERS]; extern uint16_t singlenozzle_temp[EXTRUDERS];
#if FAN_COUNT > 0 #if FAN_COUNT > 0
extern uint8_t singlenozzle_fan_speed[EXTRUDERS]; extern uint8_t singlenozzle_fan_speed[EXTRUDERS];
@ -65,5 +65,3 @@
* previous tool out of the way and the new tool into place. * previous tool out of the way and the new tool into place.
*/ */
void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false); void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false);
#endif // TOOL_CHANGE_H