[SOLVED] Z shifting after 1000s of moves on X-Controller

Ok, here’s a tricky one… :slight_smile:

I tried cutting 4 simple circular pockets and used jscut’s ramping feature (i.e. instead of straight plunging, it ramps into the required Z - or creates helical movements in my case of circular pockets, to optimize tool life). The outcome is ~9k lines of gcode, half of which involve Z moves.

In the end of running the gcode, I noticed that it went back to the given safe height of 3mm (Z WPos showing indeed 3), but it was actually about twice higher. Here’s my train of thought to debug this.

  • Wrong $102: This was my initial thought. However, a wrong $102 would only cause problems of scaling (i.e. if it was higher/lower, my Z moves would compress/expand proportionately). However, moving from Za to Zb and back to Za should go to the same Za, even if this is out of scale. In my case, Za shifts over time! Then I tried to manually give 30~40 Z moves and they were all consistent (and, btw, correct in scale too). Z0 would always go back and kiss the waistboard. So whatever happens, happens after 1000s of Z moves.

  • Probing issue: I am probing in different locations on the waistboard and when going G1 Z0 it is spot on. No probing/zeroing issues.

  • Skipped steps: This is the next area to question. However, no sign/sound of skipped steps. Furthermore, what makes me exclude this one is consistency. It would always shift the same. Even without load when “air cutting”.

  • Waistboard not level: Turns out also irrelevant. Even though I do plan to face mill the waistboard soon, I do my Z shifting comparison on the same X,Y (before running the gcode and in the end).

  • Tool slipping: That would be a possible explanation. If for some reason the tool did not engage in the collet tight enough, and the cut was too aggressive, then theoretically the tool could slip upwards and present exactly what I experience (this is a good visualization to imagine what is actually happening). However, this is out of question too… as, again, upwards Z shifting eventually occurs (by the same amount) when “air cutting” !

I am left with two areas (that I can think of) as possible culprits.

  • Buffering: If for some reason some gcode was taken out of stream, I would see Z shifts. However, the fact that I am cutting downwards and the shifting happens upwards, makes this less likely. Also, I am using bCNC which is supposed to be the (or at least one of the) best performers in streaming massive gcode.
    EDIT: Hm… If downward Z moves were dropped at buffering, could the machine think it was lower than it was so that subsequent upward Z moves would make it shift further up? It is the consistency of this happening over and over in the same pattern that puzzles me.

  • Rounding: This is the only one I have not debugged. I am using an ACME and therefore my $102 is ugly:
    (200step/rev * 2microstep/step) / (25.4mm/in / 12rev/in) = 188.976microstep/mm

Which makes me wonder if 1000s of Z roundings are enough to cause Z shifting. One thing I thought to try today is to throw my $102 out of scale with a nice round number (say 200microstep/mm) and see if the same gcode still causes Z shifting.

Btw, I am using the X-Controller with GRBL version 1.0c.20151109 . I should probably open an issue over at @SungeunJeon’s github.

Any ideas, recommendations are very welcome.

1 Like

Just to clarify it does not have this issue when cutting the circles with a straight plunge? Just to rule out a major mechanical or configuration issue (like a loose pulley set screw)

I wonder how small are the z moves? It may be some kind of rounding error or resolution issue, if it is making moves smaller that the XC minimum resolution?
~0.075mm to 0.13mm (For this I would assume 0.13mm)
Can you set the minimum resolution in jscut?

VCarve has similar options, “ramp in” (angle or cut length) or “constant” (helical)
I stay away from “constant” because with the z axis is always moving, the whole carve is the limited to the Z axis max move speed of 500 mm/min, adding hours to the carve.

Sonny has already spotted the cause in his github issues list where I also mentioned this behavior.

This can be caused by helical plunging and high Z axis acceleration. I must now experiment with my $11 and $122 (and possibly $120 & $121) values and see what happens.

So, I process the same SVG with straight plunging and I get 100x fewer Z moves of gcode!

helical plunging: 4443 Z moves
straight plunging: 45 Z moves

A few hours of experiments later…

Findings presented in the following format:
plunge method | $11 | $120 | $121 | $122 | Z shifting | comment

