Newer
Older
jeltz-klipper-config / config / macros.cfg
@Cory Tucker Cory Tucker 10 days ago 23 KB fix #1, fix #8, add in a QUERY_FILAMENT macro
  1. # gcode to run on printer start
  2. [delayed_gcode STARTUP]
  3. gcode:
  4. # grab saved variables
  5. {% set svv = printer.save_variables.variables %}
  6. {% set bed_leeway_temp = 5 %}
  7. {% set extruder_leeway_temp = 20 %}
  8. {% set hotend_filament = svv.hotend_filament %}
  9. # check if stored variables make sense, and set them to default values if not
  10. {% if not(svv.heater_mode == "auto" or svv.heater_mode == "manual" or svv.heater_mode == "slicer")%}
  11. { action_respond_info("setting heater_mode to AUTO, before: %s" % (svv.heater_mode)) }
  12. SAVE_VARIABLE VARIABLE=heater_mode VALUE='"auto"'
  13. {% endif %}
  14. # set temp variables - call variables macro
  15. VARIABLES
  16.  
  17. # kickstart fan control macro
  18. UPDATE_DELAYED_GCODE ID=FAN_CONTROL_LOOP DURATION=2
  19.  
  20. # check the current heater states and re enable heaters if able
  21. {% if svv.extruder_state == 'hot' %}
  22. {% if svv.extruder_temperature - extruder_leeway_temp <= printer.extruder.temperature %}
  23. { action_respond_info("re-enabling extruder after printer shutoff") }
  24. {% else %}
  25. { action_respond_info("extruder was enabled before last shutoff. State updated to cold.") }
  26. SAVE_VARIABLE VARIABLE=extruder_state VALUE='"cold"'
  27. {% endif %}
  28. {% endif %}
  29. {% if svv.bed_state == 'hot' %}
  30. {action_respond_info(printer.heater_bed.temperature|string)}
  31. {action_respond_info(bed_leeway_temp|string)}
  32. {action_respond_info(svv.bed_temperature|string)}
  33.  
  34. {% if svv.bed_temperature - bed_leeway_temp <= printer.heater_bed.temperature %}
  35. { action_respond_info("re-enabling bed after printer shutoff") }
  36. {% else %}
  37. { action_respond_info("bed was enabled before last shutoff. State updated to cold.") }
  38. SAVE_VARIABLE VARIABLE=bed_state VALUE='"cold"'
  39. {% endif %}
  40. {% endif %}
  41.  
  42. # check the filament load state:
  43. # exit-entry-bowden
  44. # 000 unloaded
  45. # 001 unloaded
  46. # 010 invalid
  47. # 011 unloaded
  48. # 100 runout
  49. # 101 invalid
  50. # 110 near_runout
  51. # 111 loaded
  52.  
  53. # store button vals
  54. {% set exit_sense = (printer["gcode_button extruder_exit"].state == "PRESSED") %}
  55. {% set entry_sense = (printer["gcode_button extruder_entry"].state == "PRESSED") %}
  56. {% set bowden_sense = (printer["gcode_button bowden_sensor"].state == "PRESSED") %}
  57.  
  58. # detect unloaded
  59. {% if not(entry_sense and exit_sense) or (not(entry_sense) and bowden_sense) %}
  60. {% if svv.filament_load_state != "unloaded" %}
  61. { action_respond_info("Current filament state does not match filament state on last boot. Was " ~ (svv.filament_load_state|string) ~ ", currently unloaded.") }
  62. {% endif %}
  63. SET_FILAMENT_LOAD_STATE STATE="unloaded"
  64. SET_FILAMENT_SENSOR SENSOR=bowden_encoder_sensor ENABLE=0
  65.  
  66. # loaded
  67. {% elif entry_sense and exit_sense and bowden_sense %}
  68. {% if svv.filament_load_state != "loaded" %}
  69. { action_respond_info("Current filament state does not match filament state on last boot. Was " ~ (svv.filament_load_state|string) ~ "") }
  70. {% endif %}
  71. SET_FILAMENT_LOAD_STATE STATE="loaded"
  72. SET_FILAMENT_SENSOR SENSOR=bowden_encoder_sensor ENABLE=1
  73.  
  74. # runout
  75. {% elif entry_sense and not(exit_sense) and not(bowden_sense) %}
  76. { action_respond_info("Current filament state is runout. Unable to print.") }
  77. SET_FILAMENT_SENSOR SENSOR=bowden_encoder_sensor ENABLE=0
  78.  
  79. # near_runout
  80. {% elif entry_sense and exit_sense and not(bowden_sense) %}
  81. { action_respond_info("Current filament state is runout. Unable to print.") }
  82. SET_FILAMENT_SENSOR SENSOR=bowden_encoder_sensor ENABLE=0
  83. {% endif %}
  84.  
  85. initial_duration: 2
  86.  
  87. [gcode_macro TEST]
  88. gcode:
  89. {% set svv = printer.save_variables.variables %}
  90. {break}
  91. {action_respond_info(svv.filaments|selectattr("name", "in", [svv.filament_hotend,
  92. svv.filament_extruder])|map(attribute="extruder",default='None')|max|string)}
  93.  
  94. ####### Calibration
  95. [gcode_macro calibrate_full]
  96. gcode:
  97. G28
  98. QUAD_GANTRY_LEVEL
  99. BED_MESH_CALIBRATE METHOD=rapid_scan
  100. SET_GCODE_VARIABLE MACRO=VARIABLES VARIABLE=mesh_bed_temp VALUE={printer['heater_bed'].temperature}
  101. G0 X239 Y210 F{700*60}
  102. [gcode_macro calibrate]
  103. gcode:
  104. {% set mesh_temp_leeway = printer["gcode_macro VARIABLES"].mesh_bed_temp_leeway %}
  105. {% set mesh_temp = printer["gcode_macro VARIABLES"].mesh_bed_temp %}
  106. {% set skip_mesh = params.SKIP_MESH|default(False)%}
  107. {% if "xyz" not in printer['toolhead'].homed_axes %}
  108. G28
  109. {% endif %}
  110. {% if not printer['quad_gantry_level'].applied %}
  111. QUAD_GANTRY_LEVEL
  112. {% endif %}
  113.  
  114. {action_respond_info((not printer['bed_mesh'].profile_name)|string)}
  115. {% if skip_mesh %}
  116. G0 X239 Y210 F{700*60}
  117. # if a bed mesh has not been performed, or the temperature hasn't changed by more than 15 degrees.
  118. {% elif ((not printer['bed_mesh'].profile_name) or
  119. (printer['heater_bed'].temperature <= mesh_temp - mesh_temp_leeway) or
  120. (printer['heater_bed'].temperature >= mesh_temp + mesh_temp_leeway)) %}
  121. G0 X15 Y22 F{700*60}
  122. BED_MESH_CALIBRATE METHOD=rapid_scan
  123. SET_GCODE_VARIABLE MACRO=VARIABLES VARIABLE=mesh_bed_temp VALUE={printer['heater_bed'].temperature}
  124.  
  125. G0 X239 Y210 F{700*60}
  126. {% endif %}
  127. [gcode_macro calibrate_override]
  128. gcode:
  129.  
  130. ####### PRINT START AND STOP ETC
  131. [gcode_macro START_PRINT]
  132. description: Runs before the start of a print. Checks print readyness, corrects if nessesary, and primes the nozzle.
  133. gcode:
  134. {% set svv = printer.save_variables.variables %}
  135. # check the state of the loaded filament
  136. {% if svv.filament_state in ["loaded", "primed"] and svv.filament_runout_state != "runout" %}
  137. # if in auto, set bed and extruder to loaded filament parameters.
  138. {% if svv.heater_mode == "auto" %}
  139. #SET_BED_TO_FILAMENT
  140. #SET_HOTEND_TO_FILAMENT POSITION=both
  141. # if in slicer or manual mode, quickly sanity check the set temperatures:
  142. {% else %}
  143. {% if printer['extruder'].target != 0 %}
  144. {action_raise_error("Extruder temperature is set to at or below zero")}
  145. {% endif %}
  146. {% endif %}
  147.  
  148. # check calibration
  149. CALIBRATE SKIP_MESH=True
  150. # enable the encoder filament sensor
  151. SET_FILAMENT_SENSOR SENSOR=bowden_encoder_sensor ENABLE=1
  152. {% if svv.filament_extruder == svv.filament_hotend %}
  153. PRIME_FILAMENT
  154. {% else %}
  155. PURGE_FILAMENT
  156. {% endif %}
  157. {% elif svv.filament_runout_state == "runout" %}
  158. {action_raise_error("Error, filament in runout state")}
  159.  
  160. {% else %}
  161. {action_raise_error("Error, filament not loaded. Filament is %s" %(svv.filament_state))}
  162. {% endif %}
  163.  
  164. # final enable of heaters and wait for temperature to be reached
  165. SET_HEATERS_TO_FILAMENT_AND_WAIT
  166.  
  167. [gcode_macro stop_print]
  168. gcode:
  169. {% set z = params.Z|default(50)|int %} ; z hop amount
  170.  
  171. SET_FILAMENT_SENSOR SENSOR=bowden_encoder_sensor ENABLE=0
  172.  
  173. # reduce temperature of extruder by 10c to reduce oozing
  174. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={printer['extruder'].target - 10} MODE=auto
  175. {% if (printer.gcode_move.position.z + z) < printer.toolhead.axis_maximum.z %} ; check that zhop doesn't exceed z max
  176. G91 ; relative positioning
  177. G1 Z{z} F900 ; raise Z up by z hop amount
  178. {% else %}
  179. G0 Z{printer.toolhead.axis_maximum.z}
  180. { action_respond_info("Pause zhop exceeds maximum Z height.") }
  181. {% endif %}
  182. G90 ; absolute positioning
  183. G1 Y{258} F6000 ; park toolhead
  184.  
  185.  
  186. [gcode_macro PAUSE]
  187. description: Pause the actual running print
  188. rename_existing: PAUSE_MAINSAIL
  189. gcode:
  190. # Parameters
  191. {% set z = params.Z|default(10)|int %} ; z hop amount
  192. #{% set idle_timeout = client.idle_timeout|default({60*5}) %}
  193. {% set idle_timeout = 60*5 %}
  194. # if printer is not already paused...
  195. {% if printer['pause_resume'].is_paused|int == 0 %}
  196. # set variables for reference in resume macro
  197. SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=posx VALUE={printer['gcode_move'].gcode_position.x}
  198. SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=posy VALUE={printer['gcode_move'].gcode_position.y}
  199. SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=posz VALUE={printer['gcode_move'].gcode_position.z}
  200.  
  201. SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=etemp VALUE={printer['extruder'].target}
  202. SET_GCODE_VARIABLE MACRO=RESUME VARIABLE=btemp VALUE={printer['heater_bed'].target}
  203. SAVE_GCODE_STATE NAME=PAUSE
  204.  
  205. # set a new idle_timeout value
  206. SET_IDLE_TIMEOUT TIMEOUT={idle_timeout}
  207. # {client.user_pause_macro|default("")}
  208.  
  209. # reduce temperature of extruder by 10c to reduce oozing
  210. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={printer['extruder'].target - 10} MODE=auto
  211. {% if (printer.gcode_move.position.z + z) < printer.toolhead.axis_maximum.z %} ; check that zhop doesn't exceed z max
  212. G91 ; relative positioning
  213. G1 Z{z} F900 ; raise Z up by z hop amount
  214. {% else %}
  215. G0 Z{printer.toolhead.axis_maximum.z}
  216. { action_respond_info("Pause zhop exceeds maximum Z height.") }
  217. {% endif %}
  218. G90 ; absolute positioning
  219. G1 Y{258} F6000 ; park toolhead
  220. SAVE_GCODE_STATE NAME=PAUSEPARK ; save parked position in case toolhead is moved during the pause (otherwise the return zhop can error)
  221. {% endif %}
  222. [gcode_macro RESUME]
  223. description: Resume the actual running print
  224. rename_existing: RESUME_MAINSAIL
  225. variable_posx: 0
  226. variable_posy: 0
  227. variable_posz: 0
  228. variable_zhop: 0
  229. variable_etemp: 0
  230. variable_btemp: 0
  231. gcode:
  232. # Parameters
  233. {% set e = params.E|default(2.5)|int %} ; hotend prime amount (in mm)
  234. {% set client = printer['gcode_macro _CLIENT_VARIABLE']|default({}) %}
  235. {% set velocity = printer.configfile.settings.pause_resume.recover_velocity %}
  236. {% set sp_move = client.speed_move|default(velocity) %}
  237. {% set runout_resume = True if client.runout_sensor|default("") == "" # no runout
  238. else True if not printer[client.runout_sensor].enabled # sensor is disabled
  239. else printer[client.runout_sensor].filament_detected %} # sensor status
  240. {% set can_extrude = True if printer.toolhead.extruder == '' # no extruder defined in config
  241. else printer[printer.toolhead.extruder].can_extrude %} # status of active extruder
  242. {% set do_resume = False %}
  243. {% set prompt_txt = [] %}
  244.  
  245. # if printer is paused...
  246. {% if printer['pause_resume'].is_paused|int == 1 %}
  247. SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; set timeout back to configured value
  248.  
  249. RESTORE_GCODE_STATE NAME=PAUSEPARK MOVE=1 MOVE_SPEED=200 ; go back to parked position in case toolhead was moved during pause (otherwise the return zhop can error)
  250.  
  251. # reset temperatures
  252. {% if etemp > 0 %}
  253. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={etemp} MODE=auto
  254. {% endif %}
  255. {% if btemp > 0 %}
  256. SET_HEATER_TEMPERATURE_AND_WAIT HEATER=heater_bed TARGET={btemp} MODE=auto
  257. {% endif %}
  258. {% if etemp > 0 %}
  259. SET_HEATER_TEMPERATURE_AND_WAIT HEATER=extruder TARGET={etemp} MODE=auto ; Wait for hotend temp
  260. {% endif %}
  261. G91 ; relative positioning
  262. M83 ; relative extruder positioning
  263. {% if printer[printer.toolhead.extruder].temperature >= printer.configfile.settings.extruder.min_extrude_temp %}
  264. G1 Z{zhop * -1} E{e} F900 ; prime nozzle by E, lower Z back down
  265. {% else %}
  266. G1 Z{zhop * -1} F900 ; lower Z back down without priming (just in case we are testing the macro with cold hotend)
  267. {% endif %}
  268. RESTORE_GCODE_STATE NAME=PAUSE MOVE=1 MOVE_SPEED=60 ; restore position
  269. {% endif %}
  270.  
  271. [gcode_macro CANCEL_PRINT]
  272. rename_existing: CANCEL_PRINT_MAINSAIL
  273. gcode:
  274. {% set z = params.Z|default(10)|int %} ; z hop amount
  275.  
  276. SET_IDLE_TIMEOUT TIMEOUT={printer.configfile.settings.idle_timeout.timeout} ; set timeout back to configured value
  277. CLEAR_PAUSE
  278. PRINT_END
  279. # reduce temperature of extruder by 10c to reduce oozing
  280. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={printer['extruder'].target - 10} MODE=auto
  281. {% if (printer.gcode_move.position.z + z) < printer.toolhead.axis_maximum.z %} ; check that zhop doesn't exceed z max
  282. G91 ; relative positioning
  283. G1 Z{z} F900 ; raise Z up by z hop amount
  284. {% else %}
  285. G0 Z{printer.toolhead.axis_maximum.z}
  286. { action_respond_info("Pause zhop exceeds maximum Z height.") }
  287. {% endif %}
  288. G90 ; absolute positioning
  289. G1 Y{258} F6000 ; park toolhead
  290. # clear pause_next_layer and pause_at_layer as preparation for next print
  291. SET_PAUSE_NEXT_LAYER ENABLE=0
  292. SET_PAUSE_AT_LAYER ENABLE=0 LAYER=0
  293.  
  294. ###### HEATER AUTO HANDLING
  295. [gcode_macro SET_HEATERS_TO_FILAMENT_AND_WAIT]
  296. description:
  297. gcode:
  298. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={svv.filaments|selectattr("name", "equalto", svv.filament_hotend)|map(attribute="extruder",default='None')|first|string} MODE=auto
  299. SET_HEATER_TEMPERATURE_AND_WAIT HEATER=heater_bed TARGET={svv.filaments|selectattr("name", "equalto", svv.filament_hotend)|map(attribute="bed",default='None')|first|string} MODE=auto
  300. SET_HEATER_TEMPERATURE_AND_WAIT HEATER=extruder TARGET={svv.filaments|selectattr("name", "equalto", svv.filament_hotend)|map(attribute="extruder",default='None')|first|string} MODE=auto
  301.  
  302. [gcode_macro SET_HOTEND_TO_FILAMENT]
  303. description: sets the temperature of the hotend to the temperature required by the stored filament
  304. gcode:
  305. {% set position = params.POSITION|default('extruder')|string|lower %}
  306. {% if position == 'extruder' %}
  307. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={svv.filaments|selectattr("name", "in", [svv.filament_extruder])|map(attribute="extruder",default='None')|max|string} MODE=auto
  308. {% elif position == 'hotend' %}
  309. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={svv.filaments|selectattr("name", "in", [svv.filament_hotend])|map(attribute="extruder",default='None')|max|string} MODE=auto
  310. {% elif position == 'both' %}
  311. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={svv.filaments|selectattr("name", "in", [svv.filament_hotend, svv.filament_extruder])|map(attribute="extruder",default='None')|max|string} MODE=auto
  312. {% endif %}
  313. [gcode_macro SET_BED_TO_FILAMENT]
  314. description: sets the temperature of the bed to the temperature required by the stored filament
  315. gcode:
  316. {% set position = params.POSITION|default('extruder')|string|lower %}
  317. {% if position == 'extruder' %}
  318. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={svv.filaments|selectattr("name", "in", [svv.filament_extruder])|map(attribute="bed",default='None')|max|string} MODE=auto
  319. {% elif position == 'hotend' %}
  320. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={svv.filaments|selectattr("name", "in", [svv.filament_hotend])|map(attribute="bed",default='None')|max|string} MODE=auto
  321. {% elif position == 'both' %}
  322. SET_HEATER_TEMPERATURE HEATER=extruder TARGET={svv.filaments|selectattr("name", "in", [svv.filament_hotend, svv.filament_extruder])|map(attribute="bed",default='None')|max|string} MODE=auto
  323. {% endif %}
  324.  
  325. ## MISC MACROS
  326.  
  327. [gcode_macro DUMP_VARIABLES]
  328. gcode:
  329. {% set filter_name = params.NAME|default('')|string|lower %}
  330. {% set filter_value = params.VALUE|default('')|string|lower %}
  331. {% set show_cfg = params.SHOW_CFG|default(0)|int %}
  332. {% set out = [] %}
  333.  
  334. {% for key1 in printer %}
  335. {% for key2 in printer[key1] %}
  336. {% if (show_cfg or not (key1|lower == 'configfile' and key2|lower in ['config', 'settings'])) and (filter_name in key1|lower or filter_name in key2|lower) and filter_value in printer[key1][key2]|string|lower %}
  337. {% set dummy = out.append("printer['%s'].%s = %s" % (key1, key2, printer[key1][key2])) %}
  338. {% endif %}
  339. {% else %}
  340. {% if filter_name in key1|lower and filter_value in printer[key1]|string|lower %}
  341. {% set dummy = out.append("printer['%s'] = %s" % (key1, printer[key1])) %}
  342. {% endif %}
  343. {% endfor %}
  344. {% endfor %}
  345. {action_respond_info(out|join("\n"))}
  346.  
  347. [gcode_macro TEST_SPEED]
  348. # Home, get position, throw around toolhead, home again.
  349. # If MCU stepper positions (first line in GET_POSITION) are greater than a full step different (your number of microsteps), then skipping occured.
  350. # We only measure to a full step to accomodate for endstop variance.
  351. # Example: TEST_SPEED SPEED=300 ACCEL=5000 ITERATIONS=10
  352.  
  353. description: Test for max speed and acceleration parameters for the printer. Procedure: Home -> ReadPositionFromMCU -> MovesToolhead@Vel&Accel -> Home -> ReadPositionfromMCU
  354.  
  355. gcode:
  356. # Speed
  357. {% set speed = params.SPEED|default(printer.configfile.settings.printer.max_velocity)|int %}
  358. # Iterations
  359. {% set iterations = params.ITERATIONS|default(5)|int %}
  360. # Acceleration
  361. {% set accel = params.ACCEL|default(printer.configfile.settings.printer.max_accel)|int %}
  362. # Minimum Cruise Ratio
  363. {% set min_cruise_ratio = params.MIN_CRUISE_RATIO|default(0.5)|float %}
  364. # Bounding inset for large pattern (helps prevent slamming the toolhead into the sides after small skips, and helps to account for machines with imperfectly set dimensions)
  365. {% set bound = params.BOUND|default(20)|int %}
  366. # Size for small pattern box
  367. {% set smallpatternsize = SMALLPATTERNSIZE|default(20)|int %}
  368. # Large pattern
  369. # Max positions, inset by BOUND
  370. {% set x_min = printer.toolhead.axis_minimum.x %}
  371. {% if x_min < 0 %}
  372. {% set x_min = 0 %}
  373. {% endif %}
  374. {% set y_min = printer.toolhead.axis_minimum.y %}
  375. {% if y_min < 0 %}
  376. {% set y_min = 0 %}
  377. {% endif %}
  378. {% set x_min = x_min + bound %}
  379. {% set x_max = printer.toolhead.axis_maximum.x - bound %}
  380. {% set y_min = y_min + bound %}
  381. {% set y_max = printer.toolhead.axis_maximum.y - bound %}
  382. # Small pattern at center
  383. # Find X/Y center point
  384. {% set x_center = (printer.toolhead.axis_minimum.x|float + printer.toolhead.axis_maximum.x|float ) / 2 %}
  385. {% set y_center = (printer.toolhead.axis_minimum.y|float + printer.toolhead.axis_maximum.y|float ) / 2 %}
  386. # Set small pattern box around center point
  387. {% set x_center_min = x_center - (smallpatternsize/2) %}
  388. {% set x_center_max = x_center + (smallpatternsize/2) %}
  389. {% set y_center_min = y_center - (smallpatternsize/2) %}
  390. {% set y_center_max = y_center + (smallpatternsize/2) %}
  391.  
  392. # Save current gcode state (absolute/relative, etc)
  393. SAVE_GCODE_STATE NAME=TEST_SPEED
  394. # Output parameters to g-code terminal
  395. { action_respond_info("TEST_SPEED: starting %d iterations at speed %d, accel %d" % (iterations, speed, accel)) }
  396. # Home and get position for comparison later:
  397. M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
  398. # QGL if not already QGLd (only if QGL section exists in config)
  399. {% if printer.configfile.settings.quad_gantry_level %}
  400. {% if printer.quad_gantry_level.applied == False %}
  401. G28
  402. QUAD_GANTRY_LEVEL
  403. G28 Z
  404. {% endif %}
  405. {% endif %}
  406. # Move 50mm away from max position and home again (to help with hall effect endstop accuracy - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/24)
  407. G90
  408. G1 X{printer.toolhead.axis_maximum.x-50} Y{printer.toolhead.axis_maximum.y-50} F{100*60}
  409. M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
  410. G28 X Y
  411. G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{100*60}
  412. G4 P1000
  413. GET_POSITION
  414.  
  415. # Go to starting position
  416. G0 X{x_min} Y{y_min} Z{bound + 10} F{speed*60}
  417.  
  418. # Set new limits
  419. {% if printer.configfile.settings.printer.minimum_cruise_ratio is defined %}
  420. SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} MINIMUM_CRUISE_RATIO={min_cruise_ratio}
  421. {% else %}
  422. SET_VELOCITY_LIMIT VELOCITY={speed} ACCEL={accel} ACCEL_TO_DECEL={accel / 2}
  423. {% endif %}
  424.  
  425. {% for i in range(iterations) %}
  426. # Large pattern diagonals
  427. G0 X{x_min} Y{y_min} F{speed*60}
  428. G0 X{x_max} Y{y_max} F{speed*60}
  429. G0 X{x_min} Y{y_min} F{speed*60}
  430. G0 X{x_max} Y{y_min} F{speed*60}
  431. G0 X{x_min} Y{y_max} F{speed*60}
  432. G0 X{x_max} Y{y_min} F{speed*60}
  433. # Large pattern box
  434. G0 X{x_min} Y{y_min} F{speed*60}
  435. G0 X{x_min} Y{y_max} F{speed*60}
  436. G0 X{x_max} Y{y_max} F{speed*60}
  437. G0 X{x_max} Y{y_min} F{speed*60}
  438. # Small pattern diagonals
  439. G0 X{x_center_min} Y{y_center_min} F{speed*60}
  440. G0 X{x_center_max} Y{y_center_max} F{speed*60}
  441. G0 X{x_center_min} Y{y_center_min} F{speed*60}
  442. G0 X{x_center_max} Y{y_center_min} F{speed*60}
  443. G0 X{x_center_min} Y{y_center_max} F{speed*60}
  444. G0 X{x_center_max} Y{y_center_min} F{speed*60}
  445. # Small pattern box
  446. G0 X{x_center_min} Y{y_center_min} F{speed*60}
  447. G0 X{x_center_min} Y{y_center_max} F{speed*60}
  448. G0 X{x_center_max} Y{y_center_max} F{speed*60}
  449. G0 X{x_center_max} Y{y_center_min} F{speed*60}
  450. {% endfor %}
  451.  
  452. # Restore max speed/accel/accel_to_decel to their configured values
  453. {% if printer.configfile.settings.printer.minimum_cruise_ratio is defined %}
  454. SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} MINIMUM_CRUISE_RATIO={printer.configfile.settings.printer.minimum_cruise_ratio}
  455. {% else %}
  456. SET_VELOCITY_LIMIT VELOCITY={printer.configfile.settings.printer.max_velocity} ACCEL={printer.configfile.settings.printer.max_accel} ACCEL_TO_DECEL={printer.configfile.settings.printer.max_accel_to_decel}
  457. {% endif %}
  458.  
  459. # Re-home and get position again for comparison:
  460. M400 # Finish moves - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/66
  461. # G28 # This is a full G28 to fix an issue with CoreXZ - https://github.com/AndrewEllis93/Print-Tuning-Guide/issues/12
  462. # Go to XY home positions (in case your homing override leaves it elsewhere)
  463. G90motors
  464. G0 X{printer.toolhead.axis_maximum.x-1} Y{printer.toolhead.axis_maximum.y-1} F{100*60}
  465. G4 P1000
  466. GET_POSITION
  467.  
  468. # Restore previous gcode state (absolute/relative, etc)
  469. RESTORE_GCODE_STATE NAME=TEST_SPEED