Automatic nozzle alignment of IDEX printer with probe
-
Hello everybody
I am looking for an automated solution to align the nozzle of both print heads of an IDEX printer in X & Y direction where the print heads determine their offsets themselves with the help of a probe, as shown here:
I have already found a couple of automated solutions like:
nudge by zruncho3d shown in the picture above (https://github.com/zruncho3d/nudge)
NozzleAlign Ball Probe by viesturz (https://github.com/viesturz/NozzleAlign)There are also some manual solutions like:
TAMV by Danal (https://github.com/HaythamB/TAMV?tab=readme-ov-file)
XY calibration tool by EmberPrototypes (https://www.emberprototypes.com/products/cxc)I have tested the calibration tool by EmberPrototypes and it works fine (much better than the calibration prints) but it's far from automated.
I wish to use either the nudge or the ball probe but both probes provide the code only for Klipper.
I wonder if anyone has managed to get them to work under RRF or if there exists another similar solution for Duet users?
Cheers
TechNiEdit: After further digging, maybe this can be coded relatively simply with M558 & M585?
-
@TechNi i'm working on macros for automated alignment using a ball probe in xy&z which is probably more complicated than needed for a pure IDEX.
I'm using an ember prototypes cxc mainly to help check the results - plus also probably to give a manual verification option.
happy to share what I come up with in case it is of use to you.
Thoughts so far here https://forum.duet3d.com/post/351387
-
@dwuk3d My current (not yet finished) macro if it is of any interest
;AlignXYZ.g ; G90 G1 U150 V290 F20000 G1 Z50 F1000 M98 P"0:/macros/FindProbeXY.g" M574 Z1 S2 K3; Set Z to Ball Probe G1 H4 Z{global.zHit} F300 if sensors.probes[3].value[0] = 0 echo "Probe not found" break ;G1 X235 Y179 F10000 G1 Z50 F1000 ; Find basic Z position var Zpos = {50,49,48,48,48} var Zrate = {300,200,100,80} var Xpos = {10,8,8,8,7} var Ypos = {10,8,8,8,7} var XYrate = {1000,800,300,100,100} var prev = false var pXM = 0 var pYM = 0 while iterations < 4 M574 Z1 S2 K3; Set Z to Ball Probe G90 G1 Z{var.Zpos[iterations]} F300 G91 G1 H4 Z-10 F{var.Zrate[iterations]} ;echo "Z", {move.axes[2].userPosition} var ZP = move.axes[2].userPosition G1 Z5 F5000 M574 Z1 S2 K0; configure Z axis endstop ; Now find X middle G91 G1 X{0-var.Xpos[iterations]} F5000 G90 G1 Z{var.ZP-0.2} F300 G91 M574 X1 S2 K3 G1 H4 X+10 F{var.XYrate[iterations]} ;echo "X1", {move.axes[0].userPosition} var X1 = move.axes[0].userPosition G1 Z5 F300 G1 X{var.Xpos[iterations]} F5000 G1 Z-5 F300 G1 H4 X-10 F{var.XYrate[iterations]} ;echo "X2", {move.axes[0].userPosition} var X2 = move.axes[0].userPosition G1 Z5 G90 var XM = (var.X1+var.X2)/2 ;echo "XM", {var.XM} G1 X{var.XM} M574 X1 S3 ; configure X axis endstop ; Now Y G91 G1 Y{0-var.Ypos[iterations]} F5000 G1 Z-5 F300 M574 Y1 S2 K3 G1 H4 Y+10 F{var.XYrate[iterations]} ;echo "Y1", {move.axes[1].userPosition} var Y1 = move.axes[1].userPosition G1 Z5 F300 G1 Y{var.Ypos[iterations]} F5000 G1 Z-5 F300 G1 H4 Y-10 F{var.XYrate[iterations]} ;echo "Y2", {move.axes[1].userPosition} var Y2 = move.axes[1].userPosition var YM = (var.Y1 + var.Y2) / 2 echo "G92 X"^{var.XM}, "Y"^{var.YM}, "Z"^{var.ZP}," ;---X1,2",{var.X1},{var.X2},"--Y1,2",{var.Y1},{var.Y2} echo "G92 U"^{var.XM}, "V"^{var.YM}, "Z"^{var.ZP+5} if (var.prev == true) echo "variation X:",{var.pXM-var.XM}, "V:", {var.pYM-var.YM} set var.pXM = var.XM set var.pYM = var.YM set var.prev = true if exists(global.ballProbeX) == false global ballProbeX = var.XM global ballProbeY = var.YM global ballProbeZ = var.ZP else set global.ballProbeX = var.XM set global.ballProbeY = var.YM set global.ballProbeZ = var.ZP G1 Z5 F300 G90 G1 X{var.XM} Y{var.YM} F2000 M574 Y1 S3 ; configure Y axis endstop G90
With find probe here
;FindProbeXY.g ; G90 G1 U150 V320 F20000 G1 Z50 F1000 G1 X235 Y170 F10000 if exists(global.zHit) == false global zHit = 44.5 ; See if already in correct position M574 Z1 S2 K3; Set Z to Ball Probe G1 H4 Z{global.zHit} F300 if sensors.probes[3].value[0] = 0 G1 Z50 F1000 G1 Y170 X230 F10000 G1 H4 Z{global.zHit} F300 if sensors.probes[3].value[0] = 1000 break M574 Z1 S2 K0; configure Z axis endstop var y = 150 M574 X1 S2 K3; Set Z ball to X while var.y<200 G1 H4 X270 F1000 if sensors.probes[3].value[0] = 1000 break G1 H4 Y{var.y+5} F1000 if sensors.probes[3].value[0] = 1000 break G1 H4 X230 F1000 if sensors.probes[3].value[0] = 1000 break set var.y = var.y + 10 G1 H4 Y{var.y} F1000 if sensors.probes[3].value[0] = 1000 break M574 X1 S3 ; configure X axis endstop back G1 Z50 F1000