straight | 0.02 | 500 | 500 | 50 | 0 | the default values presented NO shifting when plunging straight
helical | 0.02 | 500 | 500 | 50 | +2 | this started the whole troubleshooting
helical | 0.01 | 500 | 500 | 50 | +4 | halving the junction deviation makes things worse
helical | 0.02 | 25 | 25 | 25 | +18 | slowing down all axes produces the worst results
helical | 0.01 | 25 | 25 | 25 | +14 | small improvement with deviation halving, but still very bad
helical | 0.01 | 100 | 100 | 50 | +3 | trying higher accelerations again, improvement
helical | 0.02 | 100 | 100 | 50 | +4 | back to default deviation, worse
helical | 0.02 | 500 | 500 | 70 | +1 | higher accel ratio same as my step/mm XY:Z, big improvement
helical | 0.01 | 500 | 500 | 70 | +3 | half deviation, worse
helical | 0.02 | 500 | 500 | 100 | +2 | correcting deviation, increasing ratio, worse than w/ equal ratio
helical | 0.02 | 500 | 500 | 80 | +1.5 | decreasing ratio, better, but still worse than w/ equal ratio
helical | 0.02 | 250 | 250 | 35 | +3.5 | keep ratio, decrease accel, much worse
helical | 0.02 | 1000 | 1000 | 140 | +1.5 | increase accel, better, but worse than 500-500-70
helical | 0.03 | 500 | 500 | 70 | +1.5 | back to 500-500-70, increase deviation, still slightly worse
helical | 0.02 | 25 | 25 | 3.5 | +4.5 | keep ratio, very low accel, bad (but a lot better than 25-25-25)
helical | 0.02 | 600 | 600 | 85 | +0.8 | looking for sweetspot around 500-500-70, best so far
helical | 0.02 | 700 | 700 | 100 | +1 | moving up, a bit worse
helical | 0.02 | 550 | 550 | 78.57 | +1.3 | moving down, still a bit worse
helical | 0.02 | 650 | 650 | 92.86 | +1.1 | getting closer
helical | 0.02 | 610 | 610 | 87.14 | +1.2 | about the same, try below 600
helical | 0.02 | 590 | 590 | 84.29 | +0.8 | getting closer
helical | 0.02 | 600 | 600 | 84.67 | +0.8 | getting closer
helical | 0.02 | 595 | 595 | 83.96 | +0.7 | best I could get
straight | 0.02 | 595 | 595 | 83.96 | 0 | just to make sure that straight plunging is still ok


  • Z shifting indeed occurs with helical plunging eventually
  • the values of X,Y,Z acceleration and junction deviation directly affect the amount of shifting
  • the ratio of X&Y to Z acceleration that performed best was the same as the X&Y to Z step/mm ratio
  • surprisingly small values of acceleration performed worse
  • straight plunging could care less :slight_smile:

Mystery solved. Thanks @SungeunJeon for pointing me to the right direction.

1 Like

Interesting. Your results are the exact opposite of what I was expecting, and trying to find a happy medium in your settings shouldn’t be required. I think there may be something else involved. Can you describe in detail what your machine is, provide your Grbl settings, give a link to the testing g-code you are running, and how you are running the test? I’d like to see if I can reproduce this on a bench.

Lastly, I’d like to get a clarification on what Z+ error means in your results. Does this mean that the Z-axis is physically higher than what’s reported in Grbl? Or is the Z-axis physically lower? It’s typically lower, but if it’s higher, that would be unusual.

Sorry for the late reply, I was away… Here’s the info requested.

My machine is a 500mm X-Carve with these mods.

I have also switched my Z
1:2 microstepping / 1:1 gearing / GT2 belt
1:1 microstepping / 1:2 gearing / GT3 belt (same $102, more torque)

The GRBL settings are:
$0=10 (step pulse, usec)
$1=255 (step idle delay, msec)
$2=0 (step port invert mask:00000000)
$3=3 (dir port invert mask:00000011)
$4=0 (step enable invert, bool)
$5=0 (limit pins invert, bool)
$6=0 (probe pin invert, bool)
$10=3 (status report mask:00000011)
$11=0.020 (junction deviation, mm)
$12=0.002 (arc tolerance, mm)
$13=0 (report inches, bool)
$20=1 (soft limits, bool)
$21=0 (hard limits, bool)
$22=1 (homing cycle, bool)
$23=3 (homing dir invert mask:00000011)
$24=25.000 (homing feed, mm/min)
$25=750.000 (homing seek, mm/min)
$26=250 (homing debounce, msec)
$27=1.000 (homing pull-off, mm)
$30=0. (rpm max)
$31=0. (rpm min)
$100=26.667 (x, step/mm)
$101=26.667 (y, step/mm)
$102=188.976 (z, step/mm)
$110=8000.000 (x max rate, mm/min)
$111=8000.000 (y max rate, mm/min)
$112=500.000 (z max rate, mm/min)
$120=595.000 (x accel, mm/sec^2)
$121=595.000 (y accel, mm/sec^2)
$122=83.960 (z accel, mm/sec^2)
$130=263.000 (x max travel, mm)
$131=314.000 (y max travel, mm)
$132=90.000 (z max travel, mm)

Here is the test gcode 1_waistboard_8.5mm_insert_13-14mm_deep.gcode (232.2 KB). This basically creates 4 holes for threaded inserts. With Z0 on the top of the workpiece, the deepest Z is Z-14 .

My testing process was as follows.

  • home and cancel offsets (G92.1)
  • go on top of front central hole
  • place a 20mm thick piece of MDF on the waistboard (any piece thicker than 14mm which is the deepest Z will allow “air cutting”)
  • probe on top of that piece of MDF and set Z to the thickness of the probe (G92)
  • check that Z0 barely touches the MDF
  • move Z up (to a predefined G30)
  • start air cutting
  • when done move to the same X,Y where the probing was initially done
  • place MDF on top of waistboard again
  • go to Z0
  • measure the gap between the MDF and the bit (with callipers when gap>2mm, with 0.1mm-step jogging when gap<=2mm)

To answer your last question, Z is physically higher (and creates a gap as mentioned above). I guess when missing downward steps while helically plunging makes GRBL think it is lower, while it is actually higher. Therefore, a Z0 takes the bit higher than the surface (the top of the MDF in the test).