Skip to content

Fix incorrect XY scaling when axis_steps_per_mm is not 100.#5062

Open
fosterish wants to merge 1 commit intoprusa3d:masterfrom
fosterish:fix-steps-per-unit
Open

Fix incorrect XY scaling when axis_steps_per_mm is not 100.#5062
fosterish wants to merge 1 commit intoprusa3d:masterfrom
fosterish:fix-steps-per-unit

Conversation

@fosterish
Copy link

@fosterish fosterish commented Dec 31, 2025

Problem

Issuing M92 (for instance, to compensate for 1.5mm pitch belt pulleys on the CORE One) produces incorrect results. The nature of the error depends on where in the gcode the command is issued in relation to a G28 command.

Inverted scaling

If M92 is issued before G28, the resulting scale factor will be inverted (values lower than 100 produce a larger print, and values higher than 100 produce a smaller print).

Cause

This happens because G28 calls MarlinSettings::reset_motion, which resets the planner's axis_steps_per_mm (and not mm_per_step et al.), which never gets restored during the call to Motion_Parameters::load at the end of the command. So then we're using the default 100 steps per mm to generate step counts in Planner::buffer_segment, but then consume them with a scaled mm_per_mstep in Planner::_populate_block.

Solution

I've unified motion_parameters_t and planner_settings_t. Maybe this causes issues elsewhere, but the two were so similar I didn't understand why they were separate. At the very least, this causes axis_steps_per_mm to get saved and loaded with the rest of the motion parameters. I also call Planner::refresh_positioning anytime we change that value.

Ignored scaling

If M92 is issued after G28, there is no effect on the scale of the print.

Cause

A print move gets converted into motor movements through a convoluted chain of conversions: mm -> ministeps -> mm -> duration@speed -> rotation speed. The final step of this chain relies on AxisMotorParams::mm_to_rev, which gets calculated only once, at startup, and not anytime axis_steps_per_mm changes.

Solution

I've created phase_stepping::update_axis_motor_params, which I call from inside Planner::refresh_positioning. It does the same thing as the initialization, but pulls its values from the planner and not the defaults.

Note: I would never claim to be familiar with concurrent programming in C++, so someone who actually knows what they're doing should look at this. I noticed that axis_motor_params is getting read thousands of times per second by the step ISR, so I figured we'd be dabbling in some light UB if we didn't at least disable interrupts before modifying it.

Background

I have a Prusa CORE One, and have recently swapped the stock belts and pulleys for 1.5mm pitch belts and pulleys, as many people are experimenting with, to combat VFAs. Because the pitch diameter of the new pulleys is slightly smaller than that of the stock pulleys, one needs to configure the machine's steps per mm to compensate.

The common solution found in the forums and in videos is to issue M92 X98.44 Y98.44 at the start of your gcode, which does indeed have an enlarging effect on the print. However, this solution has problems:

  1. It makes no sense. The new pulleys are slightly smaller than the stock, so they need to rotate more to cover the same distance. This command does the opposite by telling the machine to take fewer steps per mm. This is clearly just a bug.
  2. It leaves the printer in a strange state where calibration of the X or Y axes, or home, fails.

With this PR, I hope to get the ball rolling on a fix. I've tested it on my own CORE One, and it works very well. With this fix, one can correctly issue the appropriate M92 command, and get properly sized prints using 1.5mm pitch belts and pulleys without leaving your printer in a weird state:

scale = old pitch diameter / new pitch diameter
scale = (16 * 2 / pi) / (21 * 1.5 / pi)
scale = 32 / 31.5
scale ~= 1.015873

M92 X101.5873 Y101.5873

I believe this solves #4619, #4675, and the first part of #4946, though I haven't tested it on any printer other than the CORE One.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant