Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    Automatic nozzle alignment of IDEX printer with probe

    Scheduled Pinned Locked Moved
    General Discussion
    2
    3
    261
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • TechNiundefined
      TechNi
      last edited by TechNi

      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:

      25841294-81be-44a9-9aa6-3f1fe6430a65-Probing.gif

      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
      TechNi

      Edit: After further digging, maybe this can be coded relatively simply with M558 & M585?

      dwuk3dundefined 1 Reply Last reply Reply Quote 1
      • dwuk3dundefined
        dwuk3d @TechNi
        last edited by

        @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

        dwuk3dundefined 1 Reply Last reply Reply Quote 0
        • dwuk3dundefined
          dwuk3d @dwuk3d
          last edited by

          @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
          
          
          
          
          
                  
          
          
          
          
          
          
          1 Reply Last reply Reply Quote 1
          • First post
            Last post
          Unless otherwise noted, all forum content is licensed under CC-BY-SA