Speeding up Z axis

I have a problem that seems to get more complicated the more I think about it. Perhaps some of you can help…
I am trying to get the best 3D carving performance from my MPCNC Portable Primo. After changing the stock leadscrew for a 1-start 2mm/rev one (so that the heavy spindle won’t fall down if the stepper motor loses power), my max rate for moving up and down is limited by the torque/rpm curve of stepper motors. (I am using a Teensy 4.1 controller with grblHAL firmware, so pulse rate is not a limitation). I have tried varying parameters that might affect torque, such as microsteps, voltage (40V now), max current, stepper driver cooling, stepper motor cooling, and of course, making sure the leadscrew and bearings all move freely. I seem to be “stuck” at about 25-30mm/sec vertical before the stepper motor squeaks and skips steps. It could happen in either up or down. This seems like a pretty good Z rate, but alas, I have recently learned that at least in VcarvePro, when carving a finishing pass of a 3D carving (such as terrain/relief maps), the same feedrate setting applies to X, Y and Z. Charlotte “Charlie” at Vectric said, “Each line of GCode can only have one feedrate which will be the feedrate the machine will attempt to use for all Axes, so always limit this to the maximum safe rate of your slowest Axis.” (The number I plug in for “plunge rate” is not used during the finishing pass toolpath except when it starts a cut.)

Carvings are painfully slow if X and Y are also set to 25mm/sec (the Feedrate setting) to accommodate the max Z my machine can handle. My X and Y can easily go 5x faster.

Here’s the thing I am pondering: For most movements (lines of Gcode) the distance moved in Z will be quite a bit less than the distance moved in X and Y, depending on the shape of the thing being carved. So what does the motion controller do with a feedrate setting like, say 25mm/sec to apply it to all three axes? Does Marlin do something different than grbl?
What I would like is for the CAM software to have two settings, an X-Y feedrate and a max Z feedrate, and to only reduce the XY movement speed if it would exceed the max Z speed. Is this possible?

1 Like

Would splitting the difference with a 2-start lead screw help? I know Marlin has separate max feedrates for X, Y, and Z, but I’m not sure what happens to X and Y when Z hits its max.

1 Like

Just 30mm/sec seems a bit low. I’m running 48V, 1.04Arms, 1/4 microstepping, 1.8* motors, and 1-start at 116mm/sec (100 accel) with no skipped steps carrying a 65mm watercooled spindle. When mine had a 4-start screw, the z would drop on it’s own even with just a bosch colt router installed (so very smooth mechanics). Perhaps there is some mechanical binding somewhere in the z gantry that is consuming too much torque?

I’m not sure what you can do about Vectric changing axis rates on the fly like that. Doing helix/ramp plunges and 3d carving would be torture if XY are obeying plunge rate limits. That seems flawed to me. I can get very fast xy during plunge for example in F360. It has been a while so I’d have to go back and see what I did, but my cnc drag race run was a good example of that… xy were shaking as it plunged down. I had a much, much slower z axis as well.


I think this is what Marlin already does. I’m not sure about Grbl.

The feed rate in the gcode applies to the overall 3-dimensional speed, so a combined X+Y+Z movement will move slower in each of the axes depending on the angles. Limiting the overall feedrate to the slowest axis is a simple approach so that the feed rate does not need to consider the constituent X, Y, and Z components. It is definitely possible to calculate an overall feed rate that stays within the individual axes speeds. As I said, Marlin already does this, and as an alternative I think it could be implemented as a post-processor. But for a high-dollar product it should really be integrated into the gcode generation.


I disagree with this. I agree with Jamie. You do need to set your max z feedrate (and M203 takes mm/s, not mm/min).

The max speeds are so different that it should be easy to test.

G1 X100 Y100 Z100 F4800

(Starting from zero) should take about 4s if your max z feedrate is 25mm/s. It should be limited by the Z speed. Along the line, it has to travel 175mm, and at 4800mm/min, that is 2.1s. If it is exceeding the Z feedrate, then you will either skip steps, or it will finish much quicker than 4s.

You can make it even more extreme by setting the max Z feedrate to something like 5mm/s. Then that test would take even longer (20s vs. 2.1s).


Great suggestions and info from all of you, thanks! I will order a 2-start screw to “split the difference”, and in the mean time, test out the movement under simple 3D linear movements with a stopwatch to figure out what exactly grbl is doing. (Or maybe delve into the code, ugh) I have a feeling my Handibot, which uses the Fabmo motion controller, was more clever about mixing X,Y and Z speeds than my current MPCNC with grblHAL. So I will run some tests on that, too. And perhaps comparing CAM in F360 vs VcarvePro to see if I need to get back on to Vectric to improve their post-processor.

One possibility I have not tried is to carve 3D models the way a 3D printer works: layer by layer, so there are only tiny Z movements. I know F360 has a toolpath for that. But with terrain, there would be a lot of rapids and plunges to get to the valleys, so I am not sure if this would speed things up overall. Have any of you tried this?

I haven’t used grblHAL (yet) but the version I’m on (1.1 f or g I think) noticeably slows on z moves. I cut a chess board with grim reapers on it that had fair stretches of flat cuts and it would zip right along, then decelerate and crawl up or down, then zip zip zip again.

Steve, I think also layer by layer will leave undesireable mill marks (will look 3d printed as well. I’ve done this strategy before (3d contour in f360), and while it can be run very fast, it still takes a while to hit all the corners, and it leaves layer lines.

When I first setup my primo I played with f360’s “parallel” operation, which runs the bit in slices along either x or y. (like contour, but layers in x or y instead). That cut was setup for 60ipm with 30ipm plunge, and it ran quite smoothly the whole time (no weird fluctuations in feedrate). That is is a fast plunge rate for a mostly vertical move, but it is OK as long as it doesn’t have to plunge in a pure z direction (which might break a bit or overspeed z). Parallel offers multiple step downs, but not sure about carving etc. If the z movement for the operation is mostly shallow ramping, you might be able to get away with just using a high z rate as a workaround… just make sure any vertical plunges/lifts obey z max rate. Doing this automatically would be a nice improvement to any pp.

1 Like

Thanks, Robert. I installed a 2-start lead screw and that really helped! I can cut 3D terrain with Z max feedrate set to 50mm/sec (and XY feedrate at 60mm/sec or faster). From looking at it, the XY is slowed in proportion to keep the Z at or below its max setting in grbl, when a 3D move is commanded. But I have not gotten around to measuring speeds of diagonal moves as JeffeB3 suggested.

I have also moved from the TB6600 stepper controller for my Z axis to a TMC2160 controller chip (on a Makerbase board). Unfortunately, this board does not break out a missed-steps alarm condition to allow me to halt a run if things go pear shaped. I could patch in to the TMC chip via its SPI bus and keep querying it, but that is a lot of programming I would rather not have to do. I have a closed-loop stepper motor and driver in a box waiting for me to try it out. But with the new lead screw, I did a big complex 3D roughing pass quite quickly, no problems. We will see how the finishing pass goes.