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.
    • OwenDundefined
      OwenD
      last edited by OwenD

      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
      
      o_lampeundefined User3Dundefined danzaywerundefined 3 Replies Last reply Reply Quote 5
      • o_lampeundefined
        o_lampe @OwenD
        last edited by o_lampe

        @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
        • bruceundefined
          bruce
          last edited by

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

          1 Reply Last reply Reply Quote 0
          • User3Dundefined
            User3D @OwenD
            last edited by

            @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...!!!!

            OwenDundefined 1 Reply Last reply Reply Quote 0
            • OwenDundefined
              OwenD @User3D
              last edited by

              @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.

              User3Dundefined 1 Reply Last reply Reply Quote 0
              • User3Dundefined
                User3D @OwenD
                last edited by

                @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
                • OwenDundefined
                  OwenD
                  last edited by OwenD

                  @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
                  
                  jelonealundefined 1 Reply Last reply Reply Quote 1
                  • jelonealundefined
                    jeloneal @OwenD
                    last edited by

                    @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.

                    psychotik2k3undefined 1 Reply Last reply Reply Quote 0
                    • psychotik2k3undefined
                      psychotik2k3 @jeloneal
                      last edited by

                      @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

                        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
                        • OwenDundefined OwenD referenced this topic
                        • danzaywerundefined
                          danzaywer @OwenD
                          last edited by

                          @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

                          OwenDundefined 1 Reply Last reply Reply Quote 0
                          • OwenDundefined
                            OwenD @danzaywer
                            last edited by

                            @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
                            
                            zaptaundefined 1 Reply Last reply Reply Quote 0
                            • zaptaundefined
                              zapta @OwenD
                              last edited by

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

                              OwenDundefined 1 Reply Last reply Reply Quote 0
                              • OwenDundefined
                                OwenD @zapta
                                last edited by OwenD

                                @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 Reply Quote 1
                                • Phaedruxundefined
                                  Phaedrux Moderator @OwenD
                                  last edited by

                                  @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

                                  OwenDundefined 1 Reply Last reply Reply Quote 0
                                  • OwenDundefined
                                    OwenD @Phaedrux
                                    last edited by

                                    @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.

                                    zaptaundefined 1 Reply Last reply Reply Quote 1
                                    • zaptaundefined
                                      zapta @OwenD
                                      last edited by zapta

                                      @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
                                      • OwenDundefined
                                        OwenD
                                        last edited by OwenD

                                        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
                                        • SACRED SERPENTundefined
                                          SACRED SERPENT
                                          last edited by

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

                                          OwenDundefined 1 Reply Last reply Reply Quote 0
                                          • OwenDundefined
                                            OwenD @SACRED SERPENT
                                            last edited by

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

                                            1 Reply Last reply Reply Quote 0
                                            • justGunerundefined justGuner referenced this topic
                                            • First post
                                              Last post
                                            Unless otherwise noted, all forum content is licensed under CC-BY-SA