Skip to content

Commit

Permalink
✨ EDITABLE_STEPS_PER_UNIT (MarlinFirmware#26618)
Browse files Browse the repository at this point in the history
Co-authored-by: Scott Lahteine <[email protected]>
  • Loading branch information
plampix and thinkyhead authored Jan 10, 2024
1 parent 1d46e67 commit 854f331
Show file tree
Hide file tree
Showing 38 changed files with 711 additions and 607 deletions.
7 changes: 6 additions & 1 deletion Marlin/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -1231,11 +1231,16 @@

/**
* Default Axis Steps Per Unit (linear=steps/mm, rotational=steps/°)
* Override with M92
* Override with M92 (when enabled below)
* X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]]
*/
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 500 }

/**
* Enable support for M92. Disable to save at least ~530 bytes of flash.
*/
#define EDITABLE_STEPS_PER_UNIT

/**
* Default Max Feed Rate (linear=mm/s, rotational=°/s)
* Override with M203
Expand Down
8 changes: 4 additions & 4 deletions Marlin/src/feature/encoder_i2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,22 +422,22 @@ void I2CPositionEncoder::calibrate_steps_mm(const uint8_t iter) {
travelledDistance = mm_from_count(ABS(stopCount - startCount));

SERIAL_ECHOLNPGM("Attempted travel: ", travelDistance, "mm");
SERIAL_ECHOLNPGM(" Actual travel: ", travelledDistance, "mm");
SERIAL_ECHOLNPGM(" Actual travel: ", travelledDistance, "mm");

//Calculate new axis steps per unit
// Calculate new axis steps per unit
old_steps_mm = planner.settings.axis_steps_per_mm[encoderAxis];
new_steps_mm = (old_steps_mm * travelDistance) / travelledDistance;

SERIAL_ECHOLNPGM("Old steps/mm: ", old_steps_mm);
SERIAL_ECHOLNPGM("New steps/mm: ", new_steps_mm);

//Save new value
// Save new value
planner.settings.axis_steps_per_mm[encoderAxis] = new_steps_mm;

if (iter > 1) {
total += new_steps_mm;

// swap start and end points so next loop runs from current position
// Swap start and end points so next loop runs from current position
const float tempCoord = startCoord[encoderAxis];
startCoord[encoderAxis] = endCoord[encoderAxis];
endCoord[encoderAxis] = tempCoord;
Expand Down
7 changes: 7 additions & 0 deletions Marlin/src/gcode/config/M92.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
*
*/

#include "../../inc/MarlinConfigPre.h"

#if ENABLED(EDITABLE_STEPS_PER_UNIT)

#include "../gcode.h"
#include "../../module/planner.h"

Expand All @@ -37,6 +41,7 @@
* H<microsteps> - Specify micro-steps to use. Best guess if not supplied.
* L<linear> - Desired layer height in current units. Nearest good heights are shown.
*/

void GcodeSuite::M92() {

const int8_t target_extruder = get_target_extruder_from_command();
Expand Down Expand Up @@ -127,3 +132,5 @@ void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/
UNUSED(e);
#endif
}

#endif // EDITABLE_STEPS_PER_UNIT
5 changes: 4 additions & 1 deletion Marlin/src/gcode/gcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 87: M87(); break; // M87: Cancel Hotend Idle Timeout
#endif

case 92: M92(); break; // M92: Set the steps-per-unit for one or more axes
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
case 92: M92(); break; // M92: Set the steps-per-unit for one or more axes
#endif

case 114: M114(); break; // M114: Report current position

