配置信息
[probe]
pin: ! PD4
x_offset: 0
y_offset: 0
z_offset: - 0. 20
speed: 10
samples: 2
samples_result: average
sample_retract_dist: 5
samples_tolerance: 0. 05
samples_tolerance_retries: 5
入口
def load_config ( config) : return PrinterProbe( config, ProbeEndstopWrapper( config) )
初始化
class PrinterProbe : def __init__ ( self, config, mcu_probe) : self. printer = config. get_printer( ) self. name = config. get_name( ) self. mcu_probe = mcu_probeself. speed = config. getfloat( 'speed' , 5.0 , above= 0. ) self. lift_speed = config. getfloat( 'lift_speed' , self. speed, above= 0. ) self. x_offset = config. getfloat( 'x_offset' , 0. ) self. y_offset = config. getfloat( 'y_offset' , 0. ) self. z_offset = config. getfloat( 'z_offset' ) self. probe_calibrate_z = 0. self. multi_probe_pending = False self. last_state = False self. last_z_result = 0. self. gcode_move = self. printer. load_object( config, "gcode_move" ) if config. has_section( 'stepper_z' ) : zconfig = config. getsection( 'stepper_z' ) self. z_position = zconfig. getfloat( 'position_min' , 0. , note_valid= False ) else : pconfig = config. getsection( 'printer' ) self. z_position = pconfig. getfloat( 'minimum_z_position' , 0. , note_valid= False ) self. sample_count = config. getint( 'samples' , 1 , minval= 1 ) self. sample_retract_dist = config. getfloat( 'sample_retract_dist' , 2. , above= 0. ) atypes = { 'median' : 'median' , 'average' : 'average' } self. samples_result = config. getchoice( 'samples_result' , atypes, 'average' ) self. samples_tolerance = config. getfloat( 'samples_tolerance' , 0.100 , minval= 0. ) self. samples_retries = config. getint( 'samples_tolerance_retries' , 0 , minval= 0 ) self. printer. lookup_object( 'pins' ) . register_chip( 'probe' , self) self. printer. register_event_handler( "homing:homing_move_begin" , self. _handle_homing_move_begin) self. printer. register_event_handler( "homing:homing_move_end" , self. _handle_homing_move_end) self. printer. register_event_handler( "homing:home_rails_begin" , self. _handle_home_rails_begin) self. printer. register_event_handler( "homing:home_rails_end" , self. _handle_home_rails_end) self. printer. register_event_handler( "gcode:command_error" , self. _handle_command_error) self. gcode = self. printer. lookup_object( 'gcode' ) self. gcode. register_command( 'PROBE' , self. cmd_PROBE, desc= self. cmd_PROBE_help) self. gcode. register_command( 'QUERY_PROBE' , self. cmd_QUERY_PROBE, desc= self. cmd_QUERY_PROBE_help) self. gcode. register_command( 'PROBE_CALIBRATE' , self. cmd_PROBE_CALIBRATE, desc= self. cmd_PROBE_CALIBRATE_help) self. gcode. register_command( 'PROBE_ACCURACY' , self. cmd_PROBE_ACCURACY, desc= self. cmd_PROBE_ACCURACY_help) self. gcode. register_command( 'Z_OFFSET_APPLY_PROBE' , self. cmd_Z_OFFSET_APPLY_PROBE, desc= self. cmd_Z_OFFSET_APPLY_PROBE_help)
初始化打印機對象和探針參數 :
self.printer
:通過 config.get_printer()
獲取打印機對象。self.name
:通過 config.get_name()
獲取探針名稱。self.mcu_probe
:保存傳入的 MCU 探針對象。速度設置:speed
、lift_speed
、x_offset
、y_offset
、z_offset
和 probe_calibrate_z
等控制探針的移動速度和偏移。
推斷探針的 Z 軸位置 :
根據配置文件,確定探針在探測過程中的 Z 軸移動位置。 如果配置中有 stepper_z
段,使用其中 position_min
定義的 Z 軸最小位置。 否則,從 printer
配置的 minimum_z_position
獲取 Z 軸最小位置。配置里minimum_z_position: -5
多重采樣設置(提高測量精度) :
sample_count
:設定采樣次數,以便進行多次測量來提高精度。sample_retract_dist
:設定每次采樣后探針提升的距離。samples_result
:采樣結果的處理方式,可以選擇 ‘median’(中位數)或 ‘average’(平均值)。samples_tolerance
和 samples_retries
:設定采樣的誤差容忍度和重試次數,用于提高多重采樣的穩定性。
注冊探針的 Z 虛擬端點 :
使用 self.printer.lookup_object('pins').register_chip('probe', self)
將探針注冊為 Z 虛擬端點,使其在打印機控制系統中可以作為端點來使用。
注冊歸位事件處理器 :
homing
相關事件處理器會在歸位過程的不同階段觸發,分別在歸位移動開始和結束時執行 _handle_homing_move_begin
和 _handle_homing_move_end
,在歸位軌道的開始和結束時執行 _handle_home_rails_begin
和 _handle_home_rails_end
。如果在 GCode 命令中遇到錯誤,則會觸發 _handle_command_error
。
注冊 GCode 命令 :
PROBE
:觸發一次探針操作。QUERY_PROBE
:查詢探針狀態。PROBE_CALIBRATE
:校準探針的 Z 軸偏移。PROBE_ACCURACY
:測量探針的精度。Z_OFFSET_APPLY_PROBE
:將當前 Z 軸偏移應用到探針。
class ProbeEndstopWrapper : def __init__ ( self, config) : self. printer = config. get_printer( ) self. position_endstop = config. getfloat( 'z_offset' ) self. stow_on_each_sample = config. getboolean( 'deactivate_on_each_sample' , True ) gcode_macro = self. printer. load_object( config, 'gcode_macro' ) self. activate_gcode = gcode_macro. load_template( config, 'activate_gcode' , '' ) self. deactivate_gcode = gcode_macro. load_template( config, 'deactivate_gcode' , '' ) ppins = self. printer. lookup_object( 'pins' ) pin = config. get( 'pin' ) pin_params = ppins. lookup_pin( pin, can_invert= True , can_pullup= True ) mcu = pin_params[ 'chip' ] self. mcu_endstop = mcu. setup_pin( 'endstop' , pin_params) self. printer. register_event_handler( 'klippy:mcu_identify' , self. _handle_mcu_identify) self. get_mcu = self. mcu_endstop. get_mcuself. add_stepper = self. mcu_endstop. add_stepperself. get_steppers = self. mcu_endstop. get_steppersself. home_start = self. mcu_endstop. home_startself. home_wait = self. mcu_endstop. home_waitself. query_endstop = self. mcu_endstop. query_endstopself. multi = 'OFF'
初始化打印機對象和配置參數 :
self.printer
使用 config.get_printer()
獲取打印機對象。self.position_endstop
設定了 z_offset
(Z 軸端點偏移量),用于定義探針的初始位置或偏移。self.stow_on_each_sample
用于配置探針是否在每次采樣后停放,默認為 True
。
加載 GCode 宏 :
使用 gcode_macro
對象從配置中加載探針激活和停用的 GCode 模板:
activate_gcode
:在探針激活時執行的 GCode。deactivate_gcode
:在探針停用時執行的 GCode。
創建端點對象 :
使用 pins
對象(通過 self.printer.lookup_object('pins')
獲得)查找探針的 pin
(引腳)配置。 通過 lookup_pin()
配置引腳參數,包括是否可以反轉或上拉電阻,隨后得到引腳參數 pin_params
。 使用引腳所在的 mcu
芯片設置一個 endstop
引腳對象 mcu_endstop
,負責處理探針狀態。
注冊事件處理程序 :
注冊事件 klippy:mcu_identify
,當觸發該事件時調用 _handle_mcu_identify
方法。這個方法通常用于在初始化或連接時對探針或端點進行識別和確認。
簡化調用的包裝函數 :
定義一些包裝函數用于直接調用 mcu_endstop
對象的相關方法,包括:
get_mcu
:獲取探針所在的 MCU 對象。add_stepper
:將步進電機添加到探針控制中。get_steppers
:獲取當前與探針關聯的步進電機。home_start
和 home_wait
:用于控制探針的歸位和等待狀態。query_endstop
:查詢端點的當前狀態(是否被觸發)。
多重探針狀態 :
定義 self.multi
,表示多重探針采樣狀態,默認為 'OFF'
。
class ProbePointsHelper : def __init__ ( self, config, finalize_callback, default_points= None ) : self. printer = config. get_printer( ) self. finalize_callback = finalize_callbackself. probe_points = default_pointsself. name = config. get_name( ) self. gcode = self. printer. lookup_object( 'gcode' ) if default_points is None or config. get( 'points' , None ) is not None : self. probe_points = config. getlists( 'points' , seps= ( ',' , '\n' ) , parser= float , count= 2 ) self. horizontal_move_z = config. getfloat( 'horizontal_move_z' , 5. ) self. speed = config. getfloat( 'speed' , 50. , above= 0. ) self. use_offsets = False self. lift_speed = self. speedself. probe_offsets = ( 0. , 0. , 0. ) self. results = [ ]
該對象會在 bed_mesh 和 delta_calibrate 模塊加載時進行初始化,并傳入回調函數和探測點points等信息。
探測判斷
ProbePointsHelper. start_probe ( probe. py) - > ProbePointsHelper. _move_next ( probe. py) - >
DeltaCalibrate. probe_finalize ( delta_calibrate. py)
ProbePointsHelper. start_probe ( probe. py) - > ProbePointsHelper. _move_next ( probe. py) - >
BedMeshCalibrate. probe_finalize ( bed_mesh. py)
探測是否結束代碼邏輯
def _move_next ( self) : toolhead = self. printer. lookup_object( 'toolhead' ) speed = self. lift_speedif not self. results: speed = self. speedtoolhead. manual_move( [ None , None , self. horizontal_move_z] , speed) if len ( self. results) >= len ( self. probe_points) : toolhead. get_last_move_time( ) res = self. finalize_callback( self. probe_offsets, self. results) if res != "retry" : return True self. results = [ ] nextpos = list ( self. probe_points[ len ( self. results) ] ) if self. use_offsets: nextpos[ 0 ] -= self. probe_offsets[ 0 ] nextpos[ 1 ] -= self. probe_offsets[ 1 ] toolhead. manual_move( nextpos, self. speed) return False
提升探針或工具頭
通過調用 toolhead.manual_move
,將探針或工具頭移動到指定的高度 self.horizontal_move_z
。 如果這是第一次探測(self.results
為空),會使用較快的初始速度(self.speed
)。否則使用探針提升速度(self.lift_speed
)。
檢查探測是否完成
檢查已完成探測點的數量是否達到預定的探測點總數(len(self.probe_points)
)。 如果所有點都探測完成:
調用 toolhead.get_last_move_time()
記錄最后的移動時間。 執行 self.finalize_callback
,處理探測結果(如計算網格調整數據等)。
處理探測結果
finalize_callback
返回值決定后續操作:如果返回值不是 "retry"
,探測結束,方法返回 True
。 如果返回值為 "retry"
,表示需要重新探測,清空結果 self.results
并從頭開始。
移動到下一個探測點
確定下一個探測點的坐標:
從 self.probe_points
列表中取出對應位置的點。 如果啟用了偏移(self.use_offsets
),會調整 X、Y 坐標以考慮探針的實際偏移量。
將探針移動到下一個點,準備進行探測。
返回繼續探測
方法返回 False
,表示探測未完成,需要繼續執行探測流程。