Unsolved Z-axis / tramming issues with 3.6.0-alpha2+3
-
My bed.g is pretty basic but am posting just i case it helps..
bed.g -
;------------------------------------------------------------------------------- ; MoveZStepper Macro ;------------------------------------------------------------------------------- ; Moves one Z stepper independently, for manual, coarse tramming. Creates ; (or reuses) an A axis for the purpose, then hides it when done. ; ; Parameters: ; N Stepper number (default: 7) ; Z Distance. which may be negative to move up (default: 1) ; S Speed (default: 150) ;------------------------------------------------------------------------------- ; Don Stauffer July, 2024 ;------------------------------------------------------------------------------- ;if global.DebugLevel >= 1200 ; var This = "MoveZStepper" ; set var.This = var.This^(exists(param.N) ? " N"^param.N : "") ; set var.This = var.This^(exists(param.Z) ? " Z"^param.Z : "") ; set var.This = var.This^(exists(param.S) ? " S"^param.S : "") ; echo var.This ;------------------------------------------------------------------------------- ; Parameters ;------------------------------------------------------------------------------- var StepperNum = (exists(param.N) ? param.N : 7) var Distance = (exists(param.Z) ? param.Z : 1) var Speed = (exists(param.S) ? param.S : 150) ;------------------------------------------------------------------------------- ; Echo back what will be done ;------------------------------------------------------------------------------- echo "Moving Z stepper", var.StepperNum, "by", var.Distance ;------------------------------------------------------------------------------- ; Create A axis if necessary; make it visible if it already exists ;------------------------------------------------------------------------------- var DoesAAxisExist = false while iterations < #move.axes if move.axes[iterations].letter != "A" continue set var.DoesAAxisExist = true break if var.DoesAAxisExist M584 P4 M584 A{var.StepperNum} ;------------------------------------------------------------------------------- ; Configuration adapted from config.g. Not sure if everything is needed here ;------------------------------------------------------------------------------- M669 K1 ; CoreXY mode M350 A16 I1 ; 16x microstepping for axes & extruder, w/interpolation M574 A1 S2 ; Set Endstop configuration (P"pin_name"); S2 = Z probe M906 A1500 I60 ; Set motor currents (mA) M203 A{var.Speed} ; Maximum speeds (mm/min) M566 A12 ; Jerk M201 A90 ; Max acceleration M208 A635 ; Set axis maxima & high homing switch positions M208 A-0.5 S1 ; Set axis minima & low homing switch positions M92 A3200 ; Steps/mm ;------------------------------------------------------------------------------- ; Move the Z stepper as the "A axis" ;------------------------------------------------------------------------------- G91 G1 A{var.Distance} H2 ;------------------------------------------------------------------------------- ; Reset everything back to the same as config.g ;------------------------------------------------------------------------------- M584 X0 Y1 Z5:6:7 ; Map Z to drivers 5, 6, 7. M669 K1 ; CoreXY mode M350 Z16 I1 ; 16x microstepping for axes & extruder, w/interpolation M574 Z1 S2 ; Set Endstop configuration (P"pin_name"); S2 = Z probe M906 Z1500 I60 ; Set motor currents (mA)M203 Z600 M203 Z600 ; Maximum speeds (mm/min) M566 Z12 ; Jerk M201 Z90 ; Max acceleration M208 Z635 ; set axis maxima & high homing switch positions M208 Z-0.5 S1 ; set axis minima & low homing switch positions M92 Z3200 ; Steps/mm ;------------------------------------------------------------------------------- ; Hide A-axis by setting number of visible axes back to 3 ;------------------------------------------------------------------------------- M584 P3 ;------------------------------------------------------------------------------- ;if global.DebugLevel >= 1200 ; echo "Leaving MoveZStepper" ;-------------------------------------------------------------------------------
-
@gloomyandy If you tell me the procedure I'll revert and then test it.
It's possible that the direction problem is that when a negative adjustment is needed, it does a positive adjustment. That does happen. I don't know if it happens the other way around, but I have seen this.
-
@DonStauffer @Exerqtor @edsped thanks for reporting this. I'm sorry for any damage caused.
I don't have a system with multiple Z motors that I can test on, but I think I know what is causing this. It's to do with getting the motor direction wrong when switching between normal Z moves and leadscrew adjustment moves. Please can you identify for me which of the following is happening:
- When the first bed tramming move is executed, some of the motors move in the wrong direction.
- Immediately after the first bed tramming move is executed, when executing a normal Z move (which could be part of a new G32 probing sequence), some of the the Z motors move in the wrong direction.
- Both of the above.
If the main problem is #2 then a workaround for now might be to insert M400 after the G32 call, to ensure motion stops before another Z move is executed.
-
@dc42 said in Z-axis / tramming issues with 3.6.0-alpha2+3:
@DonStauffer @Exerqtor @edsped thanks for reporting this. I'm sorry for any damage caused.
It's part of the course with testing pre-release stuff imo! Win some loose some
😅
I don't have a system with multiple Z motors that I can test on, but I think I know what is causing this. It's to do with getting the motor direction wrong when switching between normal Z moves and leadscrew adjustment moves. Please can you identify for me which of the following is happening:
- When the first bed tramming move is executed, some of the motors move in the wrong direction.
- Immediately after the first bed tramming move is executed, when executing a normal Z move (which could be part of a new G32 probing sequence), some of the the Z motors move in the wrong direction.
- Both of the above.
If the main problem is #2 then a workaround for now might be to insert M400 after the G32 call, to ensure motion stops before another Z move is executed.
Well, when I think back the first time it happened for me was during the Z homing routine before tramming start. I think it was between one of the "tolerance" moves when doing G30. Did the first move, went to lower the bed to specified dive height, but rather than switching over the two front axis to rise up again to "engage" the second probe once dive height was reached they contiuned on a downwards motion.
The other times it happened it seemd to apply the axis adjustements wronlgy (in 1 or all axis) when it was done with the G30 moves for tramming.
If that made sense?
-
@dc42 I have not had bed tramming without one of the motors going the wrong direction since installing alpha 2. I will have to test for #2. I don't think I've seen it but I wasn't looking for it.
-
@edsped Here's my bed.g, and the DefineBed macro you have to run to create the global Bed variable it uses for the data points:
;------------------------------------------------------------------------------- ; bed.g ;------------------------------------------------------------------------------- ; Bed leveling macro. ;------------------------------------------------------------------------------- ; Don Stauffer July, 2024 ;------------------------------------------------------------------------------- ; Subscript Constants ;------------------------------------------------------------------------------- var LEV = 1 ;------------------------------------------------------------------------------- ; Other Constants ;------------------------------------------------------------------------------- var ITERATION_COUNT_MAX = 15 var ERR_ALLOWED = 0.005 ;------------------------------------------------------------------------------- ; Clear any existing bed transform and move up ;------------------------------------------------------------------------------- M561 G1 H2 Z5 ;------------------------------------------------------------------------------- ; Start NeoPixel progress meters ;------------------------------------------------------------------------------- ;M98 P"0:/macros/Lights/NeoPixel/Progress/BedLeveling/StartProgressMeters" E{var.ERR_ALLOWED} ;------------------------------------------------------------------------------- ; Iteratively attempt to level the bed ;------------------------------------------------------------------------------- var Raw = null var Abs = null var Sign = null var x = null var y = null var z = null var Err = pow(2, 31) ; "infinity" while iterations < var.ITERATION_COUNT_MAX && var.Err > var.ERR_ALLOWED ;--------------------------------------------------------------------------- ; Retrieve and probe the points ;--------------------------------------------------------------------------- while iterations < #(global.Bed[var.LEV]) ;----------------------------------------------------------------------- ; Decode probe point coordinates ;----------------------------------------------------------------------- set var.Raw = mod(global.Bed[var.LEV][iterations], pow(2, 15)) set var.Abs = mod(var.Raw, pow(2, 14)) set var.Sign = floor((var.Raw - var.Abs) / pow(2, 14) + 0.5) set var.x = var.Abs * (1 - var.Sign * 2) set var.Raw = floor((global.Bed[var.LEV][iterations]-var.Raw)/pow(2, 15)+ 0.5) set var.Abs = mod(var.Raw, pow(2, 14)) set var.Sign = floor((var.Raw - var.Abs) / pow(2, 14) + 0.5) set var.y = var.Abs * (1 - var.Sign * 2) ;----------------------------------------------------------------------- ; Moving this way updates move.axes[i].userPosition faster ; (Important for NeoPixel progress meter for index) ;----------------------------------------------------------------------- set var.z =sensors.probes[0].diveHeights[0]-sensors.probes[0].offsets[2] ;----------------------------------------------------------------------- ; Probe the point ;----------------------------------------------------------------------- if iterations == #(global.Bed[var.LEV]) - 1 G30 P{iterations} X{var.x} Y{var.y} Z-99999 S3 ;G30 P{iterations} X{var.x} Y{var.y} Z-99999 S{#(global.Bed[var.LEV])} else G30 P{iterations} X{var.x} Y{var.y} Z-99999 ;--------------------------------------------------------------------------- ; Calculate the error sum ;--------------------------------------------------------------------------- set var.Err = abs(move.calibration.initial.mean) set var.Err = var.Err + move.calibration.initial.deviation if global.DebugLevel > 1000 echo "Error="^var.Err,"Mean="^move.calibration.initial.mean,"Dev="^move.calibration.initial.deviation if var.Err > var.ERR_ALLOWED echo "Leveling didn't converge;",var.ITERATION_COUNT_MAX,"tries. Error="^var.Err else echo "Leveling converged. Error="^var.Err ;------------------------------------------------------------------------------- ; Move to center (necessary for NeoPixel progress meters to detect done) ;------------------------------------------------------------------------------- G53 G1 X150 Y150 F9000 ;------------------------------------------------------------------------------- ; Wait for NeoPixel progress mweter processes to end themselves ;------------------------------------------------------------------------------- ;M98 P"0:/macros/Lights/NeoPixel/Progress/WaitForEnd"
;------------------------------------------------------------------------------- ; DefineBed Macro ;------------------------------------------------------------------------------- ; Initializes global.Bed. ; global.Bed[var.LEV] contains the 3 probe points for bed leveling, encoded ; as bitmaps to save memory. ; ; This is intended to be called from config.g. ; ; The X and Y coordinates of each point are compressed into a single integer ; for memory conservation. The decoding routine is at the bottom of this file. ;------------------------------------------------------------------------------- ; Don Stauffer July, 2024 ;------------------------------------------------------------------------------- ;if global.DebugLevel >= 1200 ; echo "DefineBed" ;------------------------------------------------------------------------------- ; Subscript Constants ;------------------------------------------------------------------------------- var HTR = 0 var OM = 0 ;var STATE = 1 var LEV = 1 ;------------------------------------------------------------------------------- ; Create global.Bed if necessary ;------------------------------------------------------------------------------- if !exists(global.Bed) global Bed = vector(2, null) set global.Bed[var.HTR] = vector(2, null) set global.Bed[var.LEV] = vector(3, null) ;------------------------------------------------------------------------------- ; Define probe points for bed leveling; bitmap encode to save memory ;------------------------------------------------------------------------------- var x = {10, 10, 265} var y = {12, 228, 100} while iterations < 3 ;--------------------------------------------------------------------------- ; Encode x and y coordinates into a single integer ;--------------------------------------------------------------------------- var xEnc = abs(var.x[iterations]) + (var.x[iterations] < 0 ? pow(2, 14) : 0) var yEnc = abs(var.y[iterations]) * pow(2, 15) set var.yEnc = var.yEnc + (var.y[iterations] < 0 ? pow(2, 29) : 0) set global.Bed[var.LEV][iterations] = var.xEnc + var.yEnc ;------------------------------------------------------------------------------- ; Set up bed heater information ;------------------------------------------------------------------------------- while iterations < #heat.bedHeaters if heat.bedHeaters[iterations] != -1 set global.Bed[var.HTR][var.OM] = iterations break ;------------------------------------------------------------------------------- ;if global.DebugLevel >= 1200 ; echo "Leaving DefineBed" ;------------------------------------------------------------------------------- M99 ;------------------------------------------------------------------------------- ; To decode bitmap-encoded probe points: ;------------------------------------------------------------------------------- while iterations < 3 var P = global.Bed[var.LEV][iterations] var xRaw = mod(var.P, pow(2, 15)) var yRaw = floor((var.P - var.xRaw) / pow(2, 15) + 0.5) var xAbs = mod(var.xRaw, pow(2, 14)) var yAbs = mod(var.yRaw, pow(2, 14)) var xSign = floor((var.xRaw - var.xAbs) / pow(2, 14) + 0.5) var ySign = floor((var.yRaw - var.yAbs) / pow(2, 14) + 0.5) var xDec = var.xAbs * (1 - var.xSign * 2) var yDec = var.yAbs * (1 - var.ySign * 2) echo "("^var.xDec^",", var.yDec^")"
-
Just slapped together a stripped down
bed.g
, hopefully i get time to test it either today or tomorrow. -
@dc42 Here are my testing results.
In bed.g, I inserted immediately after my first G30:
G1 Z25 F75 M99
Then I homed and did a G32. Nothing that happened was unexpected. The motors all ran in the correct direction. So the only issue I can confirm is that the adjustment when the G30 with the S parameter executes goes in the wrong direction for one of the motors - and not always the same one. Initially it was #7. Then when I did my "manual" tramming with bed.g doing S-1 to report the correct adjustments, it was #6. I did that manual tramming over and over, making very conservative adjustments, and throughout several hours it remained #6. But it absolutely was a different motor than the problem started on. And there's no doubt it isn't just a simple reversal - it's conditional, only apparently happening on the G30 S adjustments.
So, my answer is "neither #1 nor #2".
-
Switched back to 3.6 alpha 2 +3 and for me at least it looks like it's applying the the leadscrew adjustments in the wrong direction. If you look at my screenshot the offsets pretty much double on each iteration. Note, for the initial print adjustments were similar to what I got on 3.5.2 but G32 after the print gave the wonky adjustments.
Disregard the bed.g warnings I inadvertently hit save when exiting out of the editor.
-
@edsped Running a second tram immediately following the above resulted in my front left leadscrew ending ~4mm higher than the other two... FWIW, the front left side of my bed is also where my nozzle crashed due to that corner of the bed being too high. I should clarify, higher on my printer is actually - Z
Edit:
Powered down and back up and now get the following on G32...8/3/2024, 4:38:57 PM Error: Compensation or calibration cancelled due to probing errors
8/3/2024, 4:38:52 PM Error: G30: Probe was not triggered during probing move -
@edsped Interesting. I was only having one of the three go in the wrong direction.
-
@DonStauffer That's what mine was doing the first time. I reverted to 3.5.2 then back to 3.6 a2+3 and added the M400 as suggested by @dc42 and what I posted above are my results. This time knowing what I was looking for I was able to bail before anything bad happened.
-
Currently, after performing probing a bed tramming move is executed with all Z motors moving simultaneously in different amounts and a mixture of directions. Would there be any problem if the Z motor moves were executed one at a time sequentially instead?
-
@dc42 Could this in some situations cause a nozzle strike? I'm thinking of a situation with a very highly tilted bed and homing/probing in the middle portion of the bed, you could in theory end up with the nozzle lower then one edge of the bed and if you then raise the (currently) lower edge first the bed would hit the nozzle? The same situation with a simultaneous move may not cause the strike? Probably not very likely though.
Possible mitigating actions: Perform any negative (moving the bed away from the nozzle) moves first? Limit the distance each motor moves in one operation and cycle through the motors until the move is complete?
-
@gloomyandy said in Z-axis / tramming issues with 3.6.0-alpha2+3:
ould this in some situations cause a nozzle strike? I'm thinking of a situation with a very highly tilted bed and homing/probing in the middle portion of the bed, you could in theory end up with the nozzle lower then one edge of the bed and if you then raise the (currently) lower edge first the bed would hit the nozzle?
If the probe had to make a deeper than normal move ton reach the lower edge, it will still rise to the dive height above the Z=0 reference afterwards. So I don't think this is a risk, provided that the maximum permitted correction is less than the dive height - which already needs to be the case if nozzle strikes are to be avoided.
-
@dc42 said in Z-axis / tramming issues with 3.6.0-alpha2+3:
Currently, after performing probing a bed tramming move is executed with all Z motors moving simultaneously in different amounts and a mixture of directions. Would there be any problem if the Z motor moves were executed one at a time sequentially instead?
@gloomyandy said in Z-axis / tramming issues with 3.6.0-alpha2+3:
@dc42 Could this in some situations cause a nozzle strike? I'm thinking of a situation with a very highly tilted bed and homing/probing in the middle portion of the bed, you could in theory end up with the nozzle lower then one edge of the bed and if you then raise the (currently) lower edge first the bed would hit the nozzle? The same situation with a simultaneous move may not cause the strike? Probably not very likely though.
Possible mitigating actions: Perform any negative (moving the bed away from the nozzle) moves first? Limit the distance each motor moves in one operation and cycle through the motors until the move is complete?
I don't know if this is possible, but is it possible to do it sequentially like you are proposing, but RRF "automatically" choose which axis/stepper to move 1st, 2nd, 3rd, etc. depending on the specified adjustmen that has to be made (taking my drive mapping as example)?
; (While looking at the printer top down) ; 0.0-----0.1 ; | 0.2 | ; |-------| ; |0.3|0.4| ; ---+--- ; Front ; Driver 0.1 & 0.2 is for the CoreXY motion, 0.2-0.4 is for the bed kinematics.
Example 1:
Adjustments needed after probing:- Driver
0.2
= -0.5mm - Driver
0.3
= -0.2mm - Driver
0.4
= +0.9mm
To avoid potential nozzle craches RRF will move the driver/axis that needs to adjust TOWARDS the nozzle last, and the driver/axis that needs to move the most AWAY from the nozzle first:
- Lower driver
0.4
by 0.9mm. - Raise driver
0.3
by 0.2mm. - Raise driver
0.2
by 0.5mm.
This should both put the least mechanical strain on the bed (depending on how the bed is built ofc.), and it would provide maximal clearance to the nozzle.
Example 2:
Adjustments needed after probing:- Driver
0.2
= +3.7mm - Driver
0.3
= -0.3mm - Driver
0.4
= +1.1mm
Adjustment order:
- Lower driver
0.2
by 3.7mm. - Lower driver
0.4
by 1.1mm. - Raise driver
0.3
by 0.3mm.
- Driver
-
@Exerqtor that's a good idea.
-
@Exerqtor said in Z-axis / tramming issues with 3.6.0-alpha2+3:
To avoid potential nozzle craches RRF will move the axis the driver/axis that needs to adjust TOWARDS the nozzle last, and the driver/axis that needs to move the most AWAY from the nozzle first:
Yes that's what I was suggesting with:
@gloomyandy said in Z-axis / tramming issues with 3.6.0-alpha2+3:
Possible mitigating actions: Perform any negative (moving the bed away from the nozzle) moves first
-
@dc42 Got any builds I/we could test incorporating this commit?