#if ENABLED(CAPABILITIES_REPORT)
Expand Down
8 changes: 5 additions & 3 deletions Marlin/src/gcode/gcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
* 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.
* M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
* M92 - Set planner.settings.axis_steps_per_mm for one or more axes.
* M92 - Set planner.settings.axis_steps_per_mm for one or more axes. (Requires EDITABLE_STEPS_PER_UNIT)
*
* M100 - Watch Free Memory (for debugging) (Requires M100_FREE_MEMORY_WATCHER)
*
Expand Down Expand Up @@ -719,8 +719,10 @@ class GcodeSuite {
static void M87();
#endif

static void M92();
static void M92_report(const bool forReplay=true, const int8_t e=-1);
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
static void M92();
static void M92_report(const bool forReplay=true, const int8_t e=-1);
#endif

#if ENABLED(M100_FREE_MEMORY_WATCHER)
static void M100();
Expand Down
2 changes: 2 additions & 0 deletions Marlin/src/inc/SanityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
#if ENABLED(I2C_POSITION_ENCODERS)
#if !ALL(BABYSTEPPING, BABYSTEP_XY)
#error "I2C_POSITION_ENCODERS requires BABYSTEPPING and BABYSTEP_XY."
#elif DISABLED(EDITABLE_STEPS_PER_UNIT)
#error "EDITABLE_STEPS_PER_UNIT is required for I2C_POSITION_ENCODERS."
#elif !WITHIN(I2CPE_ENCODER_CNT, 1, 5)
#error "I2CPE_ENCODER_CNT must be between 1 and 5."
#endif
Expand Down
7 changes: 7 additions & 0 deletions Marlin/src/inc/Warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,3 +833,10 @@
#if ALL(FT_MOTION, I2S_STEPPER_STREAM)
#warning "FT_MOTION has not been tested with I2S_STEPPER_STREAM."
#endif

/**
* User doesn't have or disabled G92?
*/
#if DISABLED(EDITABLE_STEPS_PER_UNIT)
#warning "EDITABLE_STEPS_PER_UNIT is required to enable G92 runtime configuration of steps-per-unit."
#endif
38 changes: 22 additions & 16 deletions Marlin/src/lcd/e3v2/creality/dwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1619,23 +1619,27 @@ void hmiMaxAccelerationXYZE() {

#endif // CLASSIC_JERK

void hmiStepXYZE() {
EncoderState encoder_diffState = encoderReceiveAnalyze();
if (encoder_diffState == ENCODER_DIFF_NO) return;
if (applyEncoder(encoder_diffState, hmiValues.maxStepScaled)) {
checkkey = ID_Step;
encoderRate.enabled = false;
#if ENABLED(EDITABLE_STEPS_PER_UNIT)

void hmiStepXYZE() {
EncoderState encoder_diffState = encoderReceiveAnalyze();
if (encoder_diffState == ENCODER_DIFF_NO) return;
if (applyEncoder(encoder_diffState, hmiValues.maxStepScaled)) {
checkkey = ID_Step;
encoderRate.enabled = false;
if (WITHIN(hmiFlag.step_axis, X_AXIS, LAST_AXIS))
planner.settings.axis_steps_per_mm[hmiFlag.step_axis] = hmiValues.maxStepScaled / MINUNITMULT;
drawEditFloat3(select_step.now, hmiValues.maxStepScaled);
return;
}
// Step limit
if (WITHIN(hmiFlag.step_axis, X_AXIS, LAST_AXIS))
planner.settings.axis_steps_per_mm[hmiFlag.step_axis] = hmiValues.maxStepScaled / MINUNITMULT;
drawEditFloat3(select_step.now, hmiValues.maxStepScaled);
return;
LIMIT(hmiValues.maxStepScaled, min_steps_edit_values[hmiFlag.step_axis] * MINUNITMULT, max_steps_edit_values[hmiFlag.step_axis] * MINUNITMULT);
// Step value
drawEditFloat3(select_step.now, hmiValues.maxStepScaled, true);
}
// Step limit
if (WITHIN(hmiFlag.step_axis, X_AXIS, LAST_AXIS))
LIMIT(hmiValues.maxStepScaled, min_steps_edit_values[hmiFlag.step_axis] * MINUNITMULT, max_steps_edit_values[hmiFlag.step_axis] * MINUNITMULT);
// Step value
drawEditFloat3(select_step.now, hmiValues.maxStepScaled, true);
}

#endif // EDITABLE_STEPS_PER_UNIT

// Draw X, Y, Z and blink if in an un-homed or un-trusted state
void _update_axis_value(const AxisEnum axis, const uint16_t x, const uint16_t y, const bool blink, const bool force) {
Expand Down Expand Up @@ -4279,7 +4283,9 @@ void dwinHandleScreen() {
#if ENABLED(CLASSIC_JERK)
case ID_MaxJerkValue: hmiMaxJerkXYZE(); break;
#endif
case ID_StepValue: hmiStepXYZE(); break;
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
case ID_StepValue: hmiStepXYZE(); break;
#endif
default: break;
}
}
Expand Down
5 changes: 4 additions & 1 deletion Marlin/src/lcd/e3v2/creality/dwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,10 @@ void hmiPrintSpeed();
void hmiMaxFeedspeedXYZE();
void hmiMaxAccelerationXYZE();
void hmiMaxJerkXYZE();
void hmiStepXYZE();
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
void hmiStepXYZE();
#endif

void hmiSetLanguageCache();

void updateVariable();
Expand Down
139 changes: 77 additions & 62 deletions Marlin/src/lcd/e3v2/jyersui/dwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2364,6 +2364,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
else
drawMenu(ID_MaxAcceleration);
break;

#if ENABLED(CLASSIC_JERK)
case MOTION_JERK:
if (draw)
Expand All @@ -2372,12 +2373,16 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
drawMenu(ID_MaxJerk);
break;
#endif
case MOTION_STEPS:
if (draw)
drawMenuItem(row, ICON_Step, GET_TEXT_F(MSG_STEPS_PER_MM), nullptr, true);
else
drawMenu(ID_Steps);
break;

#if ENABLED(EDITABLE_STEPS_PER_UNIT)
case MOTION_STEPS:
if (draw)
drawMenuItem(row, ICON_Step, GET_TEXT_F(MSG_STEPS_PER_MM), nullptr, true);
else
drawMenu(ID_Steps);
break;
#endif

#if HAS_HOTEND
case MOTION_FLOW:
if (draw) {
Expand All @@ -2388,6 +2393,7 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
modifyValue(planner.flow_percentage[0], MIN_FLOW_RATE, MAX_FLOW_RATE, 1, []{ planner.refresh_e_factor(0); });
break;
#endif

#if ENABLED(LIN_ADVANCE)
case MOTION_LA:
if (draw) {
Expand Down Expand Up @@ -2613,64 +2619,69 @@ void JyersDWIN::menuItemHandler(const uint8_t menu, const uint8_t item, bool dra
}
break;
#endif
case ID_Steps:

#define STEPS_BACK 0
#define STEPS_X (STEPS_BACK + ENABLED(HAS_X_AXIS))
#define STEPS_Y (STEPS_X + ENABLED(HAS_Y_AXIS))
#define STEPS_Z (STEPS_Y + ENABLED(HAS_Z_AXIS))
#define STEPS_E (STEPS_Z + ENABLED(HAS_HOTEND))
#define STEPS_TOTAL STEPS_E
#if ENABLED(EDITABLE_STEPS_PER_UNIT)

switch (item) {
case STEPS_BACK:
if (draw)
drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK));
else
drawMenu(ID_Motion, MOTION_STEPS);
break;
#if HAS_X_AXIS
case STEPS_X:
if (draw) {
drawMenuItem(row, ICON_StepX, GET_TEXT_F(MSG_A_STEPS));
drawFloat(planner.settings.axis_steps_per_mm[X_AXIS], row, false, STEPS_UNIT);
}
else
modifyValue(planner.settings.axis_steps_per_mm[X_AXIS], min_steps_edit_values.x, max_steps_edit_values.x, STEPS_UNIT);
break;
#endif
#if HAS_Y_AXIS
case STEPS_Y:
if (draw) {
drawMenuItem(row, ICON_StepY, GET_TEXT_F(MSG_B_STEPS));
drawFloat(planner.settings.axis_steps_per_mm[Y_AXIS], row, false, STEPS_UNIT);
}
else
modifyValue(planner.settings.axis_steps_per_mm[Y_AXIS], min_steps_edit_values.y, max_steps_edit_values.y, STEPS_UNIT);
break;
#endif
#if HAS_Z_AXIS
case STEPS_Z:
if (draw) {
drawMenuItem(row, ICON_StepZ, GET_TEXT_F(MSG_C_STEPS));
drawFloat(planner.settings.axis_steps_per_mm[Z_AXIS], row, false, STEPS_UNIT);
}
else
modifyValue(planner.settings.axis_steps_per_mm[Z_AXIS], min_steps_edit_values.z, max_steps_edit_values.z, STEPS_UNIT);
break;
#endif
#if HAS_HOTEND
case STEPS_E:
if (draw) {
drawMenuItem(row, ICON_StepE, GET_TEXT_F(MSG_E_STEPS));
drawFloat(planner.settings.axis_steps_per_mm[E_AXIS], row, false, STEPS_UNIT);
}
case ID_Steps:

#define STEPS_BACK 0
#define STEPS_X (STEPS_BACK + ENABLED(HAS_X_AXIS))
#define STEPS_Y (STEPS_X + ENABLED(HAS_Y_AXIS))
#define STEPS_Z (STEPS_Y + ENABLED(HAS_Z_AXIS))
#define STEPS_E (STEPS_Z + ENABLED(HAS_HOTEND))
#define STEPS_TOTAL STEPS_E

switch (item) {
case STEPS_BACK:
if (draw)
drawMenuItem(row, ICON_Back, GET_TEXT_F(MSG_BACK));
else
modifyValue(planner.settings.axis_steps_per_mm[E_AXIS], min_steps_edit_values.e, max_steps_edit_values.e, STEPS_UNIT);
drawMenu(ID_Motion, MOTION_STEPS);
break;
#endif
}
break;
#if HAS_X_AXIS
case STEPS_X:
if (draw) {
drawMenuItem(row, ICON_StepX, GET_TEXT_F(MSG_A_STEPS));
drawFloat(planner.settings.axis_steps_per_mm[X_AXIS], row, false, STEPS_UNIT);
}
else
modifyValue(planner.settings.axis_steps_per_mm[X_AXIS], min_steps_edit_values.x, max_steps_edit_values.x, STEPS_UNIT);
break;
#endif
#if HAS_Y_AXIS
case STEPS_Y:
if (draw) {
drawMenuItem(row, ICON_StepY, GET_TEXT_F(MSG_B_STEPS));
drawFloat(planner.settings.axis_steps_per_mm[Y_AXIS], row, false, STEPS_UNIT);
}
else
modifyValue(planner.settings.axis_steps_per_mm[Y_AXIS], min_steps_edit_values.y, max_steps_edit_values.y, STEPS_UNIT);
break;
#endif
#if HAS_Z_AXIS
case STEPS_Z:
if (draw) {
drawMenuItem(row, ICON_StepZ, GET_TEXT_F(MSG_C_STEPS));
drawFloat(planner.settings.axis_steps_per_mm[Z_AXIS], row, false, STEPS_UNIT);
}
else
modifyValue(planner.settings.axis_steps_per_mm[Z_AXIS], min_steps_edit_values.z, max_steps_edit_values.z, STEPS_UNIT);
break;
#endif
#if HAS_HOTEND
case STEPS_E:
if (draw) {
drawMenuItem(row, ICON_StepE, GET_TEXT_F(MSG_E_STEPS));
drawFloat(planner.settings.axis_steps_per_mm[E_AXIS], row, false, STEPS_UNIT);
}
else
modifyValue(planner.settings.axis_steps_per_mm[E_AXIS], min_steps_edit_values.e, max_steps_edit_values.e, STEPS_UNIT);
break;
#endif
}
break;

#endif // EDITABLE_STEPS_PER_UNIT

case ID_Visual:

Expand Down Expand Up @@ -4173,7 +4184,9 @@ FSTR_P JyersDWIN::getMenuTitle(const uint8_t menu) {
#if ENABLED(CLASSIC_JERK)
case ID_MaxJerk: return F("Max Jerk");
#endif
case ID_Steps: return GET_TEXT_F(MSG_STEPS_PER_MM);
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
case ID_Steps: return GET_TEXT_F(MSG_STEPS_PER_MM);
#endif
case ID_Visual: return F("Visual Settings");
case ID_Advanced: return GET_TEXT_F(MSG_ADVANCED_SETTINGS);
#if HAS_BED_PROBE
Expand Down Expand Up @@ -4250,7 +4263,9 @@ uint8_t JyersDWIN::getMenuSize(const uint8_t menu) {
#if ENABLED(CLASSIC_JERK)
case ID_MaxJerk: return JERK_TOTAL;
#endif
case ID_Steps: return STEPS_TOTAL;
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
case ID_Steps: return STEPS_TOTAL;
#endif
case ID_Visual: return VISUAL_TOTAL;
case ID_Advanced: return ADVANCED_TOTAL;
#if HAS_BED_PROBE
Expand Down
2 changes: 1 addition & 1 deletion Marlin/src/lcd/e3v2/jyersui/dwin.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ enum menuID : uint8_t {
ID_MaxSpeed,
ID_MaxAcceleration,
ID_MaxJerk,
ID_Steps,
OPTITEM(EDITABLE_STEPS_PER_UNIT, ID_Steps)
ID_Visual,
ID_ColorSettings,
ID_Advanced,
Expand Down
Loading

0 comments on commit 854f331

Please sign in to comment.