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

    IDEX XY calibration by electrical nozzle contact

    Scheduled Pinned Locked Moved
    Tuning and tweaking
    m558
    3
    12
    951
    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.
    • NeoDueundefined
      NeoDue
      last edited by NeoDue

      @T3P3Tony Thanks a lot! I was not aware of that option yet. That would also save me from constantly resetting the tool offset.

      It seems my attempt is just at the right time for RRF to cope with it - I have the feeling I would probably have been more or less lost with previous versions, considering the amount of comands with a "new in RRF 3.x" remark I use 😉

      1 Reply Last reply Reply Quote 0
      • oliofundefined
        oliof
        last edited by

        There is also this

        https://youtu.be/YLhYf1itSuQ?si=-q-A4dsa06cgPxI6

        Starts at 9:15

        Macro is in the comments.

        <>RatRig V-Minion Fly Super5Pro RRF<> V-Core 3.1 IDEX k*****r <> RatRig V-Minion SKR 2 Marlin<>

        NeoDueundefined 1 Reply Last reply Reply Quote 1
        • NeoDueundefined
          NeoDue @oliof
          last edited by

          @oliof Thanks a lot! You might have saved me quite some work!

          I guess it is time to dig out some of my rusty knowledge of the french language this weekend 🙂

          oliofundefined 1 Reply Last reply Reply Quote 0
          • oliofundefined
            oliof @NeoDue
            last edited by

            @NeoDue if you use a precision metal washer instead of the block, you can use M675 as well. The trick in the video is using the piezo to measure contact which alleviates the need to put a lead to the nozzle for offset measuring.

            <>RatRig V-Minion Fly Super5Pro RRF<> V-Core 3.1 IDEX k*****r <> RatRig V-Minion SKR 2 Marlin<>

            NeoDueundefined 1 Reply Last reply Reply Quote 0
            • NeoDueundefined
              NeoDue @oliof
              last edited by NeoDue

              @oliof Thanks, yet another option - this command might make the whole process simpler than I expected 🙂
              My printer has already a quadratic cutout which is millled out of the PCB that is the heat bed. PCB milling is quite precise, so this should well qualify as a suitable cavity for M675 as it is. No block or washer needed 😉

              NeoDueundefined 1 Reply Last reply Reply Quote 1
              • NeoDueundefined
                NeoDue @NeoDue
                last edited by NeoDue

                @dc42 While working on the calibration code I just stumbled upon your comment from last year at https://forum.duet3d.com/post/272898 that M675 might become obsolete soon and that you might replace it with a macro.

                Just to make sure I do not try to ride an almost dead horse here: may I ask what the state of that decision is? If it will be replaced by a macro, I would try to implement that one directly into my code if you already happen to have it at hand.

                NeoDueundefined 1 Reply Last reply Reply Quote 0
                • NeoDueundefined
                  NeoDue @NeoDue
                  last edited by NeoDue

                  Just in case anyone is interested, here is the working solution:

                  ; XY calibration in a cavity that is normally covered by the print plate
                  
                  ; Variables
                  ; print plate thickness in variable "global.Druckplattendicke" needs to be defined before running the macro, e.g. in config.g
                  var Eintauchtiefe = 1          ; how deep the nozzle shall dive into the cavity
                  var Referenzwert_X = 0
                  var Referenzwert_Y = 0
                  var Hotend2_X = 0
                  var Hotend2_Y = 0
                  
                  G28 							; Home
                  
                  ; prepare printer - insert whatever you need here...
                  
                  ; heat up hotends and bed
                  M140 S60 						; heat up bed
                  T0 P0
                  M568 P0 S220 R220				; heat up Hotend 1
                  T1 P0
                  M568 P1 S220 R220				; heat up Hotend 2 auf 220°C 
                  T-1 P0
                  M116							; wait
                  
                  ; let the user clean the nozzles
                  G1 H2 X{move.axes[0].min+50} F3000 
                  G1 H2 U{move.axes[3].max-50} F3000 
                  M400								; wait
                  
                  ; Message
                  M291 "Please clean the nozzles" R"Notice" S3
                  
                  ; Move print heads back to their parking position
                  G1 H2 X{move.axes[0].min} F3000 	
                  G1 H2 U{move.axes[3].max} F3000 	
                  
                  
                  ; lift bed close to measuring level
                  G1 H2 Z5 F6000
                  
                  ; move hotend 1 to cavity and dive in
                  G1 H2 X0 Y0 F6000
                  M400
                  G1 H2 Z{-global.Druckplattendicke - var.Eintauchtiefe} F3000 
                  
                  ; begin reference measurement
                  T0 P0 						        ; activate tool 0
                  while iterations < 8				; measure 8 times in X
                  	M675 X R1 P0 F100
                  	M400
                  	set var.Referenzwert_X = var.Referenzwert_X + move.axes[0].machinePosition   ; save value
                  set var.Referenzwert_X = var.Referenzwert_X / 8 ; calculate final reference value
                  	
                  while iterations < 8				; measure 8 times in Y	
                  	M675 Y R1 P0 F100 
                  	M400
                  	set var.Referenzwert_Y = var.Referenzwert_Y + move.axes[1].machinePosition    save value
                  set var.Referenzwert_Y = var.Referenzwert_Y / 8 ; calculate final reference value
                  
                  ; move back hotend 1
                  G1 H2 Z2 F6000  
                  M400
                  G1 H2 X{move.axes[0].min} F6000
                  
                  ; delete old offset from hotend 2:
                  G10 P1 U0 Y0
                  
                  ; move hotend 1 to cavity and dive in
                  G1 H2 U0 Y0 F6000
                  M400
                  G1 H2 Z{-global.Druckplattendicke - var.Eintauchtiefe} F3000
                  
                  
                  ; measure with hotend 2
                  T1 P0 						        ; activate tool 1
                  
                  while iterations < 8				; measure 8 times in U
                  	M675 U R1 P1 F100 
                  	M400
                  	set var.Hotend2_X = var.Hotend2_X + move.axes[3].machinePosition   ; save data
                  set var.Hotend2_X = var.Hotend2_X / 8 ; ... and calculate final value
                  
                  while iterations < 8				; measure 8 times in Y
                  	M675 Y R1 P1 F100
                  	M400
                  	set var.Hotend2_Y = var.Hotend2_Y + move.axes[1].machinePosition   ; save data
                  set var.Hotend2_Y = var.Hotend2_Y / 8    ; ... and calculate final value
                  
                  ; define new offset  and save it to a file that is read from config.g:     
                  G10 P1 U{var.Referenzwert_X - var.Hotend2_X} Y{var.Referenzwert_Y - var.Hotend2_Y}
                  echo >"Korrekturwert_xy_offset_tool1.g" "G10 P1 U"^{var.Referenzwert_X - var.Hotend2_X}^" Y"^{var.Referenzwert_Y - var.Hotend2_Y}^""
                  
                  ; bring printer back to idle state
                  T0 P0                                               
                  G1 H2 Z5 F6000						
                  G1 H2 U{move.axes[3].max} Y{move.axes[1].min} F3000 	
                  G1 Z120 F6000 
                  M568 P0 S0 R0
                  M568 P1 S0 R0
                  M140 S0
                  
                  ; notify user
                  M291 S2 P"XY-Offset of right Hotend is has been saved!"
                  

                  (edit: added remark, removed unused variables)

                  oliofundefined 1 Reply Last reply Reply Quote 2
                  • oliofundefined
                    oliof @NeoDue
                    last edited by

                    @NeoDue great stuff! You should consider some way to filter out outliers in your 8 runs (use median or just track lowest/highest and reject runs where the difference is greater than some value you deem an acceptable range).

                    <>RatRig V-Minion Fly Super5Pro RRF<> V-Core 3.1 IDEX k*****r <> RatRig V-Minion SKR 2 Marlin<>

                    NeoDueundefined 2 Replies Last reply Reply Quote 0
                    • NeoDueundefined
                      NeoDue @oliof
                      last edited by

                      @oliof That is a great idea, especially for the reference value! But for now, I have no clue on how to that in RRF. I would have to do the measurements, save them all and then do some comparison... before I dig into whatever an internet research might yield on this topic: do you happen to have some more information on how to do this with the basic math RRF offers?

                      1 Reply Last reply Reply Quote 0
                      • NeoDueundefined
                        NeoDue @oliof
                        last edited by NeoDue

                        @oliof said in IDEX XY calibration by electrical nozzle contact:

                        @NeoDue great stuff! You should consider some way to filter out outliers in your 8 runs (use median or just track lowest/highest and reject runs where the difference is greater than some value you deem an acceptable range).

                        @oliof Now I finally had the time to dust off and actually use a bit of my old statistics knowledge... Got it 🙂 - here is a test macro that removes outliers from a given array based on their z-score:

                        ; constraints out of experience: 
                        ; - electrical nozzle contact never gets activated too soon (=> too low values will never happen and are not taken into account here)
                        ;   if that does not apply, a lower acceptance limit for the z-score needs to be defined as well
                        ; - values that are too high are usually at least 0.15...0.2mm off
                        var Referenzwert = {1,1.02,1.05,1.2,1.22,1.3,1.01,}  ; test values - the three values that are too high need to be detected and removed from the mean value
                        var Referenzmittelwert = 0.0
                        var Referenzstandardabw = 0.0
                        var ReferenzZScore = vector(#var.Referenzwert,null)
                        var ZScoregrenze = 0.5
                        var Anzahlgueltig = 0
                        
                        ; calculate mean value
                        while iterations < #var.Referenzwert
                            set var.Referenzmittelwert = var.Referenzmittelwert + var.Referenzwert[iterations]
                        set var.Referenzmittelwert = var.Referenzmittelwert / #var.Referenzwert
                        
                        ; calculate standard deviation
                        while iterations < #var.Referenzwert
                            set var.Referenzstandardabw = var.Referenzstandardabw + (var.Referenzwert[iterations] - var.Referenzmittelwert) * (var.Referenzwert[iterations] - var.Referenzmittelwert)
                        set var.Referenzstandardabw = sqrt(var.Referenzstandardabw / (#var.Referenzwert - 1))
                        
                        ; calculate z-score of each measurement value
                        while iterations < #var.Referenzwert
                            set var.ReferenzZScore[iterations] = (var.Referenzwert[iterations] - var.Referenzmittelwert) / var.Referenzstandardabw
                        
                        ; re-calculate mean value without detected outliers 
                        set var.Referenzmittelwert = 0
                        while iterations < #var.Referenzwert
                            if var.ReferenzZScore[iterations] < var.ZScoregrenze
                                set var.Referenzmittelwert = var.Referenzmittelwert + var.Referenzwert[iterations]
                                set var.Anzahlgueltig = var.Anzahlgueltig + 1
                        set var.Referenzmittelwert = var.Referenzmittelwert / var.Anzahlgueltig
                        
                        echo var.Referenzmittelwert
                        

                        While I do not use that for XY calibration (at least yet - that one works perfectly well as it is so far...), I did add it to the two macros I wrote for z calibration and z-leveling of the U axis relative to the X axis. It definitely makes sense there since slight drops of filament coming out of the nozzle can cause errors.

                        1 Reply Last reply Reply Quote 2
                        • First post
                          Last post
                        Unless otherwise noted, all forum content is licensed under CC-BY-SA