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

Macro for "automatic" calibration of BL Touch

Scheduled Pinned Locked Moved
Gcode meta commands
11
20
3.5k
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.
  • undefined
    OwenD
    last edited by OwenD 12 Oct 2021, 21:15 14 Mar 2021, 04:23

    This macro uses variables so needs RRF3.3b2 or later.

    EDIT: Object model values for M558 are now stored in mm/min so no conversion necessary. - please used amended macro below which includes improvements and corrects some errors pointed out in this thread by other users.

    It prompts you to jog the nozzle to the bed and then runs 10 probe offset tests (this number is configurable as a variable)
    At the end, it discards the highest and lowest reading and averages the rest.
    You can then choose to save the result in config-overide.g

    ;Calibrate BL Touch
    ; Reprap firmware version 3.3b2 or later required!
    
    ; if two speed probing is configured in M558,we probably want to reduce the speed for this test
    var ProbeSpeedHigh = sensors.probes[0].speeds[0]*60 ; Speeds are saved in mm/sec in the object model but M558 uses mm/min
    var ProbeSpeedLow = sensors.probes[0].speeds[1]*60
    
    
    M558 F60 ; reduce probe speed to 60mm/min for accuracy - adjust F parameter as required
    
    ;define some variables to store readings
    
    var NumTests=10 ; modify this value to define number of tests
    
    ; Do not change below this line
    var RunningTotal=0
    var Average=0
    var Lowest=0
    var Highest=0
    
    
    ; If the printer hasn't been homed, home it
    if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
      G28
    else
    	G1 Z{sensors.probes[0].diveHeight} F360 ; if axes homed move to dive height
    
    M561 ; clear any bed transform
    
    M290 R0 S0 ; clear babystepping
    
    ; move nozzle to centre of bed
    G1 X{(move.axes[0].min + move.axes[0].max)/2} Y{(move.axes[1].min + move.axes[1].max)/2}
    
    M564 S0 H0 ; Allow movement beyond limits
    
    ;ensure you have room for the probe
    if move.axes[2].machinePosition < sensors.probes[0].diveHeight
    	G1 Z{sensors.probes[0].diveHeight}
    M280 P0 S160 I1 ; reset BL Touch
    G4 S0.5
    M98 P"0:/sys/retractprobe.g" ; Ensure probe is retracted & reset
    G4 S0.5
    M561 ; clear any bed transform
    ; Jog head to position
    M291 P"Jog nozzle to touch bed" R"Set nozzle to zero" S3 Z1
    
    G92 Z0 ; set Z position to zero
    M291 P"Press OK to begin" R"Ready?" S3;
    
    ; Move probe over top of same point that nozzle was when zero was set
    G1 Z{sensors.probes[0].diveHeight}; lift head
    G1 X{move.axes[0].machinePosition - sensors.probes[0].offsets[0]} Y{move.axes[1].machinePosition - sensors.probes[0].offsets[1]} F1800
    
    echo "Current probe offset = " ^ sensors.probes[0].triggerHeight ^ "mm"
    
    ; carry out 10 probes (or what is set in NumTests variable)
    
    while iterations < var.NumTests
    	G1 Z{sensors.probes[0].diveHeight} ; move to dive height
    	if sensors.probes[0].value[0]=1000 ; if probe is in error state
    		echo "Probe in error state- resetting"
    		M280 P0 S160 I1 ; reset BL Touch
    		G4 S0.5
    		M98 P"0:/sys/retractprobe.g" ; Ensure probe is retracted & reset
    		G4 S0.5
    	G30 S-1
    	M118 P2 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to Paneldue console
    	M118 P3 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to DWC console
    
    	if iterations == 0
    		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading to first probe height
    		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading to first probe height
    
    	if move.axes[2].machinePosition < var.Lowest
    		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading
    		;M118 P3 S{"new low reading = " ^ move.axes[2].machinePosition} ; send trigger height to DWC console
    		G4 S0.3
    	if move.axes[2].machinePosition > var.Highest
    		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading
    
    		;M118 P3 S{"new high reading = " ^ move.axes[2].machinePosition} ; send trigger height to DWC console
    		G4 S0.3
    	set var.RunningTotal={var.RunningTotal + move.axes[2].machinePosition} ; set new running total
    	;M118 P3 S{"running total = " ^ var.RunningTotal} ; send running total to DWC console
    	G4 S0.5
    set var.Average = {(var.RunningTotal - var.Highest - var.Lowest) / (var.NumTests - 2)} 	; calculate the average after discarding th ehigh & low reading
    
    ;M118 P3 S{"running total = " ^ var.RunningTotal} ; send running total to DWC console
    ;M118 P3 S{"low reading = " ^ var.Lowest} ; send low reading to DWC console
    ;M118 P3 S{"high reading = " ^ var.Highest} ; send high reading to DWC console
    M118 P2 S{"Average excluding high and low reading = " ^ var.Average} ; send average to PanelDue console
    M118 P3 S{"Average excluding high and low reading = " ^ var.Average} ; send average to DWC console
    
    G31 P500 Z{var.Average} ; set Z probe offset to the average reading
    M564 S0 H1 ; Reset limits
    M558 F{var.ProbeSpeedHigh}:{var.ProbeSpeedLow} ; reset probe speed to original
    G1 Z{sensors.probes[0].diveHeight} F360 ; move head back to dive height
    M291 P{"Trigger height set to : " ^ sensors.probes[0].triggerHeight  ^ " OK to save to config-overide.g, cancel to use until next restart"} R"Finished" S3
    M500 P31 ; optionally save result to config-overide.g
    
    undefined undefined undefined 3 Replies Last reply 14 Mar 2021, 09:28 Reply Quote 5
    • undefined
      o_lampe @OwenD
      last edited by o_lampe 14 Mar 2021, 09:28

      @OwenD said in Macro for "automatic" calibration of BL Touch:

      ; move nozzle to centre of bed
      G1 X{(move.axes[0].min + move.axes[0].max)/2} Y{(move.axes[1].min + move.axes[1].max)/2}

      That will be a pretty slooow move to the bed center, since the last 'F' param was F360.

      1 Reply Last reply Reply Quote 0
      • undefined
        bruce
        last edited by 14 Mar 2021, 10:07

        @OwenD if only I knew any of these are possible in a macro before today...

        1 Reply Last reply Reply Quote 0
        • undefined
          User3D @OwenD
          last edited by 17 Mar 2021, 04:32

          @OwenD

           
          ; move nozzle to centre of bed
          G1 X{(move.axes[0].min + move.axes[0].max)/2} Y{(move.axes[1].min + move.axes[1].max)/2}
           
          M564 S0 H0 ; Allow movement beyond limits
           
          ;ensure you have room for the probe
          if move.axes[2].machinePosition < sensors.probes[0].diveHeight
          	G1 Z{sensors.probes[0].diveHeight}
          

          wouldn't it be better to lift z up before moving nozzle to centre to prevent harm to both nozzle and bed...!!!!

          undefined 1 Reply Last reply 17 Mar 2021, 06:01 Reply Quote 0
          • undefined
            OwenD @User3D
            last edited by 17 Mar 2021, 06:01

            @User3D said in Macro for "automatic" calibration of BL Touch:

            @OwenD

             
            ; move nozzle to centre of bed
            G1 X{(move.axes[0].min + move.axes[0].max)/2} Y{(move.axes[1].min + move.axes[1].max)/2}
             
            M564 S0 H0 ; Allow movement beyond limits
             
            ;ensure you have room for the probe
            if move.axes[2].machinePosition < sensors.probes[0].diveHeight
            	G1 Z{sensors.probes[0].diveHeight}
            

            wouldn't it be better to lift z up before moving nozzle to centre to prevent harm to both nozzle and bed...!!!!

            @User3D
            And where do you suppose the nozzle is after this?

            ; If the printer hasn't been homed, home it
            
            if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
            
              G28
            
            else
            
            	G1 Z{sensors.probes[0].diveHeight} F360 ; if axes homed move to dive height
            

            If any axis is unhomed, it'll move to whatever you have in homeall.g
            Otherwise it'll move to dive height which is typically 5 or more mm from the bed.

            If the axis is homed but the nozzle is lower than dive height, it will be lifted to dive height in the section you quoted.

            I fail to see why you'd need to raise it further, but you can of course modify it to suit yourself.

            undefined 1 Reply Last reply 17 Mar 2021, 07:46 Reply Quote 0
            • undefined
              User3D @OwenD
              last edited by 17 Mar 2021, 07:46

              @OwenD said in Macro for "automatic" calibration of BL Touch:

              I fail to see why you'd need to raise it further, but you can of course modify it to suit yourself.

              I don't want it to be raised further. I said it considering case when axes are not homed. In this case , you home them all. If after homing , Z is at zero and you move X Y to centre then doing so might cause damage... thats all I meant!

              1 Reply Last reply Reply Quote 0
              • undefined
                OwenD
                last edited by OwenD 17 Mar 2021, 08:24

                @OwenD said in Macro for "automatic" calibration of BL Touch:

                ;Calibrate BL Touch

                Fair enough.
                Given that you need to be in front of the machine to set zero, that didn't raise as a concern as I wouldn't expect the nozzle to remain at zero at the end of homeall.g , but that scenario can easily be catered for by moving the check that the head is at or above dive height to before the move to the center of the bed.

                ;Calibrate BL Touch
                
                ; Reprap firmware version 3.3b2 or later required!
                
                 
                
                ; if two speed probing is configured in M558,we probably want to reduce the speed for this test
                
                var ProbeSpeedHigh = sensors.probes[0].speeds[0]*60 ; Speeds are saved in mm/sec in the object model but M558 uses mm/min
                
                var ProbeSpeedLow = sensors.probes[0].speeds[1]*60
                
                 
                
                 
                
                M558 F60 ; reduce probe speed to 60mm/min for accuracy - adjust F parameter as required
                
                 
                
                ;define some variables to store readings
                
                 
                
                var NumTests=10 ; modify this value to define number of tests
                
                 
                
                ; Do not change below this line
                
                var RunningTotal=0
                
                var Average=0
                
                var Lowest=0
                
                var Highest=0
                
                 
                
                 
                
                ; If the printer hasn't been homed, home it
                
                if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
                
                  G28
                
                else
                
                	G1 Z{sensors.probes[0].diveHeight} F360 ; if axes homed move to dive height
                
                 
                
                M561 ; clear any bed transform
                
                 
                
                M290 R0 S0 ; clear babystepping
                
                 ;ensure you have room for the probe
                
                if move.axes[2].machinePosition < sensors.probes[0].diveHeight
                
                	G1 Z{sensors.probes[0].diveHeight}
                
                ; move nozzle to centre of bed
                
                G1 X{(move.axes[0].min + move.axes[0].max)/2} Y{(move.axes[1].min + move.axes[1].max)/2}
                
                 
                
                M564 S0 H0 ; Allow movement beyond limits
                
                 
                
                
                
                M280 P0 S160 I1 ; reset BL Touch
                
                G4 S0.5
                
                M98 P"0:/sys/retractprobe.g" ; Ensure probe is retracted & reset
                
                G4 S0.5
                
                M561 ; clear any bed transform
                
                ; Jog head to position
                
                M291 P"Jog nozzle to touch bed" R"Set nozzle to zero" S3 Z1
                
                 
                
                G92 Z0 ; set Z position to zero
                
                M291 P"Press OK to begin" R"Ready?" S3;
                
                 
                
                ; Move probe over top of same point that nozzle was when zero was set
                
                G1 Z{sensors.probes[0].diveHeight}; lift head
                
                G1 X{move.axes[0].machinePosition - sensors.probes[0].offsets[0]} Y{move.axes[1].machinePosition - sensors.probes[0].offsets[1]} F1800
                
                 
                
                echo "Current probe offset = " ^ sensors.probes[0].triggerHeight ^ "mm"
                
                 
                
                ; carry out 10 probes (or what is set in NumTests variable)
                
                 
                
                while iterations < var.NumTests
                
                	G1 Z{sensors.probes[0].diveHeight} ; move to dive height
                
                	if sensors.probes[0].value[0]=1000 ; if probe is in error state
                
                		echo "Probe in error state- resetting"
                
                		M280 P0 S160 I1 ; reset BL Touch
                
                		G4 S0.5
                
                		M98 P"0:/sys/retractprobe.g" ; Ensure probe is retracted & reset
                
                		G4 S0.5
                
                	G30 S-1
                
                	M118 P2 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to Paneldue console
                
                	M118 P3 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to DWC console
                
                 
                
                	if iterations == 0
                
                		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading to first probe height
                
                		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading to first probe height
                
                 
                
                	if move.axes[2].machinePosition < var.Lowest
                
                		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading
                
                		;M118 P3 S{"new low reading = " ^ move.axes[2].machinePosition} ; send trigger height to DWC console
                
                		G4 S0.3
                
                	if move.axes[2].machinePosition > var.Highest
                
                		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading
                
                 
                
                		;M118 P3 S{"new high reading = " ^ move.axes[2].machinePosition} ; send trigger height to DWC console
                
                		G4 S0.3
                
                	set var.RunningTotal={var.RunningTotal + move.axes[2].machinePosition} ; set new running total
                
                	;M118 P3 S{"running total = " ^ var.RunningTotal} ; send running total to DWC console
                
                	G4 S0.5
                
                set var.Average = {(var.RunningTotal - var.Highest - var.Lowest) / (var.NumTests - 2)} 	; calculate the average after discarding th ehigh & low reading
                
                 
                
                ;M118 P3 S{"running total = " ^ var.RunningTotal} ; send running total to DWC console
                
                ;M118 P3 S{"low reading = " ^ var.Lowest} ; send low reading to DWC console
                
                ;M118 P3 S{"high reading = " ^ var.Highest} ; send high reading to DWC console
                
                M118 P2 S{"Average excluding high and low reading = " ^ var.Average} ; send average to PanelDue console
                
                M118 P3 S{"Average excluding high and low reading = " ^ var.Average} ; send average to DWC console
                
                 
                
                G31 P500 Z{var.Average} ; set Z probe offset to the average reading
                
                M564 S0 H1 ; Reset limits
                
                M558 F{var.ProbeSpeedHigh}:{var.ProbeSpeedLow} ; reset probe speed to original
                
                G1 Z{sensors.probes[0].diveHeight} F360 ; move head back to dive height
                
                M291 P{"Trigger height set to : " ^ sensors.probes[0].triggerHeight  ^ " OK to save to config-overide.g, cancel to use until next restart"} R"Finished" S3
                
                M500 P31 ; optionally save result to config-overide.g
                
                undefined 1 Reply Last reply 21 Jun 2021, 09:42 Reply Quote 1
                • undefined
                  jeloneal @OwenD
                  last edited by 21 Jun 2021, 09:42

                  @owend maybe it makes sense to preheat the nozzle near working temperature before probing? That would compensate for any heat expansion related discrepancies. At least I do that normally when setting Z-offset manually.

                  undefined 1 Reply Last reply 21 Jun 2021, 20:59 Reply Quote 0
                  • undefined
                    psychotik2k3 @jeloneal
                    last edited by 21 Jun 2021, 20:59

                    @jeloneal honnestly i just used that macro i think this is a good start to set up the bltouch parameter, and after that you jsut set the baby step to get correct adjustement.
                    i did it for my 3 tool heads on my printer

                    1 Reply Last reply Reply Quote 0
                    • littlehobbyshopundefined
                      littlehobbyshop
                      last edited by 4 Jul 2021, 19:50

                      I've only just discovered this and it works great, however the M564 command at the end needs to be changed to

                      M564 S1 H1
                      

                      Otherwise the printer can still be moved outside of the axis.

                      BLV MGN Cube w/Hemera, K8200, Sunlu S8

                      1 Reply Last reply Reply Quote 1
                      • undefined OwenD referenced this topic 8 Dec 2021, 18:55
                      • undefined
                        danzaywer @OwenD
                        last edited by 10 Dec 2021, 11:51

                        @owend said in Macro for "automatic" calibration of BL Touch:

                        var ProbeSpeedHigh = sensors.probes[0].speeds[0]*60 ; Speeds are saved in mm/sec in the object model but M558 uses mm/min var ProbeSpeedLow = sensors.probes[0].speeds[1]*60

                        Object model say mm/s but the stored value seems to be in mm/min

                        undefined 1 Reply Last reply 10 Dec 2021, 21:13 Reply Quote 0
                        • undefined
                          OwenD @danzaywer
                          last edited by 10 Dec 2021, 21:13

                          @danzaywer

                          The object model and config.g now save the probe speeds in mm/min, so no conversion is necessary.
                          Not sure when that changed.
                          Original version would have left probe speed at incorrect value until config.g was run again.

                          This is an amended version with corrections suggested by users above,

                          ;Calibrate BL Touch
                          ; Reprap firmware version 3.3b2 or later required!
                          
                          ; if two speed probing is configured in M558,we probably want to reduce the speed for this test
                          var ProbeSpeedHigh = sensors.probes[0].speeds[0] ; save currently configured speed for fast probe
                          var ProbeSpeedLow = sensors.probes[0].speeds[1] ; save currently configured speed for slow probe
                          
                          
                          M558 F60 ; reduce probe speed to 60mm/min for accuracy - adjust F parameter as required
                          
                          ;define some variables to store readings
                          
                          var NumTests=10 ; modify this value to define number of tests
                          
                          ; Do not change below this line
                          var RunningTotal=0
                          var Average=0
                          var Lowest=0
                          var Highest=0
                          
                          
                          ; If the printer hasn't been homed, home it
                          if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
                            G28
                          else
                          	G1 Z{sensors.probes[0].diveHeight} F360 ; if axes homed move to dive height
                          
                          M561 ; clear any bed transform
                          
                          M290 R0 S0 ; clear babystepping
                          
                          ; move nozzle to centre of bed
                          G1 X{(move.axes[0].min + move.axes[0].max)/2} Y{(move.axes[1].min + move.axes[1].max)/2} F3600
                          
                          M564 S0 H0 ; Allow movement beyond limits
                          
                          ;ensure you have room for the probe
                          if move.axes[2].machinePosition < sensors.probes[0].diveHeight
                          	G1 Z{sensors.probes[0].diveHeight}
                          M280 P0 S160 I1 ; reset BL Touch
                          G4 S0.5
                          M98 P"0:/sys/retractprobe.g" ; Ensure probe is retracted & reset
                          G4 S0.5
                          M561 ; clear any bed transform
                          ; Jog head to position
                          M291 P"Jog nozzle to touch bed" R"Set nozzle to zero" S3 Z1
                          
                          G92 Z0 ; set Z position to zero
                          M291 P"Press OK to begin" R"Ready?" S3;
                          
                          ; Move probe over top of same point that nozzle was when zero was set
                          G1 Z{sensors.probes[0].diveHeight}; lift head
                          G1 X{move.axes[0].machinePosition - sensors.probes[0].offsets[0]} Y{move.axes[1].machinePosition - sensors.probes[0].offsets[1]} F1800
                          
                          echo "Current probe offset = " ^ sensors.probes[0].triggerHeight ^ "mm"
                          
                          ; carry out 10 probes (or what is set in NumTests variable)
                          
                          while iterations < var.NumTests
                          	G1 Z{sensors.probes[0].diveHeight} ; move to dive height
                          	if sensors.probes[0].value[0]=1000 ; if probe is in error state
                          		echo "Probe in error state - resetting"
                          		M280 P0 S160 I1 ; reset BL Touch
                          		G4 S0.5
                          		M98 P"0:/sys/retractprobe.g" ; Ensure probe is retracted & reset
                          		G4 S0.5
                          	G30 S-1
                          	M118 P2 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to Paneldue console
                          	M118 P3 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ move.axes[2].machinePosition ^ "mm"} ; send trigger height to DWC console
                          
                          	if iterations == 0
                          		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading to first probe height
                          		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading to first probe height
                          
                          	if move.axes[2].machinePosition < var.Lowest
                          		set var.Lowest={move.axes[2].machinePosition} ; set the new lowest reading
                          		;M118 P3 S{"new low reading = " ^ move.axes[2].machinePosition} ; send trigger height to DWC console
                          		G4 S0.3
                          	if move.axes[2].machinePosition > var.Highest
                          		set var.Highest={move.axes[2].machinePosition} ; set the new highest reading
                          
                          		;M118 P3 S{"new high reading = " ^ move.axes[2].machinePosition} ; send trigger height to DWC console
                          		G4 S0.3
                          	set var.RunningTotal={var.RunningTotal + move.axes[2].machinePosition} ; set new running total
                          	;M118 P3 S{"running total = " ^ var.RunningTotal} ; send running total to DWC console
                          	G4 S0.5
                          set var.Average = {(var.RunningTotal - var.Highest - var.Lowest) / (var.NumTests - 2)} 	; calculate the average after discarding th ehigh & low reading
                          
                          ;M118 P3 S{"running total = " ^ var.RunningTotal} ; send running total to DWC console
                          ;M118 P3 S{"low reading = " ^ var.Lowest} ; send low reading to DWC console
                          ;M118 P3 S{"high reading = " ^ var.Highest} ; send high reading to DWC console
                          M118 P2 S{"Average excluding high and low reading = " ^ var.Average} ; send average to PanelDue console
                          M118 P3 S{"Average excluding high and low reading = " ^ var.Average} ; send average to DWC console
                          
                          ;suggest new G31 values
                          echo "suggested edit for G31 in config.g if not saved to config-overide.g"
                          echo "change G1 Z parameter from Z" ^ sensors.probes[0].triggerHeight 
                          echo "to Z" ^ var.Average
                          
                          G31 P500 Z{var.Average} ; set Z probe offset to the average reading
                          M564 S1 H1 ; Reset limits
                          M558 F{var.ProbeSpeedHigh}:{var.ProbeSpeedLow} ; reset probe speed to original
                          G1 Z{sensors.probes[0].diveHeight} F360 ; move head back to dive height
                          
                          M291 P{"Trigger height set to : " ^ sensors.probes[0].triggerHeight  ^ " OK to save to config-overide.g, cancel to use until next restart"} R"Finished" S3
                          M500 P31 ; optionally save result to config-overide.g
                          
                          undefined 1 Reply Last reply 11 Dec 2021, 06:02 Reply Quote 0
                          • undefined
                            zapta @OwenD
                            last edited by 11 Dec 2021, 06:02

                            @owend, do we have a place to collect those useful user contributed scripts?

                            undefined 1 Reply Last reply 11 Dec 2021, 11:02 Reply Quote 0
                            • undefined
                              OwenD @zapta
                              last edited by OwenD 12 Nov 2021, 11:41 11 Dec 2021, 11:02

                              @zapta
                              This section of the forum is for both posting macros and asking about conditional g-code and meta commands.
                              It is a little hard to "browse" though.

                              There are a couple of github repositories mentioned here
                              https://duet3d.dozuki.com/Wiki/Macros#Section_Repository

                              I have put most of my macros and associated printer config files here
                              https://github.com/owendare/RepRapFirmware-Macros

                              It would make sense to do pull requests to a single repository to allow people to find things easier.
                              file naming conflicts may arise and dependencies could be an issue in that instance.
                              edit: It looks like sub folders are created to avoid that

                              Phaedruxundefined 1 Reply Last reply 11 Dec 2021, 19:59 Reply Quote 1
                              • Phaedruxundefined
                                Phaedrux Moderator @OwenD
                                last edited by 11 Dec 2021, 19:59

                                @owend said in Macro for "automatic" calibration of BL Touch:

                                There are a couple of github repositories mentioned here
                                https://duet3d.dozuki.com/Wiki/Macros#Section_Repository

                                Those might be the most official ones to use.

                                I've been thinking of the best way to collect and share them on the forum. Having a dedicated forum section is one option, but then I think it would likely end up just being a duplicate of this forum section. So then I thought maybe having a more curated collection as a single pinned thread in this section with links to the thread for the individual macros. Or another option, maybe adding a section to the community projects section for gcode programs.

                                https://duet3d.dozuki.com/c/Community_Projects

                                What do you think?

                                Z-Bot CoreXY Build | Thingiverse Profile

                                undefined 1 Reply Last reply 11 Dec 2021, 20:40 Reply Quote 0
                                • undefined
                                  OwenD @Phaedrux
                                  last edited by 11 Dec 2021, 20:40

                                  @phaedrux
                                  A central GitHub repository such as that which is in place, seems on the surface to be suitable.
                                  Except that the ultimate goal of a repository is to merge all submissions into a single common code base.
                                  That's fine excepting for cases where there may be several different valid approaches to a task which require the file to have the same filename.
                                  Branches can cater to that somewhat bit become difficult for people to navigate to find what they want.
                                  Plus it creates just one more job that someone at Duet has to do (acting on pull requests etc)

                                  Perhaps contributors should just create their own repositories and they can be listed in community projects as you suggest?

                                  The ideal solution would be a browse-able directory tree where macros could be placed.
                                  At the top level would be links based on intended kinematics, category and description.
                                  But I can't think how to implement that without an FTP server and/or database , which opens up a whole other can of worms.

                                  The up side of the current situation (leaving it on the forum) is that it allows easy peer review and comments on submitted macros.
                                  This is probably worth the extra time it may take in finding what you want as there will inevitably be errors and revisions required for different reasons.
                                  New users will obviously be looking for drop-in solutions, but the reality is that there are to many variables in printer configuration and hardware to make any submitted macro more than a starting point that will require review and modification by them before use.
                                  Leaving it here probably forces them to learn more.

                                  undefined 1 Reply Last reply 11 Dec 2021, 22:27 Reply Quote 1
                                  • undefined
                                    zapta @OwenD
                                    last edited by zapta 12 Nov 2021, 22:27 11 Dec 2021, 22:27

                                    @owend, FYI, this is how the Voron community does it. A single github repository with a directory for each contributing user. Users can clone the repository, develop in their own copy and then submit a pull request to the maintainers.

                                    Users that don't want to deal with github can just submit their files to the maintainers.

                                    https://github.com/VoronDesign/VoronUsers/tree/master/printer_mods

                                    1 Reply Last reply Reply Quote 1
                                    • undefined
                                      OwenD
                                      last edited by OwenD 12 Dec 2021, 11:04

                                      I've revised the main macro yet again and submitted a pull request on the github repository.
                                      This mod is to allow parameters to be passed to it for speeds, nozzle & bed temps etc.
                                      This is shown in the macro call_calibrate.g
                                      If no parameters are passed or the macro is run directly, the default values will be used.

                                      I've also added some error & sanity checking.

                                      calling macro/command

                                      ; call_calibrate_BLtouch.g
                                      ; should be located in same folder as calibrate_BLtouch.g
                                      ; Reprap firmware version 3.3b2 or later required!
                                      ; If macro is called using parameters these will be used in testing
                                      ; If any parameters are omitted, the default values will be used.
                                      ; parameters which can be passed are
                                      ; T - Tool to use
                                      ; B - bed temperature to use
                                      ; R - Nozzle temperature to use (may be turned off before probing commences if configuerd to do so in config.g)
                                      ; P - probe number to use
                                      ; F -  X/Y travel speed to use (in mm/sec)
                                      var F = 80
                                      ; Z - Z travel speed to use
                                      var Z = 6
                                      ; S - Probe speed to use (in mm/sec)
                                      var S = 1
                                      ; I - Number of times to probe (high and low value will be discarded)
                                      ; the following variables are re-set at run time
                                      var R = 0
                                      var B = 0
                                      var T = 0
                                      var P = 0
                                      var maxBedTemp = floor(heat.heaters[heat.bedHeaters[0]].max) 
                                      var I = 10 ; default number of probes (two extra will be done and high/low discarded)
                                      var choice = 0
                                      M291 S5 R"Tool" P"Select Tool Number" L0 H{#tools-1} F0 J1
                                      set var.T = input
                                      var Heater = tools[var.T].heaters[0]
                                      var maxTemp = floor(heat.heaters[var.Heater].max)
                                      echo "maxTemp="^var.maxTemp
                                      var minTemp = floor(heat.coldExtrudeTemperature + 5)
                                      echo "minTemp="^var.minTemp
                                      M291 S4 R"Heat" P"Heat tool/bed ?" K{"None","Nozzle only","Bed only","Both",} F0 J1
                                      set var.choice = input
                                      if var.choice!=0
                                      	;echo "Heat choice " ^ var.choice
                                      	if (var.choice = 1) || (var.choice = 3)
                                      		;echo var.minTemp
                                      		;echo var.maxTemp
                                      		M291 S6 R"Nozzle temp" P"Set temperature for nozzle" L{var.minTemp} H{var.maxTemp} F{var.minTemp} J1
                                      		set var.R = floor(input)
                                      	if (var.choice = 2) || (var.choice = 3)
                                      		M291 S6 R"Bed temp" P"Set temperature for bed" L0 H{var.maxBedTemp} F40 J1
                                      		set var.B = floor(input)
                                      if #sensors.probes > 1
                                      	M291 S5 R"Probe" P"Select probe" L0 H{#sensors.probes-1} F0 J1
                                      	set var.P = input
                                      M291 S5 R"Cycles" P"Enter number of cycles to sample" L3 H22 F{var.I} J1
                                      set var.I = input + 2
                                      ;echo "M98 P0:/macros/bl_touch/calibrate_BLtouch.g B"^{var.B}^" T"^{var.T}^" R"^{var.R}^" P"^{var.P}^" F"^{var.F}^" Z"^{var.Z}^" S"^{var.S}^" I"^{var.I}
                                      
                                      if state.atxPower = false
                                      	M80
                                      G4 S1
                                      ; If the printer hasn't been homed, home it
                                      if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
                                      	echo "Homing - please wait"
                                      	G28
                                      	M400
                                      M98 P"0:/macros/bl_touch/calibrate_BLtouch.g" B{var.B} T{var.T} R{var.R} P{var.P} F{var.F} Z{var.Z} S{var.S} I{var.I}
                                      

                                      revised macro

                                      ;Calibrate BL Touch - (modified to use arrays.  requires RRF3.5b2 or later)
                                      ; If macro is called using parameters these will be used in testing
                                      ; parameters which can be passed are
                                      ; T - Tool to use
                                      ; B - bed temperature to use
                                      ; R - Nozzle temperature to use (may be turned off before probing commences if configuerd to do so in config.g by M558 B1)
                                      ; P - probe number to use
                                      ; F -  X/Y travel speed to use (in mm/sec)
                                      ; Z - Z travel speed to use
                                      ; S - Probe speed to use (in mm/sec)
                                      ; I - Number of times to probe (high and low value will be discarded)
                                      
                                      var NumTests = 10 ; modify this value to define default number of tests
                                      var travelSpeed = 3600 ; modify this value to define the default travel speed in mm/min
                                      var ZtravelSpeed = 360 ; modify this value to define default Z travel speed in mm/min (not probe speed)
                                      var probeSpeed = 60 ; modify this value to define default Z travel speed during probing in m/min
                                      var ProbePointX = (move.axes[0].min + move.axes[0].max)/2 ; modify to specify the X probe point.
                                      var ProbePointY = (move.axes[1].min + move.axes[1].max)/2 ; modify to specify the Y probe point.
                                      var ThisTool=0 ; default tool to use
                                      
                                      ; Do not change below this line
                                      
                                      if exists(param.T)
                                      	set var.ThisTool=param.T
                                      
                                      var bedTemp = 0 ; default to not heating bed
                                      if exists(param.B)
                                      	set var.bedTemp = param.B
                                      
                                      if !(var.bedTemp >=0) || (var.bedTemp > heat.heaters[heat.bedHeaters[0]].max)
                                      	abort "invalid bed temp - test aborted"
                                      
                                      var nozzleTemp = 0 ; default to not heating nozzle
                                      if exists(param.R)
                                      	if !exists(param.T)
                                      		abort "Nozzle temp set, but no tool specified"
                                      	set var.nozzleTemp = param.R
                                      
                                      if !(var.nozzleTemp >= 0) || (var.nozzleTemp > heat.heaters[tools[var.ThisTool].heaters[0]].max); validate temp
                                      	abort "Invalid nozzle temp - test aborted"
                                      
                                      var probeNumber = 0
                                      if exists(param.P)
                                      	set var.probeNumber = param.P
                                      
                                      if (var.probeNumber > #sensors.probes - 1) || (var.probeNumber < 0) ; validate probe number
                                      	echo "Invalid probe number (" ^ var.probeNumber ^ ") , test will be carried out using probe 0"
                                      	set var.probeNumber = 0
                                      
                                      if exists(param.I)
                                      	if param.I<=2
                                      		abort "I parameter must be > 2 - Test aborted"
                                      	else
                                      		set var.NumTests = param.I
                                      
                                      var probeResults = vector(var.NumTests,0)
                                      
                                      if exists(param.F)
                                      	set var.travelSpeed = param.F * 60
                                      
                                      if exists(param.Z)
                                      	set var.ZtravelSpeed = param.Z * 60
                                      
                                      if exists(param.S)
                                      	set var.probeSpeed = param.S * 60
                                      	if var.probeSpeed <=0 ; validate
                                      		set var.probeSpeed = 60 ; set to 1mm/sec if invalid parameter passed
                                      
                                      ; if two speed probing is configured in M558,we probably want to reduce the speed for this test
                                      var ProbeSpeedHigh = sensors.probes[0].speeds[0] ; save currently configured speed for fast probe
                                      var ProbeSpeedLow = sensors.probes[0].speeds[1] ; save currently configured speed for slow probe
                                      
                                      ; validate probe speed
                                      if var.probeSpeed > var.ProbeSpeedLow
                                      	var ErrorMsg = "Probe speed (" ^ var.probeSpeed ^ "mm/min) is set higher than defined in config.g (" ^ var.ProbeSpeedLow ^ "mm/min) Continue?"
                                      	M291 S3 R"Warning" P{var.ErrorMsg} 
                                      
                                      
                                      M558 F{var.probeSpeed} ; reduce probe speed for accuracy 
                                      
                                      
                                      var RunningTotal=0
                                      var Average=0
                                      
                                      
                                      if (var.nozzleTemp > 0) || (var.bedTemp > 0)
                                      	if exists(param.T)
                                      		if param.T > {#tools - 1}
                                      			abort "Invalid T parameter - cannot be higher than " ^ {#tools - 1}
                                      		T{var.ThisTool} ; select the tool passed
                                      	else 
                                      		T0 ; default to T0
                                      	if (var.nozzleTemp > 0)
                                      		M568 P{var.ThisTool} S{var.nozzleTemp} S{var.nozzleTemp} A2 ; set active temperatures for tool 
                                      	if (var.bedTemp > 0)
                                      		M140 H0 S{var.bedTemp}
                                      
                                      if state.gpOut[0].pwm<0.035 ; check if probe is already deployed
                                      	echo "Probe is already deployed - retracting"
                                      	M280 P0 S80 ; retract BLTouch
                                      	G4 S0.5
                                      
                                      if sensors.endstops[2].triggered ; check if probe is already triggered
                                      	echo "Probe is already triggered - resetting"
                                      	M280 P0 S160 ; reset BL Touch
                                      	G4 S0.5
                                      
                                      if sensors.probes[0].value[0]=1000 ; check if probe is in error state
                                      	echo "Probe in error state - resetting"
                                      	M280 P0 S160 I1 ; reset BL Touch
                                      	G4 S0.5
                                      	M280 P0 S80 ; retract BLTouch
                                      	G4 S0.5
                                      
                                      M561 ; clear any bed transform
                                      
                                      M290 R0 S0 ; clear babystepping
                                      
                                      ; If the printer hasn't been homed, home it
                                      if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed
                                      	echo "Homing - please wait"
                                      	G28
                                      	M400
                                      else
                                      	G1 Z{sensors.probes[0].diveHeights[0]} F{var.ZtravelSpeed} ; if axes homed move to dive height
                                      M400
                                      M291 P{"Press OK to move to probe point X" ^ floor(var.ProbePointX) ^ " Y" ^ floor(var.ProbePointY)} R"Ready?" S3;
                                      ; move nozzle to defined probe point
                                      G1 X{var.ProbePointX} Y{var.ProbePointY} F{var.travelSpeed}
                                      
                                      if (var.nozzleTemp > 0) || (var.bedTemp > 0)
                                      	echo "Waiting for temps to stabilise"
                                      	M116 ; wait for temps
                                      
                                      M564 S0 H0 ; Allow movement beyond limits
                                      
                                      ;ensure you have room for the probe
                                      if sensors.probes[0].lastStopHeight < sensors.probes[0].diveHeights[0]
                                      	G1 Z{sensors.probes[0].diveHeights[0]} F{var.ZtravelSpeed}
                                      	
                                      
                                      ; Notify user to jog nozzle to start position
                                      M291 P"Jog nozzle to touch bed" R"Set nozzle to zero" S3 Z1
                                      
                                      G92 Z0 ; set Z position to zero
                                      M291 P"Press OK to begin probing" R"Ready?" S3;
                                      
                                      ; Move probe over top of same point that nozzle was when zero was set
                                      G1 Z{sensors.probes[0].diveHeights[0]} F{var.ZtravelSpeed}; lift head
                                      G1 X{move.axes[0].machinePosition - sensors.probes[0].offsets[0]} Y{move.axes[1].machinePosition - sensors.probes[0].offsets[1]} F{var.travelSpeed}
                                      
                                      echo "Current probe offset = " ^ sensors.probes[0].triggerHeight ^ "mm"
                                      
                                      ; carry out 10 probes (or what is set in NumTests variable)
                                      
                                      while iterations < var.NumTests
                                      	G1 Z{sensors.probes[0].diveHeights[0]} F{var.ZtravelSpeed}; move to dive height
                                      		
                                      	if state.gpOut[0].pwm<0.035
                                      		echo "Probe ia already deployed - retracting"
                                      		M280 P0 S80 ; retract BLTouch
                                      		G4 S0.5
                                      	if sensors.endstops[2].triggered
                                      		echo "Probe ia already triggered - resetting"
                                      		M280 P0 S160 ; reset BL Touch
                                      		G4 S0.5
                                      	if sensors.probes[0].value[0]=1000 ; if probe is in error state
                                      		echo "Probe in error state - resetting"
                                      		M280 P0 S160 I1 ; reset BL Touch
                                      		G4 S0.5
                                      		M280 P0 S80 ; retract BLTouch
                                      		G4 S0.5
                                      	G30 S-1 ; do probe at current point
                                      	M118 P2 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ sensors.probes[0].lastStopHeight ^ "mm"} ; send trigger height to Paneldue console
                                      	M118 P3 S{"Test # " ^ (iterations+1) ^ " Triggered @ " ^ sensors.probes[0].lastStopHeight ^ "mm"} ; send trigger height to DWC console
                                      	set var.probeResults[iterations] = sensors.probes[0].lastStopHeight
                                      	set var.RunningTotal={var.RunningTotal + var.probeResults[iterations]} ; set new running total
                                      
                                      set var.Average = {(var.RunningTotal - max(var.probeResults) - min(var.probeResults)) / (var.NumTests - 2)} 	; calculate the average after discarding the high & low reading
                                      M118 P2 S{"Average excluding high and low reading = " ^ var.Average} ; send average to PanelDue console
                                      M118 P3 S{"Average excluding high and low reading = " ^ var.Average} ; send average to DWC console
                                      echo "High reading =", max(var.probeResults) , " : Low reading =", min(var.probeResults)
                                      echo "Trigger values: " , var.probeResults
                                      
                                      ;suggest new G31 values
                                      echo "suggested edit for G31 in config.g if not saved to config-overide.g"
                                      echo "change G31 Z parameter from Z" ^ sensors.probes[0].triggerHeight ^ " to Z" ^ var.Average
                                      
                                      G31 P500 Z{var.Average} ; set Z probe offset to the average reading
                                      M564 S1 H1 ; Reset limits
                                      M558 F{var.ProbeSpeedHigh}:{var.ProbeSpeedLow} ; reset probe speed to original
                                      G1 Z{sensors.probes[0].diveHeights[0]} F{var.ZtravelSpeed} ; move head back to dive height
                                      
                                      if var.bedTemp > 0
                                      	M140 R0 S0 ; set bed to zero
                                      	M140 S-276 ; turn off bed
                                      if (var.nozzleTemp > 0) && (state.currentTool >-1)
                                      	M568 R0 S0 ; set heater to zero
                                      	M568 A0 ; turn off heater on current tool
                                      
                                      M291 P{"Trigger height set to : " ^ sensors.probes[0].triggerHeight  ^ "mm. Press OK to save to config-overide.g, cancel to use until next restart"} R"Finished" S3
                                      M500 P31 ; optionally save result to config-overide.g
                                      
                                      M291 P{"Reload config.g to restore defaults?"} R"Restore?" S3
                                      M98 P"0:/sys/config.g"
                                      
                                      
                                      

                                      calibrate_BLtouch.g call_calibrate_BLtouch.g

                                      1 Reply Last reply Reply Quote 1
                                      • undefined
                                        SACRED SERPENT
                                        last edited by 21 Jun 2022, 01:53

                                        Im late to the party but how do i use this macro do i add it to the macro section or the config section ?

                                        undefined 1 Reply Last reply 21 Jun 2022, 08:47 Reply Quote 0
                                        • undefined
                                          OwenD @SACRED SERPENT
                                          last edited by 21 Jun 2022, 08:47

                                          @sacred-serpent
                                          You would typically put it in the macros folder

                                          1 Reply Last reply Reply Quote 0
                                          • undefined justGuner referenced this topic 16 Dec 2023, 22:16
                                          • First post
                                            Last post
                                          Unless otherwise noted, all forum content is licensed under CC-BY-SA